Linux に平行してベアメタルプログラムを走らせる の変更点

更新


[[公開メモ]]

#contents

* CPU でリアルタイム処理をしたい [#p86d9575]

UI や通信に関する処理を Linux で行いつつ、~
リアルタイム性能の必要な処理を別途動かしたい。

Zynq には CPU が2つあるので、1つを Linux に、
1つをベアメタルに使えば完全な並列処理ができるはず?

http://www.wiki.xilinx.com/Real-Time+Linux によれば、~
IRQ Affinity という機能で、Linux で受け取る IRQ を特定の CPU 
に回すという方法もあるらしい。そちらの CPU を常時 Idle にしておき、
割り込み処理中の追加割り込みを禁止できるなら、Linux 
だけでリアルタイム処理ができるのかもしれないけれど、
そういう話にはなっていないようで。

** まだまだ道半ばです [#b66245bd]

結構大変・・・
** 資料 [#w2117929]

シンプルな AMP : 2 つの Zynq SoC プロセッサ上で動作する Linux およびベアメタルシステム~
https://japan.xilinx.com/support/documentation/application_notes/j_xapp1078-amp-linux-bare-metal.pdf

上記に対する最新の補遺~
http://www.wiki.xilinx.com/XAPP1078+Latest+Information

むしろこっちが最新か?~
http://www.wiki.xilinx.com/Multi-OS+Support+(AMP+%26+Hypervisor)

FPGAマガジンの16に FreeRTOS をメインに動かして、
後から Linux を起動する方法が書かれている。

OpenAmp~
https://github.com/OpenAMP/open-amp ~
http://www.wiki.xilinx.com/OpenAMP

これを読めばいいのかも。

** OpenAmp を使えるとよさそう [#ya93739b]

https://github.com/OpenAMP/open-amp

Xilinx の OpenAmp というしくみを使うと、
CPU0 で走る Linux アプリから FreeRTOS や ベアメタル アプリを CPU1 で立ち上げたり、
そのリモートアプリとの間で通信をしたり、リモートアプリに Linux の資源を使わせたり
できるとのことで、まさに欲しかった機能と言えます。

- OpenAmp の機能
-- remoteproc ホストからリモートのプロセスを制御する
-- RPMsg ホストとリモートとの間での通信手段を提供する

OpenAmp は petalinux を前提としていて、libmetal に依存しているのだそうです。


* petalinux [#ma53223d]

Xilinx がメンテナンスしている Linux ディストリビューション。

開発環境、ブートローダ、カーネル、ソフトウェアパッケージ、すべてがこれでまかなえる。

ただし設定、コンパイル、デプロイにものすごく時間がかかるので、
そのままの形で開発に使うには向かないのかも。

- [[電気回路/zynq/Petalinux のビルド]]~
とりあえず標準の形で起動可能な SD カードを作成するところまで~
~
- [[電気回路/zynq/Petalinux のカスタマイズ]]~
いろいろカスタマイズして開発環境を整えた内容

上記で以下を実現できています。

- カーネルとして Linux 4.6.0-xilinx をカスタマイズして使える
- Ubuntu 16.04 のパッケージングシステムを使える
- /boot/uEnv.txt の書き換えで bootargs その他の起動方法を変更できる
- /boot/system.bit.bin の書き換えでロジックを変更できる
- /boot/devicetree.dtb の書き換えでデバイスを追加できる
- [[電気回路/zynq/Device Tree Overlay]] の手順で、
Linux を再起動せず device tree を書き換えられる

* libmetal [#nc69c479]

https://github.com/OpenAMP/libmetal

linux, freertos, baremetal で共通に使えるライブラリ API を提供し、
デバイスへのアクセスや割り込み制御、メモリ確保、その他ユーティリティ機能を提供するもの
のようです。

- Linux user space (based on UIO and VFIO support in the kernel)
- RTOS (with and without virtual memory)
- Bare-metal environments

となっているので、metal_xxx という共通の名前の関数ではあるものの、
環境によって実装を変え、適切な API 呼び出しに変換してくれる、ということみたい。

** petalinux ではチェックボックス一つでインストール可能? [#x0e2da29]

petalinux-config -c rootfs で選択できるので、 チェックするだけでインストールできルっぽい?

ただこれでやるとユーザープロジェクトもすべて petalinux のビルドシステムを使わなければならなくなってややこしい。

GitHub で公開されているソースから単独でインストールできないものか、
と四苦八苦したのがこちらですが、どうやらこういう使い方をするものじゃないみたい。~
>> [[電気回路/zynq/libmetal のインストール]] ← あんまり意味が無いことが後から判明

** そうじゃなくて Xilinx SDK から使うべき [#u1313afb]

libmetal も openamp も、ビルドには手順に沿って board support package (BSP) を使わないと、
必要なライブラリへのパスを通すのにも一苦労します。

Petalinux の操作を全て覚えればできるのかもしれませんが、片手間でやるには
Xilinx SDK の GUI から使わないととてもじゃないけど使いこなせない感じ。

以降、そっちでやってみます。

* Xilinx SDK から OpenAMP を使う [#oa16b34b]

リポジトリは https://github.com/OpenAMP/open-amp にあるけれど、
Xilinx SDK から使う分にはそのあたりを気にする必要はないようです。

これに沿ってやってみるのが良さそう~
https://www.xilinx.com/support/documentation/sw_manuals/xilinx2016_2/ug1186-zynq-openamp-gsg.pdf
https://www.xilinx.com/support/documentation/sw_manuals/xilinx2017_3/ug1186-zynq-openamp-gsg.pdf

* echo-test [#g669def7]

CPU-0 で実行中の Linux から、~
CPU-1 用に standalone 実行ファイルを読み込んで走らせる。

CPU-0 側から送った文字列を CPU-1 側から返して画面に表示する。

** standalone 側の準備 [#zf9f46f7]

*** プロジェクトの作成 [#r90bcae7]

[File]-[New]-[New Project...]~
&ref(new_project_stdalone.png,,66%);

- Project name: echo_stdalone
- OS Platform: standalone
- Processor: ps7_cortex9_1
- Language: C (C++ を選ぶと目的のテンプレートが表示されない)
- BSP: Create new

で [Next]

&ref(new_project_stdalong2.png,,66%);

- Available Template: OpenAMP echo test

で [Finish]

&ref(new_project_stdalone3.png,,66%);

プロジェクトができた。

*** echo_stdalone_bsp を Build する [#u301257c]

まずはいくつか設定

&ref(set_compiler_flag_for_bsp.png,,50%);

bsp プロジェクトを右クリックから [Board Support Package Settings]

&ref(DUNDEFINE_FILE_OPS.png,,50%);

[Overview]-[drivers]-[ps7_cortexa9_1] を選んで [extra_compiler_flags] を確認すると、
_open(), _close(), _read(), _write() をマスター側にリダイレクトするためのオプション

- -DUNDEFINE_FILE_OPS

はすでに登録されていた。

vector table を OCM に置くのが一般的なようで、

- -DVEC_TABLE_IN_OCM

も指定しておくと良いみたい。

リソースの初期化をマスター側で行う場合に必要な

- -DUSE_AMP=1

も指定しておく。

&ref(bsp-compiler-options.png,,50%);

[Ok] して bsp プロジェクトを build した。

 LANG:console
 xscugic.c:248:2: warning: #warning "Building GIC for AMP" [-Wcpp]
  #warning "Building GIC for AMP"
   ^
 xscugic_hw.c: In function 'DistInit':
 xscugic_hw.c:118:3: warning: #warning "Building GIC for AMP" [-Wcpp]
   #warning "Building GIC for AMP"
    ^
なんか warning 出た。

GIC は Generic Interrupt Controller だけど、
このライブラリを bsp から外した方が良いということかしら???

ソースファイルを見ると、

xscugic.c
 LANG:c
 static void DistributorInit(XScuGic *InstancePtr, u32 CpuID)
 {
 	u32 Int_Id;
 	u32 LocalCpuID = CpuID;
 	u32 RegValue;
 
 #if USE_AMP==1 && (defined (ARMA9) || defined(__aarch64__))
 #warning "Building GIC for AMP"
 	/*
 	 * GIC initialization is taken care by master CPU in
 	 * openamp configuration, so do nothing and return.
 	 */
 	return;
 #endif
 
 	RegValue = XScuGic_DistReadReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET);
 	if (!(RegValue & XSCUGIC_EN_INT_MASK)) {
          ...

xscugic_hw.c
 LANG:c
 static void DistInit(XScuGic_Config *Config, u32 CpuID)
 {
 	u32 Int_Id;
 	u32 LocalCpuID = CpuID;
 
 #if USE_AMP==1
 	#warning "Building GIC for AMP"
 
 	/*
 	 * The distrubutor should not be initialized by FreeRTOS in the case of
 	 * AMP -- it is assumed that Linux is the master of this device in that
 	 * case.
 	 */
 	return;
 #endif
 
 	XScuGic_WriteReg(Config->DistBaseAddress, XSCUGIC_DIST_EN_OFFSET, 0U);
        ...

となっていて、むやみに初期化してしまわないようにしている。

たぶん無視していいっぽい。

&ref(new_project_stdalone4.png,,50%);

include の下に大量の .h ファイルができた

*** echo_stdalone を Build [#xe4426f6]

Binaries の下に echo_stdalone.elf ができた

&ref(build_echo_stdalone.png,,66%);

** Linux 側の準備 [#n28cc2e7]

上記の pdf では 

- PetaLinux 上でリモート側のアプリをビルドして、~
できたファームウェアを /lib/firmware/<myfirmware> に入れる
- petalinux-config でカーネルベースアドレスを 0x10000000 にする~
ベアメタルアプリのブートサポートがアドレス 0 からになるため
- u-boot Configuration で netboot offset を (0x11000000) にする
- Enable loadable module support にチェックを付ける
- Device Drivers ---> Generic Driver Options ---> Userspace firmware loading support にチェックを付ける
- Device Drivers ---> Remoteproc drivers ---> Support ZYNQ remoteproc にチェックを付ける
- Kernel Features ---> Memory split (...)---> 2G/2G user/kernel split を選択 (1G/3G でも可)
- Kernel Features ---> High Memory Support にチェックを付ける
- rootfs の


(以下未稿)

Counter: 20417 (from 2010/06/03), today: 2, yesterday: 0