LoginSignup
1
3

More than 5 years have passed since last update.

STM32CubeMX:チュートリアル 1 RTOSでLチカしてみる

Last updated at Posted at 2018-06-19

追記
 CubeMXのバージョンアップに合わせて書き直しました
 STM32CubeMX:RTOSでLチカしてみる(v4.26.1)


対象

  • STM32マイコンを使いたい人
  • 各種エラーにめげず自分で解決できる人

開発環境

  • Win10 pro (April 2018 Update / 1803)
  • Windows Subsystem for Linux
  • STM32CubeMX v4.25.1
  • Visual Studio Code
  • arm-none-eabi-gcc 2017q4 major
  • dfuw(0.11)
  • STBee F4mini (STM32F405RGTx)

目標

  • FreeRTOSを使ってLチカを行う
  • 最低限のC++環境を整える

開発環境の構築

 Win10/WSLが必要です(それ以外の環境の場合、make等のUNIXライクコマンドを使えるようにしておいてください)。


 GCCは以下のリンクからダウンロードできます
 GNU Arm Embedded Toolchain | Downloads – Arm Developer

 Windows ZIPをダウンロードします。
 展開するとarm-none-eabi, bin, lib, shareの4フォルダになります。
これをC:\Devz\ARM\launchpadフォルダにコピーします。
bashで/mnt/c/Devz/ARM/launchpad/bin/arm-none-eabi-gcc.exe --versionが実行できれば大丈夫です。


 DFUWは以下のリンクからダウンロードします。
 STBee - DFUWでプログラムを書き込む

 ダウンロードしたら、適当な場所に展開しておきます。


 CubeMXやVS Codeは各自インストールしてください。CubeMXはちょっとクセが強いかもです。諦めずに頑張りましょう。


 STBee F4miniボードは基本的に買ったままで使えますが、できればUSBコネクタの横にあるBOOT0と書いてある3ピンのスルーホールの真ん中とPA0をジャンパしておくと便利です。こうすることにより、USR SWを押しながらリセットすることでUSB DFUを起動できます。

プロジェクトの作成

MCUの選択

2018-06-18_16-32.png

 STM32CubeMXを開き、New Project...(Ctrl-N)でNew Project画面を開きます。アップデートのチェックにそれなりに時間がかかるので、気長に待ちましょう。でもあんまり長過ぎる時は途中で止まってるかもしれません。

 左側のPart Number SearchでMCUの型番を入力します。MCU Listで目的のMCUをダブルクリックすると決定します。
 リストの左の星アイコンをクリックすると黄色くなり、次からはMCU Filtersの左上の黄色い星のアイコンでそのMCUを表示することができます。

プロジェクトの設定

 Project->Settings...からProject Settings画面を開きます。

2018-06-18_16-40.png

 Project Nameにプロジェクト名を設定します。
 Project Locationに適当なフォルダを選択します。

 Project Locationの中にProject Nameのフォルダ名が作成され、その中に各種ファイルが生成されます。

 Toolchain / IDEをMakefileに変更します。

 Code Generatorタブを開きます。

2018-06-18_16-41.png

 上図のようにチェックボックスを設定します。

 OkでProject Settingsを閉じます。

ハードウェアの設定

2018-06-18_16-46.png

 左側のツリーからRCCを展開し、High Speed Clock (HSE)をCrystal/Ceramic Resonatorに設定します。

 MCUのアイコン、左下のPA0をクリックし、GPIO_Inputを選択します。PA0を右クリックしEnter User LabelからUSER_SWと名前を設定します。
 同様に右上のPD2をGPIO_Output, USER_LEDと設定します。

クロックの設定

 Clock Configurationタブを開きます。

2018-06-18_16-49.png

 左側のInput frequencyを12に、PLL Source MuxをHSEに、System Clock MuxをPLLCLKにし、最後にHCLK to AHB bus, core, memory and DMA (MHz)に168と入力しEnterで決定します。
 これにより各逓倍・分周比が自動的に設定されます。

ソフトウェアの設定

 Configurationタブを開きます。

 左側のツリーから、FREERTOSのEnableをチェックします。
 右側のMiddlewaresのFREERTOSボタンをクリックします。

2018-06-18_16-52.png

 Config parametersタブから、USE_IDLE_HOOKをEnableに設定します。

 OkでFREERTOS Configurationを閉じます。

コードの生成

 Project->Generate Code(Ctrl-Shift-G)でコード生成を開始します。
 この際、FreeRTOSを使用している時にWARNINGが出ます。今の所、僕の使う範囲ではこれに関連する不具合は発生していません。ということで、気にせずにYesで続行しています。
 未確認ですが、おそらくFreeRTOSのコンテキストスイッチを1kHz以外にした場合や、割り込み処理の中でHALのTimeout系関数を呼んだ場合などで不具合が発生すると思われます。
 そのような状態で使用する場合はSYSのTimebase Sourceを変更してください。

 コード生成が終了すれば成功した旨のダイアログが表示されます。

コードの修正

 プロジェクトフォルダをVisual Studio Codeで開いてください。

Makefileの修正

 C_SOURCESで誤って絶対パスが指定されているファイルが有れば、適切に修正しておきます。具体的には、/Src/system_stm32f4xx.c \Src/system_stm32f4xx.c \に変更します。
 Cubeでコードを生成した場合、毎回system_stm32f4xx.cを絶対パスライクでC_SOURCESに追加しています。2回目以降の場合は、すでにC_SOURCESに追加されているので、新しく追加された絶対パスライクな方を削除します。

 C_SOURCESの下辺りに以下のコードを追加します。

CPP_SOURCES = \
Src/CCM.cpp \

 99行目前後、BINPATH =BINPATH = /mnt/c/Devz/ARM/launchpad/binに変更します。
 また、CC, AS, CP, AR, SZにそれぞれ.exe拡張子を追加します。
 CCの下の行にCPP = $(BINPATH)/$(PREFIX)g++.exeを追加します。

 162行目前後、CFLAGS +=-MT"$(@:%.o=%.d)"を削除します。

 174行目前後、LDFLAGS-specs=nano.specsを削除します。

 184行目前後、OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))OBJECTS = $(addprefix $(BUILD_DIR)/,$(C_SOURCES:.c=.o))に変更します。また、そのすこし下のOBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))OBJECTS += $(addprefix $(BUILD_DIR)/,$(ASM_SOURCES:.s=.o))に変更します。

 適当な所(# list of ASM program objectsの直上など)に以下のコードを追加します。

OBJECTS += $(addprefix $(BUILD_DIR)/,$(CPP_SOURCES:.cpp=.o))
vpath %.cpp $(sort $(dir $(CPP_SOURCES)))

 適当な所($(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)の上など)に以下のコードを追加します。

DEPS = $(OBJECTS:%.o=%.d)
-include $(DEPS)

 195行目前後の$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)の直下にmkdir -p $(dir $@);を追加します。

 197行目前後の$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@$(CC) -std=c11 -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(<:.c=.lst) $< -o $@に変更します。

 適当な所に以下のコードを追加します。

$(BUILD_DIR)/%.o: %.cpp Makefile | $(BUILD_DIR)
    mkdir -p $(dir $@);
    $(CPP) -std=c++14 -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(<:.cpp=.lst) $< -o $@

 207行目前後、$(CC) $(OBJECTS) $(LDFLAGS) -o $@$(CPP) $(OBJECTS) $(LDFLAGS) -o $@に変更します。

VS Codeの設定ファイルの作成

 とりあえず適当なソースファイル(Src/freertos.c等)を開いておきます。

 Ctrl-Shift-Pを押し、コマンドパレットを開き、>c/cpp:editconfigurationsと入力してc_cpp_properties.jsonを作成します。

 "includePath""defines"をMakefileにあるように変更します。
 "compilerPath""/mnt/c/Devz/ARM/launchpad/bin/arm-none-eabi-gcc.exe"に変更します。
 "cStandard""c11"なのを確認し、"cppStandard""c++14"に変更します。
 以下のようになるはずです。

"includePath": [
    "${workspaceFolder}/Inc",
    "${workspaceFolder}/Drivers/STM32F4xx_HAL_Driver/Inc",
    "${workspaceFolder}/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy",
    "${workspaceFolder}/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F",
    "${workspaceFolder}/Drivers/CMSIS/Device/ST/STM32F4xx/Include",
    "${workspaceFolder}/Middlewares/Third_Party/FreeRTOS/Source/include",
    "${workspaceFolder}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS",
    "${workspaceFolder}/Drivers/CMSIS/Include"
],
"defines": [
    "USE_HAL_DRIVER",
    "STM32F405xx"
],
"compilerPath": "/mnt/c/Devz/ARM/launchpad/bin/arm-none-eabi-gcc.exe",
"cStandard": "c11",
"cppStandard": "c++14",

リンカスクリプトの変更

 STM32F405RGTx_FLASH.ldを開きます。

 142行目前後の*(.ccmram*)の直下に*CCM.oを追加します。

FreeRTOSの設定の変更

 Inc/FreeRTOSConfig.hを開きます

 169行目前後、/* USER CODE END Defines */の直上に#define configAPPLICATION_ALLOCATED_HEAP 1を追加します。

Src/CCM.cppの追加

 SrcにCCM.cppファイルを作成し、以下のコードを入力します。

#include <FreeRTOS.h>

#if (configAPPLICATION_ALLOCATED_HEAP == 1)
uint8_t ucHeap[configTOTAL_HEAP_SIZE] = {1};
#endif

FreeRTOSのタスクの変更

 Src/freertos.cを開きます。

 56行目前後、USER CODE BEGIN Includesの下に#include <stm32f4xx.h>を追加します。

 80行目前後、vApplicationIdleHook関数の中にHAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);を追加します。

 131行目前後、StartDefaultTask関数の中にあるfor (;;)無限ループの中を以下のように書き換えます。

HAL_GPIO_TogglePin(USER_LED_GPIO_Port, USER_LED_Pin);
osDelay(HAL_GPIO_ReadPin(USER_SW_GPIO_Port, USER_SW_Pin) == GPIO_PIN_SET
            ? 100
            : 500);

ビルド

 プロジェクトフォルダをbashで開き、makeを実行するとビルドが始まります。正常に終わればプロジェクトフォルダ/build.bin, .dfu, .elf, .hexのようなファイルが作成されます。

書き込み

 DFUWを解凍して出てきたdfuw-0.11の中にあるdfuw.exe*.hexをドラッグアンドドロップすると書き込みが始まり、書き込みが終わればコンソールが消えます。
 MCUがDFUモードで接続されていない等、エラーが有るとすぐに画面が消えていまいます。
 ということで、dfuwはコマンドプロンプト(cmd.exe)で実行しておくと便利です。

実行

 リセットスイッチを押してMCUをリセットします。
 うまく動けばUSER LEDが1Hzで点滅します。また、USER SWを押すと、USER LEDが5Hzで点滅します。

まとめ

 ということで、STM32CubeMXでプロジェクトを作成してから書き込む所までを駆け足で解説してみました。
 Arduinoやmbedと比べるとLチカするまでがとても面倒ですが、STBee F4miniならArduinoよりも安く、STM32F0のやすいチップ単体ならPIC16よりも安いです。またSTBee F4miniはmbedよりも高速で動作します。STM32は比較的入手性が良く、またバリエーションも豊富なため、自分で好きなMCUを使えるようになれば幅広い範囲で使うことができるはずです。

 今回の方法ではprintfやmalloc/free、new/delete等は使うことができません。そのあたりは注意してください。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3