hantas's blog

ブログ移転しました→ http://blog.taniho.net/

STM32 Nucleo Boardの開発環境構築

2,3日ほどSTM32と格闘していたのでそのログを残します。
Ubuntu14.04 LTSにgccとst-linkで開発できる環境を整えました。
対象はSTM32F401REのNucleoBoardです。
(STM32 Nucleo Board STM32F401: マイコン関連 秋月電子通商 電子部品 ネット通販)
(とはいえ問題山積み……とりあえずビルド&書き込みができただけです)

また,現在格闘中でもあるので適宜追記更新を入れるので注意してください。

ビルド環境

ビルド環境としてLaunchPad GNU Embedded Toolchainを選択しました。
次のサイトの「ツールチェーンの(再)インストール」の通りに進め,問題もなく完了しました。
Ubuntu(Linux)環境のSTM32(ARM)開発環境についてのメモ その1 | メモたんく
Cコンパイラは"/usr/bin/arm-none-eabi-gcc",インクルードファイルは"/usr/arm-none-eabi/include/"に配置されました。

今回Eclipseは使用しないため,自前でライブラリとMakefileを用意します。
まずはSTの公式サイトからSTM32 Standard Peripheral Libraryをダウンロードしてきます。
Part Number Search ? STMicroelectronics
これを好きなところに展開し,"STM32F4xx_DSP_StdPeriph_Lib"というディレクトリができました。
僕の場合,これと同じディレクトリにプロジェクトのディレクトリを作成し,以降はそのディレクトリ内で作業を進めました。
便宜上,"nucleo_test"というディレクトリを作成し,その中に移動したとします。
まずは必要なファイルをコピーしてきます。
"../STM32F4xx_DSP_StdPeriph_Lib/Project/STM32F4xx_StdPeriph_Templates/"から,
 stm32f4xx_it.c
 stm32f4xx_it.h
 main.c
 main.h
 stm32f4xx_conf.h
 system_stm32f4xx.c

をプロジェクトのディレクトリに放り込みます。
もうひとつ,
"../STM32F4xx_DSP_StdPeriph_Lib/Project/STM32F4xx_StdPeriph_Templates/TrueSTUDIO/STM32F401xx/STM32F401RC.ld"
を,プロジェクトのディレクトリに"stm32_flash.ld"と名前変更して放り込みました。
(とはいえ,これ違う種類のチップのリンカスクリプトなんですよね……。
とりあえずは動きましたが良くないと思います。)

続いてMakefileを準備します。
書くのが初めてなので次の内容を参考にさせていただきました(というか丸コピして必要な箇所を改変しました)。
tokoro10g / VORAS / source / Makefile — Bitbucket
綺麗に書けなかったので要点だけ書き留めておきます。

#インクルードディレクトリを変更(ツールディレクトリも変更)
TOOLDIR = /usr/bin/
INCLUDE_DIRS = -I ../STM32F4xx_DSP_StdPeriph_Lib/Libraries \
				-I ./ \
				-I ../STM32F4xx_DSP_StdPeriph_Lib/Libraries/STM32F4xx_StdPeriph_Driver/inc \
				-I ../STM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Device/ST/STM32F4xx/Include \
				-I ../STM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Include \
				-I $(TOOLDIR)../arm-none-eabi/include \
				-I $(TOOLDIR)../arm-none-eabi/include/c++/4.9.3
#BOARD_DIRを変更
BOARD_DIR = -DHSE_VALUE=\(\(uint32_t\)8000000\) -DSTM32F401xx
#STARTUP_DIRを変更
STARTUP_DIR = ../STM32F4xx_DSP_StdPeriph_Lib/Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc_ride7
#TARGET_ARCHを変更(エラーが出るためFPU設定を消した。良くない)
TARGET_ARCH = -mcpu=cortex-m4 -mthumb
#最終出力ファイルをbin/main.binに変更
bin/main.bin: $(patsubst %.c,%.o,$(wildcard *.c)) $(patsubst %.cpp,%.o,$(wildcard *.cpp)) $(STARTUP_DIR)/startup_stm32f401xx.o ../STM32F4xx_DSP_StdPeriph_Lib/Libraries/libstm32f401xx.a
	$(LD) $(LDFLAGS) $(TARGET_ARCH) $^ -o bin/main.elf
	$(OBJCOPY) -O binary bin/main.elf bin/main.bin

とりあえずこれでmakeが通る……はず(書いてないことがあったかもしれない)。

○参考
Ubuntu(Linux)環境のSTM32(ARM)開発環境についてのメモ その1 | メモたんく
tokoro10g / VORAS / source / Makefile — Bitbucket
STM32F10x Standard Peripherals Firmware Libraryを使う - Wikimura

ダウンロード環境

Ubuntu(Linux)環境のSTM32(ARM)開発環境についてのメモ その1 | メモたんくを参考に「デバッグツールのインストール」を行います。
これで,"st-flash write bin/main.bin 0x08000000"とすることで書き込みができるはずです。
(hexファイルの書き込みはできないのですね。かなり手間取りました)
せっかくなのでMakefileから書き込みができるようにしました。

.PHONY: flash
flash:
	st-flash write bin/main.bin 0x08000000

○参考
Ubuntu(Linux)環境のSTM32(ARM)開発環境についてのメモ その1 | メモたんく

デバッグ環境

参考サイトの通りにst-util,arm-none-eabi-gdbを立ち上げるとgdbが使えました。
gdbを使ったのもこれが初めてなので,また後日まとめます。

○参考
Linux上でSTM32のプログラミング・デバッグ環境を整える - STM32 - Tokoro's Tech-Note

USART

とりあえず次の通りにすれば動いた。

	SystemInit();
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

	GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	//なぜかボーレートを3倍しないといけなかった。
	USART_InitStructure.USART_BaudRate = 9600*3;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(USART2, &USART_InitStructure);
	USART_Cmd(USART2, ENABLE);

//次のようにして文字を送れる
	USART_SendData(USART2, 'H');while( USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) ;

○参考
STM32でUSARTを使ってみる - Wikimura
STM32F4 DISCOVERYのシリアル通信(UART)をテストする(送信編): 花岡ちゃんに花束を



ひとまず今日はここまでにさせてください。
正直新しいことを学びすぎて全然頭が追い付いていない……。