[Arduino UNO R4] Visual Studio Codeによるベアメタル・プログラミング入門

Arduino UNO R4は、ルネサスのマイコンRA4M1(Arm Cortex-M4コア)を搭載し、SWDのデバッグI/Dを装備したマイコンボードです。そこでSWDを活用して、本ボードをただのRAマイコンボードとしたベアメタルのプログラミング環境を作ってみました。
Arduinoとしての機能は一切使えなくなりますが、ルネサスが提供しているFSP(Flexible Software Package)を使用してH/Wの初期化を行うことととします。一緒に提供されるHALを使用することもできます。
すでにe2studioを使用した環境構築については書きましたので、ここではVSCodeを使用する方法を説明します。ルネサスがRAマイコン用に提供しているVSCode機能拡張を使用します。

なお、e2studioを使用する場合は以下をご覧ください（姉妹編になりますので一部重複している内容もあります）。
[[Arduino UNO R4] e²Studioによるベアメタル・プログラミング入門](https://qiita.com/y_toyoyama/items/e4da6c4a2a679bacc7af)


注意 Arduinoのファームを上書きしますので、再びArduinoとして使用するにはファームの書き込みが必要となります。

# 準備
## デバッグプローブ
SWDで開発用のPCと接続するため、デバッグプローブが必要となります。ルネサスのE2エミュレータとかSEGGERのJ-Linkとかです。
ボード側のSWDコネクタはハーフピッチの10pinです。ジャンパー線は無理なのでコネクタケーブルも用意します。
以下のようにつなげます。ボード上のコネクタはボックスが無いので向きに注意、ケーブルによって違います。
<img width="500" alt="pic_0" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/a914e8f6-ec97-2d43-d68b-2c75904fd51c.jpeg">

## 開発ツール
以下の開発ツールが必要となります。一般的なツールなので既にインストールされている人は作業不要です。

- Arm GNU Toolchain
- CMake
- Make
- Python (2.7)

Pythonは3系はNGのようです。注意点は環境変数の設定で、Pythonの自体にパスを通すだけではなく、Pythonインストール先のLibのパスをPYTHONPATHに、python27.dllのインストール先のパスをPATHに設定する必要があることです。この設定が出来ていないとデバッグ開始でエラーがでます。

私は[xPacks](https://xpack.github.io/)の以下のツールを使ってますが、ようはGCC,CMake,Makeが動けば良いと思います。

- [The xPack GNU Arm Embedded GCC](https://xpack.github.io/dev-tools/arm-none-eabi-gcc)
- [The xPack CMake](https://xpack.github.io/dev-tools/cmake/)
- [The xPack Windows Build Tools (Make)](https://xpack.github.io/dev-tools/windows-build-tools/)

ちなみにxPacksのツールはxpmというパッケージマネージャで簡単にインストールできるようですが、私はManual installしてます。Manualと言ってもZipをダウンロード、解凍してパス通すだけなので。

## RA Smart Configurator
### インストール
RA Smart Configurator (RASC)はルネサス製のFSPプロジェクトのコンフィギュレータ兼ジェネレータです。
GitHubの以下からダウンロードできます。

https://github.com/renesas/fsp/releases

以下のスタンドアローンのRASCです。e2studio版はCMakeのプロジェクトを作れないようなので今回は使えません。インストーラをダウンロードし実行します。

**《注意》 私が試した限りではFSP v4.2.0ではうまくいきましたが、v4.5.0およびv4.6.0ではダメでした。途中のバージョンは確認してません。指定してないRTCの初期化コードが生成され、そこでコケました。**
<img width="500" alt="pic_0" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/01cf0979-a3fc-f551-1921-3928b444aed2.jpeg">

### Support folder pathの確認
インストールしたRASCを実行します。最初にプロジェクト作成のダイアログが開きますが、今回は何もせず閉じます。
[help]メニューから[About FSP Smart Configurator]を選択し、開いたダイアログ下部の[Installation Details]ボタンを押下すると"e²studio support area"のパスが以下のように表示されるので記録しておきます。
![pic_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/0ab7c151-563d-7091-9b56-880161ec1094.jpeg)
RASCをいったん終了します。

## VSCodeと機能拡張
### インストール
VSCodeをインストールしてない人はインストールします。VSCodeに関しては詳しい情報が他にたくさんあるので本稿では割愛します。
続いてVSCodeにルネサスの機能拡張をインストールします。これも通常のVSCodeの機能拡張のインストールと同じです。
「renesas」で検索すると以下のように二つの機能拡張が見つかりますので両方をインストールします。
![pic4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/db092362-579e-4c94-91ae-543fefbbff92.png)

### 機能拡張の設定
インストールしたRenesas Debug機能拡張を設定します。
歯車ボタンから[機能拡張の設定]を選択し、[Support folder path]にRASCで調べた"e²studio support area"のパスを設定します。
次にコマンドパレット(Shift-Ctrl-P)から[Renesas: Open Renesas Support File Manager]を選択します。Renesas Sapport File Managerが開いたら[RA]を選択し、[Install]ボタンを押下します。

以上で準備は完了です。

# プロジェクトの作成
Arduino UNO R4のベアメタル・プログラムを作っていきます。プログラムのプロジェクトを置くディレクトリを作成しVSCodeで開きます。

## VSCodeからRASCの起動
VSCodeのコマンドパレット(Shift-Ctrl-P)から[Create RA project with Smart Configurator]を選択します。
![pic_002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/84b90582-8250-21f6-b24a-cb18e8e0e0a7.jpeg)

インストールされているRASCが表示されます。複数のバージョンがインストールされている場合はそれらが表示されますので、使用するバージョンを選択します。
![pic_003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/55be6c07-e85c-bd5d-ae37-c211b4ba418a.jpeg)
目的のバージョンが表示されない場合もありますので、そのときは[Browse RA Smart Configurator]から直接選択します。自分の環境では以下でした。
`C:\Renesas\RA\sc_v2022-10_fsp_v4.2.0\eclipse\rasc.exe`

RASCでプロジェクトを作成するディレクトリが聞かれますので、プロジェクトのディレクトリを指定します。

## RASCによるプロジェクトの生成
RASCが起動するとプロジェクト作成のウィザードが実行されます。
最初の画面で任意のプロジェクト名を入力して[Next]を押します。

次の画面で対象のハードウェアなどを設定します。対応済みのルネサス純正ボードであればそのボードを選択するだけですが、本ボードは対象外なので[Custom User Board]を選択し、Deviceにマイコンの型番[R7FA4M1AB3CFM]を指定します。Toolchainsは[GNU ARM Embedded]が選択済みだと思います。
以下のようになります。
<img width="500" alt="pic_0" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/5254432c-0c10-b68d-a2e9-f31601c8f710.jpeg">
[Next]を押して進み、さらに[Next]を押し、次に[Bere Metal - Minimal]を選択して[Finish]を押すとプロジェクトが作成され、雛形となるソースコードも自動生成されます。

## RASCによるコンフィギュレーション
作成するプログラムで使用するハードウェアなどを設定していきます。最低限、クロックの設定は必要です。

[Clocks]タブを選択し以下を設定します。これを間違えるとたいがい起動しません。
[HOCO 48MHz]
[PLL Src: Disabled]
[Clock src: HOCO]
<img width="500" alt="pic_0" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/68a204c6-a20f-c9bf-90c4-30801c839fad.jpeg">
あと作成するプログラム次第ですが、ここではボード上のLEDを使えるようにします。
ポート1の11(P111)にLEDがつながってますので、これを出力ポートにします。
[Pins]タブを選択し、左のリストから[P111]を探します。[Mode]に[Output (initial High)]または(initial Low)を選択してください。
<img width="500" alt="pic_0" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/b9bcd2e7-ba81-07a3-c7f9-c5344a3a9725.jpeg">
コンフィギュレーションが終わったら、右上にある[Generate Project Content]ボタンを押してプロジェクトを自動生成します。
RASCを終了し、VSCodeに戻ります。

## CMakeの設定
VSCodeでCMakeの設定を行っていきます。
cross.cmakeファイルを開き、CMAKE_FIND_ROOT_PATHに、Toolchainのパスを設定しコメントアウトを外します。パスはbinまで必要です。区切り文字はバックスラッシュではなくスラッシュです。
次にcmake\GeneratedCfg.cmakeファイルを開きます。ここでコンパイラやリンカのオプションなどを設定できます。
リンカのオプション"RASC_CMAKE_C_FLAGS"に"-gdwarf-4"を追加してください。これでとりあえずビルド、デバッグはできると思いますので、あとは必要に応じて設定してください。
![pic_001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/136e6a8f-698b-a253-78ea-34acef6512a8.jpeg)

## ビルド
まずはビルドできるか確認しましょう。
コマンドパレット(Shift+Ctrl+P)から[CMake: Delete Cache and Reconfigure]を選択します。
![pic_008.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/cd27c3a1-ac93-0920-0745-fa1d1d9becae.jpeg)
Kitの選択を聞かれたら[未指定]を選びます。
![pic10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179541/bcb7d5ba-9a0e-e6f0-a6b9-c4ce84bfe790.png)
続いてコマンドパレットから[CMake: Build]を選択します。
ビルドが成功するとbuildディレクトリ下に実行ファイル(ELFファイル)が生成されているはずです。
この時点では何もしないプログラムができてます。何かエラーが出てビルドできない場合は、どこかが間違ってますので直しましょう。

## プログラミング
プログラムは\src\hal_entry.cに記述します。ユーザプログラムはこのsrcディレクトリ内に記述する流儀のようです（別のところにも書けますが）。
最初は空っぽのhal_entry()関数がありますにで、ここにユーザプログラムを記述します。hal_entry()関数はmain()関数から呼び出されます。main()関数自体は書き換え不可です。書き換えてもたぶん上書きされます。

まずは古の流儀にのっとり、Lチカのプログラムを書いてみます。
hal_entry()関数を以下のように書き換えます。特に説明も不要と思いますが、R_IOPORT_PinWrite()関数で出力値を変更し、R_BSP_SoftwareDelay()関数で時間待ちです。

```C
void hal_entry(void)
{
    while(1) {
        R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_11, BSP_IO_LEVEL_HIGH);
        R_BSP_SoftwareDelay (500, BSP_DELAY_UNITS_MILLISECONDS);
        R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_11, BSP_IO_LEVEL_LOW);
        R_BSP_SoftwareDelay (500, BSP_DELAY_UNITS_MILLISECONDS);
    }
}
```

再びビルドします。うまくいけばLチカの実行ファイルが完成してます。

# デバッグ実行
出来上がった実行ファイルをボードに転送してデバッグ実行します。基本的な手順は通常のVSCodeのデバッグと同じです。

## デバッグ環境の設定
VSCodeの[実行とデバッグ] (Shift-Ctrl-D)で[launch.jsonファイルを作成します]を選択し、[デバッガの選択]から[Renesas GDB Target]を選ぶと、以下の内容のlaunch.jsonファイルが開きます。

```JSON
{
	"version": "0.2.0",
	"configurations": [
		{
			"type": "renesas",
			"request": "launch",
			"name": "Renesas GDB Debugging",
			"target": {
				"deviceFamily": "",
				"device": "",
				"debuggerType": "SIMULATOR"
			}
		}
	]
}
```

以下のように値を設定します。

- **deviceFamily** ここは"RA"です。
- **device** マイコンの型番"R7FA4M1AB"です。
- **debuggerType** 使用するデバッガを指定します。

さらに**serverParameters**を追加し、デバッガのパラメータを記述します。
J-Linkの場合の例を示します。
```JSON
{
	"version": "0.2.0",
	"configurations": [
		{
			"type": "renesas",
			"request": "launch",
			"name": "Renesas GDB Debugging",
			"target": {
				"deviceFamily": "RA",
				"device": "R7FA4M1AB",
				"debuggerType": "SEGGERJLINKARM",
				"serverParameters": ["-uConnectionTimeout=","30","-uSelect=","USB","-uLowPower=","0","-uInteface=","SWD","-uIfSpeed=","4000","-uNoReset=","1","-uResetPreRun=","1","-uIdCodeBytes=","FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF","-uResetCon=","1","-uResetBefDownload=","1","-uReleaseCM3=","0","-uDisconnectionMode=","1","-uSWOcoreClock=","0","-uresetOnReload=","1","-n","0","-uFlashBp=","1","-uSimulation=","0","-ueraseRomOnDownload=","0","-ueraseDataRomOnDownload=","0","-uOSRestriction=","0","-uProgReWriteIRom=","0","-uCPUFrequency=","0","-uCECycle=","1","-uMemRegion=","0x00000000:0x40000:FLASH:e","-uMemRegion=","0x40100000:0x2000:DATA_FLASH:e","-l","-uCore=","SINGLE_CORE|enabled|1|main","-uSyncMode=","async","-uFirstGDB=","main","--english"]
			}
		}
	]
}
```
## デバッグ実行
VSCodeの[実行とデバッグ] (Shift-Ctrl-D)から[デバッグの開始]を押す、またはF5キーを押すとデバッグの開始です。
プログラムがボードに転送されてデバッグ実行が開始され、main関数の先頭でブレークがかかったら成功です。あとは通常のVSCodeでのデバッグです。

# さいごに
RAマイコンはRASCがスタンドアローンのアプリなので、e²Studioを使用せずに開発を行うのが少し楽です。もっとも環境の立ち上げやとっかかりはe²Studioの方が楽な気がしないでもないですが… でもEclipse系はあの異様な起動時間が許せないとか、設定の沼にハマったのがトラウマだとか色々あると思いますので…
もっとも前にも書きましたが、Arduino UNO R4を気軽に使いたいならArduinoとして使うのが一番手軽ではあります。