Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to fit my program in IRAM? Section .iram0.text will not fit in region iram0_0_seg. (IDFGH-408) #2566

Closed
chanibal opened this issue Oct 15, 2018 · 9 comments
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally

Comments

@chanibal
Copy link
Contributor

After an upgrade to ESP-IDF 3.1 my code stopped fitting into IRAM:

$ make
LD build/(...).elf
ld.exe: (...).elf section `.iram0.text' will not fit in region `iram0_0_seg'
ld.exe: region `iram0_0_seg' overflowed by 2245 bytes
collect2.exe: error: ld returned 1 exit status

The issues were always there, but only I have recently upgraded ESP-IDF to 3.1, my code started to have issues fitting into IRAM (in pre 3.0 I had 5K left, now I'm 2K over the limit).

Because my code wouldn't link, make size-components was unavailable.
To gather more information, I changed the linker scripts with this change to IDF:

diff --git a/components/esp32/ld/esp32.ld b/components/esp32/ld/esp32.ld
index ee41f7479..bcbbd0d1e 100644
--- a/components/esp32/ld/esp32.ld
+++ b/components/esp32/ld/esp32.ld
@@ -28,7 +28,7 @@ MEMORY
   are connected to the data port of the CPU and eg allow bytewise access. */

   /* IRAM for PRO cpu. Not sure if happy with this, this is MMU area... */
-  iram0_0_seg (RX) :                 org = 0x40080000, len = 0x20000
+  iram0_0_seg (RX) :                 org = 0x40080000, len = 0x40000

   /* Even though the segment name is iram, it is actually mapped to flash
   */

And found what took so much of my space (sorted by IRAM usage):

Archive File DRAM .data DRAM .bss IRAM flash flash code flash rodata Total
libfreertos.a 4156 776 21017 0 2479 28428
libesp32.a 3855 578 20368 25086 31087 80974
libbtdm_app.a 367 4687 19502 38774 3207 66537
libpp.a 1229 5286 13411 45641 4208 69775
libc-psram-workaround.a 1552 24 10417 104490 7657 124140
🡆 [MY COMPONENT WITH IRAM ISSUE] 0 0 🡆8657🡄 0 1178 9835
libspi_flash.a 36 323 7109 999 1648 10115
libphy.a 1284 916 5718 29751 0 37669
libsoc.a 657 8 4745 0 3573 8983
libheap.a 868 8 3847 1704 1024 7451
libcoexist.a 1365 106 3708 0 0 5179
libnet80211.a 317 8998 3577 116798 14241 143931
libdriver.a 83 37 2871 16534 11178 30703
librtc.a 0 4 2308 0 0 2312
🡆 [MY COMPONENT THAT SHOULD BE IN IRAM] 0 4 🡆1765🡄 1420 1218 4407
libbt.a 521 26403 1492 340861 141442 510719
libnewlib.a 152 272 806 843 86 2159
liblog.a 8 268 478 1400 166 2320
libpthread.a 16 12 178 1084 949 2239
libutil.a 0 1 111 612 764 1488
libgcc.a 4 20 104 5556 888 6572
libapp_update.a 0 0 0 124 845 969
[my other component] 0 0 0 2903 2590 5493
[my other component] 32 76 0 9406 7292 16806
libbootloader_support.a 0 0 0 0 0 0
libcore.a 0 5 0 817 415 1237
libcxx.a 12 16 0 770 461 1259
libesp_adc_cal.a 0 0 0 1193 706 1899
libethernet.a 0 0 0 0 0 0
[my other component] 0 0 0 643 434 1077
[my other component] 0 0 0 26878 5146 32024
libhttpclient.a 0 0 0 855 642 1497
libjson.a 12 8 0 5615 625 6260
liblwip.a 19 3365 0 99194 15239 117817
libmain.a 1 3 0 46459 7023 53486
libmbedtls.a 4 0 0 3777 256 4037
libmesh.a 1 0 0 0 0 1
libm-psram-workaround.a 0 0 0 806 0 806
libnvs_flash.a 0 32 0 11773 3121 14926
libnvs-util.a 0 0 0 1230 356 1586
libsmartconfig_ack.a 0 1 0 773 352 1126
libstdc++.a 148 4268 0 118734 66967 190117
libtcpip_adapter.a 0 124 0 6172 2510 8806
libu8g2-esp32.a 0 288 0 6746 8803 15837
[my other component] 448 8 0 2137 503 3096
libvfs.a 232 103 0 4040 399 4774
[my other component] 0 0 0 4529 2740 7269
[my other component] 0 0 0 680 501 1181
libwpa.a 0 682 0 21004 2312 23998
libwpa_supplicant.a 0 0 0 14093 2318 16411
libwpa2.a 0 1 0 0 0 1
libwps.a 0 1 0 0 0 1
[my other component] 0 3256 0 16153 6804 26213
total: 17379 60968 132189 1139057 366353 1715946

The interesting components are

  • [MY COMPONENT THAT SHOULD BE IN IRAM] -
    diagnostic tool that has all of it's functions/methods with an explicit IRAM_ATTR -
    it should be in IRAM and it mostly is with 1765 bytes in IRAM and 1420 in flash.
    This is correct behavior, provided as a counter example to the following component.
  • [MY COMPONENT WITH IRAM ISSUE] -
    a C++ component with a few abstract classes and classes that implement them using virtual methods.
    Some minor templates (shiv for std::make_unique and std::to_string).
    No static variables, no use of malloc - new and make_unique only.
    Using std::stack, std::istringstream and std::ostringstream.
    There are no calls to anything ESP specific - this code is a logic-only component that also compiles in other compilers.
    This component uses 8657 bytes of IRAM and 0 of flash. Why?
  • All of [my other component] - despite using C++ and std classes, they don't have a bit in IRAM - what is the difference?
  • libfreertos.a - IRAM_ATTR is mentioned only once, but the all of the code is in IRAM.

My question is: How does the ESP-IDF (the linker?) decide where will the code end in? How can I tweak it?
I do not want [MY COMPONENT WITH IRAM ISSUE] to end up in IRAM, it's large and there is absolutely no need for it.

Please correct me If I misunderstood some of the architecture and what is IRAM.

NB. Changing from release to debug saves a few kilobytes of memory, but it is still very tight - plus I'd like to be able to use the debug version.

@igrr
Copy link
Member

igrr commented Oct 16, 2018

Placement into IRAM can happen either at compile time or at link time.

To check that the problematic component does not get placed into IRAM at compile time, run xtensa-esp32-elf-objdump -h build/component/libcomponent.a (substituting the component name). This will give you the section sizes for this component before linking.

For placement into IRAM at link time, this is mostly done by archive file name or object file name. Can you possibly disclose the actual name of this component, and source file(s) inside it?

@Alvin1Zhang Alvin1Zhang changed the title How to fit my program in IRAM? Section .iram0.text will not fit in region iram0_0_seg. [TW#26797] How to fit my program in IRAM? Section .iram0.text will not fit in region iram0_0_seg. Oct 16, 2018
@chanibal
Copy link
Contributor Author

The component [MY COMPONENT WITH IRAM ISSUE] is named hal, it compiles to libhal.a. This is probably in the top 10 most generic names for a component, so this might be the issue.

The component is then used in app_main as a local object and it's abstract class is implemented by two other components that are instantiated also as local objects in app_main.

There is no custom compilation, just a simple component.mk with the contents:

COMPONENT_ADD_INCLUDEDIRS := .

Directory listing of components/hal/:

  • Command.cpp
  • Command.h
  • CommandSink.h
  • component.mk
  • HAL.cpp
  • HAL.h
  • HAL.md
  • hal.vcxitems
  • ISerializable.h
  • JsonWriter.h
  • make_unique.h
  • Nodes.h
  • Primitive.cpp
  • Primitive.h
  • SerializedInput.cpp
  • SerializedInput.h
  • SerializedInputAndOutputChr.h
  • SerializedOutput.cpp
  • SerializedOutput.h
  • test/ (directory with unit tests, not in include path of the main project)

Directory listing of build/hal/:

  • Command.d
  • Command.o
  • component_project_vars.mk
  • HAL.d
  • HAL.o
  • libhal.a
  • Primitive.d
  • Primitive.o
  • SerializedInput.d
  • SerializedInput.o
  • SerializedOutput.d
  • SerializedOutput.o

By esp32-elf-objdump I guess, you mean xtensa-esp32-elf-objdump.exe? I'm using release/v3.1 and toolchain 20180110, and don't have this binary.

Results of xtensa-esp32-elf-objdump.exe -h build/hal/libhal.a (too large to paste in the issue).

@igrr
Copy link
Member

igrr commented Oct 16, 2018

Indeed component name is the issue. It conflicts with Xtensa HAL library used in ESP-IDF (components/esp32/libhal.a). Linker script has a line which places contents of libhal.a into IRAM:

*libhal.a:(.literal .text .literal.* .text.*)
.

Can you rename the component to something else?

@chanibal
Copy link
Contributor Author

Thank you, didn't think of that. Changing the directory name fixed the issue. Now I have got almost 6K free.

Perhaps the list of taken component names should be documented? I thought of looking at collisions with something at esp-idf/components, but did not think about checking out binary names.

@negativekelvin
Copy link
Contributor

#2087

@gunarthon
Copy link

gunarthon commented Nov 19, 2018

I have the same problem, except I don't think that I have a component name issue.
I was changing from master branch to stable version v3.2 and suddenly the IRAM region wouldn't fit any more. I changed from compiling in debug mode to release and now it's on 97.6% usage.
But as there are more functionalities planned (like http server and BLE), this is just a temporary solution.

Seeing that this was the only post I could find with the same issue, I suspect it must be either a bug or that I did something wrong with my configuration.

The size-components, after changing to release, gives this output:

Python requirements from C:/msys32/home/gunar.kroeger/esp/esp-idf/requirements.txt are satisfied.

Total sizes:

 DRAM .data size:   15828 bytes

 DRAM .bss  size:   82184 bytes

Used static DRAM:   98012 bytes (  26568 available, 78.7% used)

Used static IRAM:  127880 bytes (   3192 available, 97.6% used)

      Flash code: 1140241 bytes

    Flash rodata:  272148 bytes

Total image size:~1556097 bytes (.bin may be padded larger)

Per-archive contributions to ELF file:

            Archive File DRAM .data & .bss   IRAM Flash code & rodata   Total

                 libbt.a        195  43448   1512     304343    82618  432116

           libnet80211.a        321   9213   3577     112174    14045  139330

            libmbedtls.a         92    264      0     109091    21354  130801

               liblwip.a         19   4172      0     100100    16939  121230

 libc-psram-workaround.a       1804     62  15946      85626     6349  109787

              libesp32.a       3153   2642  19873      27292    30237   83197

             libdriver.a        119    183   4031      43679    31417   79429

                 libpp.a       1229   5286  13407      45710     4208   69840

               libmain.a        142   9637      0      40341    16971   67091

           libbtdm_app.a        255   2203  19607      40838     3617   66520

                libphy.a       1284    915   5710      29799        0   37708

             libspiffs.a          0     12      0      24450     1407   25869

                libwpa.a          0    682      0      21016     2312   24010

              libminiz.a          0      0      0      18407     5113   23520

           libfreertos.a       4156    776  15958          0     2166   23056

              libfatfs.a          4     47      0      19995     2184   22230

             libnghttp.a          0      0      0      15226     4141   19367

          libnvs_flash.a          0     32      0      13382     3261   16675

     libwpa_supplicant.a          0      0      0      13524     2318   15842

                libsoc.a        245      4   8139        727     4145   13260

              libsdmmc.a          0      0      0       9190     3687   12877

          libspi_flash.a         36    323   7036       1561     1791   10747

    libesp_http_client.a          0      0      0       7113     2047    9160

                libvfs.a        240    103      0       8245      559    9147

 libm-psram-workaround.a          4      0      0       6994      541    7539

               libheap.a        884      8   3867       1546      920    7225

            libcoexist.a       1365    106   3704       1523        0    6698

                libgcc.a          4     20    104       5564      888    6580

        libesp_ringbuf.a          0      0      0       4643      594    5237

             libstdc++.a          8     20      0       2689     1253    3970

 libbootloader_support.a          0      4      0       2585     1268    3857

      libtcpip_adapter.a          0    124      0       3094      353    3571

      libtcp_transport.a          0      0      0       2513      610    3123

         libapp_update.a          0     80      0       2136      725    2941

             libnewlib.a        152    272    830       1155      167    2576

            libesp-tls.a          0      0      0       1735      770    2505

                librtc.a          0      4   2304          0        0    2308

        libesp_adc_cal.a          0      0      0       1014      674    1688

            libpthread.a         16     12    178        874      607    1687

                liblog.a          8    268    478        810       98    1662

         libsd_logging.a          0   1028      0        279       73    1380

               libcore.a          0      5      0        821      415    1241

    libsmartconfig_ack.a          0      1      0        766      257    1024

                libhal.a          0      0    515          0       32     547

                libcxx.a          0      0      0         11        0      11

libxtensa-debug-module.a          0      0      8          0        0       8

               libwpa2.a          0      1      0          0        0       1

                libwps.a          0      1      0          0        0       1

           libethernet.a          0      0      0          0        0       0

               libmesh.a          0      0      0          0        0       0

Can someone see what the problem could be?

@projectgus projectgus changed the title [TW#26797] How to fit my program in IRAM? Section .iram0.text will not fit in region iram0_0_seg. How to fit my program in IRAM? Section .iram0.text will not fit in region iram0_0_seg. (IDFGH-408) Mar 12, 2019
@nmendozam
Copy link

You could reduce the IRAM consumption by disabling the next options in menuconfig:
(10KB saved)
https://docs.espressif.com/projects/esp-idf/en/v4.0/api-reference/kconfig.html#config-esp32-wifi-iram-opt
(17KB saved)
https://docs.espressif.com/projects/esp-idf/en/v4.0/api-reference/kconfig.html#config-esp32-wifi-rx-iram-opt
(10KB saved)
https://docs.espressif.com/projects/esp-idf/en/v4.0/api-reference/kconfig.html#config-lwip-iram-optimization
or rather change the compilation optimization from debug to release (also in the menuconfig).
https://docs.espressif.com/projects/esp-idf/en/v4.0/api-reference/kconfig.html#config-compiler-optimization

0xFEEDC0DE64 pushed a commit to 0xFEEDC0DE64/esp-idf that referenced this issue May 5, 2021
@projectgus
Copy link
Contributor

We're in the process of adding a new Performance Guide section to the ESP-IDF Programmers Guide that includes a list of options to reduce IRAM usage of a project. This issue will be updated when it has merged.

@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: Done Issue is done internally labels Jun 4, 2021
@ESP-Marius
Copy link
Collaborator

On latest master we've added a kconfig option for using parts of SRAM1 as IRAM in 5cbd311 which will help with this issue.

We've also focused on reducing IRAM usage/making placement optional for several components. For an full overview of all such option see Optimizing-iram-usage. All new options for saving IRAM we add will be listed in this chapter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

8 participants