4

I tested running bare bones code using ESP IDF on an ESP32 chip using duinotech XC-3800, and obtained the following results in terms of image size.

Analysis Binary Size for ESP32

Folder Structure

  • temp/
    • main/
      • CMakeLists.txt
      • main.c
    • CMakeLists.txt

File contents

CMakeLists.txt

# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(temp)

main>CMakeLists.txt

idf_component_register(SRCS "main.c"
                    INCLUDE_DIRS "")

Test 1 main>main.c

#include <stdio.h>

void app_main(void) {
  printf("Hello world!\n");
  for (int i = 10; i >= 0; i--) {
    printf("Restarting in %d seconds...\n", i);
  }
  printf("Restarting now.\n");
  fflush(stdout);
}

Test 2 main>main.c

#include <stdio.h>

void app_main(void) { printf("Hello world!\n"); }

Test 3 main>main.c

void app_main(void) {}

Size comparison

Obtained by running idf_size.py build/temp.map

Test 1

Total sizes:
 DRAM .data size:    8320 bytes
 DRAM .bss  size:    4072 bytes
Used static DRAM:   12392 bytes ( 168344 available, 6.9% used)
Used static IRAM:   38804 bytes (  92268 available, 29.6% used)
      Flash code:   75408 bytes
    Flash rodata:   23844 bytes
Total image size:~ 146376 bytes (.bin may be padded larger)

Test 2

Total sizes:
 DRAM .data size:    8320 bytes
 DRAM .bss  size:    4072 bytes
Used static DRAM:   12392 bytes ( 168344 available, 6.9% used)
Used static IRAM:   38804 bytes (  92268 available, 29.6% used)
      Flash code:   75240 bytes
    Flash rodata:   23796 bytes
Total image size:~ 146160 bytes (.bin may be padded larger)

Test 3

Total sizes:
 DRAM .data size:    8320 bytes
 DRAM .bss  size:    4072 bytes
Used static DRAM:   12392 bytes ( 168344 available, 6.9% used)
Used static IRAM:   38804 bytes (  92268 available, 29.6% used)
      Flash code:   75004 bytes
    Flash rodata:   23780 bytes
Total image size:~ 145908 bytes (.bin may be padded larger)

Analysis

Size for code obtained by running stat --format="%s" main/main.c

All Sizes are in Bytes

Test No. | Code |  Image | Flash Code | Flash rodata
-------- | -----| ------ | ---------- | ------------
       1 |  207 | 146376 |      75408 |        23844
       2 |   70 | 146160 |      75240 |        23796
       3 |   43 | 145908 |      75004 |        23780

At least 145KB of boiler plate code just to get an empty main run.

Speculation

I suspect that the 145KB is made up of a number of libraries that are always loaded onto the chip whether you use them or not. Some of them must be the FreeRTOS, WiFi, HTTP etc.

Can we bring down this size somehow and load only the bare minimum required for operation?

Rijul Gupta
  • 1,045
  • 13
  • 20

1 Answers1

3

You can get more detailed size information by running idf.py size-components and idf.py size-files. Here are the results for your "Test 3" (i.e. empty function) on my dev environment (note that my Total Image Size is already slightly larger than the one you posted.

Total sizes:
 DRAM .data size:    7860 bytes
 DRAM .bss  size:    4128 bytes
Used static DRAM:   11988 bytes ( 168748 available, 6.6% used)
Used static IRAM:   32706 bytes (  98366 available, 25.0% used)
      Flash code:   76002 bytes
    Flash rodata:   32164 bytes
Total image size:~ 148732 bytes (.bin may be padded larger)
Per-archive contributions to ELF file:
            Archive File DRAM .data & .bss   IRAM Flash code & rodata   Total
                  libc.a          0      0      0      55348     3829   59177
              libesp32.a       2132   2351   6767       5976     8076   25302
           libfreertos.a       4140    776  12432          0     1653   19001
             libdriver.a         76     20      0       4003     7854   11953
                libsoc.a        161      4   4953        612     3852    9582
                libvfs.a        240    103      0       5464      950    6757
               libheap.a        877      4   3095        830      986    5792
          libspi_flash.a         24    290   1855        779      890    3838
              libefuse.a         16      4      0       1142     2213    3375
             libnewlib.a        152    272    766        830       96    2116
         libapp_update.a          0      4    109        159     1221    1493
        libesp_ringbuf.a          0      0    848          0      209    1057
                liblog.a          8    268    429         82        0     787
                libhal.a          0      0    515          0       32     547
            libpthread.a          8     12      0        256        0     276
                libgcc.a          0      0      0          0      160     160
 libbootloader_support.a          0      0      0        126        0     126
                  libm.a          0      0      0         88        0      88
                libcxx.a          0      0      0         11        0      11
libxtensa-debug-module.a          0      0      8          0        0       8
               libmain.a          0      0      0          5        0       5
                   (exe)          0      0      0          0        0       0
         libmbedcrypto.a          0      0      0          0        0       0
            libmbedtls.a          0      0      0          0        0       0
     libwpa_supplicant.a          0      0      0          0        0       0
Per-file contributions to ELF file:
             Object File DRAM .data & .bss   IRAM Flash code & rodata   Total
        lib_a-vfprintf.o          0      0      0      14193      756   14949
       lib_a-svfprintf.o          0      0      0      13838      756   14594
      lib_a-svfiprintf.o          0      0      0       9642     1210   10852
       lib_a-vfiprintf.o          0      0      0       9945      738   10683
              uart.c.obj         44     12      0       2985     7293   10334
             tasks.c.obj         12    700   5546          0      531    6789
          vfs_uart.c.obj         48     63      0       3680      808    4599
             panic.c.obj       2023      5   1989          0        0    4017
   esp_err_to_name.c.obj          0      0      0         50     3947    3997
           portasm.S.obj       3084      0    484          0        0    3568
            lib_a-dtoa.o          0      0      0       3522       13    3535
        multi_heap.c.obj        873      0   2277          0        0    3150
        intr_alloc.c.obj          8     22    618       1703      722    3073
 esp_efuse_utility.c.obj          0      0      0        867     2205    3072
         cpu_start.c.obj          0      1   1068        331     1352    2752
             queue.c.obj          0      0   2310          0      325    2635
           lib_a-mprec.o          0      0      0       2134      296    2430
           rtc_clk.c.obj        161      4   2098          0        0    2263
         dbg_stubs.c.obj          0   2072     32        108        0    2212
               vfs.c.obj        192     40      0       1784      142    2158
        rtc_periph.c.obj          0      0      0          0     2080    2080
   esp_timer_esp32.c.obj          8     26   1068        262      538    1902
    xtensa_vectors.S.obj          8      0   1776          0       36    1820
        flash_mmap.c.obj          0    264   1092        114      339    1809
          task_wdt.c.obj         53      4      0       1178      548    1783
         heap_caps.c.obj          4      0    818         52      617    1491
            timers.c.obj          8     56   1006          0      233    1303
       cache_utils.c.obj          4     14    749         81      402    1250
 soc_memory_layout.c.obj          0      0      0          0     1181    1181
    heap_caps_init.c.obj          0      4      0        778      369    1151
              port.c.obj          0     16    625          0      493    1134
       esp_ota_ops.c.obj          0      4      0        147      965    1116
   xtensa_intr_asm.S.obj       1024      0     51          0        0    1075
           ringbuf.c.obj          0      0    848          0      209    1057
          rtc_time.c.obj          0      0    815          0      198    1013
memory_layout_utils.c.ob          0      0      0        612      393    1005
          rtc_init.c.obj          0      0    992          0        0     992
       periph_ctrl.c.obj          8      0      0        615      280     903
          lib_a-fseeko.o          0      0      0        866        0     866
              time.c.obj          0     32    122        703        0     857
               clk.c.obj          0      0     64        559      221     844
         esp_timer.c.obj          8     16    261        406      134     825
      dport_access.c.obj          8     40    444        189      137     818
               log.c.obj          8    268    429         82        0     787
           rtc_wdt.c.obj          0      0    743          0        0     743
         partition.c.obj          0      8      0        522      149     679
               ipc.c.obj          0     28    159        283      120     590
             locks.c.obj          8      0    485          0       94     587
     crosscore_int.c.obj          8      8    193        130      156     495
     syscall_table.c.obj        144    240      0         82        0     466
        system_api.c.obj          0      0    439          0        0     439
             timer.c.obj         16      0      0        112      281     409
           int_wdt.c.obj          0      1     91        306        0     398
    freertos_hooks.c.obj          8    128     43        216        0     395
      esp_app_desc.c.obj          0      0    109         12      256     377
          brownout.c.obj          0      0      0        149      201     350
       windowspill_asm.o          0      0    311          0        0     311
        rtc_module.c.obj          8      8      0        291        0     307
    xtensa_context.S.obj          0      0    306          0        0     306
          cpu_util.c.obj          0      0    305          0        0     305
dport_panic_highint_hdl.          8      0    242          0        0     250
           lib_a-reent.o          0      0      0        232        0     232
           lib_a-fopen.o          0      0      0        224        0     224
        lib_a-snprintf.o          0      0      0        214        0     214
     esp_efuse_api.c.obj          0      4      0        193        0     197
pthread_local_storage.c.          8      4      0        180        0     192
     cache_err_int.c.obj          0      0     56         98        0     154
       xtensa_intr.c.obj          0      0    108          0       35     143
              list.c.obj          0      0    142          0        0     142
          syscalls.c.obj          0      0     91         45        0     136
          lib_a-assert.o          0      0      0         68       60     128
           lib_a-flags.o          0      0      0        127        0     127
 bootloader_common.c.obj          0      0      0        126        0     126
         lib_a-s_frexp.o          0      0      0        110        0     110
         flash_ops.c.obj         20      4     14         62        0     100
         lib_a-vprintf.o          0      0      0         94        0      94
    lib_a-s_fpclassify.o          0      0      0         88        0      88
        lib_a-fiprintf.o          0      0      0         84        0      84
           pthread.c.obj          0      8      0         76        0      84
  esp_efuse_fields.c.obj          0      0      0         82        0      82
                 clock.o          0      0     72          0        0      72
        reent_init.c.obj          0      0     68          0        2      70
state_asm--restore_extra          0      0     62          0        0      62
state_asm--save_extra_nw          0      0     62          0        0      62
xtensa_vector_defaults.S          0      0     46          0        0      46
           lib_a-fseek.o          0      0      0         45        0      45
               _divdi3.o          0      0      0          0       40      40
               _moddi3.o          0      0      0          0       40      40
              _udivdi3.o          0      0      0          0       40      40
              _umoddi3.o          0      0      0          0       40      40
       xtensa_init.c.obj          0      4     32          0        0      36
  interrupts--intlevel.o          0      0      0          0       32      32
   esp_efuse_table.c.obj         16      0      0          0        8      24
           lib_a-errno.o          0      0      0         10        0      10
          pm_esp32.c.obj          0      0      0          8        0       8
 int_asm--set_intclear.o          0      0      8          0        0       8
               eri.c.obj          0      0      8          0        0       8
cxx_exception_stubs.cpp.          0      0      0          6        0       6
      cxx_guards.cpp.obj          0      0      0          5        0       5
  hello_world_main.c.obj          0      0      0          5        0       5
  FreeRTOS-openocd.c.obj          4      0      0          0        0       4
    dummy_main_src.c.obj          0      0      0          0        0       0
  bootloader_flash.c.obj          0      0      0          0        0       0
 bootloader_random.c.obj          0      0      0          0        0       0
    bootloader_sha.c.obj          0      0      0          0        0       0
  esp_image_format.c.obj          0      0      0          0        0       0
  flash_partitions.c.obj          0      0      0          0        0       0
           lib_a-fputs.o          0      0      0          0        0       0
          lib_a-printf.o          0      0      0          0        0       0
            lib_a-putc.o          0      0      0          0        0       0
         lib_a-putchar.o          0      0      0          0        0       0
            lib_a-puts.o          0      0      0          0        0       0
         lib_a-sprintf.o          0      0      0          0        0       0
        lib_a-strerror.o          0      0      0          0        0       0
        lib_a-u_strerr.o          0      0      0          0        0       0
  lib_a-xpg_strerror_r.o          0      0      0          0        0       0
              gpio.c.obj          0      0      0          0        0       0
         hw_random.c.obj          0      0      0          0        0       0
          pm_locks.c.obj          0      0      0          0        0       0
            _addsubdf3.o          0      0      0          0        0       0
               _cmpdf2.o          0      0      0          0        0       0
               _divdf3.o          0      0      0          0        0       0
              _fixdfsi.o          0      0      0          0        0       0
            _floatdidf.o          0      0      0          0        0       0
            _floatsidf.o          0      0      0          0        0       0
               _muldf3.o          0      0      0          0        0       0
          _popcountsi2.o          0      0      0          0        0       0
          platform.c.obj          0      0      0          0        0       0
     platform_util.c.obj          0      0      0          0        0       0
            sha256.c.obj          0      0      0          0        0       0
           esp_mem.c.obj          0      0      0          0        0       0
       gpio_periph.c.obj          0      0      0          0        0       0
spi_flash_rom_patch.c.ob          0      0      0          0        0       0
      md5-internal.c.obj          0      0      0          0        0       0

From a library point of view, the major contributor is libc which is the C standard library. While you could probably cherry-pick some functions and drop others from there, I don't think anyone would recommend that.

Next up is libesp32, which provides critical functions such as start_cpu0(). Again, you may be able to cherry-pick only the functions you need, if you really want to.

You can figure out what a library provides by looking up the .a file (e.g. find build -name libesp32.a, and then running nm build/esp-idf/esp32/libesp32.a on the found path.

The second table lists the same size-data, but split per source-file instead of per library.

Niobos
  • 880
  • 4
  • 15