LoginSignup
11
9

More than 5 years have passed since last update.

STM32 Nucleo Board実行ファイル作成

Last updated at Posted at 2017-10-17

STM32 Nucleo Board実行ファイル作成

RaspberryPiでSTM32開発環境の構築でプログラム作成について省略したため、
ここで実行ファイルの作成を行う。

開発ターゲット

STM32 Nucleo Board STM32F303K8

実行ファイル作成に必要なもの

実行ファイル作成は次のような流れになる。
design.png
以上から実行ファイル作成にはスタートアップルーチン、メインプログラム、リンカスクリプト、Makefileが必要になる。

スタートアップルーチン

スタートアップルーチンはSTM32 Nucleo Boardスタートアップルーチンのstartup_stm32f303x8.sを使用する。

リンカスクリプト

リンカスクリプトはSTM32 Nucleo BoardリンカスクリプトのSTM32F303K8Tx_FLASH.ldを使用する。
環境へ取り込むにあたってSTM32F303K8.ldとファイル名を変更。

メインプログラム

このプログラムはLEDを点滅させる(Lチカ)プログラム。
詳細はこの記事では省略するが、GPIO B3が本体のLEDとつながっており、
GPIO B3出力のHigh/Lowを繰り返すことで点滅させる。

main.c
#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はソフトウェアまわりの備忘録を参考に作成。

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が点滅した!!

4A1F4CAA-6A7E-4665-AFC6-44CFB6E41063.jpeg

ソースコード

開発をするにあたってGithubにソースをおいてみた。
mitazet/stm32/v01

参考サイト

yuki-sato.com

11
9
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
11
9