OpenAMP on ZYBO (Zynq) 3回目: How to Debug Linux Application

- [1回目: とりあえずサンプルを動かす](https://qiita.com/take-iwiw/items/ff46792eb107d978cd0b)
- [2回目: 通信方法やメモリマップについて](https://qiita.com/take-iwiw/items/3922ec5cae6aa35c5e81)
- __[3回目: How to Debug Linux Application](https://qiita.com/take-iwiw/items/8b589650c15a6f705f35)<--- 今回の内容__
- [4回目: How to Debug Baremetal Firmware](https://qiita.com/take-iwiw/items/5f7c24bd0475274ded23)

# 本記事について
Linux + ベアメタル(or FreeRTOS)のマルチ環境を、OpenAMPを使用してZYBOで実現させました。

- CPU0: Linux
- CPU1: ベアメタル (or FreeRTOS)

1回目では、動作確認用Linuxアプリケーションとして、自動でインストールされた`echo_test`を使用しました。今回は、LinuxアプリケーションをXilinx SDKで開発(実装、デバッグ)します。

# 環境
- 開発用PC: Windows 10 64-bit 
	- Vivado 2017.4 WebPACKライセンス
	- Xilinx SDK 2017.4
- 開発用PC (Linux): Ubuntu 16.04 本家 (日本語版じゃない) (on VirtualBox 5.2.4)
	- PetaLinux 2017.4
- ターゲットボード: ZYBO (Z7-20) 

# プロジェクトの作成
## Linux System Rootの準備
_今回の場合は、これはやらなくても大丈夫かもしれません。また、この手順自体はOpenAmpに限らず、通常のLinuxアプリケーション開発でも同じです。_

PetaLinuxでオリジナルのLinuxイメージを作成して、標準ではないライブラリをインストールしたとします。XSDK(on Windows)にも、最低限のものはインストールされていますが、無い場合があります。この場合、ヘッダやライブラリが必要になります。そのため、PetaLinuxからSystem Rootをコピーする必要があります。

まず、Linuxイメージを作成したPetaLinuxプロジェクトのディレクトリ内で、下記コマンドでSystem Rootをアーカイブ化します。ポイントは、シンボリックリンクを実体化することです。シンボリックリンクのままだと、Windowsにコピーしたときに使えなくなってしまいます。

```sh:PetaLinuxプロジェクトディレクトリ(Ubuntu)
zip -r plnx_arm.zip build/tmp/sysroots/plnx_arm
```

これを、Windowsの適当な場所に解凍します。(例: `C:\asd\dev\zynq\vivado\project_openamp\project_openamp.sdk\sysroots\plnx_arm`)

## XSDKプロジェクトの作成
XSDKを起動して、メニューバー -> File -> New -> Application Projectを開きます。
下記設定で、my_echo_testというプロジェクトを作成します。重要な点は、Linux System Rootの設定です。

![01.jpg](https://qiita-image-store.s3.amazonaws.com/0/214268/38696ed5-434f-2635-b5b5-564262e7c08f.jpeg)

## XSDKプロジェクトの設定
Project Explorer -> 作成したプロジェクト(my_echo_test) -> 右クリック -> Properties -> C/C++ Build -> Settings -> ARM v7 Linux gcc linker -> Miscellaneous、を選びます。
Linker Flagsに下記値を設定します。パスは適当に置き換えてください。

`--sysroot=C:\asd\dev\zynq\vivado\project_openamp\project_openamp.sdk\sysroots\plnx_arm`

場合によっては、ライブラリしていが必要になるかもしれません。(今回は不要です。)
Project Explorer -> 作成したプロジェクト(my_echo_test) -> 右クリック -> Properties -> C/C++ Build -> Settings -> ARM v7 Linux gcc linker -> Libraries、を選びます。Librariesの所に、`metal`を追加。


# ソースコードを書く
面倒なので、echo_testと同じコードを持ってきます。下記ソースコードをコピペします。
https://github.com/Xilinx/meta-openamp/blob/rel-v2017.4/recipes-openamp/rpmsg-examples/rpmsg-echo-test/echo_test.c

ビルドが成功したら、my_echo_test.elfが作られているはずです。

# デバッグする
## OpenAMP環境を用意する
my_echo_testは、エコーバックするベアメタル(BM)ファームウェアと協調して動作します。そのため、1回目と同様に、BM側ファームウェアをロードして、OpenAMPを開始する必要があります。

下記コマンドで、エコーバックするデモファームウェアを開始します。

```sh:OpenAMP開始コマンド
modprobe rpmsg_user_dev_driver
echo image_echo_test > /sys/class/remoteproc/remoteproc0/firmware
echo start > /sys/class/remoteproc/remoteproc0/state
```

## デバッグする
デバッグ方法は、通常のLinuxアプリのデバッグと同じです。(https://qiita.com/take-iwiw/items/8134ca7098622219b177 )
まず、ZYBOのUARTターミナル上で、`ifconfig`などでIPアドレスを確認しておいてください。(192.168.1.87とします)

- XSDK上で、my_echo_test.elfで右クリック -> Debug As -> Debug Configurations、を開きます
- `Xilinx C/C++ applications (system Debugger)`の下になにもなければ、ダブルクリックします
- Target Setupタブで、Connection横のNewをクリック
	- Hostに192.168.1.87を設定します

![02.jpg](https://qiita-image-store.s3.amazonaws.com/0/214268/2d2f0d02-162e-a32a-8857-d69fead6f3bd.jpeg)

- Applicationタブで、my_echo_test.elfが選択されていることを確認します
- Apply、Debugをクリックします。
    - 2回目以降は、直接Debugボタンで実行できます

うまく動けば、main関数先頭で止まります。
その後、Resumeすると、プログラムが動き出します。
好きなところで止めたり、変数を確認したりできるはずです。

## 再実行するとき
前回も記載しましたが、再度実行するときには、一度OpenAMPを終了する必要があります。

```sh:ZYBOターミナル
echo stop > /sys/class/remoteproc/remoteproc0/state
echo start > /sys/class/remoteproc/remoteproc0/state
```

# (おまけ) Pythonの場合
Pythonからは下記のようなコードで通信できる。
注意点は、`open("/dev/rpmsg0", "r+")`で開くとうまく通信出来なかった。`os.open("/dev/rpmsg0", os.O_RDWR)`だと出来た。

```python
def main():
	while(not (os.path.exists("/dev/rpmsg0"))):
		sleep(1)

	rpmsg = os.open("/dev/rpmsg0", os.O_RDWR)

	os.write(rpmsg, "ABC")
	readValue = os.read(rpmsg, 20)
	print("readValue = " + readValue)

	os.close(rpmsg)

if __name__ == '__main__':
	main()
```