STM32でWDTでプログラム暴走時のリスタート処理
1.本日の内容
(1) プログラム暴走時のリスタート処理について、説明する。
(1) STM32マイコンで、WDT(ウォッチドックタイマ)の中でもIWDGを使用して、
プログラムが強制リセット出来ることを確認する。
・目次
2.内容
(1) やる内容の詳細
・CubeIDEでIWDGの設定を行う。
・IWDGの開始及びリセットのプログラムを作成する。
・カウンタを用意し、下記2点を確認する。
(a) WDTをリセットしなかった場合、マイコンが強制リセットされ、
カウントの値がリセットされるか。
(b) WDTをリセットした場合、マイコンの強制リセットされず、上昇し続ける。
(2) CubeMXの設定
・カウント確認用にprintfを使用する為、下記記事のUARTのピンを設定する。
→STM32マイコン_2(UART通信:TeraTermにHellow表示) - Project_OKI’s diary
・CubeIDEのIWDGの設定 (※CubeMXもCubeIDEも基本設定内容は同じ)
(a) Pin設定画面のSystem CoreのIWDGを選択
(b) Activatedのチェックを入れる。
これによって、IWDGがEnableになる。
IWDGの設定項目は主に3つあり、この3つの項目からリセットまでの時間を決定する。
(c) IWDG couter clock prescaler :今回は256
(d) IWDG down-counter reload value:今回は250
(e) LSIクロック周波数:今回は32kHz
(f) 今回は、(c)~(e)の設定にし、2秒間WDTがクリアされなかったら強制的にマイコンをリセットするようにした。
計算: IWDGタイムアウト期間 =
(IWDG down-counter reload × IWDGカウンタクロックプリスケーラ) / LSIクロック周波数
IWDGタイムアウト時間 = 250 × 256 / 32000[Hz]
= 2 [s]
(3) プログラムの作成
動作:LEDを500ms点灯、500ms消灯を繰り返す。
・500msでiのカウントを+1。
・IWDGをクリアした時としなかった時のiの値を比較する。
・IWDGをクリアしなかった場合2秒でリセットする為、
4カウント目を表示せず1からのカウントに戻る。
※printfについては、下記記事を参照。
この記事のprintf.c及びprintf.hを使用している。
/* USER CODE BEGIN Includes */ #include "printf.h" /* USER CODE END Includes */
/* USER CODE BEGIN 1 */ //変数宣言、初期化 uint8_t x = 0; //LED ON/OFF変更用変数 uint8_t i=0; //カウント用変数 /* USER CODE END 1 */
/* USER CODE BEGIN 2 */ setbuf(stdout,NULL); //ウォッチドックタイマ開始 MX_IWDG_Init(); /* USER CODE END 2 */
/* USER CODE BEGIN 3 */ //LED点滅 HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,x); i++; if(i<10){ //5秒以下の時 x = (x == 0) ? 1 : 0; //LED ON/OFF変更 } HAL_Delay(500); //0.5秒wait //IWDGの確認 //IWDGによってリセットされた場合i=0にリセットされる。 //IWDGによってリセットされない場合iは増加していく。 printf("i=%d\n",i); //IWDGクリア:これが有効になってない場合2秒でシステムがリセットする。 HAL_IWDG_Refresh(&hiwdg); } /* USER CODE END 3 */
STM32マイコンのIWDGの動作を確認 pic.twitter.com/7LBwu4slDS
— Project OKI (@oki_project) 2023年3月4日
(4) プログラムの説明
(5) 用語説明
WDT(ウォッチドックタイマ)について
(a) 組み込みにおいて、何かの拍子にプログラムが暴走し、
意図せず停止してしまった場合、それを検出する必要がある。
この異常検知としてウォッチドックタイマ(WDT)が使用される。
(b) WDTを開始すると、カウントが開始される。
指定したカウントになるとマイコンが強制的にリセットされる。
これにより、プログラムが停止した場合、強制リセットすることが出来る。
(c) (2)によって、マイコンがリセットしないように、
通常時はカウントをリセットして初期値に戻す必要がある。
使い方としては、
・WDTを開始(WDT時間を指定)
・プログラムのどこかでWDTをリセット
という形になる。
そのため、設計時に、WDTをリセットする部分について検討しておく必要がある。
(d) STM32には、2つのWDTが存在する。
・IWDG(Independent Watchdog):独立型ウォッチドッグ
→独立した内部オシレータ(LSI)のクロック信号を使用し、
あらかじめ決められた時間をカウントする。
その時間内にカウントがリフレッシュされなかった場合、
システムをリセットする。
→クロックの安定性の低下、ソフトウェアの無限ループ、フリーズなど
システムが停止してしまった場合などの対策として使用される。
・WWDG(Window Watchdog):システムウィンドウ型ウォッチドッグ
→マイコンのメインクロック(APBクロック)を使用し、
あらかじめ設定された時間内にリフレッシュされなかった場合又は、
許容した時間範囲(ウィンドウ)を設定し、
ウィンドウ外でWWDGがリフレッシュされた場合、
システムをリセットする。
・違い
IWDGは、独立したクロックを使用するのに対し、
WWDGは、マイコンのメインクロックを使用する。
IWDGは、早いタイミングでリセットされても、動作し続けるが、
WWDGは、早いタイミングでリセットされた場合などの検知し、
システムをリセットさせることも可能。
どちらもソフトウェアの障害の検知に使用される。
特にWWDGは、正確なタイムウィンドウ内で動作する必要のあるアプリケーションで使用する。
参考:
3.関連記事
・STM32マイコン_2(UART通信:TeraTermにHellow表示) - Project_OKI’s diary
・STM32マイコン_3(UART通信:複数文字送信) - Project_OKI’s diary
・STM32マイコン_4(NVICの設定内容) - Project_OKI’s diary
・STM32マイコン_5(スイッチ入力とLED点灯、消灯) - Project_OKI’s diary
その他:
・CubeIDEの使い方(起動~デバック実行) - Project_OKI’s diary
C言語:
・組み込みの為のC言語基礎知識1(printf) - Project_OKI’s diary
・C言語基礎知識2(for分で処理を繰り返す) - Project_OKI’s diary
・C言語基礎知識3(配列) - Project_OKI’s diary