Renesas


Renesas Electronics Corporation (TSE: 6723), the world's number one supplier of microcontrollers, is a premier supplier of advanced semiconductor solutions including microcontrollers, SoC solutions and a broad range of analog and power devices.

You are viewing an older revision! See the latest version

GR PEACH knowhow database

Information

Japanese version is available in lower part of this page.
このページの後半に日本語版が用意されています.

[OS] The way to adjust the total stack size of threads

The way to adjust the total stack size of threads for Cortex-A9 CMSIS-RTOS RTX is show below.
In the current setting, you have 32Kbyte total stack size of thread. Normally, you can use it without adjustments.
However, in some cases, you need to adjust the size.

Cases you need to adjust the stack size


  • Fail to generate the thread
    If return value of "osThreadCreate()" is "NULL", your program fails to generate the thread. One possible cause is a lack of the total stack size of thread. You would be able to solve the issue by increasing the total stack size of thread.

  • User RAM size is not enough.
    When user RAM is not enough, you can reduce the total stack size of the thread.

  • Thread stack overflow
    If an error in RTOS occurs during thread execution, os_error() => mbed_die() is called.
    By setting the following macro to "1", you can see it happens and LED1 ~ LED4 to blink.
    <<code title = (mbed-src Top)\libraries\mbed\targets\hal\TARGET_RENESAS\TARGET_RZ_A1H\device.h  line 64>>
          
    1. define DEVICE_ERROR_PATTERN 0      ⇒ #define DEVICE_ERROR_PATTERN 1 <</code>>
      It is possible that thread has a stack overflow. In this case, check if the issue is solved when you increase the stack size set in osThreadDef(). Then you need to restore the stack size in osTreadDef() and add the increased size to the total stack size of thread.


How to adjust the total stack size of thread

Adjust target macro

The total stack size of the thread is defined as the macro in the configurator file of the OS as below.

(mbed-rtos Top)\rtos\rtx\TARGET_CORTEX_A\RTX_Conf_CA.c line 78

     #define  OS_PRIVSTKSIZE 8192


In Cortex-A9 CMSIS-RTOS RTX, the total stack size is defined in word units(4 bytes), actual total stack size of the thread is 4 times of OS_PRIVSTKSIZE.
In the above case, the total stack size is as follows.

  Total stack size = OS_PRIVSTKSIZE * 4 = 8192 * 4 = 32Kbyte



Relation of the total number of threads and total stack size

If you want to adjust the total number of threads, you can modify the settings of OS_PRIVCNT macro.
If the total number of threads and the total stack size are defined as below,

example of setting

#define  OS_PRIVCNT   10
#define  OS_PRIVSTKSIZE 10240

Note:mbed-rtos as of 2015/1/12, "OS_PRIVCNT" is set to "8" and "OS_PRIVSTKSIZE" is set to "8192".

The total stack size is;

  Total stack size = OS_PRIVSTKSIZE * 4 = 10240 * 4 = 40Kbyte

The above total stack size, 40Kbyte, is shared by threads defined in OS_PRIVCNT.
So the average stack size per thread can be estimated as follows.

  Total stack size / OS_PRIVCNT = 40Kbyte / 10 = 4Kbyte

However, the actual stack size of each thread can be freely set by the user. In concrete, you can specify the stack size of the thread in the third argument of osThreadDef().

stack size settings

osThreadDef(sample_thread, osPriorityNormal, 1024);
                                             ^^^^

For example, you can also set a 10 thread's stack as follows.

 Thread 1:   1 Kbyte
 Thread 2:   1 Kbyte
 Thread 3:   2 Kbyte
 Thread 4:   5 Kbyte
 Thread 5:   10 Kbyte
 Thread 6:   10 Kbyte
 Thread 7:   1 Kbyte
 Thread 8:   3 Kbyte
 Thread 9:   2 Kbyte
 Thread 10:   5 Kbyte
 --------------------------------
 sum       40 Kbyte


Plan for the method of setting total thread stack size

There's a difference between Cortex-A9 and Cortex-M regarding the method.
User program can obtain the total stack size of the thread dinamically on CMSIS-RTOS RTX of Cortex-M, on the other hand user program obtain it statically.
Renesas will migrate the dinamic method from Cortex-M to Cortex-A OS, you need to adjust it by your self until then.

The following is the information about the OS difference.

Cortex-MDynamically obtain the stack area to each thread.
⇒ during thread creation, you don't need to care about the total stack size of the thread. You can generate threads while RAM is available.
Cortex-A9Statically obtain the total stack size of the thread in the configurator settings of the OS.
⇒ it is necessary to check if it's enough and adjust it if necessary.


[OS]スレッドの総スタックサイズ調整方法

Cortex-A9 CMSIS-RTOS RTXの、スレッドの総スタックサイズ調整方法を説明します。
現在の設定では、スレッドの総スタックサイズを32Kbyte確保しています。
過去実績からすると調整なしでお使い頂けると思います。
ただし、調整が必要なケースがありますので、以下をご参照ください。

調整が必要なケース

以下の現象が発生した場合、スレッドの総スタックサイズを調整する必要があります。

  • スレッドの生成に失敗する
    osThreadCreate()戻り値がNULLの場合、スレッドの生成に失敗しています。
    スレッドの総スタックサイズ不足が原因の可能性があります。
    この場合、スレッドの総スタックサイズを増加させる必要があります。

  • RAMが不足し、スタックサイズを削りたい
    現在のmbed-rtosの設定では、スレッドの総スタックサイズ = 32KBとしています。
    システムとしてRAMが不足し、スタックサイズを減らしたい場合はスレッドの総スタックサイズを調整します。

  • スレッドのスタックオーバーフロー
    スレッド実行中にOS内でエラーが発生した場合、os_error()⇒mbed_die()がコールされます。
    以下のマクロを1にすることで、LED1~LED4が点滅し、エラー発生を確認できます。

    <<code title = (mbed-src Top)\libraries\mbed\targets\hal\TARGET_RENESAS\TARGET_RZ_A1H\device.h  64行目>>
          
    1. define DEVICE_ERROR_PATTERN 0      ⇒ #define DEVICE_ERROR_PATTERN 1 <</code>>
      上記現象が発生した場合、スレッドがスタックオーバーフローを起こした可能性があります。
      この場合、osThreadDef()にて指定したスタックサイズを増加させ、現象が改善するか確認ください。
      増加させたスタックサイズに合わせて、総スタックサイズも調整する必要があります。


調整方法

調整対象マクロ

調整対象となるスレッドの総スタックサイズは、OSのコンフィギュレータファイルにマクロで定義されています。
スレッドの総スタックサイズを調整する場合は、下記マクロの設定値を修正します。

(mbed-rtos Top)\rtos\rtx\TARGET_CORTEX_A\RTX_Conf_CA.c 78行目

     #define  OS_PRIVSTKSIZE 8192


Cortex-A9 CMSIS-RTOS RTXでは、ワード単位でスタックサイズを確保する仕様のため、スレッドの総スタックサイズはOS_PRIVSTKSIZE を4倍したサイズが確保されます。
上記の場合、総スタックサイズは、以下のようになります。

  総スタックサイズ = OS_PRIVSTKSIZE * 4 = 8192 * 4 = 32Kbyte



総スレッド数と総スタックサイズの関係

総スレッド数を調整する場合は、OS_PRIVCNTマクロの設定値を修正します。
総スレッド数、および総スタックサイズを以下で定義した場合、

設定例

#define  OS_PRIVCNT   10
#define  OS_PRIVSTKSIZE 10240

(※2015/1/12時点のmbed-rtosでは、それぞれ以下となっていますが、ここでは値を変更して説明します。)

   #define  OS_PRIVCNT   8
   #define  OS_PRIVSTKSIZE 8192


総スタックサイズは、

  総スタックサイズ = OS_PRIVSTKSIZE * 4 = 10240 * 4 = 40Kbyte

となります。
上記総スタックサイズ 40Kbyte を、OS_PRIVCNTにて定義したスレッド数で分け合います。
目安として、1スレッドあたりの平均スタックサイズは、以下のように見積もれます。

  総スタックサイズ / OS_PRIVCNT = 40Kbyte / 10 = 4Kbyte

各スレッドのスタックサイズの内訳はユーザが自由に設定できます。
具体的にはソースコード上で、osThreadDef()を定義した際、第三引数でスレッドのスタックサイズを指定します。

スレッドのスタックサイズの指定

osThreadDef(sample_thread, osPriorityNormal, 1024);
                                             ^^^^

例えば、以下のように10スレッドのスタックを設定することもできます。

 Thread 1:   1 Kbyte
 Thread 2:   1 Kbyte
 Thread 3:   2 Kbyte
 Thread 4:   5 Kbyte
 Thread 5:   10 Kbyte
 Thread 6:   10 Kbyte
 Thread 7:   1 Kbyte
 Thread 8:   3 Kbyte
 Thread 9:   2 Kbyte
 Thread 10:   5 Kbyte
 ――――――――――
合計       40 Kbyte


今後の対応

Cortex-A9とCortex-MとでCMSIS-RTOS RTXの仕様に以下の差分があります。
Cortex-M用 CMSIS-RTOS RTXでは、ユーザがスレッドの総スタックサイズを意識しないでよい仕様となっておりますが、Cortex-A9用 CMSIS-RTOS RTXではユーザにスレッドの総スタックサイズの調整を任せる仕様となっています。
Cortex-A9の仕様をCortex-Mの仕様に合わせる方針(対応調整中)ですが、それまでの間、ユーザ側でのスレッドの総スタックサイズ調整(不足時)が必要になります。

以下、OS差分に関する情報です。

Cortex-Mスタック領域をスレッド別に動的に確保。
⇒スレッド生成時、スレッドの総スタックサイズを意識しないでよい。
RAMが許す限り、スレッドを生成できる。
Cortex-A9スレッドの総スタックサイズをOSのコンフィギュレータ設定にて静的に確保。
⇒総スタックサイズを最初に検討/調整する必要がある。
コンフィギュレータにて設定したスタックサイズ内でスレッドを生成する必要がある。

All wikipages