Petalinux2018.3でPLとDevice Treeを動的に変更する のバックアップ差分(No.4)

更新


  • 追加された行はこの色です。
  • 削除された行はこの色です。
[[公開メモ]]

* 再起動せずにプログラマブルロジック及び Device Tree を更新する [#m94ce4dd]

Device Tree Overlay を使うと、再起動なしに Device Tree を更新できる
- https://okchan08.hateblo.jp/entry/2019/02/05/000000

FPGA Region という機能を使うと再起動なしにプログラマブルロジックを更新できる
- https://okchan08.hateblo.jp/entry/zynq-fpga_region

作業手順としては、
- [[電気回路/zynq/Petalinux2018.3環境を整える]]
- [[電気回路/zynq/Petalinux2018.3によるzynq-7000ブート用SDカード作成]]

の続き。

** 目次 [#p702fcfb]

#contents


* Device Tree Overlay [#v5d9c94b]

[[電気回路/zynq/Device Tree Overlay]] ではまだできなかった、
configfs を用いた方法が使えるようになっているみたいだ。

** カーネル設定 [#j404620e]

[[電気回路/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 からカーネルソースを取ってきた場合には
これらは元々チェックが付いていた。

** やりかた [#j424db65]

ブート直後、すでに /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 も device tree overlay 
を用いた設定方法なので、以下では fpga region を試す。



* FPGA Region によるプログラマブルロジック書き換え [#qc05dbec]

** カーネル設定 [#f82da98e]

[[電気回路/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 ファイルに変換する [#rd04c9cc]

 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 デバイス [#qd5ca1ee]

 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 として定義されている。

** ロジックの書き込み [#mc0ccfe8]

 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 にシンボルを埋め込む [#fc20918e]

https://qiita.com/ikwzm/items/03d518b7c46d1ee49943#device-tree-compilerdtc-%E3%82%92%E7%9B%B4%E6%8E%A5%E4%BD%BF%E3%81%86%E5%A0%B4%E5%90%88

を参考にすると、dtb にシンボルを埋め込むには dtc 1.4.2 以上でなければならないらしい。
ところが petalinux のツールチェインに含まれる dtc は古いのでシンボルに対応していない。
ところが petalinux のツールチェインに含まれる dtc は 1.4.2 なのでシンボルに対応していない。
ちなみに母艦の Ubuntu 16.04LTS の dtc は 14.0 だった。

そこで、zynq 側に持っていってコンパイルする。
そこで、zynq 側に入れた Ubuntu 18.04LTS の dtc 1.4.5 を使ってコンパイルする。

system.dtb のソースファイルは
components/plnx_workspace/device-tree/device-tree/system-top.dts
にあるのだけれど、これは C のプリプロセッサを通し #include 
を処理しないとそのままでは dtc でコンパイルできない。

そのため、母艦の gcc のプリプロセッサを通して dts を1つにまとめてから
zynq に持っていく。ただ、dtc でのコンパイル時に
components/plnx_workspace/device-tree/device-tree/system-conf.dtsi
を必要とするので、こちらも一緒に zynq に移す必要がある。

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
 $ sudo apt-get install -y device-tree-compiler
 $ /usr/bin/dtc -v
  Version: DTC 1.4.0
 $ 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 mount /mnt/sdcard1/
 $ sudo cp images/linux/system.dts /mnt/sdcard1/
 $ sudo cp cp components/plnx_workspace/device-tree/device-tree/system-conf.dtsi /mnt/sdcard1/
 $ sudo 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";
                  ...
  ...

警告は出るけれど何とかコンパイルできた。
起動も問題ないみたい。


Counter: 7751 (from 2010/06/03), today: 4, yesterday: 0