Stack pointer area?

eriksl
Posts: 154
Joined: Fri May 22, 2015 6:22 pm

Stack pointer area?

Postby eriksl » Wed Jan 03, 2018 3:50 am

Hello All,

This has been puzzling me more and more lately and I don't seem to find out anything about it (googled it...)

According to https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map:

3FFFC000h 4000h RAM ETS system data RAM.
3FFE8000h 14000h RAM RW User data RAM. Available to applications.

In other words: 80kbytes of RAM available to application, from 0x3ffe8000 on. Every other source I consult (including the linkmap) confirms this.

When I print the value of the stack pointer, I get values outside this area, some examples:
0x3fffff00 (parameter on stack)
0x3ffffef8 (variable on stack)

They are right inside the above mentioned "ETS system data RAM" area. I can get no information about this. I'd expect them to be right on top of the "user data ram" area, i.o.w. somehwere around 0x3fffbfff, growing downwards towards the heap.

Does this mean we have an additional (up to) 16kbytes of memory (more or less) dedicated to the stack? How much of this area is actually available? What if we overrun it (which is easily possible)? I must say 96 kbytes or RAM sounds more plausible than 80 kbytes, but who knows...

User avatar
iot-bits.com
Posts: 23
Joined: Tue Dec 05, 2017 2:53 pm
Location: Pune, India
Contact:

Re: Stack pointer area?

Postby iot-bits.com » Fri Jan 05, 2018 3:10 pm

The DRAM is actually 96kB.
With nonOS SDK, the remaining 16kB gets used for ROM code.
In RTOS SDK, you have the entire 96kB for data, bss, rodata and heap.
Because heap is the flexible one here, it depends on the size of (data+bss+rodata).
- Pratik Panda
Nerd and Embedded Design Consultant
www.iot-bits.com

eriksl
Posts: 154
Joined: Fri May 22, 2015 6:22 pm

Re: Stack pointer area?

Postby eriksl » Fri Jan 05, 2018 4:18 pm

Hi Pratik,

Good to see you're still around here ;)

You say this:
The DRAM is actually 96kB.
With nonOS SDK, the remaining 16kB gets used for ROM code.
In RTOS SDK, you have the entire 96kB for data, bss, rodata and heap.
Because heap is the flexible one here, it depends on the size of (data+bss+rodata).

This is exactly the text I found in some of the Espressif documents that where updated since I read them last time, so I suspect you're the author there ;).

Anyway, this statement simply doesn't add up. I am using (of course) the nonOS SDK. So the 16 kb area would be used for "ROM code". To begin with, I am not quite sure what's meant by that. Is the area used for mirroring the ROM code, like the IRAM area does for SPI FLASH? If so, why would the RTOS SDK not need it?

But as the stack pointer appears to be IN this area, this is not very likely. So I assume what's meant is that area is dedicated to data storage for SDK/ROM code, that would sound logical. But, still, it doesn't add up:
- why does the RTOS SDK not need it?
- why does the heap already get's used (a little) without me ever using it -> sounds like the SDK code stores it data there instead
- why does my stack pointer end up in the top of this area?

In the end I am not really interested what is where and why, but I do need to know how much stack space I have available. If the 16 kb area isn't used at all, I've got 16 kb for my stack (which is a tad on the big size, I only need about 300 bytes, I am very careful to avoid placing large stuff on the stack). If it is really 16 kb, I may want to change that strategy.

If the 16 kb area is used, I'd really like to know, how much of it, so I know what's left for the stack.

Ultimately I am thinking of implementing a stack painting mechanism where one can see how many stack has been used up to a certain point, so one can now how much is left before crashing.

Thx Pradik.

User avatar
iot-bits.com
Posts: 23
Joined: Tue Dec 05, 2017 2:53 pm
Location: Pune, India
Contact:

Re: Stack pointer area?

Postby iot-bits.com » Mon Jan 08, 2018 12:55 am

Well you guessed the author right.
Well, all I can say is that the nonOS SDK has tasks with priorities too (as in the os_task APIs). It is not a preemptive scheduling system, but it is something anyway. In FreeRTOS yo uhave the framework taking care of everything, all you need to do is have your assembly code in place to allow FreeRTOS to work.

I no longer work actively with Espressif, and cannot confirm from them before sharing any potentially "not-so-public" information. So I'd have to kill you if I told you. ;)
Hope you understand!

But I think you can just go with a recursive function to see how far you can go before the stack overflows. Or you could keep checking how heap is affected if you put large amounts of data on the stack.
- Pratik Panda
Nerd and Embedded Design Consultant
www.iot-bits.com

eriksl
Posts: 154
Joined: Fri May 22, 2015 6:22 pm

Re: Stack pointer area?

Postby eriksl » Mon Jan 08, 2018 1:59 am

Totally understood ;)

I already guessed that would be the way to go if nobody could give me this information (either because unknown or because classified (for some stupid reason)).

I'd simply allocate some growing array on the stack though, rather than having a function recurse on itself. Issue is just, some size may work well for weeks and then suddenly fail for no apparent reason. And that's why I'd really like to know the size (or at least a hint) first hand.

Thanks for you help. I really still hope some Espressif employee will step in here.

eriksl
Posts: 154
Joined: Fri May 22, 2015 6:22 pm

Re: Stack pointer area?

Postby eriksl » Fri Jan 12, 2018 5:53 pm

I am sharing my experiences about this here. I really hope some of the Espressif employees will step in and comment. Otherwise it may serve as starting point for others that have the same question.

BTW this is all non-OS SDK.

To start with, during the very early boot process, some functions in user code can be called from the SDK code:
- user_spi_flash_dio_to_qio_pre_init
- user_rf_cal_sector_set
- user_rf_pre_init
During this period the stack pointer points to an area half way through the memory area designated as user ram area (dram0). Weird.

When the SDK code is done initialising, user_init() is called. After that, optionally a function user_init2() can be called from SDK code (after which all wlan initialisation has finished). In both functions the stack pointer is on the top of the memory area designated as "system ram" (as mentioned before) and remains there. So apparently "non-OS SDK" user code has it's stack there.

Now is the question, how big is the usable stack area? It could be anything between 16kbytes (where the sysram area starts and the dram0 area ends, writing beyond there will corrupt the heap) and 384 bytes (the max stack space I am using now and which doesn't seem to be a problem).

So I started "painting" the sysram area with a magic number (4 bytes) and watched the area. Conclusions from that:

- If you write anything in the area between the sysram start (3fffc000) and halfway through (3fffe000) the system will crash. Especially if started from the top of this area (3fffe000) downwards, so I suspect that's where the stack is that's used for system functions (interrupts, some sort of CPU supervisor mode, background SDK code?)
- Writing in the area between 3fffe000 and 3fffeb2c is "harmless", everything will keep working, but there is a huge caveat, somewhere in the process between user_init2 and regular execution of the user code, the last part (top area, a few bytes below 3fffeb2c) gets overwritten by the SDK code, with zero's. So you can't use it as stack area.
- The area between 3fffeb2c and 3fffffff is "clear".

My conclusion:
- The area between 3fffeb30 and 3fffffff is the designated area for the user stack and is 5328 bytes in size (not too bad anyway)
- The area between 3fffe000 and 3fffeb2c could maybe be used for some storage, but take care that a small part of it gets overwritten during the startup. When all is up and running, the SDK doesn't write there. So it's not suitable for use as stack, but it might be used for extra storage, outside the heap, of size of about 2.5 kbytes, when memory is really tight.
- The area between 3fffe000 and 3fffc000 is used for system/SDK usage, don't touch it.

To be able to keep monitoring this and just for info, I implemented "stack painting" where at system start I write the complete stack area with signature long words. Everywhere the stack has been, the signature will be overwritten, so the effectively needed stack size can be determined. From the other side of the area, everywhere the SDK has been written, the signature will be lost as well, so this can be monitored. As for the moment, I haven't seen that happening, luckily.

User avatar
iot-bits.com
Posts: 23
Joined: Tue Dec 05, 2017 2:53 pm
Location: Pune, India
Contact:

Re: Stack pointer area?

Postby iot-bits.com » Wed Jan 17, 2018 2:49 pm

That's some cool information, I'd have to request permission to include all this in a guest post on my website. :D
- Pratik Panda
Nerd and Embedded Design Consultant
www.iot-bits.com

eriksl
Posts: 154
Joined: Fri May 22, 2015 6:22 pm

Re: Stack pointer area?

Postby eriksl » Wed Jan 17, 2018 5:20 pm

Or even better: just, public (!) confirmation from Espressif (or adjustments of course).

Who is online

Users browsing this forum: No registered users and 7 guests