Flash size constraints

Hi,

I am working with nRF52833 DK with nRF Connect SDK. All was going great until I had to add a GNU GSL library. I need it because I need matrix multiplications with complex numbers and eigen decomposition of matrices. When I added the the library code size exceeded FLASH size for 10 KB with linker error: arm-none-eabi/bin/ld.bfd: zephyr/zephyr_prebuilt.elf section `rodata' will not fit in region `FLASH'; arm-none-eabi/bin/ld.bfd: region `FLASH' overflowed by 10800 bytes.

So I started throwing code out that was not necessary (like printk), I minimized string constants of necessary printk statements, I used function for repeating code and used smaller data types (float instead of double and uint8_t instead of uint32_t). I managed to save 2.7 KB of code. But that is not enough. But I managed to get the code working with just excluding one of GSL functions that is less necessary. That gave me motivation so I took closer look at generated code.

 I checked the generated zephyr.map file to see which functions take most of the space. I saw that some GNU GSL functions that I was clearly not using (and I am pretty sure that functions that I used do not use them) were compiled too. Like the ones in the provided screenshot. Functions like matrix multiplications for all possible types of matrices were included and I just used one of them. Including all this functions in the build is clearly why my code size exceeds FLASH size. I also included output of ninja rom report.

 ninja_rom_report.txt

Is this because I cross-copiled GNU GSL library beforehand and I just included it in CMake build process or I just included library wrong in CMake build process? How can I get rid of these extra functions that eat my FLASH size? I cross-copiled GNU GSL library with command: ./configure --prefix=$HOME/opt/GNU_GSL_ARM_COMPILED --build=x86_64-unknown-linux-gnu --host=arm-none-eabi --target=arm-none-eabi CFLAGS="--specs=nosys.specs -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16". Below is included CMakeLists.txt file for how I included library in CMake process. Library is positioned in project_dir/src/gnu_gsl directory.

#
# Copyright (c) 2021 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.13.1)

set(GNU_GSL_LIB_DIR  ${CMAKE_CURRENT_SOURCE_DIR}/src/gnu_gsl)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/gnu_gsl/include)
#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/gnu_gsl/include)




find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})

project(direction_finding_connectionless_rx)

target_sources(app PRIVATE
  src/main.c
)

add_library(gnu_gsl_lib STATIC IMPORTED GLOBAL)
set_target_properties(gnu_gsl_lib PROPERTIES IMPORTED_LOCATION ${GNU_GSL_LIB_DIR}/lib/libgsl.a)
target_link_libraries(app PUBLIC gnu_gsl_lib)


add_library(gnu_gslcblas_lib STATIC IMPORTED GLOBAL)
set_target_properties(gnu_gslcblas_lib PROPERTIES IMPORTED_LOCATION ${GNU_GSL_LIB_DIR}/lib/libgslcblas.a)
target_link_libraries(app PUBLIC gnu_gslcblas_lib)





Do you know any other tricks for code optimization for smaller size? I looked for -O optimization parameter of compiler but I do not know how to include it in CMake build process.

Can FLASH size be optimized with excluding some code? I tracked that someones are excluding bootloader for example. I searched for linker files but nRF Connect SKD works differently so I looked at dts files of board but I could not find any information on where different code sections are stored in FLASH.

I know that writing code for nearly full FLASH size is bad idea for future use but I currently do not have access to for example nRF5340 with bigger FLASH size. Also I think that with including just necessary functions from GNU GSL library my code size would be greatly reduced.

Any help would be appreciated.

Ales

Parents
  • Hi Ales

    -O is enabled by default, so you don't have to do anything in order to set this parameter. 

    I assume you have checked that there are no alternative libraries that could do the job, such as this one, or this one?

    Can you let me know what the flash usage of the GNU GSL library alone is, when you build the code?

    Maybe you can share the .map file with me?

    Best regards
    Torbjørn

  • Hi,

    first of all thanks for suggestions.

    1.

    -O is enabled by default, so you don't have to do anything in order to set this parameter. 

     As I know -O can have number of possible optimization. -Os is suppose to be optimize for size. Can I include this one? Or is it possible to remove debug information to reduce size?

    2. 

    I assume you have checked that there are no alternative libraries that could do the job, such as this one, or this one?

      -  (first link) as I know a uC with DSP is needed which nRF52833 does not support.

      -  (second link) I looked at zscilib but it does not support multiplications on matrices with complex values (only real)

    3.

    Can you let me know what the flash usage of the GNU GSL library alone is, when you build the code?

    Can you please tell me where can I check that?

    4.

    Maybe you can share the .map file with me?

    1464.zephyr.map

  • Hi Ales

    Ales said:
     As I know -O can have number of possible optimization. -Os is suppose to be optimize for size. Can I include this one? Or is it possible to remove debug information to reduce size?

    You could try to set CONFIG_SIZE_OPTIMIZATIONS in your project configuration, as described here.

    This should ensure that the optimization is set for size. 

    Ales said:
    Can you please tell me where can I check that?

    I think the easiest way is to check the build output before you enable the GLS library, and then check it again after. 

    When you have built a project you should see a report of the total RAM and flash consumption, similar to this:

    [9/9] Linking C executable zephyr\zephyr.elf
    Memory region         Used Size  Region Size  %age Used
               FLASH:      197400 B         1 MB     18.83%
                SRAM:       46605 B       256 KB     17.78%
            IDT_LIST:          0 GB         2 KB      0.00%

    Best regards
    Torbjørn

  • You could try to set CONFIG_SIZE_OPTIMIZATIONS in your project configuration, as described here.

    Thanks for that. Unfortunately this method did not show any effect on size of code in my example.

    Here is the output with commented function calls for GNU GSL:

    In case I include the library than this output is not present as errors are displayed. In this case I get error "region `FLASH' overflowed by 10800 bytes".

  • Hi 

    If that is the case the GNU GSL library alone needs more than 400kB of flash...

    I asked for some input from the software developers, but they didn't have any good suggestions either. The linker should remove any unused functions automatically, so if it still doesn't fit in flash there isn't much you can do. 

    The 'simple' solution is to get an nRF52840DK or an nRF5340DK. 

    Theoretically it is possible to run code directly from the external flash chip on the DK, and I will do some checking internally to see if it is possible to configure a project in the nRF Connect SDK to do this. 

    Best regards
    Torbjørn

Reply
  • Hi 

    If that is the case the GNU GSL library alone needs more than 400kB of flash...

    I asked for some input from the software developers, but they didn't have any good suggestions either. The linker should remove any unused functions automatically, so if it still doesn't fit in flash there isn't much you can do. 

    The 'simple' solution is to get an nRF52840DK or an nRF5340DK. 

    Theoretically it is possible to run code directly from the external flash chip on the DK, and I will do some checking internally to see if it is possible to configure a project in the nRF Connect SDK to do this. 

    Best regards
    Torbjørn

Children
No Data
Related