13.5 スタック・サイズの見積もり
13.5.1 システムのスタック・サイズ

システムのスタック・サイズの計算式を以下に示します。

【式1:システム・スタック・サイズ】

sys_stk = MAX(sys_stkA, sys_stkB, sys_stkC)+2 (バイト)

【式2:システム・スタック・サイズが使用されるパターンA】

sys_stkA = tsksvc+int0+int1+int2+int3

【式3:システム・スタック・サイズが使用されるパターンB】

sys_stkB = アイドル・ルーチン上のユーザ使用サイズ

【式4:システム・スタック・サイズが使用されるパターンC】

sys_stkC = 初期化ルーチン上のユーザ使用サイズ

【式5:タスクで実行したサービス・コール中,最大のシステム・スタック使用サイズ】

タスクで実行したサービス・コール中,最大のシステム・スタック使用サイズ

【式6:int0,int1のサイズ】

Intx = レベルxの割り込みの中で,最もスタックが使用される割り込みのサイズ
= 割り込み上のユーザ使用サイズ


【式7:int2,int3のサイズ】

intx = レベルxの割り込みの中で,最もスタックが使用される割り込みのサイズ
= 割り込み上のユーザ使用サイズ+allsvc+18


【式8:割り込み上で使用するサービス・コールの使用サイズ合計】

allsvc = 発行元スタック引数用+発行元スタック内部処理用+システム・スタック内部処理用

システム・スタック・サイズは,システム・コンフィギュレーション・ファイルへ指定します。ただし,実際はコンフィギュレータに指定する値+2バイトのサイズが確保されます。よって,実際にシステム・コンフィギュレーション・ファイルに指定する値は式1で求めたsys_stkから2バイトを減算したものとなります。

なお,システム・スタック・サイズは,スタックのオーバフローの危険を減らすため,この見積もり結果よりも多めに取ることを推奨します。

以下に,例を示します。

【条件】

- タスクtask1はpol_flgサービス・コールを実行。

- タスクtask2はsnd_mbxサービス・コールを実行。

- 割り込みint0はレベル0のOS管理外の割り込み処理。割り込み上でスタック使用なし。

- 割り込みint2はレベル2のOS割り込みハンドラ。snd_mbxサービス・コールを実行,割り込み上で12バイトのスタック使用。

- 割り込みint3Aはレベル3のOS割り込みハンドラ。pol_flgサービス・コールを実行,割り込み上で16バイトのスタック使用。

- 割り込みint3Bはレベル3のOS割り込みハンドラ。Timer_Handlerを実行,割り込み上でスタック使用なし。

- アイドルidlはスタック使用なし。

- 初期化ルーチンiniは初期化ルーチン上で24バイトのスタック使用。

【計算式】

tsksvc = MAX(pol_flg のシステム・スタック使用サイズ,snd_mbx のシステム・スタック使用サイズ)
= MAX(16,8) = 16バイト


int0 = 0+0 = 0バイト

int1 = 定義なし = 0バイト

int2 = 12+( 0+6+4 )+18 = 40バイト

int3 = MAX(int3A, int3B) = MAX(56,32) = 56バイト

int3A = 16+( 0+6+16 )+18 = 56バイト

int3B = 0 +( 0+0+14 )+18 = 32バイト

sys_stkA = tsksvc+int0+int1+int2+int3
= 16+0+0+40+56
= 112バイト ※sys_stkA,B,C内で最大なので,このサイズを確保



sys_stkB = アイドル・ルーチンのユーザ使用スタック・サイズ = 0バイト

sys_stkC = 初期化ルーチンのユーザ使用スタック・サイズ = 20バイト

sys_stk = MAX(sys_stkA, sys_stkB, sys_stkC)+2
= MAX(112, 0, 20)
= 112+2 = 114バイト



以上から,システム・スタック・サイズはsys_stkAの112バイトです。

システム・コンフィギュレーション・ファイルへ指定するサイズは,この112バイトとなります。

備考 以下に,例で使用するサービス・コール/関数のスタック使用サイズを示します。

発行元スタック

引数用

発行元スタック

内部処理用

システム・スタック

内部処理用

pol_flgサービス・コール

0

6

16

twai_flgサービス・コール

4

6

16

snd_mbxサービス・コール

0

6

4

Timer_Handler関数

0



14



13.5.2 タスクのスタック・サイズ

タスクのスタック・サイズの計算式を以下に示します。

【式1:タスク上で割り込みが発生しない場合】

タスク・スタック・サイズ = ユーザ使用サイズ+サービス・コールの引数用サイズ+6 (バイト)

【式2:タスク上で割り込みが発生する場合】

タスク・スタック・サイズ = ユーザ使用サイズ+サービス・コールの引数用サイズ+6+20 (バイト)

タスク・スタック・サイズはシステム・コンフィギュレーション・ファイルへ指定します。ただし,実際は“コンフィギュレータに指定した値+6バイト”のサイズが確保されます。よって,実際にシステム・コンフィギュレーション・ファイルに指定する値は,式1または式2で求めた値から6バイトを減算したものとなります。

この6バイトには,サービス・コール発行時に使用されるスタック・サイズが含まれています。ただし,サービス・コール発行時に使用されるスタック・サイズの中でも,引数用スタック・サイズは6バイトとは別にユーザ使用サイズとして確保する必要があります。なお,各サービス・コールで使用される引数用スタック・サイズは異なります。その一覧表は表12−1 にまとめてあります。

タスク・スタック・サイズは“対象タスク上で最もスタックが使用される場合のスタック・サイズ”ですので,サービス・コールで,引数用スタックが4バイトのものと,8バイトのものがあれば,よりスタックが使用されるパターンの8バイト分を確保します。

以上は,割り込みを受け付けない(すべて割り込み禁止の)タスクに関するものです。割り込みを受け付けるタスクに関しては,さらに20バイトの領域を確保する必要があります。

なお,この20バイトの中には,割り込み開始時に呼び出しが必要な関数_kernel_int_entry呼び出し時のスタック・サイズも含まれています。_kernel_int_entryは20バイトのデータをスタックへ退避しただけで復帰は行いません。復帰は割り込み終了時に呼び出しが必要な関数_kernel_int_exit呼び出し時に行われます。

例1 タスクtask1でtwai_flgサービス・コールとsnd_mbxサービス・コールを使用し,ほかにスタックを使用する関数や処理がなく,タスク上で割り込みは受け付けられない場合

task1上で割り込みは受け付けられないので,使用する計算式は式1です。

スタックを使用する関数や処理はないことから,ユーザ使用サイズは0バイトです。

全サービス・コールの引数用サイズを調査すると,以下となります。

サービス・コールの引数用サイズ(twai_flg) = 4バイト

サービス・コールの引数用サイズ(snd_mbx) = 0バイト

最もスタックが使用されるのは,twai_flg呼び出し時のスタック・サイズなので,この値を式1へ指定します。

タスク・スタック・サイズ = ユーザ使用サイズ+サービス・コールの引数用サイズ(twai_flg)+6
= 0+4+6
= 10バイト



システム・コンフィギュレーション・ファイルへ指定するサイズは,上記から6を減算した4バイトとなります。

例2 タスクtask1で関数A(スタックを12バイト使う)上からtwai_flgサービス・コールを呼び出し,関数B(スタックを20バイト使う)上からsnd_mbxサービス・コールを呼び出し,タスク上で割り込みが受け付けられる場合

task1上で割り込みは受け付けられるので,使用する計算式は式2です。最もスタックが使用されるパターンを見つけるため,パターンを列挙します。

パターンA = ユーザ使用サイズ(関数Aの場合)+サービス・コールの引数用サイズ(twai_flg)+6+20
= 12+4+6+20
= 42バイト



パターンB = ユーザ使用サイズ(関数Bの場合)+サービス・コールの引数用サイズ(snd_mbx)+6+20
= 20+0+6+20
= 26バイト



以上のパターンAとパターンBを比較し,最もスタックが使用されるものはパターンAの42バイトです。

システム・コンフィギュレーション・ファイルへ指定するサイズは,上記から6を減算した36バイトとなります。