STM32CubeMXが生成するプロジェクトと自動生成ファイルのユーザ処理追記箇所を解説します。STM32マイコンのソフト開発は、この出力ファイルへ、ユーザ処理コードを追記して完成しますので、どのファイルのどこに追記すれば良いかを知ることが重要です。
前回記事でSTM32CubeMXの使用ライブラリにHAL: Hardware Abstraction Layerを選びました。UM1718の5章に、HAL単独、LL単独とHAL/LL混合の各ライブラリ使用時のSTM32CubeMX生成ファイル詳細説明があります。本ブログ記事は、このHAL単独版に相当します。
STM32CubeMXの設定条件
STM32CubeMXは、設定により出力プロジェクトの生成ファイルが様々に異なりますので、STM32マイコンテンプレート開発で使う下記条件でコード生成します。
前提条件
評価ボード:STM32F072RB(ARM Cortex-M0)
3ウイザード:Pinout、Clock Configurationは評価ボードデフォルト設定、ConfigurationはEXTI line 4 to 15 interruptsに☑設定
使用ライブラリ:HAL
出力プロジェクトとユーザ処理追記が必要なファイル
STM32CubeMXの出力プロジェクトのうち、ユーザ処理を追記する必要があるファイルは、Inc(ヘッダーファイル)とSrc(ソースファイル)にあります。これらInc/Srcフォルダ内のファイル概要とユーザコード追記箇所の有無一覧が下記です。
フォルダ>ファイル | 概要 | ユーザ処理追記箇所 | STM32CubeMX再生成時 | |
Src | main.c | main処理(動作クロックとHAL初期設定生成コード含む) | あり | ユーザ処理以外上書き |
stm32f0xx_it.c | 割込み処理(EXIT1 4_15) | あり(自動割付済み) | ||
stm32f0xx_hal_msp.c | HAL MSP処理とエラー処理 | あり(可能性は低い) | ||
system_stm32f0xx.c | システムクロック設定 | なし | ||
Inc | main.h | IOピンのラベル定義 | あり(Pinoutウイザード設定分のみ) | 完全上書き |
stm32f0xx_it.h | 割込み定義 | なし | ||
stm32f0xx_hal_conf.h | HAL構成定義 | なし |
Incフォルダのmain.hユーザ追記部分は、Pinoutウイザードでピン名を追加した分のみです。つまり、ウイザード出力があるだけで実質ユーザ追記は不要です。STM32CubeMXで再度コード生成した場合は、ヘッダーファイルは全て上書きされます。
従って、再生成してもユーザ追記コードが残るのは「あり」で示した、main.c、stm32f0xx_it.c、stm43f0xx_hal_msp.cのSrcフォルダ内の3ファイルです。
このうちstm43f0xx_hal_msp.cは、HALライブラリのMSP: MCU Support Package処理(≒ハード抽象化)やエラー処理ファイルですので、通常はユーザが追記する可能性は低いと思います。
結局、ユーザ処理の追記が必要なファイルは、Srcフォルダのmain.cとstm32f0xx_it.c(割込み処理)の2ファイルです。
ユーザ追記コード(割込み処理)
先ず、割込み処理を説明します。
HALライブラリを使うと、割込みの前処理(割込み要因フラグ確認、フラグリセット、ユーザ処理関数callback)は、全てSTM32CubeMXが自動生成する割込みハンドラが行います。但し、この割込みハンドラ名には、HAL_という接頭語が付いていて、コアの割込みハンドラ名と異なるため、コア割込みハンドラと生成割込みハンドラの対応付けが必要です。
このハンドラ名称の対応付けを行うのが、stm32f0xx_it.cです。評価ボードのデモソフト(STM32マイコン統合開発環境参照の5)動作検証参照)の例で示すと、stm32f0xx_it.cの下記部分です。但し、この割付は、ConfigurationウイザードでEXTI line 4 to 15 interruptsに☑設定した結果、自動割付済みです。つまり、ここもウイザード出力結果が反映されていて、実質ユーザ追記が不要です。
ハンドラがコールするユーザ処理関数は、Callback以外がハンドラ名と同じHAL_GPIO_EXIT_Callback()という関数名というSTM独自の決まりがあります。このCallback関数は、main.c内にあり下記部分です。
まとめると、割込み処理は
EXTI4_15_IRQHandler()は、 コアの割込みハンドラ(startup_stm32f072xb.sに記述)
HAL_GPIO_EXTI_IRQHandler()は、 STM32CubeMX自動生成の割込みハンドラでHAL_GPIO_EXTI_Callback()をコールバック
HAL_GPIO_EXTI_Callback()は、 ユーザが追記する割込み処理でmain.cに処理内容を追記
という3段構成なので、最終的にユーザが追記する割込み処理の箇所は、Callback()の中身つまりmain.cのみです。
ユーザ追記コード(割込み処理以外)
当然main.cは、割込み処理以外にも、様々なユーザ処理を追記します。STM32CubeMXが自動生成する「ナマ(生)のmain.c」を以下に示します。
ユーザ追記箇所を解り易くするために、ソースを折りたたんでいます。先に示した割込み処理HAL_GPIO_EXTI_Callback()の追記箇所は、ソース構造から、USER CODE BEGIN 4の個所であることが判ります。
/* USER CODE BEGIN xyz */から/* USER CODE END xyz */のコメント間にユーザ処理を追記すれば、STM32CubeMXで再生成しても追記部分は、そのまま残ります。
USER CODE xyzのコメントを読んで、追記が必要なユーザ処理を追加していきます。但し、GPIOやシステム動作クロックの初期設定は、STM32CubeMXが自動生成済みですので、更なる追記は、本当にユーザ処理の部分のみということが判ります。デモの場合なら、LED2の点滅速度変更処理LED2_Blink()のみです。
以上をまとめると、STM32CubeMXが自動生成するプロジェクトとファイルへは、
- 3ウイザードさえ間違わずに設定すれば、main.cのみの最小限ユーザ追記でアプリ完成
- たとえウイザード設定に間違えても修正し再生成すれば、USER CODE xyzへ追記したユーザコードは保持され安心
STM32CubeMX自動生成の活かし方
プログラムサイズが大きい場合には、全てのユーザ追加ソースを1つのmain.cファイルに記述するのは現実的ではありません。しかし、単機能のサンプルソフト程度であれば、STM32CubeMXが自動生成するmain.cへユーザ処理を追記してもさほど可読性は悪くなりません。
STM32CubeMXは、STM32マイコンソフトを効率的に開発するツールです。なるべく小さく単機能ソフトをSTM32CubeMXで開発し、単体でバグが取れた後に、各機能を結合して目的のソフトへ仕上げるのが、STM32CubeMX自動生成出力を活かす方法です。
この活かす方法を使って次回は、評価ボードUART入出力をUSB経由でパソコンと繋げるUART-USB(VirtualUART)機能と、評価ボードデモの2つを結合し、パソコンコマンドでボードのLED点滅速度を変えるソフト開発の話をする予定です。これは実は、STM32マイコンのシンプルテンプレートに相当します。ご期待ください。
※固定ページ(本ブログの上部タブリンク)を、CurieからSTM32Fxマイコン開発へ全面変更いたしました。