How to reduce the size of an executable file?

Hello,

I have modified the central_uart example to make the nRF52832 communicate with an ESP32 in MessagePack. After having disabled the logger configuration in the proj.conf file the size of the *.bin file is 225.8 kB which is too large for an nRF52805 (flash of 192 kB). Is there any way to reduce the bin file size?

Below the proj.conf file:

#
# Copyright (c) 2018 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# Enable the UART driver
CONFIG_UART_ASYNC_API=y
CONFIG_NRFX_UARTE0=y
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y

# Enable the BLE stack with GATT Client configuration
CONFIG_BT=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_SMP=y
CONFIG_BT_GATT_CLIENT=y

# Enable the BLE modules from NCS
CONFIG_BT_NUS_CLIENT=y
CONFIG_BT_SCAN=y
CONFIG_BT_SCAN_FILTER_ENABLE=y
CONFIG_BT_SCAN_UUID_CNT=1
CONFIG_BT_SCAN_ADDRESS_CNT=1
CONFIG_BT_GATT_DM=y
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_BT_MAX_PAIRED=1
CONFIG_BT_MAX_CONN=1

# This example requires more workqueue stack
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048

# Enable bonding
CONFIG_BT_SETTINGS=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_SETTINGS=y

# Enable use of the non-minimal C functionality (stdio.h).
CONFIG_NEWLIB_LIBC=y

# Config logger
CONFIG_LOG=n
CONFIG_USE_SEGGER_RTT=y
CONFIG_LOG_BACKEND_RTT=n
CONFIG_LOG_BACKEND_UART=n
CONFIG_LOG_PRINTK=n
CONFIG_BT_DEBUG_LOG=n
CONFIG_BT_GATT_DM_DATA_PRINT=n

CONFIG_ASSERT=y

# Config I2C
CONFIG_GPIO=y
CONFIG_I2C=y
CONFIG_I2C_NRFX=y

CONFIG_SHELL=y
CONFIG_I2C_SHELL=y

Regards,

Marco

Parents Reply Children
  • Good Morning James,

    Thank you.

    Adding the two header files solved my initial problem. However, the linker is now complaining about undefined reference to sscanf(), rand() and srand().

    Note, I am already #including <stdio.h> and <stdlib.h>.

    The compiler is sending only a warning about sscanf()

    warning: implicit declaration of function 'sscanf' [-Wimplicit-function-declaration]

    It looks like the MINIMAL_LIBC does not include these functions.

    Thank you for your help.

    Mohamed

    1> Linking ‘zephyr_prebuilt.elf’
    1> C:\Zypher\v1.7.0\toolchain\opt/bin/arm-none-eabi-gcc zephyr/CMakeFiles/zephyr_prebuilt.dir/misc/empty_file.c.obj -Wl,-T zephyr/linker_zephyr_prebuilt.cmd -Wl,-Map=C:/Sandbox/HomeBeacon_dev_sb/build_nrf52833dk_nrf52833_v149_tuning/zephyr/zephyr_prebuilt.map -Wl,--whole-archive app/libapp.a zephyr/libzephyr.a zephyr/arch/common/libarch__common.a zephyr/arch/arch/arm/core/aarch32/libarch__arm__core__aarch32.a zephyr/arch/arch/arm/core/aarch32/cortex_m/libarch__arm__core__aarch32__cortex_m.a zephyr/arch/arch/arm/core/aarch32/mpu/libarch__arm__core__aarch32__mpu.a zephyr/lib/libc/minimal/liblib__libc__minimal.a zephyr/lib/posix/liblib__posix.a zephyr/soc/arm/common/cortex_m/libsoc__arm__common__cortex_m.a zephyr/soc/arm/nordic_nrf/nrf52/libsoc__arm__nordic_nrf__nrf52.a zephyr/subsys/bluetooth/common/libsubsys__bluetooth__common.a zephyr/subsys/bluetooth/host/libsubsys__bluetooth__host.a zephyr/subsys/bluetooth/controller/libsubsys__bluetooth__controller.a zephyr/subsys/dfu/boot/libsubsys__dfu__boot.a zephyr/subsys/net/libsubsys__net.a zephyr/subsys/random/libsubsys__random.a zephyr/drivers/adc/libdrivers__adc.a zephyr/drivers/gpio/libdrivers__gpio.a zephyr/drivers/i2c/libdrivers__i2c.a zephyr/drivers/pwm/libdrivers__pwm.a zephyr/drivers/sensor/nrf5/libdrivers__sensor__nrf5.a zephyr/drivers/spi/libdrivers__spi.a zephyr/drivers/flash/libdrivers__flash.a zephyr/drivers/entropy/libdrivers__entropy.a modules/nrf/subsys/dfu/dfu_target/lib..__nrf__subsys__dfu__dfu_target.a modules/mcuboot/boot/bootutil/zephyr/libmcuboot_util.a modules/hal_nordic/nrfx/libmodules__hal_nordic__nrfx.a modules/segger/libmodules__segger.a -Wl,--no-whole-archive zephyr/kernel/libkernel.a zephyr/CMakeFiles/offsets.dir/./arch/arm/core/offsets/offsets.c.obj -Lc:/zypher/v1.7.0/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/thumb/v7e-m/nofp -LC:/Sandbox/HomeBeacon_dev_sb/build_nrf52833dk_nrf52833_v149_tuning/zephyr -lgcc zephyr/arch/common/libisr_tables.a -mcpu=cortex-m4 -mthumb -mabi=aapcs -Wl,--gc-sections -Wl,--build-id=none -Wl,--sort-common=descending -Wl,--sort-section=alignment -Wl,-u,_OffsetAbsSyms -Wl,-u,_ConfigAbsSyms -nostdlib -static -no-pie -Wl,-X -Wl,-N -Wl,--orphan-handling=warn -o zephyr\zephyr_prebuilt.elf
    1> c:/zypher/v1.7.0/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(debug_console.c.obj): in function `debug_MainMenu':
    1> C:\Sandbox\HomeBeacon_dev_sb\build_nrf52833dk_nrf52833_v149_tuning/../src/debug/debug_console.c:411: undefined reference to `sscanf'
    1> c:/zypher/v1.7.0/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(debug_menu_power.c.obj): in function `debug_PowerMenu':
    1> C:\Sandbox\HomeBeacon_dev_sb\build_nrf52833dk_nrf52833_v149_tuning/../src/debug/debug_menu_power.c:137: undefined reference to `sscanf'
    1> c:/zypher/v1.7.0/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(debug_menu_radio.c.obj): in function `debug_RadioMenu':
    1> C:\Sandbox\HomeBeacon_dev_sb\build_nrf52833dk_nrf52833_v149_tuning/../src/debug/debug_menu_radio.c:184: undefined reference to `sscanf'
    1> c:/zypher/v1.7.0/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(debug_menu_sensors.c.obj): in function `debug_SensorsMenu':
    1> C:\Sandbox\HomeBeacon_dev_sb\build_nrf52833dk_nrf52833_v149_tuning/../src/debug/debug_menu_sensors.c:149: undefined reference to `sscanf'
    1> c:/zypher/v1.7.0/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(link_manager.c.obj): in function `link_GenerateSessionKey':
    1> C:\Sandbox\HomeBeacon_dev_sb\build_nrf52833dk_nrf52833_v149_tuning/../src/link/link_manager.c:972: undefined reference to `rand'
    1> c:/zypher/v1.7.0/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(link_message_handler.c.obj): in function `link_ProcessCommand':
    1> C:\Sandbox\HomeBeacon_dev_sb\build_nrf52833dk_nrf52833_v149_tuning/../src/link/link_message_handler.c:347: undefined reference to `rand'
    1> c:/zypher/v1.7.0/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: C:\Sandbox\HomeBeacon_dev_sb\build_nrf52833dk_nrf52833_v149_tuning/../src/link/link_message_handler.c:387: undefined reference to `rand'
    1> c:/zypher/v1.7.0/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(link_message_testing.c.obj): in function `link_Test_Process':
    1> C:\Sandbox\HomeBeacon_dev_sb\build_nrf52833dk_nrf52833_v149_tuning/../src/link/link_message_testing.c:912: undefined reference to `rand'
    1> c:/zypher/v1.7.0/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: C:\Sandbox\HomeBeacon_dev_sb\build_nrf52833dk_nrf52833_v149_tuning/../src/link/link_message_testing.c:936: undefined reference to `rand'
    1> c:/zypher/v1.7.0/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(main.c.obj): in function `main':
    1> C:\Sandbox\HomeBeacon_dev_sb\build_nrf52833dk_nrf52833_v149_tuning/../src/main.c:321: undefined reference to `srand'
    1> c:/zypher/v1.7.0/toolchain/opt/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: app/libapp.a(utils.c.obj): in function `util_RandFromToCount':
    1> C:\Sandbox\HomeBeacon_dev_sb\build_nrf52833dk_nrf52833_v149_tuning/../src/utils/utils.c:256: undefined reference to `rand'
    1> collect2.exe: error: ld returned 1 exit status
    Build failed

  • Good morning Mohamad,

    For rand() and srand() you need to enable CONFIG_MINIMAL_LIBC_RAND to expose those. Once you have that then having the #include <stdlib.h> should be fine. Unfortunately, the minimal library does not implement the sscanf functionality. I'm not sure of anything equivalent either.

    I just found this lightweight implementation of sscanf that may work? I have not tried it, but would be worth you checking: https://github.com/tusharjois/bscanf

  • Good Afternoon James,

    Thank you.

    For rand() and srand() you need to enable CONFIG_MINIMAL_LIBC_RAND to expose those.

    It worked as expected.

    the minimal library does not implement the sscanf functionality

    I addressed this by replacing calls to sscanf() with strtol(). I can now build the application. I just hope I have not introduced another problem by switching from sscanf() to strtol().

    Thank you again for your help.

    Kind regards

    Mohamed

  • Hey Mohamad,

    You're more than welcome and glad to hear you got it working!

  • Hi James,

    I just hope I have not introduced another problem by switching from sscanf() to strtol().

    Guess what! I have. Quite a fatal one.

    [00:20:07.178,344] <inf> uart: -> ProcessRxByte: 0x0D
    [00:23:21.285,461] <err> os: ***** MPU FAULT *****
    [00:23:21.285,461] <err> os: Instruction Access Violation
    [00:23:21.285,461] <err> os: r0/a1: 0x00000002 r1/a2: 0x00000003 r2/a3: 0x20009446
    [00:23:21.285,491] <err> os: r3/a4: 0x20009448 r12/ip: 0x20009446 r14/lr: 0x00000000
    [00:23:21.285,491] <err> os: xpsr: 0x21000000
    [00:23:21.285,491] <err> os: Faulting instruction address (r15/pc): 0x200041f4
    [00:23:21.285,491] <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
    [00:23:21.285,522] <err> os: Current thread: 0x20001d30 (main)
    [00:23:21.664,062] <err> os: Halting system

    It looks like I am having a stack overflow problem but the error message above suggests otherwise.

    Any idea?

    Kind regards

    Mohamed

Related