Zynq開発フローで、".hdfが外部から提供される&&アプリケーションプロジェクトはcmakeで独自ビルド" の場合の実行環境検討

# 概要
Zynqの実際の開発現場において
・.hdfファイルから外部のハードウェアチームからリリースされる
・applicationのelfはcmakeで生成する
前提で、提供された.hdfから
・JTAGデバッグまでのプロセス
・Boot.bin作成までのプロセス
の方法を確認、検討する

# 環境
- Ultra96 V2

# 参考資料
[Zynq UltraScale+ MPSoC: エンベデ ッ ド  デザイ ンチュー ト リ アル](https://japan.xilinx.com/support/documentation/sw_manuals_j/xilinx2018_3/ug1209-embedded-design-tutorial.pdf)

# 最終的なワークスペース構成
説明の前に概要として、最終的なワークスペース構成を示す。
★はBoot.binに含まれるバイナリ

```text:
.
|-- app  
|-- bsp                          # R5 FreeRTOS設定のBSP
|-- bsp_fsbl                     # FSBL Appのプロジェクト作成のときにFreeRTOS設定のbspは使えなかったので、もう１つbspがある（Xilinxのワークフローとしてあっているかは謎）
|-- fsbl_r5
|   |-- Debug
|   |   |-- fsbl_r5.elf★
|-- hdf
|   `-- ultra96.hdf
|-- hw
|   |-- design_1_wrapper.bit★
|   `-- system.hdf
`-- ultra96_only_app_cmake       # Xilinx SDKではなく独自につくったcmake環境
    |-- armr5_toolchain.cmake
    |-- build
    |   |-- main
    |   |   |-- app.elf★        # cmake, makeで作成したelf
    |-- CMakeLists.txt
    `-- main
        |-- CMakeLists.txt
        `-- src
```

# JTAGデバッグで実行する方法
ワークスペースフォルダ名を `ws` して以下は記載する。

## 環境取得
`git clone git@github.com:azukibar0713/ultra96_ws.git`

## 各種プロジェクトの生成
XSCTを開く
※XSCTとは : https://www.xilinx.com/html_docs/xilinx2018_1/SDK_Doc/xsct/intro/xsct_introduction.html

```shell:xscl
xsct% cd "wsフォルダ"
xsct% source ./config/setup_from_hdf.tcl
```

## Build
```shell:xscl
xsct% projects -build
```

※個別のビルドも `xsct% projects -build -type bsp -name bsp` などで可能
※XSCTでワークスペースを開いているとEclipseで同じワークスペースは開けないので、どちらかを閉じる必要がある

## CMakeのAppプロジェクト
`ultra96_only_app_cmake` フォルダは「Xilinx SDKのプロジェクトではない、cmakeでビルドするアプリケーションプロジェクト」と仮定する
※ツールチェーンはXilinx SDKを使っているので、ツールチェーンにpathが通っていることが前提

```console:git,cmake実行できるconsole
$ cd ultra96_only_app_cmake/build
$ cmake -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=./armr5_toolchain.cmake -DBSP_DIR=../../bsp -DAPP_DIR=../../../app ..
$ make
Scanning dependencies of target app.elf
...
[100%] Linking C executable app.elf
[100%] Built target app.elf
```

## アプリケーションプロジェクトは空のままで、cmakeで作成したelf実行してみる
ここまでで、XSCTからつくったアプリケーションプロジェクトは空だが、elfはできたので実行してみる。

```console:XSCT
xsct% connect
      ...(いろいろ出力される)
xsct% targets
  1  PS TAP
     2  PMU
     3  PL
  4  PSU
     5  RPU (Reset)
        6  Cortex-R5 #0 (RPU Reset)
        7  Cortex-R5 #1 (RPU Reset)
     8  APU (L2 Cache Reset)
        9  Cortex-A53 #0 (APU Reset)
       10  Cortex-A53 #1 (APU Reset)
       11  Cortex-A53 #2 (APU Reset)
       12  Cortex-A53 #3 (APU Reset)
```

psu_initを実行
※ *がついているのが選択されているターゲット

```console:XSCT
xsct% targets
  1  PS TAP
     2  PMU
     3  PL
  4  PSU
     5  RPU (Reset)
        6  Cortex-R5 #0 (RPU Reset)
        7  Cortex-R5 #1 (RPU Reset)
     8  APU (L2 Cache Reset)
        9  Cortex-A53 #0 (APU Reset)
       10  Cortex-A53 #1 (APU Reset)
       11  Cortex-A53 #2 (APU Reset)
       12  Cortex-A53 #3 (APU Reset)
xsct% targets -set -filter {name=~ "PSU"}
xsct% targets
  1  PS TAP
     2  PMU
     3  PL
  4* PSU
     5  RPU (Reset)
        6  Cortex-R5 #0 (RPU Reset)
        7  Cortex-R5 #1 (RPU Reset)
     8  APU (L2 Cache Reset)
        9  Cortex-A53 #0 (APU Reset)
       10  Cortex-A53 #1 (APU Reset)
       11  Cortex-A53 #2 (APU Reset)
       12  Cortex-A53 #3 (APU Reset)
xsct%
xsct% source ./hw/psu_init.tcl
xsct% psu_init
```

cmakeで作ったelfをダウンロードする

```console:XSCT
xsct% targets
  1  PS TAP
     2  PMU
     3  PL
  4* PSU
     5  RPU (Reset)
        6  Cortex-R5 #0 (RPU Reset)
        7  Cortex-R5 #1 (RPU Reset)
     8  APU (L2 Cache Reset)
        9  Cortex-A53 #0 (APU Reset)
       10  Cortex-A53 #1 (APU Reset)
       11  Cortex-A53 #2 (APU Reset)
       12  Cortex-A53 #3 (APU Reset)
xsct% targets -set -filter {name =~ "Cortex-R5 #0"}
xsct% rst -processor
Info: Cortex-R5 #0 (target 6) Stopped at 0xffff0000 (Suspended)
xsct% dow ./ultra96_only_app_cmake/build/main/app.elf
Downloading Program -- F:/work_xilinx/ws03/ultra96_only_app_cmake/build/main/app.elf
        section, .vectors: 0x00000000 - 0x00000513
        section, .text: 0x00100000 - 0x0010f4a7
        section, .init: 0x0010f4a8 - 0x0010f4b3
        section, .fini: 0x0010f4b4 - 0x0010f4bf
        section, .rodata: 0x0010f4c0 - 0x001102e3
        section, .data: 0x001102e8 - 0x001113c3
        section, .eh_frame: 0x001113c4 - 0x001113c7
        section, .ARM.exidx: 0x001113c8 - 0x001113cf
        section, .init_array: 0x001113d0 - 0x001113d7
        section, .fini_array: 0x001113d8 - 0x001113db
        section, .bss: 0x001113e0 - 0x001220f3
        section, .heap: 0x001220f4 - 0x001240ff
        section, .stack: 0x00124100 - 0x001278ff
100%    0MB   0.4MB/s  00:00
Setting PC to Program Start Address 0x0000003c
Successfully downloaded F:/work_xilinx/ws03/ultra96_only_app_cmake/build/main/app.elf
```

mainにブレーク張って、実行
ローカル変数確認して、再度実行してプログラムを走らせる

```console:XSCT
xsct% bpadd -addr &main
0
xsct% Info: Breakpoint 0 status:
   target 6: {Address: 0x100e10 Type: Hardware}
xsct% con
Info: Cortex-R5 #0 (target 6) Running
xsct% Info: Cortex-R5 #0 (target 6) Stopped at 0x100e10 (Breakpoint)
main() at freertos_hello_world.c: 75
75: {
xsct% local
x10seconds  : 1090063
xsct% con
Info: Cortex-R5 #0 (target 6) Running
```

ターミナルには↓のように出力されているので、うまくいっているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/cb937298-c916-4798-f188-34fdb3da0281.png)

## EclipseのGUI上でデバッグしたい
これから書く
※以下はメモです
xsct% importsources -name app -path ./ultra96_only_app_cmake/main/src/
と、やるとapp/srcにフラットにコードがコピーされるようだ
importsourcesの後にSDKを立ち上げると、app/src以下にファイルが見えなかった。srcフォルダを右クリックして"Refresh"すると表示された。
importprojectsでやるとどうなるのだろう

# Boot.bin生成して実行する方法
## 参考
[Xilinx Bootgen ユーザーガイド](https://www.xilinx.com/support/documentation/sw_manuals_j/xilinx2018_3/ug1283-bootgen-user-guide.pdf)
[BOOT.binを作る](https://qiita.com/iwatake2222/items/ece0cdf83e6e1908fad8#bootbin%E3%82%92%E4%BD%9C%E3%82%8B-1)
http://nahitafu.cocolog-nifty.com/nahitafu/2018/10/ultra96-2da8.html
https://www.element14.com/community/docs/DOC-95649

## Boot.bin生成

### GUIで作る
Create Boot Imageを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/e4fa7539-4663-0d71-67f2-e495c1fb7803.png)
以下でCreateImageする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/e8c1a165-c7bf-bdf8-54ad-1ec0431b640b.png)

<font color="red">相対パスはサポートされていない↓ので書き換える</font>
  https://japan.xilinx.com/support/answers/55562.html

※作成された.bifファイルの中身は以下のようになる。

```fsbl_r5.bif
//arch = zynqmp; split = false; format = BIN
the_ROM_image:
{
	[fsbl_config]r5_single
	[bootloader]F:\work_xilinx\ultra96_ws\fsbl_r5\Debug\fsbl_r5.elf
	[destination_device = pl]F:\work_xilinx\ultra96_ws\hw\design_1_wrapper.bit
	[destination_cpu = r5-0]F:\work_xilinx\ultra96_ws\ultra96_only_app_cmake\build\main\app.elf
}
```

### XSCTで作る
あとで書く

## Boot.binを実行する
### Ultra96 V2 BootModeの設定
以下のSDカードからのBoot設定をする。
[Ultra96 V2 Getting Started Guide](https://www.element14.com/community/docs/DOC-95649)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/7dec4343-35f6-8b71-74e0-2d53470c20d2.png)

### SDカードにコピー、実行
FAT32でSDカードをフォーマットして、生成したBOOT.binをコピーする。
基盤の電源を入れると、JTAG実行と同じようにターミナルにメッセージが出力されます。

## 実行中のデバッグ
https://www.xilinx.com/html_docs/xilinx2018_1/SDK_Doc/xsct/use_cases/xsdb_debug_program_running_on-target.html


# 困ったことのメモ
## XSCTでFSBLが作れない
XSCTのサンプル
https://www.xilinx.com/html_docs/xilinx2018_1/SDK_Doc/xsct/sdk/reference_sdk_createapp.html
通り実行しても以下のエラーになる

```console
xsct% createapp -name fsbl_r5 -app {Zynq FSBL} -hwproject hw -proc psu_cortexr5_0
App name
Description
App name
Description
Specified template name 'Zynq FSBL' is not valid for configuration. Reason: This application is supported only for CortexA9 processors.
```

ヘルプを見ると、、
Ultra96の場合 `Zynq MP FSBL` が正解だった。

```console
xsct% repo -apps
App name
Description
================================================================================
                        APPLICATION   SUPPORTED PROCESSOR   SUPPORTED OS
================================================================================
                   DDR self refresh   psu_cortexr5          standalone
--------------------------------------------------------------------------------
                          Dhrystone   microblaze            standalone
                                      ps7_cortexa9
--------------------------------------------------------------------------------
                  Empty Application   microblaze            standalone
                                      ps7_cortexa9          xilkernel
                                      psu_cortexa53         freertos10_xilinx
                                      psu_cortexr5
                                      psv_cortexr5
                                      psu_cortexa72
                                      psv_cortexa72
--------------------------------------------------------------------------------
               FreeRTOS Hello World   psu_cortexr5          freertos10_xilinx
                                      psv_cortexr5
                                      ps7_cortexa9
                                      psu_cortexa53
                                      microblaze
--------------------------------------------------------------------------------
          FreeRTOS lwIP Echo Server   psu_cortexa53         freertos10_xilinx
                                      psu_cortexr5
                                      ps7_cortexa9
                                      microblaze
--------------------------------------------------------------------------------
      FreeRTOS lwIP TCP Perf Client   psu_cortexa53         freertos10_xilinx
                                      psu_cortexr5
                                      ps7_cortexa9
                                      microblaze
--------------------------------------------------------------------------------
      FreeRTOS lwIP TCP Perf Server   psu_cortexa53         freertos10_xilinx
                                      psu_cortexr5
                                      ps7_cortexa9
                                      microblaze
--------------------------------------------------------------------------------
      FreeRTOS lwIP UDP Perf Client   psu_cortexa53         freertos10_xilinx
                                      psu_cortexr5
                                      ps7_cortexa9
                                      microblaze
--------------------------------------------------------------------------------
      FreeRTOS lwIP UDP Perf Server   psu_cortexa53         freertos10_xilinx
                                      psu_cortexr5
                                      ps7_cortexa9
                                      microblaze
--------------------------------------------------------------------------------
                        Hello World   microblaze            standalone
                                      ps7_cortexa9          xilkernel
                                      psu_cortexa53
                                      psu_cortexr5
                                      psv_cortexr5
                                      psu_cortexa72
                                      psv_cortexa72
--------------------------------------------------------------------------------
                  Libmetal AMP Demo   psu_cortexr5          freertos10_xilinx
                                                            standalone
--------------------------------------------------------------------------------
                   lwIP Echo Server   psu_cortexa53         standalone
                                      psu_cortexr5
                                      ps7_cortexa9
                                      microblaze
--------------------------------------------------------------------------------
               lwIP TCP Perf Client   psu_cortexa53         standalone
                                      psu_cortexr5
                                      ps7_cortexa9
                                      microblaze
--------------------------------------------------------------------------------
               lwIP TCP Perf Server   psu_cortexa53         standalone
                                      psu_cortexr5
                                      ps7_cortexa9
                                      microblaze
--------------------------------------------------------------------------------
               lwIP UDP Perf Client   psu_cortexa53         standalone
                                      psu_cortexr5
                                      ps7_cortexa9
                                      microblaze
--------------------------------------------------------------------------------
               lwIP UDP Perf Server   psu_cortexa53         standalone
                                      psu_cortexr5
                                      ps7_cortexa9
                                      microblaze
--------------------------------------------------------------------------------
                       Memory Tests   microblaze            standalone
                                      ps7_cortexa9
                                      psu_cortexa53
                                      psu_cortexr5
--------------------------------------------------------------------------------
                  OpenAMP echo-test   psu_cortexr5          freertos10_xilinx
                                      ps7_cortexa9          standalone
--------------------------------------------------------------------------------
 OpenAMP matrix multiplication Demo   psu_cortexr5          freertos10_xilinx
                                      ps7_cortexa9          standalone
--------------------------------------------------------------------------------
                   OpenAMP RPC Demo   psu_cortexr5          freertos10_xilinx
                                      ps7_cortexa9          standalone
--------------------------------------------------------------------------------
                   Peripheral Tests   ps7_cortexa9          standalone
                                      psu_cortexa53         xilkernel
                                      psu_cortexr5
                                      microblaze
                                      psv_cortexa72
                                      psv_cortexr5
--------------------------------------------------------------------------------
             RSA Authentication App   ps7_cortexa9          standalone
--------------------------------------------------------------------------------
                    SREC Bootloader   microblaze            standalone
--------------------------------------------------------------------------------
                SREC SPI Bootloader   microblaze            standalone
--------------------------------------------------------------------------------
                         versal PLM   psu_pmc               standalone
                                      psv_pmc
--------------------------------------------------------------------------------
                versal PSM Firmware   psu_psm               standalone
                                      psv_psm
--------------------------------------------------------------------------------
       Xilkernel POSIX Threads Demo   microblaze            xilkernel
--------------------------------------------------------------------------------
                 Zynq MP DRAM tests   psu_cortexa53         standalone
--------------------------------------------------------------------------------
                       Zynq MP FSBL   psu_cortexa53         standalone
                                      psu_cortexr5
--------------------------------------------------------------------------------
                ZynqMP PMU Firmware   psu_pmu               standalone
--------------------------------------------------------------------------------
                    Zynq DRAM tests   ps7_cortexa9          standalone
--------------------------------------------------------------------------------
                          Zynq FSBL   ps7_cortexa9          standalone
--------------------------------------------------------------------------------
                       async_buffer   ai_engine             freertos10_xilinx
                                                            standalone
                                                            linux
--------------------------------------------------------------------------------
                     GMIO_bandwidth   ai_engine             freertos10_xilinx
                                                            standalone
                                                            linux
--------------------------------------------------------------------------------
            Linux Empty Application   ps7_cortexa9          linux
                                      psu_cortexa53
                                      microblaze
                                      psv_cortexa72
--------------------------------------------------------------------------------
                  Linux Hello World   ps7_cortexa9          linux
                                      psu_cortexa53
                                      microblaze
                                      psv_cortexa72
--------------------------------------------------------------------------------
```

## FSBLがビルドエラー
以下になってしまう。

```console
xsct% projects -build -type app -name fsbl_r5
Building '/fsbl_r5'
16:14:42 **** Build of configuration Debug for project fsbl_r5 ****
make all
Building file: F:/work_xilinx/ws03/hw/psu_init.c
Invoking: ARM R5 gcc compiler
armr5-none-eabi-gcc -DARMR5 -Wall -O0 -g3 -I"F:\work_xilinx\ws03\hw" -c -fmessage-length=0 -MT"src/psu_init.o" -mcpu=cortex-r5 -mfloat-abi=hard  -mfpu=vfpv3-d16 -Os -flto -ffat-lto-objects -I../../fsbl_r5_bsp/psu_cortexr5_0/include -MMD -MP -MF"src/psu_init.d" -MT"src/psu_init.o" -o "src/psu_init.o" "F:/work_xilinx/ws03/hw/psu_init.c"
F:/work_xilinx/ws03/hw/psu_init.c:37:10: fatal error: xil_io.h: No such file or directory
 #include <xil_io.h>
          ^~~~~~~~~~
```

https://japan.xilinx.com/support/answers/55517.html
にあるが、BSPのOSをstandaloneしないとダメらしい。
↓でOKとなった。BSPがfreertos, standaloneで2つで来ている状態になった

```
$ createapp -name fsbl_r5 -app {Zynq MP FSBL} -hwproject hw -bsp bsp_fsbl -proc psu_cortexr5_0 -os standalone
$ projects -build -type bsp -name bsp_fsbl
$ projects -build -type app -name fsbl_r5
```