今回はHALのassert_param()を使ってみます。
投稿時の開発環境を記しておきます。
PC:Windows10 OS
IDE: STM32CubeIDE Version1.3.0
Configurator: STM32CubeMX Version5.6.0
Board: STM32Nucleo-F401RE
アサートとは?
アサート(アサーション)とは、断言、主張などの意味を持つ英語です。
プログラムが実行される時に通常は満たされるべき条件を記述しておき、実行時にチェックする仕組みをアサーションといいます。
開発者はプログラムの任意の位置にアサーションを入れておき、その箇所に差しかかった際に満たされているべき条件を記述しておきます。プログラムは実行時にアサーションの記述した条件を評価し、これが満たされていない場合にはエラーや例外を発生させたり、メッセージを表示する等の処理を行います。
HALでアサートを使うには?
HALでは assert_param()というマクロを使うことができますが、デフォルトでは無効になっています。
プロジェクトの Core\Inc\stm32f4xx_hal_conf.h を開いてみてください。
422行目に以下の記述があります。(コメント部分は省略しています)
#ifdef USE_FULL_ASSERT
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif
ということですから例えば
#define USE_FULL_ASSERT 1
という定義をしてあげればアサーションを仕掛けることができ、その条件がはずれた時に assert_failed() を実行することができるようになります。
assert_failed() は main.c に記述されますので、その中に処理を書きます。
assert_failed()は例えば以下のコードで、printf()出力が動くようにしておけば、どのファイルの何行目でアサーションエラーが発生したのかわかるようになります。
void assert_failed(uint8_t *file, uint32_t line)
{
printf("Assert failed: file %s on line %d\r\n", file, line);
}
コーディングしてみる
それでは実際にassert_failed()の処理が行われるようにして動作を確認してみます。
まず STM32 printf でデバッグする の記事を参考にしてデバッガ上の View にprintf()出力する機能を用意しておきます。
プロジェクトは STM32 HALを使ってI2Cでメモリーにアクセスする で作成したものを使ってみます。
assert_failed()関数は上に記述したものを使いますので、コーディングしてください。
それではエラーが起きるように HAL_I2C_Mem_Write()関数の第4引数を例えば 2 に書き換えてみます。
s = HAL_I2C_Mem_Write(&hi2c1, DEVICE_ADDR, 0, 2, sbuf, BYTES_PER_PAGE, 1000);
ビルドして Run – Debug します。
HAL_Init()でプログラムが停止しますので、SWV ITM Data Console をクリックし、Start Trace ボタンを押します。(以下の画像の〇部分)
Run – Resume すると SWV ITM Data Console にエラーメッセージが表示されました。
いかがでしたか?
皆さまの環境でも、うまく assert_failed()を動かすことができましたか?
HALのAPI関数には、いろいろな場所に assert_param() が実装されています。
その内容を理解していくことでお勉強になります。
ぜひ、arrset_param() を使ってみてください。
コメントを書く