Arduino未満，HDL以上．〜マイコンプログラミング入門 その1 環境構築編〜

この記事は[eeic Advent Calendar 2016](http://qiita.com/advent-calendar/2016/eeic) 20日目の記事 **その1** です．（[その2](http://qiita.com/tellusium/items/f38f7ae55370d3739dc5)）
（※12/20 1:10 追記）

# はじめに

ここでは，マイコンプログラミング入門について書こうと思います．
EEIC（東京大学工学部電気電子工学科・電子情報工学科）では，主に2つの言語を扱います．

* C言語
* Verilog HDL

また，[BDMと呼ばれる製作課題](http://www.ee.t.u-tokyo.ac.jp/j/special/pdf/special04.pdf)などで，Arduino，ラズパイを使う人が多く，さらにFPGAを扱う実験もあり，ArduinoやFPGAは触ったことがある，という人が多いのではと思います．

さて，私がEEICに入った後，実験にも講義でも扱うことがなく不思議に思ったのが，マイコンプログラミングです．
高専時代，ロボコンに出場する団体に入りマイコンプログラミングの面白さから電気系に入った身としては，マイコンを触ってないのに，[大して使い慣れていないVerilogHDLを使っていきなりCPUを作る実験](http://www.mtl.t.u-tokyo.ac.jp/~jikken/cpu/wiki/)とかあるのですごいなぁと思います．

以上の理由が，マイコンプログラミング入門という記事を書いてみようと思ったきっかけです．

**※注意**
以下では，マイコンを実際に試してみようということで，Nucleoというマイコンの評価キットのための環境構築について説明します．
環境構築の説明は非常に長いので，必要がないという方は，[その2](http://qiita.com/tellusium/items/f38f7ae55370d3739dc5)の方をごらんください．

# マイコンの選定

私が初めてマイコンに触ったのは，高専でロボコンを始めた時で，その時はH8マイコンという，今はルネサスエレクトロニクスが作っているマイコンを使いました．おそらく授業で使わなくなったマイコンをもらっていたのだと思います．

「電子工作」とかで検索すると，Arduino以前は **PICマイコン** という，Microchipが作っているマイコンがよく出てきていましたが，今や[トラ技](http://toragi.cqpub.co.jp/)ですら特集で扱わなくなってしまいました．トラ技，最近ラズパイ特集が多いですよね…

Arduinoの本体は，Atmelが作っている **AVRマイコン** というものです．[Atmelは上述のMicrochipに買収されましたが…](http://www.atmel.com/ja/jp/microsite/microchip-acquires-atmel.aspx)
しかし，AVRを直にかけるようになっても，「Arduinoでよくない？」となってしまいそうなので，今回は見送りました．

さて，もうひとつ選択肢があり，それが[ソフトバンクによる買収で話題になった](http://www.itmedia.co.jp/news/articles/1609/06/news052.html)ARMマイコンです．
ARM社はマイコンを作っているのではなく，設計仕様書を作っています．ICメーカ各社は，ARMから設計図を購入して，それに独自技術を追加してICを製造しています．それらをまとめて **ARMマイコン** と呼んでいます．[1]

たくさんあるARMマイコンの中で，入手しやすく，安価に使えるものはないかと調べたところ，ありました．

STマイクロエレクトロニクスが製造している， **STMマイコン** の評価キットである，「[Nucleo](http://www.st.com/ja/evaluation-tools/stm32-mcu-nucleo.html?querycriteria=productId=LN1847)」というボードです．

<img width="500" alt="スクリーンショット 2016-11-05 0.58.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/143819/7813b2bf-3f27-f47f-c527-5fad5e25b41d.png">


[秋月電子通商](http://akizukidenshi.com/catalog/top.aspx)でも，[1500円という値段で購入](http://akizukidenshi.com/catalog/g/gM-07724/)できます．さらに，ST-LINKというライタ・デバッガも付属しています．

マイコンを扱う上で障壁となるのが，ライタとデバッガです．
例えば上で述べたPICマイコンは，マイコン単体は[数百円](http://akizukidenshi.com/catalog/g/gI-04430/)で購入できるのですが，肝心のライタ・デバッガが[6000円近く](http://akizukidenshi.com/catalog/g/gM-03608/)します．

一方こちらは1500円でコミコミです．
さらにスペックもPICマイコンより上です．

# 環境構築

それでは，STMマイコンを扱う上で，必要な環境を構築していきます．
環境構築は，次のサイトを参考にさせていただきました．

* http://qiita.com/Ted-HM/items/760759b6b152230b48a8
* http://www.carminenoviello.com/2014/12/28/setting-gcceclipse-toolchain-stm32nucleo-part-1/

これらのリンクは双方Windows環境のため，ほとんど同じですがMac版として以下に手順を書いておきます．
差別化としては，画像を多めに貼ったつもりです．

## 1. Eclipseのインストール

IDEとしては，Eclipseを使います．

* https://eclipse.org/downloads/

からダウンロードし，インストールします．

## 2. C/C++ Development Tools のインストール

次に，Eclipse内のプラグインをインストールしていきます．
メニューのHelpを選択し，Install New Softwareをクリックします．
![スクリーンショット 2016-12-18 17.30.34.png](https://qiita-image-store.s3.amazonaws.com/0/143819/3e610824-057b-8476-5569-1c0a2a1e8e6f.png "スクリーンショット 2016-12-18 17.30.34.png")

出てきた画面のWork withの欄に，"CDT"と入力すると，候補が出てくるので，新しい方を選択し，次のものを選択し，Nextを押します．
特に変更はないので，そのままインストールします．

![スクリーンショット 2016-12-18 17.32.27.png](https://qiita-image-store.s3.amazonaws.com/0/143819/eec4b8f4-6052-b183-5004-8dfbaa27d64b.png "スクリーンショット 2016-12-18 17.32.27.png")

## 3. GNU ARM plugin のインストール

次に，ARMの開発用のプラグインであるGNU ARM Pluginをインストールします．Eclipse上でARM向けにコンパイルするためのツール集です．
Install New Softwareで出てくるウィンドウに，

* Name: GNU ARM Eclipse Plug-ins
* Location: https://sourceforge.net/projects/gnuarmeclipse/files/Eclipse/updates/

と入力します．
GNU ARM Eclipse Plug-ins を選択して，次の画像のものにチェックを入れインストールします．一応全てインストールした方がいいかもしれません．

![スクリーンショット 2016-12-18 21.35.34.png](https://qiita-image-store.s3.amazonaws.com/0/143819/f0b6df38-c991-08dd-afac-56a100417250.png "スクリーンショット 2016-12-18 21.35.34.png")
（アイコンの色が違うのは，すでに私の環境ではインストール済みなためです）


## 4. GCC ARM Toolchainのインストール

ARMプロセッサのコンパイラ，デバッガです．
https://launchpad.net/gcc-arm-embedded/+download にアクセスし，対応するバージョンをインストールします．
今回はMacの環境なので，gcc-arm-none-eabi-5_4-2016q3-20160926-mac.tar.bz2をダウンロードし，解凍します．

解凍したファイルは，適当な場所に配置します．今回は，

```
/usr/local/gcc-arm-none-eabi-5_4-2016q3/
```

に配置しました．このパスは後で必要になるので，覚えておきます．

（Windowsの場合，Build Toolのインストールが必要みたいです．詳細は参考のリンクを参照してください）

## 5. OpenOCDのインストール

次に，OpenOCD (Open On Chip Debugger) をインストールします．こちらは書き込みなどに用いるデバッガソフトウェアです．
https://github.com/gnuarmeclipse/openocd/releases のリンクから，対応するバージョン（今回はgnuarmeclipse-openocd-osx-0.10.0-201610281609-dev.pkg）をインストールします．
インストーラを実行すると，```/Applications/GNU\ ARM\ Eclipse/OpenOCD/```にインストールされます．

## 6. ST-LINKのファームウェアアップグレード

http://www.st.com/ja/embedded-software/stsw-link007.html の一番下，Get Softwareからダウンロードします．
ダウンロードには会員登録かメールアドレスが必要となります．

いよいよここでNucleoボードをPCに接続します．
先ほどダウンロードしたフォルダを解凍した後，AllPlatforms/STLinkUpgrade.jarを実行します．

# Eclipse上でプログラミング

お疲れ様でした．もう少しです！（うまくいっていればですが…）
ここから先も，http://qiita.com/Ted-HM/items/760759b6b152230b48a8#eclipse%E3%81%AE%E8%A8%AD%E5%AE%9A を大きく参考にしています．
ここでは，要点をまとめたいと思います．

## 1. プロジェクトの作成

次の画像のように，~~C++ Project~~ **C Project** (※12/20 1:10 追記，次の画像とは違うので注意）を選択します．

![スクリーンショット 2016-12-18 22.01.56.png](https://qiita-image-store.s3.amazonaws.com/0/143819/50b79eca-937a-f45b-0b4a-32fd5dcb6afb.png "スクリーンショット 2016-12-18 22.01.56.png")

次に，

* ProjectName（任意）
* ProjectType: STM32F10x C/C++ Project
* Toolchains: Cross ARM GCC

としてNextを押します．

![スクリーンショット 2016-12-18 22.02.56.png](https://qiita-image-store.s3.amazonaws.com/0/143819/1e3f7404-fb68-4f0e-c3d6-7721c51e6d45.png "スクリーンショット 2016-12-18 22.02.56.png")

しばらくは（ほとんどの場合）変更はいらないはずなので，Nextを押していきます．
最後のこのページでは，先ほどGNU ARM Toolchainをインストールしたパスを指定しまう．今回は```/usr/local/gcc-arm-none-eabi-5_4-2016q3/bin/```となります．

![スクリーンショット 2016-12-18 22.06.21.png](https://qiita-image-store.s3.amazonaws.com/0/143819/b92a4ed7-d970-9aa3-f75e-91741b52ac6b.png "スクリーンショット 2016-12-18 22.06.21.png")



## 2. OpenOCDの接続テスト

Run -> External Tools -> External Tools Configration...
を選択します．

![スクリーンショット 2016-12-19 14.57.31.png](https://qiita-image-store.s3.amazonaws.com/0/143819/a35b51b1-3e14-d7a6-8fe8-c5a8b4df5c74.png "スクリーンショット 2016-12-19 14.57.31.png")

表示された画面で，左上の新規作成アイコンを押し，Name, Location , Working Directory, Argumentsを次のように入力します．

* Name: 任意（例えばnucleo_OpenOCD）
* Location: ```${openocd_path}\${openocd_executable}```
* Working Directory: ```${openocd_path}\..\scripts```
* Arguments: -```s "${openocd_path}\..\scripts" -f board/st_nucleo_f103rb.cfg```

![スクリーンショット 2016-12-19 14.59.57.png](https://qiita-image-store.s3.amazonaws.com/0/143819/02a90f28-aac0-e5ab-06c0-ae1e2ec60c6a.png "スクリーンショット 2016-12-19 14.59.57.png")

別のタブに移動し

* Buildタブ: Build before launchのチェックを外す
* Commonタブ: Display in Favorites Menuにチェック

を行います．あとは，Apply -> Closeで大丈夫です．

さて，OpenOCDを起動させてみます．
Run -> External Tools -> nucleo_OpenOCDか，
画像のように下三角ボタンから選択し，起動します．

![スクリーンショット 2016-12-19 15.13.05.png](https://qiita-image-store.s3.amazonaws.com/0/143819/e18d358b-6f45-5bf4-61ca-7ce8c8f55829.png "スクリーンショット 2016-12-19 15.13.05.png")

すると次のようにコンソール画面に赤文字が表示されると思います．（これは環境によって異なるかもしれません）

![スクリーンショット 2016-12-19 15.14.39.png](https://qiita-image-store.s3.amazonaws.com/0/143819/f3e2414b-d198-0c5c-4165-bc2cfa057f28.png "スクリーンショット 2016-12-19 15.14.39.png")

TargetVoltageが表示されていれば，正しく起動できていると思います．
これで確認は終了なので，コンソール画面の右上にある赤い四角ボタンを押して終了し，×ボタンを押して消去しておきます．

## 3. デバッグ設定

さて，この設定が終われば，ついにマイコンにプログラムを書き込むことができます．

まずは，プロジェクトをビルドしておきます．MacではCmd+Bで，またはProject -> Build Allからビルドできます．
おそらくエラーは出ないはずです．

Run -> Debug Configrationを選択します．
![スクリーンショット 2016-12-19 15.19.21.png](https://qiita-image-store.s3.amazonaws.com/0/143819/f8346aa1-dde1-6781-84cb-d1904ff1109e.png "スクリーンショット 2016-12-19 15.19.21.png")

右の"GDB OpenOCD Debugging"を選択して，左上の新規作成ボタンを押します．そしたら，

* Mainタブ
	* Name: 任意（ここではnucleo_Debug）
	* Project: Browseから先ほど作成したプロジェクトを選択
	* C/C++ Application: Search Projectから作成したプロジェクト名のelfファイルを選択
* Debuggerタブ
	* Executable: ```${openocd_path}/${openocd_executable}```
	* GDB Port: 3333
	* Telnet Port: 4444
	* Config Options: ```-s "${openocd_path}/../scripts" -f board/st_nucleo_f103rb.cfg```
* Commonタブ
	* Display in favorites menuのDebugにチェック

と設定します．Apply -> Closeで終了します．
私の環境ではこれで動作しましたが，うまくいかない場合，http://qiita.com/Ted-HM/items/760759b6b152230b48a8#eclipse%E3%81%AE%E8%A8%AD%E5%AE%9A のサイトに詳しい説明があるので，試してみてください．
画像を示します．

![スクリーンショット 2016-12-19 15.24.49.png](https://qiita-image-store.s3.amazonaws.com/0/143819/b5421e85-351e-b06d-26ef-27fd77fe2b8f.png "スクリーンショット 2016-12-19 15.24.49.png")

![スクリーンショット 2016-12-19 15.25.47.png](https://qiita-image-store.s3.amazonaws.com/0/143819/fcea7982-9315-91e5-1c6c-288ea6666e08.png "スクリーンショット 2016-12-19 15.25.47.png")

## 4. 書き込みテスト

それでは，いよいよ書き込みを行います．
BuildAll（Cmd+B）を実行し，虫のようなアイコンの下三角を押し，
先ほど設定したデバッガを実行します．ここではnucleo_Debugです．

![スクリーンショット 2016-12-19 15.31.20.png](https://qiita-image-store.s3.amazonaws.com/0/143819/9f76b20f-698d-14b8-2606-7bdbfa6a5a4e.png "スクリーンショット 2016-12-19 15.31.20.png")

うまく実行されれば，Perspectiveを変更しますか？と聞かれるのでYesと答えて，次のようにデバッグ専用の見た目に変化します．

![スクリーンショット 2016-12-19 15.34.18.png](https://qiita-image-store.s3.amazonaws.com/0/143819/de81815c-9b42-196e-b1b9-72e00d0f0ab7.png "スクリーンショット 2016-12-19 15.34.18.png")

ここまできたら，左上の右三角の実行ボタンを押せば，

```
Hello ARM World!
System clock: 72000000 Hz
Second 1
Second 2
Second 3
…
```

とコンソールに表示されるはずです．成功です．おめでとうございます．

この画面では，左上の一時停止ボタンを押せば一時停止されますし，停止ボタンを押せば終了します．
ソースの行番号をクリックすればブレークポイントも設定できます．
コンソール右上の停止ボタン，×ボタンを押せばデバッガは終了し，元の見た目に戻したければ，画面右上のC/C++と言う名前のボタンを押せば元に戻ります．

さて，プログラムは動いたのですが，本当はこのプログラム，LEDも点滅するはずです．BlinkLED.cとかあるんでそう思いますよね．
LEDが光らないのは，どうやら設定されているピン番号が違うかららしいです．
右のProjectExplorerから，プロジェクト名 -> src -> BlinkLed.cpp -> BlinkLed.hを選択すると，BlinkLed.cppの中の```#include "BlinkLed.h"```の部分にハイライトがかかるので，右クリック -> Open DeclarationでBlinkLed.hが開きます．
19行目と20行目を次のように修正します．
LEDはPORTAの5番に接続されているようなので，そのように変更します．

* ```#define BLINK_PORT_NUMBER (0)```
* ```#define BLINK_PIN_NUMBER  (5)```

![スクリーンショット 2016-12-19 15.46.44.png](https://qiita-image-store.s3.amazonaws.com/0/143819/a9562c44-81a4-7604-16da-957ff9ade277.png "スクリーンショット 2016-12-19 15.46.44.png")

先程と同様にBuildAllからDebugで書き込むと，ボード上のLD2が点滅していることがわかります．
これで **LEDチカチカ** ，いわゆる **電子工作におけるHello World** ができました．

# 終わりに

ここまでで，Nucleoボードの環境構築が終了しました．
[その2](http://qiita.com/tellusium/items/f38f7ae55370d3739dc5)では，いよいよ **伝統的な** マイコンプログラミングを行なっていきたいと思います．

[その2](http://qiita.com/tellusium/items/f38f7ae55370d3739dc5)

# 参考文献
[1] 『[トランジスタ技術2011年3月号 合点! ARMマイコン超入門](http://toragi.cqpub.co.jp/tabid/426/Default.aspx)』CQ出版