Petalinux2018.3でPLとDevice Treeを動的に変更する の履歴(No.2)
更新- 履歴一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- 電気回路/zynq/Petalinux2018.3でPLとDevice Treeを動的に変更する へ行く。
再起動せずにプログラマブルロジック及び Device Tree を更新する†
Device Tree Overlay を使うと Device Tree を更新できる
FPGA Region という機能を使うとプログラマブルロジックを更新できるらしい
Device Tree Overlay†
電気回路/zynq/Device Tree Overlay ではまだできなかった、 configfs を用いた方法が使えるようになっているみたいだ。
カーネル設定†
電気回路/zynq/Petalinux2018.3によるzynq-7000ブート用SDカード作成#t9b088e3 の続きから、
LANG:console
$ cd ~/petalinux/zturn-v2018.3/kernel-source
$ make ARCH=arm menuconfig
Device Tree and Open Firmware support --->
[*] Device Tree overlays
[*] Device Tree Overlay ConfigFS interface
Petalinux からカーネルソースを取ってきた場合には これらは元々チェックが付いていた。
やりかた†
ブート直後、すでに /sys/kernel/config が使えるようになっていた。
LANG:console $ mount | grep configfs configfs on /sys/kernel/config type configfs (rw,relatime)
あとは、
https://okchan08.hateblo.jp/entry/zynq-device_tree_overlay#ConfigFS%E3%81%AE%E6%BA%96%E5%82%99
などを参考にすればいいはず。
FPGA Region によるプログラマブルロジック書き換え†
カーネル設定†
電気回路/zynq/Petalinux2018.3によるzynq-7000ブート用SDカード作成#t9b088e3 の続きから、
LANG:console
$ cd ~/petalinux/zturn-v2018.3/kernel-source
$ make ARCH=arm menuconfig
Device Drivers --->
FPGA Configuration Framework --->
<*> FPGA Region
<*> Xilinx Zynq FPGA
<*> FPGA Bridge Framework
<*> Xilinx LogiCORE PR Decoupler
Petalinux からカーネルソースを取ってきた場合には これらは元々チェックが付いているようだ。
.bit ファイルを .bin ファイルに変換する†
LANG:console $ cd $ sudo curl https://raw.githubusercontent.com/topic-embedded-products/meta-topic/master/recipes-bsp/fpga/fpga-bit-to-bin/fpga-bit-to-bin.py -o /usr/local/bin/fpga-bit-to-bin.py $ sudo chown root:root /usr/local/bin/fpga-bit-to-bin.py $ sudo chmod a+x /usr/local/bin/fpga-bit-to-bin.py $ sudo mkdir -p /lib/firmware/bit.bin $ sudo fpga-bit-to-bin.py --flip /boot/system.bit /lib/firmware/bit.bin/system.bit.bin
fpga region デバイス†
LANG:console
$ dtc -I dtb -O dts /boot/devicetree.dtb
/dts-v1/;
/ {
#address-cells = <0x1>;
#size-cells = <0x1>;
compatible = "xlnx,zynq-7000";
cpus {
...
};
fpga-full {
compatible = "fpga-region";
fpga-mgr = <0x3>;
#address-cells = <0x1>;
#size-cells = <0x1>;
ranges;
};
...
のように /fpga-full として定義されている。
ロジックの書き込み†
LANG:console
$ mkdir fpga-region
$ cd fpga-region/
$ cat << EOT > fpga-region.dts
> // Device Tree File for FPGA Region: fpga_reg.dts
> /dts-v1/;
> /plugin/;
> / {
> fragment@1 {
> target-path = "/fpga-full";
> #address-cells = <1>;
> #size-cells = <1>;
> __overlay__ {
> #address-cells = <1>;
> #size-cells = <1>;
> firmware-name = "bit.bin/system.bit.bin";
> };
> };
> };
> EOT
$ dtc -I dts -O dtb fpga-region.dts -o fpga-region.dtbo
$ sudo mkdir -p /sys/kernel/config/device-tree/overlays/fpga-region
$ cat /sys/kernel/config/device-tree/overlays/fpga-region/status
unapplied
$ sudo cp fpga-region.dtbo /sys/kernel/config/device-tree/overlays/fpga-region/dtbo
$ cat /sys/kernel/config/device-tree/overlays/fpga-region/status
applied
これでできた。
標準で /fpga-full というラベルで fpga region のデバイスが宣言されているので、 そこをめがけて device tree ovelay すればいいらしい。
status に 1 を書き込む必要はなく、dtbo への書き込みだけでいい。
ただ、もう一度 dtbo へ書き込んでも DONE の LED に変化がないので、 内容を更新できているのかどうかよく分からない。
system.dtb にシンボルを埋め込む†
を参考にすると、dtb にシンボルを埋め込むには dtc 1.4.2 以上でなければならないらしい。 ところが petalinux のツールチェインに含まれる dtc は古いのでシンボルに対応していない。
そこで、zynq 側に持っていってコンパイルする。
system.dtb のソースファイルは components/plnx_workspace/device-tree/device-tree/system-top.dts にあるのだけれど、これは C のプリプロセッサを通し #include を処理しないとそのままでは dtc でコンパイルできない。
https://qiita.com/ikwzm/items/b07af1a861d6f1c0fde2
を参考に、
LANG:console $ which dtc /opt/petalinux_2018.3/tools/linux-i386/petalinux/bin/dtc $ dtc -v Version: DTC 1.4.1 $ gcc -E -P -x assembler-with-cpp -I project-spec/meta-user/recipes-bsp/device-tree/files/ components/plnx_workspace/device-tree/device-tree/system-top.dts > images/linux/system.dts $ sudo cp images/linux/system.dts /mnt/sdcard1/ $ sudo cp cp components/plnx_workspace/device-tree/device-tree/system-conf.dtsi /mnt/sdcard1/ $ sudo umount /mnt/sdcard1/
としておいて、zynq 側で
LANG:console
$ dtc -v
Version: DTC 1.4.5
$ sudo dtc -I dts -O dtb -@ -i /boot /boot/system.dts -o /boot/devicetree.dtb
/boot/devicetree.dtb: Warning (unit_address_vs_reg): Node /memory has a reg or ranges property, but no unit name
/boot/devicetree.dtb: Warning (unit_address_format): Node /amba/spi@e000d000/flash@0/partition@0x00000000 unit name should not have leading "0x"
/boot/devicetree.dtb: Warning (unit_address_format): Node /amba/spi@e000d000/flash@0/partition@0x00000000 unit name should not have leading 0s
/boot/devicetree.dtb: Warning (unit_address_format): Node /amba/spi@e000d000/flash@0/partition@0x00500000 unit name should not have leading "0x"
/boot/devicetree.dtb: Warning (unit_address_format): Node /amba/spi@e000d000/flash@0/partition@0x00500000 unit name should not have leading 0s
/boot/devicetree.dtb: Warning (unit_address_format): Node /amba/spi@e000d000/flash@0/partition@0x00520000 unit name should not have leading "0x"
/boot/devicetree.dtb: Warning (unit_address_format): Node /amba/spi@e000d000/flash@0/partition@0x00520000 unit name should not have leading 0s
/boot/devicetree.dtb: Warning (unit_address_format): Node /amba/spi@e000d000/flash@0/partition@0x00fa0000 unit name should not have leading "0x"
/boot/devicetree.dtb: Warning (unit_address_format): Node /amba/spi@e000d000/flash@0/partition@0x00fa0000 unit name should not have leading 0s
$ dtc -O dts /boot/devicetree.dtb
...
__symbols__ {
cpu0 = "/cpus/cpu@0";
cpu1 = "/cpus/cpu@1";
fpga_full = "/fpga-full";
regulator_vccpint = "/fixedregulator";
amba = "/amba";
adc = "/amba/adc@f8007100";
...
...
警告は出るけれど何とかコンパイルできた。