JP7FKFの備忘録

ヒトは,忘れる生き物だから.

STM32/CubeMX/SW4STM32/ST-Linkv2(nucleo)でLチカする話

前回の記事でmacでのSTMマイコンの開発環境構築までを行った.
macでstm32な環境をとりあえず作る

今回は,構築した開発環境でプロジェクトを作成してプログラムを書き,プログラマ(ST-LINKv2)を利用してマイコンチップにプログラムの書き込みを行い,Lチカを動作させるところまでを紹介しようと思う.

前回の最後でDFUでの書き込みを行いたいと述べたが,ST-LINKを使った方が簡単だったので,まずはそちらの手法を述べたいと思う.

STM32CubeMXでコードを生成する

STMマイコンのプログラムを書くにあたって,ペリフェラルまわりの設定を簡単に行えて,それをコードとして吐き出してくれるのがこのSTM32CodeMXである.これを使うと初期設定がとても楽に行えるので,まずはこれで使うペリフェラルの設定を行う.

STM32CodeMXを開いて,New Projectを選択. f:id:jp7fkf:20171214090035p:plain

するとMCUを選択する画面が現れる.今回は秋月でも手に入る,STM32F042K6T6を利用する.PartNumberSearchから型番を選び,チップを選択してプロジェクトを作成する. f:id:jp7fkf:20171214090049p:plain f:id:jp7fkf:20171214090101p:plain

するとPinOutの画面が出る. 左側にはペリフェラルが並んでおり,使いたいペリフェラルがある場合はここで選択して欲しいペリフェラルを有効にする.すると右側のPinOutの画面にも出力/入力ピン等が反映されるようになっている. f:id:jp7fkf:20171214090117p:plain ここではLチカに最低限必要な設定を行う. 適当なGPIPピンを選択してGPIO_OutPutを選択する. すでに色が変化しているところは何かの機能がすでに予約されているピンなので注意する. f:id:jp7fkf:20171214093308p:plain すると選択したピンはGPIO_OutPutとして設定され,ピンの色が緑色に変化する. さらに,ピンの名前はピンを右クリックし,EnterUserLabelから自由に変更することが可能である. f:id:jp7fkf:20171214093415p:plain f:id:jp7fkf:20171214090301p:plain

次にMCUを動かすクロックの設定を行う. Clock Configurationタブをクリックしてクロックに関する設定を行う. f:id:jp7fkf:20171214090401p:plain 問題がなければそのままの設定で動作する. ペリフェラルによってはクロックの設定が誤っていると動作しないものがあるが,このソフトウェアはそのような状況の場合は警告を出し,自動で訂正する機能が備えてある. 今回は内臓クロック48MHzで動作させる.他にもConfigurationタブ等でペリフェラルの詳細設定ができるが,今回は行わない.参考までにUSBでDFUモードとして動作させる時はconfigurationタブでこんな設定をすれば良さそうである. f:id:jp7fkf:20171214090525p:plain

ここまでできたら,Generate Codeアイコンをクリックしてコードを生成するが,初回はsetting画面が出る. ToolChain/IDEは,System Workbench for STM32を使う場合はSW4STM32を選択する.
(出てこなかったらProject->Settingsを開いて設定する) f:id:jp7fkf:20171214090720p:plain OKをクリックするとコードが生成される. これで基本的なコードの生成は完了だ.

WorkbenchでSTM32CubeMXで生成されたコードを開いてLチカコードを挿入!

ここからは,STM32CubeMXで生成したコードをSystem Workbench for STM32で読み込んでプログラムを記述する過程を紹介する. まずは先ほどCubeMXで生成したコードをインポートする. インポートは下記のofficialのサイトが説明をしてくれているので参照する.
OpenSTM32 Community Site | Importing a STCubeMX generated project

Fileからimportを選択する. Existing Projects into Workspaceを選択して,先ほど生成したコードのディレクトリの該当ファイルをopenする. f:id:jp7fkf:20171214090900p:plain

するとimportされ,Src->main.cを見るとこのようになっている. これらがCubeMXで生成されたコードになる. f:id:jp7fkf:20171214090924p:plain

/* USER CODE BEGIN 〜 */

/* USER CODE END 〜 */

という範囲があるがこのBEGINとENDの中にコードを記述していく. この範囲に記述することで,あとでCubeMXに戻って再度ペリフェラル等の設定を変更してCode Generate を再度行っても,この範囲にあるコードは変更されずに残り,ペリフェラルの初期化コード等がキチンと追加されるようになっている.つまりこの範囲外に書いたコードは再びCode Generate すると消えてしまうことになるので注意する.

ここでコードを一瞥してもらうと,下の方にGPIOのinitがあり,先ほど定義したRED_LED等が見える. f:id:jp7fkf:20171214091011p:plain

これらのGPIOを繰り返しON/OFFするコードを追加しよう.

mainループのwhile内に,

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

という記述があるが,この/* USER CODE BEGIN 3 */の下に

HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_0);
HAL_GPIO_TogglePin(GPIOF, RED_LED_Pin);
HAL_Delay(1000);

を追加しよう. f:id:jp7fkf:20171214091048p:plain

これらメソッドは,HAL Driverを使ってMCUのGPIOとDelayを制御するメソッドである. STM32CubeMXをつかうと自動的にHALなコードが生成され,以前のStdPeriphではなく,HALを使ってコードを書いていくことになるらしい.StdPeriphと比べ,HALは抽象化されており,よりオブジェクト指向的な要素が強いようである.これからの開発にはHALを用いることが推奨されているようなので,今回はHALを用いて書いていく.

HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_0);

はGPIOFのGPIO_PIN_0のOUTPUTを反転させるメソッドである. この辺りの引数に何を入れるかは,先ほど見たMX_GPIO_Initメソッドを覗くことで理解できると思うので割愛する. ピン名には先ほどCubeMXで自分が変更したRED_LEDというPinもLED_RED_Pinという形で指定することができるようだ.

ここまで終了したらBuildをする. とんかちのアイコンをクリックすることでBuildできる. 正しくBuildされるとプロジェクトツリーにBinariesの下に.elfという拡張子でバイナリファイルが生成されているはずである.こいつを次のセクションでMCUに書き込む.

書き込み!

ST-LINKv2をつくる

書き込みをするにあたってwriterを必要とする. 今回はST-LINKv2を使って書き込みを行っていこうと思うが,この書き込み機を買うと結構なお値段となる.今回はSWD方式での書き込みをやっていこうと思うが,SWD方式の書き込み機であれば秋月でも手に入るnucleo boardという開発ボードの一部がこの書き込み機となっており,分離して使用することができる.お値段的にもこちらのほうがリーズナブルなので,今回はこちらのnucleo boardの書き込み機部分(ST-LINKv2部分)を分離して書き込み機に変身させる. とはいっても作業はものすごく簡単で,パキッと折るだけである. 作業自体は下記の記事を参考にすると良いと思う.

NucleoとかいうST-LinkをFRISKケースに入れる - STM32 - Tokoro's Tech-Note
STM32に手を出してみた

あとはピンヘッダ等が邪魔なので取り除く. ジャンパピン部分はジャンパする必要は特にない. CN4という左側の6本のピンヘッダがMCUと接続するピンとなっているので,書き込み機として使いやすいようなコネクタ等に付け替えておくと便利だ. 私は普通のピンヘッダのメスを横につけており,そこからオスオスの延長ケーブル経由で書き込んだりということもできるようにしてある.なかなか便利だ. f:id:jp7fkf:20171214092704j:plain f:id:jp7fkf:20171214092727j:plain 書き込み機の準備はこれで完了である.

チップに配線!

ST-LINKのCN4は上(1番ピン)から下記のようなピンアサインとなっている.

Pin No. Name
1 VDD_TARGET
2 SWCLK
3 GND
4 SWDIO
5 NRST
6 SWO

これらをチップの適切な端子に接続する. 接続するピンに関してはデータシートを参照する.

電源ライン,およびBOOT0ピンの配線も行う. BOOT0ピンはGNDレベルにすることでFlashからロードするモードとなるので,今回はGNDに落とす.

いよいよ書く!

書き込むにはデバイスにあらかじめ3.3Vの電源を供給しておく必要がある.これを忘れると書き込み時にWrong Device Detectedと言われて書き込むことができない.

書き込みを実行するにあたり,Debugのconfigurationを行う. Run -> Debug Configurations を選択し,Ac6 STM32 Debuggingにプロジェクトが設定されていることを確認する.DebugをクリックするとBuildされ,書き込まれる. なお上部のバーの虫のアイコン(BUGだ)でも同様のことができる. f:id:jp7fkf:20171214091450p:plain 書き込みするときのコンソールはこんな感じ.

Open On-Chip Debugger 0.10.0-dev-00275-gd486ac2-dirty (2017-03-06-15:17)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
srst_only separate srst_nogate srst_open_drain connect_assert_srst
srst_only separate srst_nogate srst_open_drain connect_assert_srst
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : clock speed 950 kHz
Info : STLINK v2 JTAG v23 API v2 M v10 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 0.007890
Error: target voltage may be too low for reliable debugging
Info : STM32F042K6Tx.cpu: hardware has 4 breakpoints, 2 watchpoints
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
adapter speed: 950 kHz
STM32F042K6Tx.cpu: target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0xc1000000 pc: 0x08000e74 msp: 0x20001800
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
adapter speed: 4000 kHz
** Programming Started **
auto erase enabled
Info : device id = 0x10006445
Info : flash size = 32kbytes
STM32F042K6Tx.cpu: target state: halted
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x2000003a msp: 0x20001800
wrote 5120 bytes from file Debug/led_test.elf in 0.310023s (16.128 KiB/s)
** Programming Finished **
** Verify Started **
STM32F042K6Tx.cpu: target state: halted
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x2000002e msp: 0x20001800
verified 4612 bytes in 0.047620s (94.580 KiB/s)
** Verified OK **
** Resetting Target **
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
adapter speed: 950 kHz
shutdown command invoked

きちんとSTLINKv2として認識されて書き込みとVerifyができた. 正しく書き込めるとnucleoなST-LINKv2のLEDが緑色に光るようだ. 書き込み機をマイコンから外して,電源ON/OFFまたはリセットをしてもきちんと動く.

f:id:jp7fkf:20171214092958j:plain

これでLチカまで到達できた. Lチカができたということは開発の一通りの流れが理解できたということなので,ここまでくればこっちのものである.あとは自由にペリフェラルを追加して自分の思うままにコードを書くだけだ.めでたし.

ちなみに種々のペリフェラルに関しては下記の記事がとても参考になる. CubeHALでSTM32を使うお勉強 : しろうさぎのblog

References