1.記事一覧
記事は複数回に分けて投稿する予定です。AMD/XilinxのARM SoC(ZynqMP Kria K26 SOM)で動作する、AMD/Xilinx公式認定Ubuntuやベアメタル開発を勉強していく覚書きです。
ZynqMP(APU:Cortex-A53,Arm64) 組込みLinux入門編
- 【ZynqMP】1. 認定UbuntuでPLのGPIOを使う
- 【ZynqMP】2. 認定Ubuntuのカーネルビルド
- 【ZynqMP】3. 認定UbuntuのDeviceTree変更
- 【ZynqMP】4. 認定UbuntuでOpenAMPを試す【CR5Lockstep】
- 【ZynqMP】5. UARTでAMP【コア間通信】
- 【Linux】6. crash toolでカーネルメモリを見る
ZynqMP(RPU:Cortex-R5,Arm32) RPU入門編
- 【ZynqMP】1. Cortex-R5でHelloworld
- 【ZynqMP】1.1.Vitis Unified IDE設定のあれこれ←本記事
- 【ZynqMP】2. Cortex-R5でRTOS+GPIO
- 【ZynqMP】3. PL EthernetでTCP/IP【動作編】
- 【ZynqMP/RasPi】4. CAN通信デバイスを試す
2.新Vitis(v2023.2以降)で気づいたことまとめ
注:この記事は2024/7頃に記述した内容です。内容が古い場合はご了承ください。投稿時点でVitis v2024.2がリリースされていますが、本記事では扱いません。
2-1. 新Vitisについて
Vitisのv2023.2より、新Vitis(Vitis Unified IDE)がリリースされました。Eclipse Theia IDEというVSCodeのオープンソース版がベースになっているようです。以前のEclipseらしいUIの旧Vitisは”Vitis Classic”と呼ばれ、まだサポートは続けられていますが、新Vitisへの移行が進められています。新Vitisもいくつかの機能は試験実装期間中か未実装なものもあります。
企業が提供するIDEを一新するのは下手をすると何十年に一度の一大イベントのはずなので、IDEを一新するという決定の判断ができるのは正直尊敬します。とんでもない予算がかかりますしね。
ただし、ユーザ側としてはIDEを乗り換えるというのは多くの方は重い腰が上がらないと思います(みなさんも…そうですよね?)。私は今のところ完全趣味でやっているので、のんきに新しいツールにワクワクしてますが、業務で使っている方はたまったものではないでしょう。
私はXilinx製品に触ったのがここ数年なので知らなかったのですが、Xilinx社の開発環境はここ10年間でもえらくコロコロ移り変わっていると思います。正直ここまでのものはなかなか無いと思います。ここ10年はAIブームの影響が強いので、市場の動向に追いついて行こうとした結果でしょうか。
さて、今回はEclipse系IDEに慣れている旧Vitisユーザが新Vitisを使う際つまづきそうな点について、私が気づいたことのメモを残しておこうと思います。
注:今更ですが、私は旧Vitisをほとんど使ったことがありません。他社のEclipse系IDEの使用経験はあります。旧Vitisより、Eclipse系IDE目線で書いていきます。
内容
- 隠れているファイル類を表示する
- ユーザ定義ソースツリーの追加
- デバッグビルドとリリースビルド
- 条件付きブレークポイント
- 複数コアの同時デバッグ
- クロストリガで複数コアを同期ブレーク
- デバッグ時ロードされるbitstreamの落とし穴
- エディタのインデントラインずれ
- VSCodeの拡張機能は使える?
注1:Vitis Unified IDE v2024.1.1で確認しています。今後仕様が変わる可能性もあります。既にv2023.2からv2024.1で多くの変更点や機能追加があります。
注2:この記事の話はあくまでZynqMPのサブコアのCortex-R5(CR5)のエンベデッドアプリケーション開発向けの話です。アクセラレータ開発など、Vitisはもっと多機能です。私も大半の機能を把握していませんのでご承知ください。
環境
開発PC | Ubuntu20.04 LTS |
開発ツール | AMD/Xilinx社 Vivado v2024.1.1 Vitis Classic v2024.1 Vitis Unified IDE v2024.1.1 |
ターゲットボード | Xilinx社製 Kria KR260 ロボティクススターターキット(SK-KR260-G) SOM : Xilinx社 Kria K26 SOM (Zynq UltraScale+ MPSoCベース) APU : Arm CA53x4 1333MHz arm64 RPU : Arm CR5x2 533MHz armv7-R SDRAM : DDR4 4GB |
2-2. 隠れているファイル類を表示する
VitisでPlatformコンポーネント(=Platformプロジェクト)とApplicationコンポーネント(=Applicationプロジェクト)を作成します。左ペインのホーム記号の様なアイコンをクリックすると、プロジェクトファイルツリーのようなものが表示されます。
ソースファイルやリンカスクリプトファイルにアクセスできますが、全てのファイルは表示されません。困ることも多いと思いますので、全て表示出来るように設定します。
上部ペイン View > Explorerをクリックすると、左ペインに新たなマークが出現します。VSCodeでよく見るやつです。残念ながら、IDEを再起動すると、この設定はリセットされますので、毎回行う必要があるようです。
普段あまり触ることはありませんが、CMakeLists.txtなどもここからアクセスできるようになります。
2-3. ユーザ定義ソースツリーの追加
オリジナルのApplicationプロジェクトを作成する場合のコツを書き残しておこうと思います。
VitisでExampleテンプレートからApplicationコンポーネントを作成し、そこからユーザが作成したソースとヘッダファイルを追加することを想定します。
新VitisではビルドシステムにCMakeが使われています。旧Vitisではわかりませんが、おそらくEclipse CDTが使われているのかと勝手に思っています。
CMakeといえばCMakeLists.txtと呼ばれるビルド設定ファイルを各フォルダ階層に用意して、CMakeツールがトップ階層から順次読み込んでいくことにより、Makefileを構築します。各階層に設定ファイルを置くのでフォルダ階層が複雑なソースコード群も移植が楽になります。特にinclude解決が優秀です。
ユーザがソース・ヘッダファイルを追加する場合は通常はCMakeLists.txtを編集することによってビルド対象に加えるようにしますが、新Vitisの場合はその必要はありません。
試しに以下の構造のソースファイルを追加します。別記事でやっているUART-AMPのコードになります。includeヘッダファイルは”/aap/inc/”と”/test/inc/”以下にあるので、2つのincludePATHを設定する必要があります。
$ tree
.
├── app
│ ├── inc
│ │ ├── hardware_def.h
│ │ ├── led.h
│ │ ├── uart.h
│ │ └── user_def.h
│ ├── led.c
│ └── uart.c
├── lscript.ld
├── main.c
└── test
├── inc
│ ├── reg_dump.h
│ ├── uart_loopback_test.h
│ ├── uart_recv_test.h
│ └── uart_send_test.h
├── reg_dump.c
├── uart_loopback_test.c
├── uart_recv_test.c
├── uart_send_test.c
└── uart_send_test_data.c
ソース追加でやることは2つ
- Applicationコンポーネントのsrcフォルダにコード一式を配置
- UserConfig.cmakeにincludePATHを追加
CMakeLists.txtの編集・作成は不要です。
それではやってみましょう。ファイルマネージャでsrcフォルダの中にコード一式をコピペします。
Vitisにフォルダが見えるようになります。テンプレートから作成されたmain()が存在するソースファイルは無効化してあります。
次にIncludePATHを追加します。Browseボタンを押してヘッダのあるフォルダを指定します。
設定すると以下のようになります(一例)。
これでビルド可能になります。
ところでCMakeLists.txtはどうなっているのでしょうか。前章で書いた隠れているファイルを見えるようにする設定を行い、srcフォルダ直下のCMakeLists.txtを見てみます。
(...)
if(CMAKE_EXPORT_COMPILE_COMMANDS)
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES})
endif()
collect (PROJECT_LIB_SOURCES test/uart_recv_test.c)
collect (PROJECT_LIB_SOURCES test/uart_loopback_test.c)
collect (PROJECT_LIB_SOURCES test/uart_send_test_data.c)
collect (PROJECT_LIB_SOURCES test/uart_send_test.c)
collect (PROJECT_LIB_SOURCES test/reg_dump.c)
collect (PROJECT_LIB_SOURCES app/led.c)
collect (PROJECT_LIB_SOURCES app/uart.c)
collect (PROJECT_LIB_SOURCES main.c)
collector_list (_sources PROJECT_LIB_SOURCES)
linker_gen("${CMAKE_CURRENT_SOURCE_DIR}/linker_files/")
string(APPEND CMAKE_C_FLAGS ${USER_COMPILE_OPTIONS})
string(APPEND CMAKE_CXX_FLAGS ${USER_COMPILE_OPTIONS})
string(APPEND CMAKE_C_LINK_FLAGS ${USER_LINK_OPTIONS})
string(APPEND CMAKE_CXX_LINK_FLAGS ${USER_LINK_OPTIONS})
(...)
6~13行目に先ほどコピペしたソースファイルがビルド対象になるように既に設定されています。調べたところ、ビルド実行時に毎回srcフォルダ以下のファイル探索を行い、CMakeLists.txtが再生成されていました。
再生成というのは、srcフォルダ以下のファイルスキャンを行うスクリプトを、Vitis独自の機能として組んでいるようです。CMakeLists.txt知らなくても扱えるのは良いですね。
おまけですが、CMakeLists.txtの先頭あたりを見ると、妙な行間が空いていました。
# Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.14.7)
include(${CMAKE_CURRENT_SOURCE_DIR}/Freertos_hello_worldExample.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/UserConfig.cmake)
set(APP_NAME freertos_hello_world)
project(${APP_NAME})
find_package(common)
enable_language(C ASM)
collect(PROJECT_LIB_DEPS xilstandalone;xiltimer;freertos)
collect(PROJECT_LIB_DEPS freertos)
collect(PROJECT_LIB_DEPS xil)
collect(PROJECT_LIB_DEPS xiltimer)
collect(PROJECT_LIB_DEPS gcc)
(...)
この行間ですが、ビルドするたびに増えます。どうやら1~12行目までの内容は、既存のCMakeLists.txtの内容を引き継いで、広い行間の下(22行目以降)は再生成されるようです。このときに空行が混じり、行間がビルドのたびに広がるみたいです。
もしCMakeLists.txtで設定したい場合は広い行間の上側に書く必要があります。
2-4. デバッグビルドとリリースビルド
Eclipseだとデバッグビルドとリリースビルドの切替がワンボタンでしたが、新Vitisでは今の所その様な機能は無さそうです(私が見つけられないだけかも)。
そのため、コンパイルオプションを直接書き換えます。
Platformコンポーネントのデバッグリリース切替
Platformコンポーネントのコンパイルオプションは以下の場所にあります。
“proc_extra_compiler_flags”の”-g”オプションを外すとリリースビルドになります。上にある、”proc_compiler_flags”は書き換えられないので”-O2″最適化を外す方法は今の所私はしりません。
Applicationコンポーネントのデバッグリリース切替
Applicationコンポーネントは以下の場所(UserConfig.cmake)で設定できます。
この設定はCMakeスクリプト(.cmake)で書かれているので、コードエディタに切り替えると、直接編集できます。
2-5. 条件付きブレークポイント
新Vitisと言うより、VSCode固有の機能なのですが、ブレークポイントにいくつか種類があります。
- 普通のやつ
- 式がtrueのときブレークするやつ
- 指定した回数通過するとブレークするやつ
- 通過するとブレークせずログメッセージを出力するやつ←使用不可
この内、ログメッセージを残す以外のブレークポイントは一応使えました。これが使えると、デバッグ用にprint文を挿入してビルドする必要が無くなるのですが、未実装であると書かれたダイアログが出ます。
式がTrueのときブレーク
条件文の式がTrueの場合にブレークします。注意点として、IDEの動作がそこそこ重くなります。私のPCが骨董品レベルなのでそれが原因だと良いのですが、条件文の処理を開発PC側で行っているためと思われます。
行番号の左側の空白を右クリックし、”Add Conditional Breakpoint…”を押します。下の例では119行目あたりで行っています。
“Expression”を選択し、右側に式を記述します。今回はInitLed関数の戻り値retが以下の条件になったときにブレークするようにします。
“ret != eSUCCESS”:eSUCCESSはenum型
条件がtrueだとブレークします。
指定した回数通過するとブレークするやつ(ヒットカウントブレーク)
指定した回数を通過するとブレークするブレークポイントです。ただし、少し癖があります。Vitis特有な仕様なのかは不明ですが、指定した回数+1回通過した瞬間ブレークします。
つまり、5回を指定すると、5回はスルーして、6回目にブレークします。
やり方は、行番号の左の空白で右クリックし、メニューの”Add Conditional Breakpoint…”を選択します。
“Hit Count”を選択し、通過する回数を入力します。例では5としています。
2-6. 複数コアの同時デバッグ
複数コアの同時デバッグとは複数コアそれぞれのELFをJTAGで同時にロードし、各コアそれぞれでステップ実行や同時スタート・停止が出来るようになります。
デバッグ設定
今回の例はCR5の0コアと1コアの同時デバッグを行います。Platform・Applicationコンポーネントを各コアで既に作成し、ビルド済みであることを前提とします。
デバッグ設定はlaunch.jsonファイルで記述しますが、GUI設定が可能です。各コア用にlaunch.jsonがそれぞれ存在しますが、今回は0コアのみ編集すれば問題ありません。
0コア用のApplicationコンポーネントのlaunch.jsonを開きます。
“+”印ボタンを押して新しくデバッグ設定を作成し、右下のプロセッサ指定に新しく設定を追加します。今回は1コアのELFを指定して追加します。これで設定は完了です。
デバッグ開始
新しく作成したデバッグ設定をクリックして虫マークを押します。
CR5の0コアと1コアそれぞれがmain関数先頭で停止します。”RPU”の部分を選択すると、同時スタート、同時停止も可能です。個別に操作やステップ実行する場合は各コアを選択します。
2-7. クロストリガで複数コアを同期ブレーク
ARM CoresightデバッグIPでは、コア制御用のデバッグ信号を別コアに送信する機能があります。私は使ったことが無いので、詳細はわかりませんが、Xilinxドキュメントではクロストリガと呼んでいました。
いつか使う日が来るかもしれないので、練習として、少し触ってみます。
下記の資料でPLのILA(埋込みロジアナIP)とCPUの間でクロストリガを掛ける内容をやっているので、これを参考にCR5の0コアと1コア間でトリガを掛けてみます。
具体的には0コアがブレークポイントでブレークすると1コアも同時にブレークするように、ブレーク信号をバイパスするようにしてみます。
デバッグ設定
前章で説明した複数コアの同時デバッグの設定を改変します。”Enable Cross Triggering”にチェックをいれ、”Add item”を開きます。
設定を2つ追加します。
- Input : R5-0/DBGTRIGGER[0]、Output : R5-1/EDBGRQ[8]
- Input : R5-1/DBGTRIGGER[8]、Output : R5-0/EDBGRQ[0]
デバッグ実行
- CR5-0コア側でブレークポイントを設定
- CR5-1コアを実行開始
- CR5-0コアを実行開始
- CR5-0コアがブレークすると、CR5-1コアも同タイミングで停止する
2-8. デバッグ時ロードされるbitstreamの落とし穴
Vivadoで更新したハードウェアエクスポートファイル(.xsa)をVitisに適用する際、以下のPlatformコンポーネントの設定(vitis-comp.json)で”Switch XSA”ボタンから更新が出来るようです。
ただし、デバッグで使用されるbitstreamファイルは更新されないままになります。
Vitis IDEでデバッグを開始する際、PLにbitstreamがロードされます。そのbitstream本体のファイルの場所は以下デバッグ設定(launch.json)で設定されています。
このbitstreamは新規作成時にハードウェアエクスポートファイルの中身から複製されたものです。これが、”Switch XSA”による更新時に複製先が古いままになることに注意です。
対応としては、bitstreamの参照PATHをVivadoのrunsフォルダの中身に変更するか、ローカルコピーのファイルを手動で更新するしか無さそうです。
2-9. エディタのインデントラインずれ
デフォルトでエディタのインデント(TAB)はスペース文字*4文字に置換する設定になっていると思います。このインデントの位置を縦線で表示してくれているのですが、フォントサイズとあっていないので、ずれて表示されます。下図ではカーソルをスペース4文字の位置に置いていますが、微妙にずれてしまっています。違和感がかなりあります。
解決方法
- フォントサイズを12または16に変更する。(デフォルトは14)
- インデントを表示する設定に変更
フォントサイズの変更
File>Preferences>Open Settings(UI)を開き、上の検索欄に”font”と入力します。
“Editor: Font Size“の項目を変更します。保存はAutosaveです。
インデントを表示
フォントサイズを変える以外では、インデントを表示する方法もいけました。
File>Preferences>Open Settings(UI)を開き、上の検索欄に”white”と入力します。
“Editor: Render Whitespace“の項目を”boundary”に変更します。この設定は単語間の1スペース文字以外の空文字(スペース、TAB)を可視化します。スペースは「点」の記号、TABは「→」と表示されます。下図でインデントが可視化されると、インデントラインとカーソルが一致します。
2-10. VSCodeの拡張機能は使える?
新Vitisの大元のVSCodeはExtensionsと呼ばれる拡張プラグインで機能を追加できました。EclipseではMarketplaceで同じことが出来ます。
Vitis v2024.1から試験的に新機能プレビューがいくつか開放されています。その中に”Extension Marketplace”が出てきたので有効にしてみます。
View>New Feature Previewで新機能メニューを開きます。
“Extension Marketplace”を有効化します。
Extensions(拡張機能)が有効化します。Built-inタブにある機能はプリインストールされているプラグインです。Git関係やLintツールなどが既に入っています。
試しに上の検索欄でプラグインを検索してみます。VSCodeはMS社が運営するVisual Studio Marketplaceに接続されていますが、Eclipse Theia IDEはEclipse Foundationが運営する、Open VSX Registryに接続されています。
Eclipse Theia IDEの様なMS社の製品でないアプリはVisual Studio Marketplaceを利用できない規約が存在するため、この様な形になったらしいです。
そのため、全てのExtensionプラグインが利用できるわけではありません。
今回はプラグインが動作するのかどうかの確認として、適当なものをいれてみました。一応機能しているようです。