CubeMXに慣れるために、LEDチカチカを作ってみました。ホストOSはLinux、ターゲットはNucleo F722です。ビルドはSW4STM32を使います。
なお、CubeMXのオンラインマニュアルは非常に良く書かれています。一度通して読んだ方がいいでしょう。300ページも有りますが、1300ページ有るリファレンス・マニュアルを精読するよりも楽です。
準備
最初にSW4STM32とCubeMXはインストールしておいてください。また、SW4STM32のプロジェクトを作るために、SW4STM32でワークスペースを作っておいてください。
CubeMXで設定を行い、スケルトンプロジェクトをSW4STM32で作ったワークスペース内に出力します。順番を逆にすると最初からやり直しです(切り抜ける方法はあるけれど面倒)。
CubeMXの起動とターゲットの選定
ワークスペースを作り終えたらCubeMXを起動します。起動すると以下のような画面が現れます。
無駄に大きな画面ですが、ここでは新規でスケルトンを作るか、以前作ったスケルトンを編集するか選びます。以前作ったスケルトンを編集する場合も、ユーザーが追加したコードは変更されずに残すことができます。ルールを守って書けば、ですが。
新しいスケルトンを作るためにNew Projectをクリックします。すると、以下の画面が現れます。
これはチップ選択画面で、たくさんあるSTM32シリーズの中からターゲットMPUを選ぶことができます。ST Microelectornicsは非常に多くのMPUを製造しており、パッケージ品種やコア品種をフィルタとして選択を絞ることもできます。
ところで、隣のタブをクリックするとボード選択画面になります。
これはST Microelectronicsが製造しているボードの一覧です。
MPUと違ってボードはLEDやボタンスイッチといった配線済みペリフェラルや、発振器の初期化パラメタが設定されています。MPUから設定してもいいのですが、まずはツールになれると言うことでボードを選びます。
Nucleo F722ZEをダブルクリックします。
設定画面を概観する
ボードをダブルクリックすると新規プロジェクトが開きます。
デフォルトでは、Pinoutの設定が面が表示されています。
この設定画面はPinoutタブの画面なのですが、少々名前が紛らわしいです。
確かに右側の画面はICのピンを見ながら、その機能を設定できます。しかしながら、左側は利用する機能の設定であり、直接ピンを操作できるわけではありません。これは少々戸惑いました。
左側のツリーを操作して「この機能を使う」「このミドルウェアを使う」と設定していきます。今回はLチカが目的です。LED用の出力ピンはデフォルトで設定されているので特に触る必要はありません。
機能モジュールとしてはFreeRTOSにチェックを入れておきます。
となりのタブはClock Configurationです。
これがCubeMXの真骨頂と言えるところで、面倒なクロックツリーの設定をマウスだけで終わらせることができます。これを使うためだけでもCubeMXを学ぶ価値があります。今回はデフォルトでNucleo用に設定が終わっているため、何もする必要はありません。
そのとなりのタブはConfigurationです。
これはPinoutで選んだ機能モジュールやハードウェア・モジュールの設定を行います。今回は特に何も変更しません。
スケルトン・プロジェクトを生成する
メニューバーからProject -> Generate Codeを選ぶと、スケルトンを含んだプロジェクトの生成が始まります。
生成前に最終設定用のダイアログが現れます。この辺は多少ちぐはぐしたUIです。
ダイアログのProjectタブではどのようなプロジェクトを生成するか指定します。Project Nameは好きな名前にしてください。Project Locationは先ほどSW4STM32で作成したワークスペースを指定します。Toolchain Folder Locationは無視して結構です。
Toolchain/IDEは、ビルドに利用する環境を指定します。SW4STM32を選びます。
Code Generatorについては、まずはデフォルトでかまいません。ここでOKを押すとビルドが始まります。
のですが、必要なファームウェア・パッケージが無いのでダウンロードしてよいかという確認が。
よいです。
545MBのダウンロードが始まりました。コーヒーでも飲みましょう。
タイムベースの変更
どういうわけか、デフォルトのパラメタに一部修正が必要です。
コーヒーを飲み終えた頃、ダウンロードが終わるとこんな警告が表示されました。
FreeRTOSを使う場合にはHALのタイムベースをSystick以外にした方がいいよという警告です。Systickはコア内部にありますから、通常のタイマと扱いが違いますしね。ここでは一旦 Noを押してコードの生成を中止します。
Pinoutタブに戻り、Sysノードを展開します。これはシステム設定ですが、この中にTimebase Sourceがあります。SystickからTIM14に変更しました。TIM14はたくさんあるタイマの最後のものです。タイマーをたくさん使う場合には、低機能タイマをTimebase Sourceにするとよいでしょう。
さて、変更して再度メニューバーからProject -> Generate Codeを選ぶと、無事コード生成が終了します。
Open Projectを押しましょう。SW4STM32が起動します。
SW4STM32でビルド、実行する
SW4STM32が起動したら、先ほど作ったワークスペースを開いてください。生成したプロジェクトが登録されているはずです。
ここでプロジェクトをクリックして選択し、右クリックでコンテキスト・メニューの中からBuildを実行しましょう。
特に問題なくビルドは終了するはずです。表示されているのは生成されたコードのサイズです。RTOS込みでコードサイズが8kB強ですから、FreeRTOSは随分と小さなカーネルです。
ビルド出来ることを確認したら、次にLEDを点滅するコードを追加します。
追加すべき場所は上の図のmain.c 299行と300行の間です。
StartDefaultTask()はCubeMXが生成したタスクの実行コードです。これは見ての通り1mS遅延を無限に繰り返すループです。この遅延を500mSに変更し、ループの中でLEDを反転すれば点滅コードが完成します。
LEDの点滅はGPIOを使って行います。Nucleoのマニュアルを見ればどのGPIOを使っているかわかりますが、手を抜いてCubeMXを調べましょう。Pinout画面でLD2とラベルが打ってあるピンを調べます。
PB7とありますので、GPIOPのPin7だとわかります。
LEDの点滅にはHAL_GPIO_TogglePin()を使います。HALの名前はST MicroelectronicsのページからUM1905をダウンロードして調べるしかありません。一方、SW4STM32は入力補完機能を持っていますので、HAL_GPIOと入力してAlt-/をタイプすれば、それらしい候補を教えてくれます。大変便利な機能です。
/* StartDefaultTask function */ void StartDefaultTask(void const * argument) { /* USER CODE BEGIN 5 */ /* Infinite loop */ for(;;) { HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7); osDelay(500); } /* USER CODE END 5 */ }
修正が完了したら、ビルドしましょう。問題なければいよいよ実行です。
まず、PCにNucleoをUSBケーブル接続します。接続方法はマニュアルで確認します。正しく認識されているようならば、SW4STM32のメニューバーからRun->Run As->Ac6 STM32 C/C++ Applicationを実行します。
接続にトラブルが無ければ、青いLEDが点滅します。
まとめ
ざっと触ったところでは、CubeMXが出力するコードは面倒な初期化を簡単にしてくれています。今後もう少し深く触ってみます。