STM32F4 DiscoveryをOS Xで使う (2) - 標準入出力, CMake

前回の続き。OpenOCDでの標準入出力とCMakeを使ったビルドについて。

ところで全然関係ないんですが、OpenOCDを終了してもう一度起動すると、だいたい接続に失敗してUSBを繋ぎ直さないといけないんですが何なんですかね。面倒。

標準入出力

動作確認に何かと便利な printf() を使いたいので、これをOpenOCDに出力できるようにします。

ねむいさんのぶろぐ | Discovery系基板を中心とした小ネタいろいろ 等を参考に試した結果、自分の環境では以下のようになりました。

ソースコード

予め initialise_monitor_handles() を呼んでおかなければならない点に注意します。

// printf.c
#include <stdio.h>

extern void initialise_monitor_handles(void);

int main(){
  initialise_monitor_handles();
  printf("Hello STM32F4.\n");
  while(1);
  return 0;
}

コンパイル

libopencm3-examplesを見て必要そうなオプションを並べるとこんな感じになりました。(libopencm3-examplesの一つ上のディレクトリでprintf.cが保存されている前提) -Iオプションは実際のところprintf.cに関しては必要ないですが。

$ arm-none-eabi-gcc -Wall -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb -mcpu=cortex-m4 \
-Ilibopencm3-examples/libopencm3/include -Llibopencm3-examples/libopencm3/lib -lopencm3_stm32f4 \
--specs=rdimon.specs -T libopencm3-examples/examples/stm32/f4/stm32f4-discovery/stm32f4-discovery.ld -nostartfiles \
printf.c -o printf.elf
$ arm-none-eabi-objcopy -Obinary printf.elf printf.bin

実行

あとは出来上がったバイナリを前回同様OpenOCDで書き込んで実行するわけですが、そのままでは何も出力されません。telnetでOpenOCDに接続した後、 arm semihosting enable を実行しておく必要があります。arm semihosting enable の後にプログラムを実行すると、OpenOCDを起動している端末にマイコンからの標準出力が表示されます。またキーボードでの標準入力も可能です。

CMakeでクロスコンパイル

コードを書くにあたって、毎度gccを長い長いオプションとともに自分で実行するわけにもいかないので、何らかのIDEやビルドツールを使用することになります。 自分の場合はMakefileが書けないのでCMakeを使っています。ここではCMakeそのものの使い方は省略して、クロスコンパイルの方法を中心に書いておきます。

ツールチェインの設定

CMakeでクロスコンパイルする場合、ビルド内容を決める CMakeLists.txt 自体はPCのプログラミングで使用する場合と同様に記述できます。ただしクロスコンパイル専用の処理が必要な場合、CMAKE_CROSSCOMPILING フラグを参照して分岐します。 コンパイラ等のツールチェインの指定は、別途 Toolchain-*.cmake を作成することで行います。

# Toolchain-arm-none-eabi.cmake
include(CMakeForceCompiler)

set(CMAKE_SYSTEM_NAME Generic)

CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU)
CMAKE_FORCE_CXX_COMPILER(arm-none-eabi-g++ GNU)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

CMakeは通常、プロジェクト生成前にコンパイラが実際に動作するか確認してから各ファイルを生成しています。しかし今回の記事の通りコンパイル時には多くのオプションが必要で、かつプロジェクトによって使用したいリンカオプションは異なってきます。リンカオプションは CMakeLists.txt でプロジェクト/ターゲット毎に指定したいので、 CMakeForceCompiler を使用してコンパイル確認をスキップしています。

プロジェクトの生成

ツールチェインファイルができたら、CMakeでMakefileを生成します。-DCMAKE_TOOLCHAIN_FILE で使用するツールチェインファイルを指定します。

$ cmake -DCMAKE_TOOLCHAIN_FILE=Toolchain-arm-none-eabi.cmake .
$ make

CMakeは-Gオプションを使うことでMakefileだけでなく色々なIDE向けのプロジェクトを生成できるので、好きなエディタやIDEを使って開発することができるようになります。

作ったコードはとりあえず置いておきますね。 https://github.com/yuya-oc/stm32f4-discovery-cmake