Previous: 8. メモリ管理 |
Up: 8. メモリ管理 |
Next: 8.2. スタックオーバーフローの検知 |
FreeRTOSでは複数のタスクを並行して実行可能ですが、これは、実行中でないタスクの状態(変数・レジスタ)をすべてメモリに保存しているからこそ行える仕組みです。この仕組みの実現のため、FreeRTOSはタスクの作成の際には、そのタスク専用のメモリ領域を確保します。このメモリ領域のことをRTOSではスタック領域と呼んでいます。各タスクはスタック領域内に、そのタスクで使用する変数を記録します。加えて、コンテキストスイッチが発生する際には、CPUのレジスタをスタック領域に待避(保管)します。
そうするとタスクの作成の際に確保するスタック領域は、そのタスクで使用する変数とレジスタを保管するのに十分な容量を持っていることが必要になります。ここでいう領域の容量とは、タスクの作成時にxTaskCreate関数の引数usStackDepthで指定する数値のことです。
スタック領域の容量がどれぐらい必要なのかを簡単に見積もることができればよいのですが、これはそう簡単にはいきません。タスク内で宣言されている自動変数というのはタスク毎に異なりますし、タスク内で呼び出している関数がまた変数を宣言するという場合も多いでしょう。タスク内のシナリオがどう展開するかによっても、変数の使用量は異なるはずです。
スタックが足らなくなることをスタックオーバーフローと呼んでいます。通常スタックオーバーフローが発生すると、OSの動作が停止します。システム全体にとっては致命的なエラーです。
そこでタスクには十分なメモリ領域を割り当てたいところです。しかし組み込みマイコンのRAM容量は限定的です。STM32は8ビットクラスのマイコンに比べると潤沢なRAM容量がありますが、それでもむやみやたらに容量を割り当てていくと、すぐにメモリが足らなくなってしまいます。
そこで現実的には、通常のタスクで必要になるスタック領域を算段しておき、足らなければスタック領域を増やすという手順を踏むのがよいでしょう。STM32版のFreeRTOSの場合、推奨されている最小スタック領域の量は128です。これはワード単位なので確保されるスタック領域は512バイトということになります。もっとも筆者が実験した限りでは、128では頻繁にスタックオーバーフローが発生します。192程度にしておくと、安定して動作することが確認できましたので、各サンプルでは192(768バイト)を指定しています。中容量デバイスではRAMが16Kバイトしかないので、タスク一つを動かすためだけに768バイトも必要になるのはちょっとつらいです。そのため実行周期が近いタスクは処理を一つにまとめるなどして、タスクを増やしすぎないという配慮も必要になります。
Previous: 8. メモリ管理 |
Up: 8. メモリ管理 |
Next: 8.2. スタックオーバーフローの検知 |