8.2.2. スタックオーバーフローのフック

マイコン入門spacer ad
トップページに戻る(マイコン徹底入門:STM32で始めるARM/Cortex-M3組み込み開発)
「マイコン徹底入門」とは? |  「マイコン徹底入門」を読む |  ダウンロード |  掲示板 |  筆者の自己紹介


Previous: 8.2.1. スタック領域残量の確認

Up: 8.2. スタックオーバーフローの検知

Next: 9. FreeRTOSを利用したマウスロボット


マイコン徹底入門:RTOS編:フリーのリアルタイムOS活用法: 8. メモリ管理: 8.2. スタックオーバーフローの検知:

8.2.2. スタックオーバーフローのフック

 FreeRTOSにはスタックオーバーフローの発生を検知する機能が備わっています。下記のプロトタイプに従ったvApplicationStackOverflowHook関数を作成しておくと、FreeRTOSがスタックオーバーフローを検出したときに、vApplicationStackOverflowHook関数が呼び出されます。この関数の呼び出しの際には、スタックオーバーフローを発生させたタスクハンドラとタスク名が引数として渡されますから、これらをターミナルに表示させるなどして、スタックオーバーフローの原因タスクを特定することができます。なおスタックオーバーフローの検知機能は完全ではなく、スタックオーバーフローが発生しても、vApplicationStackOverflowHook関数が呼び出されない可能性があります。またこの機能を実行させると、プログラム全体の実行速度が遅くなります。

関数名

vApplicationStackOverflowHook関数

関数プロトタイプ

void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed portCHAR *pcTaskName )

動作

スタックオーバーフローが発生したときに実行したい任意の処理をユーザーが定義します。

引数

*pxTask

スタックオーバーフローを発生させたタスクのハンドラ

*pcTaskName

スタックオーバーフローを発生させたタスクのタスク名

戻り値

無し

 繰り返しますが、この関数はFreeRTOSに備わっている関数ではなく、FreeRTOSが呼び出す関数ですので、自分でコーディングしてプログラム中に含めておく必要があります。

 スタックオーバーフロー発生時にvApplicationStackOverflowHook関数が呼び出されるようにしたい場合には、FreeRTOSConfig.h中のマクロconfigCHECK_FOR_STACK_OVERFLOW1又は2に定義されている必要があります。

12かはスタックオーバーフローを検知する方式の違いです。1の場合は、コンテキストスイッチ時に、スタック領域にデータを保存したポインタが確保したスタック領域の範囲内にあるかどうかをチェックします。2にすると、1のチェックに加えて、予めスタック領域の後尾に一定のデータパターンを書き込んでおき、このパターンが書き換えられていないかをチェックします。1より2の方法の方がスタックオーバーフローを検知できる可能性は上がりますが、実行速度はより遅くなります。

 サンプルプログラムでは以下のようにして、スタックオーバーフローの発生時にメッセージを表示させています。引数でタスクのハンドラとタスク名が得られるという仕様ですが、これも確実ではなく、渡されたハンドラやポインタが正しい値とならない場合があります。

void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed portCHAR *pcTaskName)

{

? cprintf("\r\nStack Overflowed.\r\n");

 

? cprintf("The name of the task make its stack overflowed is :");

? cprintf((int8_t *)pcTaskName);

? cprintf("\r\n");

 

? if (pxTask == xHandlerTaskHandle)

??? {

????? cprintf ("The name of the task make its stack overflowed is : HandlerTask\r\n");

??? }

}

 スタック領域を192にして実行した場合には、スタックオーバーフローは発生しません。プログラムは停止せず、実行し続けます。

Handler task called.

89 stack spaces available.

Handler task called.

67 stack spaces available.

Handler task called.

67 stack spaces available.

Handler task called.

67 stack spaces available.

~~~~~~~~~~~~~

 スタック領域を128にした場合には、スタックオーバーフローが発生しますが、プログラムが突然停止するだけで、検知できませんでした。

Handler task called.

7

 スタック領域を64にした場合にはスタックオーバーフローを検知できました。ただし引数は正しくなく、正常に表示されませんでした。

Hellow Cortex-M3/STM32 and FreeRTOS World!

Expand your creativity and enjoy making.

 

Handler task called.

36 stack spaces available.

 

Stack Overflowed.

The name of the task make its stack overflowed is :


 この通りこの検知機能はまだ完全なものではありませんが、大変便利なものですので、今後の改善を期待したいと思います。

コラム 1?2 configTOTAL_HEAP_SIZE

 FreeRTOSConfig.hにはconfigTOTAL_HEAP_SIZEという設定項目があります。これはFreeRTOSが使用することのできるRAMの最大領域です。タスクを増やしていって、使用しているスタック領域の総量がconfigTOTAL_HEAP_SIZE を超えると、タスクの生成に失敗します。そのためconfigTOTAL_HEAP_SIZE は大きめにしておく方がよいのですが、RAMの総量ぎりぎりにしてしまうと、今度はグローバル変数や、OSの管理外の関数が使用するローカル変数の領域が足りなくなります。領域確保に失敗する場合には、リンクエラーになります。コンパイル時リンクエラーが出た場合には、configTOTAL_HEAP_SIZEを増やしすぎではないかチェックするようにしてください。


Previous: 8.2.1. スタック領域残量の確認

Up: 8.2. スタックオーバーフローの検知

Next: 9. FreeRTOSを利用したマウスロボット


このページはITと知的財産の法律情報「法務ネット」の管理人が制作・運営しています。