The Keil RTX RTOS thread stack size

1.4k Views Asked by At

In the Keil RTX RTOS configuration file, user could configure the default user thread stack size. In general, the stack holds auto/local variables. The "ZI data" section holds uninitialized global variables.

So if I change the user thread stack size in the RTX configuration file, the stack size will increase and the "ZI data" section size will not increase.

I test it, the test result shows that if I increase user thread stack size. The "ZI data" section size will increase synchronously with the same size.

In my test program, there is 6 threads and each has 600 bytes stack. I use Keil to build the program and it shows me that:

      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   

     36810       4052       1226        380       6484     518461   Grand Totals
     36810       4052       1226        132       6484     518461   ELF Image Totals (compressed)
     36810       4052       1226        132          0          0   ROM Totals

==============================================================================

    Total RO  Size (Code + RO Data)                38036 (  37.14kB)
    Total RW  Size (RW Data + ZI Data)              6864 (   6.70kB)
    Total ROM Size (Code + RO Data + RW Data)      38168 (  37.27kB)  

But if I changed each thread stack size to 800 bytes. Keil shows me as follows:

==============================================================================


      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   

     36810       4052       1226        380       7684     518461   Grand Totals
     36810       4052       1226        132       7684     518461   ELF Image Totals (compressed)
     36810       4052       1226        132          0          0   ROM Totals

==============================================================================

    Total RO  Size (Code + RO Data)                38036 (  37.14kB)
    Total RW  Size (RW Data + ZI Data)              8064 (   7.88kB)
    Total ROM Size (Code + RO Data + RW Data)      38168 (  37.27kB)

==============================================================================

The "ZI data" section size increase from 6484 to 7684 bytes. 7684 - 6484 = 1200 = 6 * 200. And 800 - 600 = 200. So I see the thread stack is put in "ZI Data" section.

My question is: Does it mean auto/local variables in the thread will be put in "ZI Data" section, when thread stack is put in "ZI data" section in RAM ? If it's true, it means there is no stack section at all. There are only "RO/RW/ZI Data" and heap sections at all.

This article gives me the different answer. And I am a little confused about it now. https://developer.mbed.org/handbook/RTOS-Memory-Model

2

There are 2 best solutions below

6
On

The linker determines what memory sections exist. The linker creates some memory sections by default. In your case, three of those default sections are apparently named "RO Data", "RW Data", and "ZI Data". If you don't explicitly specify which section a variable should be located in then the linker will assign it to one of these default sections based on whether the variable is declared const, initialized, or uninitialized.

The linker is not automatically aware that you are using an RTOS. And it has no special knowledge of which variables you intend to use as thread stacks. So the linker does not automatically create independent memory sections for your thread stacks. Rather, the linker will treat the stack variables like any other variable and include them in one of the default memory sections. In your case the thread stacks are apparently being put into the ZI Data section by the linker.

If you want the linker to create special independent memory sections for your thread stacks then you have to explicitly tell the linker to do so via the linker command file. And then you also have to specify that the stack variables should be located in your custom sections. Consult the linker manual for details on how to do this.

0
On

Tasks stacks have to come from somewhere - in RTX by default they are allocated statically and are of fixed size.

The os_tsk_create_user() allows the caller to supply a stack that could be allocated in any manner (statically or from the heap; allocating from the caller stack is possible, but unusual, probably pointless and certainly dangerous) so long as it has 8 byte alignment. I find RTX's automatic stack allocation almost useless and seldom appropriate in all but the most trivial application.