VSCode+gdb+OpenOCDでARMの開発をやる

# はじめに

もうEclipseベースのわけわからんIDEで組み込みC書きたくない人向けです

## できること
* VSCodeでそこそこ快適にCを書いてビルド
* VSCode上でブレークポイント仕掛けたりして良い感じにOpenOCDとgdbを使ったデバッグ

## できないこと
* Makefile生成 (仕方ないのでここだけNetBeans使ってやります)

## 環境
Windows 10

VSCode 1.10.2

gcc version 5.3.1 20160307

OpenOCD 0.10.0+dev-g9656532-dirty (自前ビルドの執筆時点でだいぶ新しいやつ)

# 下準備

## 必須アイテム
[Visual Studio Code](https://code.visualstudio.com/)

[GNU ARM Embedded Toolchain](https://launchpad.net/gcc-arm-embedded)

Cygwinかなんか (makeとbashにパス通ってる良い感じの環境)

OpenOCD Windows向けバイナリとかは[この辺](http://www.besttechnology.co.jp/modules/knowledge/?OpenOCD)とかから良い感じに落とす (+なんとなくアタッチできるだけの設定ファイル類)


## 必要に応じて入れる物
NetBeans (Makefileの生成に使うだけなので手書きとか他の何か使うとかでもOK)

[gdb-openocd](https://github.com/misodengaku/gdb-openocd/releases) という謎の実行ファイル

## VSCodeに入れるもの
[C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) by Microsoft

[Native Debug](https://marketplace.visualstudio.com/items?itemName=webfreak.debug) by webfreak

# やりたいことベースの解説

## ビルドしたい
VSCodeではMakefileの生成などはできないのでNetBeansとか使って開発できるところまでプロジェクトを作る、プロジェクトルートでmake叩いてバイナリ出来上がる環境ならOK

VSCodeの`フォルダーを開く`でプロジェクトルートを開いた状態でCtrl+Shift+B押すと `タスクランナーの構成` 的なのが出るのでクリック

種類訊かれるのでなんでもいいけどとりあえず `Others` を選ぶ。tasks.jsonというファイルが開かれるはずなので以下の設定流す、 `make -jN` のNの値はお好みで

tasks.jsonがある状態でCtrl+Shift+B押すと良い感じにmakeしてくれるはず

```
{
	"version": "0.1.0",
	"command": "bash",
	"isShellCommand": true,
	"args": [
		"-c"
	],
	"showOutput": "always",
	"tasks": [
		{
			"taskName": "build",
			"suppressTaskName": true,
			"isBuildCommand": true,
			"args": [
				"make -jN"
			],
			"problemMatcher": {
				"owner": "c",
				"fileLocation": [
					"relative",
					"${workspaceRoot}"
				],
				"pattern": [
					{
						"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error|fatal error):\\s+(.*)$",
						"file": 1,
						"line": 2,
						"column": 3,
						"severity": 4,
						"message": 5
					}
				]
			}
		}
	]
}
```

ビルドエラーもパースして表示してくれるはず

![image](https://qiita-image-store.s3.amazonaws.com/0/102824/43fb5848-d672-833e-8835-e0388e5e122f.png)

## 実機デバッグしたい

Ctrl+Shift+D押してサイドバーでデバッグメニュー開く

`デバッグの開始` ボタン横ボックスから `構成の追加` 選ぶとlaunch.jsonが開くので以下の設定流す

```
{
	"version": "0.2.0",
	"configurations": [
		{
			"name": "OpenOCD Debug",
			"type": "gdb",
			"request": "attach",
			"executable": "VSCodeで開いてるディレクトリを基準にしたELFファイルへの相対パス",
			"target": ":3333",
			"remote": true,
			"cwd": "${workspaceRoot}",
			"autorun": [
				"interrupt",
				"monitor reset halt",
				"monitor flash erase_sectorとか",
				"起動時にgdbで叩きたいコマンドをなんとなくこの辺に書く"
				"load",
				"break main"
			],
			"gdbpath": "GDBへのパス or gdb-openocd.exeへのパス"
		}
	]
}
```


注意点がいくつかあり、

* "executable" の項目はMCUに書き込みたい実行ファイルに合わせてプロジェクト毎に変えないとダメ（当然）
* "autorun":[] 以下の項目はMCUに合わせて良い感じの設定を見付ける
* "gdbpath"はたぶんGCCのインストール先にarm-none-eabi-gdb.exeが転がってるはずなのでそれを or gdb-openocd.exe(後述)へのパス

以上をそれぞれ適切に設定する必要がある。

![image](https://qiita-image-store.s3.amazonaws.com/0/102824/97ee51b6-c53c-2eb9-afc2-85ad12a2d42c.png)

ブレークポイント仕掛けられるし変数の中身とかスタックトレースも見られて良い感じ

挙動がおかしいときはデバッグコンソールからgdb生で叩けるのでそれもアリ

### gdb+OpenOCD

.gdbinitでgdb起動時に良い感じにOpenOCDが上がるようになってるならそれでいいのだけどWindowsがタコくてどうにも手軽に出来ないので雑なラッパーを書いた

[gdb-openocd.exe](https://github.com/misodengaku/gdb-openocd/releases)


gdb-openocd.exeとはgdbと一緒にOpenOCDを立ち上げてくれるだけの実行ファイルであり、設定ファイルにOpenOCDの設定やらパスやらを書くだけで両方良い感じにしてくれるアイテムとなっている

で、gdb-openocd.exeを使うためにはプロジェクトルートにgdb_wrapper.jsonというファイル名で以下のような設定ファイルを置く必要がある。

```
{
	"openocd_path": "C:\\openocd\\openocd.exe",
	"openocd_option": "-s c:\\openocd\\tcl -f interface/stlink-v2.cfg -f target/stm32f4x.cfg",
	"gdb_path": "C:\\arm\\bin\\arm-none-eabi-gdb.exe"
}
```

適切に設定した状態で `gdb-openocd 実行したいELFファイルパス` と叩くとOpenOCDを起動しつつgdbを上げてくれるのであとはそのままgdbのつもりでコンソール叩ける

こんなもん必要なくて済むならない方がいいのでなんとかする術をお持ちの方は是非教えてください