Project_OKI’s diary

エンジニアの勉強ブログ

STM32マイコン23(WDTでプログラム暴走時のリスタート処理)

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

UART

 

 ・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] 

 

IWDG設定1

 

IWDG設定2

 

(3) プログラムの作成

動作:LEDを500ms点灯、500ms消灯を繰り返す。

 ・500msでiのカウントを+1。

 ・IWDGをクリアした時としなかった時のiの値を比較する。

 ・IWDGをクリアしなかった場合2秒でリセットする為、

  4カウント目を表示せず1からのカウントに戻る。

 

※printfについては、下記記事を参照。 

 この記事のprintf.c及びprintf.hを使用している。

 ・STM32マイコン22(printfのソースファイル、ヘッダファイルの作成)
 
main.c
/* 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 */
動作確認

 
(4) プログラムの説明
 (a) MX_IWDG_Init();
  ・IWDGを初期化するための関数
  ・CubeIEDの設定によって自動生成した内容が反映される。
 
 (b)  x = (x == 0) ? 1 : 0; //LED ON/OFF変更
  これは、下記プログラムを条件演算子によって短くしたもの。
  動作は同じとなる。
if(x == 0){
	 x = 1;
}else{
	 x = 0;
}
  条件演算子参考:C言語基礎知識21(演算子) - Project_OKI’s diary
 
 (c) HAL_IWDG_Refresh(&hiwdg);
  IWDGをリフレッシュする為の関数。
  これが実行されると、IWDGカウンタが最大値にリセットし、
  IWDGタイマを再開される。
  規定時間内にこれが実行されないと、自動的にシステムがリセットされる。
   
(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は、正確なタイムウィンドウ内で動作する必要のあるアプリケーションで使用する。

 

   参考:

   ・STM32WB-WWDG資料(pdf)

   ・STM32WB-IWDG資料(pdf)

   ・STM32 WDG機能注意点: Crescent

    ・WatchDogタイマで対策

 

3.関連記事

関連記事一覧:
 
組み込みC言語