#STM32 Nucleo Board実行ファイル作成
RaspberryPiでSTM32開発環境の構築でプログラム作成について省略したため、
ここで実行ファイルの作成を行う。
##開発ターゲット
STM32 Nucleo Board STM32F303K8
[startup]: https://qiita.com/mitazet/items/54713ec4e89f0b57ac6e
[linker]: https://qiita.com/mitazet/items/83ddd6cdffc43dd42f21
##実行ファイル作成に必要なもの
実行ファイル作成は次のような流れになる。
以上から実行ファイル作成にはスタートアップルーチン、メインプログラム、リンカスクリプト、Makefileが必要になる。
###スタートアップルーチン
スタートアップルーチンは[STM32 Nucleo Boardスタートアップルーチン][startup]のstartup_stm32f303x8.sを使用する。
###リンカスクリプト
リンカスクリプトは[STM32 Nucleo Boardリンカスクリプト][linker]のSTM32F303K8Tx_FLASH.ldを使用する。
環境へ取り込むにあたってSTM32F303K8.ldとファイル名を変更。
###メインプログラム
このプログラムはLEDを点滅させる(Lチカ)プログラム。
詳細はこの記事では省略するが、GPIO B3が本体のLEDとつながっており、
GPIO B3出力のHigh/Lowを繰り返すことで点滅させる。
#include "stm32f303x8.h"
void ConfigureTIM6(void)
{
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
TIM6->PSC = 9999;
TIM6->ARR = 4200 * 2;
TIM6->CNT = 0;
TIM6->CR1 |= TIM_CR1_CEN;
}
void ConfigureGPIOB3(void)
{
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
GPIOB->MODER = GPIO_MODER_MODER3_0;
GPIOB->OTYPER = 0x0000;
GPIOB->PUPDR = 0x000000000;
}
// Main -----------------------------------------------------------------------
int main(void)
{
ConfigureTIM6();
ConfigureGPIOB3();
int i = 0;
// Loop forever
while(1){
if(TIM6->SR){
TIM6->SR = 0;
if(GPIOB->ODR & GPIO_ODR_3){
GPIOB->ODR &= ~GPIO_ODR_3;
}else{
GPIOB->ODR |= GPIO_ODR_3;
}
i++;
}
}
return 0;
}
###Makefile
Makefileはソフトウェアまわりの備忘録を参考に作成。
# Minimal makefile for STM32F3 Neucleo board.
TARGET := arm-none-eabi
# devtools
CC := $(TARGET)-gcc
LD := $(TARGET)-ld
AS := $(TARGET)-as
OBJCOPY := $(TARGET)-objcopy
STFLASH := st-flash
PORT := /dev/ttyACM0
CFLAGS = -g3 -mcpu=cortex-m4 -mthumb -nostdlib -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -std=c99
INCLUDE = -I./include
#オブジェクトファイルが出力されるディレクトリ
OBJDIR = obj
#Cソースの検索とオブジェクトファイルを出力するディレクトリの設定
SOURCES = $(shell find * -name "*.c")
SRCDIR = $(dir $(SOURCES))
BINDIR = $(addprefix $(OBJDIR)/, $(SRCDIR))
#アセンブラソースの検索とオブジェクトファイルを出力するディレクトリの設定
ASMS = $(shell find * -name "*.s")
ASMDIR = $(dir $(ASMS))
ASMBIN = $(addprefix $(OBJDIR)/, $(ASMDIR))
#オブジェクトファイル群
OBJECTS = $(addprefix $(OBJDIR)/, $(patsubst %.c, %.o, $(SOURCES))) $(addprefix $(OBJDIR)/, $(patsubst %.s, %.o, $(ASMS)))
DEPENDS = $(OBJECTS:.o=.d)
ifeq "$(strip $(OBJDIR))" ""
OBJDIR = .
endif
#リンカスクリプト指定
MEMORYMAP = STM32F303K8.ld
#実行ファイル名指定
OBJECTNAME = STM
#サフィックスルール
default :
@[ -d $(OBJDIR) ] || mkdir -p $(OBJDIR)
@[ -d "$(BINDIR)" ] || mkdir -p $(BINDIR)
@[ -d "$(ASMBIN)" ] || mkdir -p $(ASMBIN)
@make all --no-print-directory
all: $(OBJECTS) $(OBJECTNAME).out $(OBJECTNAME).bin
$(OBJECTNAME).bin: $(OBJECTNAME).out
$(OBJCOPY) $(OBJECTNAME).out -I ihex -O binary $(OBJECTNAME).bin
$(OBJECTNAME).out: $(OBJECTS)
$(LD) -T $(MEMORYMAP) $(OBJECTS) -o $(OBJECTNAME).out
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
$(OBJDIR)/%.o: %.s
$(AS) -g $< -o $@
.PHONY: clean flash
st-flash: $(OBJECTNAME).bin
$(STFLASH) write $(OBJECTNAME).bin 0x8000000
clean:
rm -rf $(OBJDIR) *.out *.bin
##実行ファイル作成
makeを実行する。
$ make
上記のMakefileだとSTM.outとSTM.binが作成される。
STM.outは実行ファイル。
STM.binは書き込み用ファイル。
##実行
現状、STM.binをツールで書き込んで動かすには至っていない。
STM.outを用いてgdbからloadする。
実行するとLEDが点滅した!!
##ソースコード
開発をするにあたってGithubにソースをおいてみた。
mitazet/stm32/v01
##参考サイト
yuki-sato.com