Skip to content

cpu/esp8266: most .rodata sections are moved from DRAM to IROM (flash)#10981

Merged
smlng merged 3 commits intoRIOT-OS:masterfrom
gschorcht:cpu/esp8266/rodata_IROM/pr
Mar 29, 2019
Merged

cpu/esp8266: most .rodata sections are moved from DRAM to IROM (flash)#10981
smlng merged 3 commits intoRIOT-OS:masterfrom
gschorcht:cpu/esp8266/rodata_IROM/pr

Conversation

@gschorcht
Copy link
Contributor

@gschorcht gschorcht commented Feb 9, 2019

Contribution description

With this PR most .rodata sections are moved from DRAM to IROM (flash) which makes more RAM available for applications.

Background

Since IROM (flash) access requires 32-bit word aligned reads, usually all .rodata sections are placed in DRAM by the Espressif SDK.

Solution

Using the LoadStoreError exception handler from esp-open-rtos makes it possible to place .rodata sections also in IROM (flash) to save RAM resources.

This PR adds the LoadStoreError handler and moves most of the .rodata sections to IROM, saving 12 kBytes of DRAM for an application such as examples/gnrc_networking. Since the LoadStoreError exception handler may reduce the performance of IROM access, performance-critical parts of .rodata section, e.g., core.a, cpu.a and periph.a are still kept in DRAM.

Note

This PR is only relevant for applications that use the SDK version of the RIOT port for ESP8266 where available memory is critical. In non-SDK version available memory is not critical.

Testing procedure

  1. Compile examples/gnrc_networking with and without the PR and check the size of .rodata in the output of size command.
    USEMODULE=esp_wifi make BOARD=esp8266-esp-12x -C examples/gnrc_networking
    size -Ax examples/gnrc_networking/bin/esp8266-esp-12x/gnrc_networking.elf
    
    Without PR you should get something like:
    size -Ax examples/gnrc_networking/bin/esp8266-esp-12x/gnrc_networking.elf
    ...
    .rodata           0x3fb0   0x3ffe8fa0
    .bss              0xb0d0   0x3ffecf50
    ...
    
    That is .rodata has a size of 0x3fb0 (16.304 bytes) and is placed at 0x3ffe8fa0 which is in DRAM. With PR you should get something like:
    size -Ax examples/gnrc_networking/bin/esp8266-esp-12x/gnrc_networking.elf
    ...
    .rodata            0xfb0   0x3ffe8fa0
    .bss              0xb0e0   0x3ffe9f50
    ...
    
    .rodata is much smaller0xfb0 (4.016 bytes) and .bss starts at lower address. That is, much more memory is available for dynamic memory allocation which is essential for the ESP8266 WiFi interface.

The difference of about 12 kBytes is additionally available as RAM.

  1. Flash the application and use command help
    USEMODULE=esp_wifi make BOARD=esp8266-esp-12x -C examples/gnrc_networking flash test
    > help
    
    Help text is read from IROM.

Issues/PRs references

This PR depends on #10980.
Changes of this PR have to be ported to PR #10883.

Usually, the access to the IROM (flash) memory requires 32-bit word aligned reads. Attempts to access data in the IROM (flash) memory less than 32 bits in size triggers a LoadStoreError exception. With the exception handler from esp-open-rtos it becomes possible to access data in IROM (flash) with a size of less than 32 bits and thus to place .rodata sections in the IROM (flash).
@gschorcht gschorcht added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Platform: ESP Platform: This PR/issue effects ESP-based platforms Area: cpu Area: CPU/MCU ports labels Feb 9, 2019
Usually, all .rodata sections are placed in RAM by the Espressif SDK since IROM (flash) access requires 32-bit word aligned reads. thanks to the LoadStoreError exception handler from esp-open-rtos which is used now in RIOT-OS, it is also possible to place .rodata sections in IROM (flash) to save RAM resources.
@gschorcht gschorcht force-pushed the cpu/esp8266/rodata_IROM/pr branch from 4f0fefd to cda45fa Compare February 9, 2019 19:04
@gschorcht gschorcht changed the title cpu/esp8266: move most .rodata sections from RAM to IROM (flash) cpu/esp8266: most .rodata sections are moved from DRAM to IROM (flash) Feb 10, 2019
Introduction of LoadStoreError handler requires new .UserExceptionTrampoline.tex section in ld script.
@gschorcht
Copy link
Contributor Author

gschorcht commented Mar 29, 2019

@smlng I also would like to get it merged before code freeze since it is an important enhancement which saves a lot of RAM.

@smlng
Copy link
Member

smlng commented Mar 29, 2019

if I understand correctly this is only moving memory around but does not safe bytes, right? Because in total I see an increase of 500 bytes compared to master, but I also see the mem shift as you described using size -Ax.

Master:

280909	   3989	  45264	 330162	  509b2	/data/riotbuild/riotbase/examples/gnrc_networking/bin/esp8266-esp-12x/gnrc_networking.elf

section             size         addr
.data              0xf95   0x3ffe8000
.rodata           0x3fe0   0x3ffe8fa0
.bss              0xb0d0   0x3ffecf80
.text             0x723a   0x40100000
.irom0.text      0x39733   0x40210000

This PR:

281417	   3989	  45280	 330686	  50bbe	/data/riotbuild/riotbase/examples/gnrc_networking/bin/esp8266-esp-12x/gnrc_networking.elf

section             size         addr
.data              0xf95   0x3ffe8000
.rodata            0xf7c   0x3ffe8fa0
.bss              0xb0e0   0x3ffe9f20
.text             0x73ea   0x40100000
.irom0.text      0x3c7e3   0x40210000

@gschorcht
Copy link
Contributor Author

@smlng Yes, you are right, it does not save any bytes of code. But, code size isn't a problem since you have between 1 MByte and 4 Mbyte flash memory.

The problem is that .rodata section isn't placed in flash as usually expected but in RAM. The reason is that flash requires aligned 32-bit word access. Therefore, the goal of this PR is to move const data to flash memory .irom0.text section to save RAM. The difference of .rodata section size is the RAM you save which can be used as heap which is especially important for the WiFi interface.

Copy link
Member

@smlng smlng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested ACK!

@smlng smlng added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 3-testing The PR was tested according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines labels Mar 29, 2019
@smlng smlng self-assigned this Mar 29, 2019
@smlng smlng merged commit e9072b1 into RIOT-OS:master Mar 29, 2019
@gschorcht
Copy link
Contributor Author

@sming Thanks a lot for reviewing and testing.

@gschorcht gschorcht deleted the cpu/esp8266/rodata_IROM/pr branch March 30, 2019 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: cpu Area: CPU/MCU ports CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ESP Platform: This PR/issue effects ESP-based platforms Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 3-testing The PR was tested according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants