PYNQ: PYTHON PRODUCTIVITY

Dynamic Devicetree Overlays

I am attempting to utilize the sensors96b Vivado hardware project with PYNQ on my Ultra96v2 board. This overlay is available with the external Ultra96-PYNQ board repo. Found here.. I have also attempted to post this issue there with a referral to the PYNQ forums.

In particular, I am interested in configuring PL UART drivers in Linux upon loading the PYNQ overlay. I would like to ensure a device tree overlay is properly added when loading the sensor96b.bit overlay with PYNQ.

Examining the PYNQv2.5 - Ultra96v2 SD card image supplied, there is no .dtbo file availble anywhere, at least in ROOTFS. In an effort to produce one, I followed the Ultra96-PYNQ build instructions in the README. I have had success with building for both the provided BSP and from scratch BSPs, with the v2.5 branches of both this repo and PYNQ.

From my NOT-extensive knowledge of how the the PYNQ build process behaves, it seems the device tree is built successfully with system-top.dtb reflecting the absence of pl.dtsi nodes as PYNQ 2.5 no longer includes PL in the base devicetree. Additionally, I can see that there are device tree overlays (system.dtbo and PL.dtbo) being produced by PYNQ, which seemed hopeful.

With no deviation from the build instructions, boot is seems successful with the needed UART16550a kernel module being loaded with 4 supported ports and no dmesg mentions of any compatible devices, as they haven’t been loaded to PL yet.

pynq kernel: [ 2.467237] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled

Upon loading the sensors96b.bit overlay with PYNQ, the FPGA is programmed successfully and /var/log/sysylog shows:

xilinx@pynq:~$ tail /var/log/syslog 
pynq kernel: [15100.142784] fpga_manager fpga0: writing sensors96b.bin to Xilinx ZynqMP FPGA Manager

However, after loading this overlay, the device tree seems to remain the same (accessed through /proc) with no additional entries for the two UART IP of the sensors96b block diagram. There are also no configuration changes to any of the available /dev/ttySX entries.

xilinx@pynq:~$ setserial -g /dev/ttyS*
/dev/ttyS0, UART: unknown, Port: 0x0000, IRQ: 0
/dev/ttyS1, UART: unknown, Port: 0x0000, IRQ: 0
/dev/ttyS2, UART: unknown, Port: 0x0000, IRQ: 0
/dev/ttyS3, UART: unknown, Port: 0x0000, IRQ: 0

With no automatic device tree updates, I figured I would add the .dtbo file myself as the PYNQ documentation suggests that a dtbo can be explicitly provided when instantiating and loading an overlay.

overlay = Overlay('your_overlay.bit', dtbo='your_overlay.dtb')

Not knowing which of the PYNQ produced .dtbo files to use, I attempted to use both after transferring them to the home directory.

overlay = Overlay("/home/xilinx/pynq/overlays/sensors96b/sensors96b.bit", dtbo="/home/xilinx/pl.dtbo")
overlay = Overlay("/home/xilinx/pynq/overlays/sensors96b/sensors96b.bit", dtbo="/home/xilinx/system.dtbo")

With syslog error entry for both being similar:

pynq kernel: [16909.758757] fpga_manager fpga0: writing sensors96b.bin to Xilinx ZynqMP FPGA Manager
pynq kernel: [16909.918772] OF: overlay: remove: Could not find overlay #0
pynq kernel: [16909.948244] fpga_manager fpga0: writing .bin to Xilinx ZynqMP FPGA Manager
pynq kernel: [16909.948283] fpga_manager fpga0: Direct firmware load for .bin failed with error -2
pynq kernel: [16909.948291] fpga_manager fpga0: Error requesting firmware .bin
pynq kernel: [16909.954193] fpga_region region0: failed to load FPGA image
pynq kernel: [16909.959679] OF: overlay: overlay changeset pre-apply notifier error -2, target: /fpga-full
pynq kernel: [16909.967941] OF: overlay: overlay changeset pre-apply notify error -2
pynq kernel: [16909.974302] create_overlay: Failed to create overlay (err=-2)

From syslog, I can see that the call to PYNQ’s overlay instantiatation triggers a fpga_manager call that is successful. Presumably the expected behavior of just passing in an overlay bitstream. However, the subsequent syslog entries show fpga_manager failing, with attempts to write “.bin” to it. This led me to discover the device tree outputs of PYNQ when using the sensor96b-v2.bsp produce the pl.dtsi file with the contents:

...
/ {
	fragment@0 {
		target = <&fpga_full>;
		overlay0: __overlay__ {
			#address-cells = <2>;
			#size-cells = <2>;
			firmware-name = ".bin";
			resets = <&zynqmp_reset 116>;
		};
	};
...

I am simply not sure why the firmware-name is being left blank? Presumably this should reflect the /lib/firmware/sensors96b.bin firmware referenced by the above successful overlay instantiation with no dtbo file specified. Without this fix, which may be a more PYNQ related issue (I don’t know), I am unable to try the produced .dtbo files to see if they would correctly bring in the PL device nodes.

Not even sure if the .dtbo files are correct, I tried to load overlays with the system.dtb (same directory as the system.dtbo) and it produces less but still an error. Syslog:

pynq kernel: [21277.735116] fpga_manager fpga0: writing sensors96b.bin to Xilinx ZynqMP FPGA Manager
pynq kernel: [21277.911333] create_overlay: Failed to create overlay (err=-22)

From the documentation of the PYNQ images and BSP for Ultra96 there is no mention of how to access the PL UART IP of the sensor96b design in the expected way, with a driver. This would be okay if the devicetree automatically updated and configured drivers but it doesn’t seem to. PYNQ supplies basic MMIO access to PL IP, and it does work for verifying that the UART IP are there. However, this isn’t any better than just mmap’ing /dev/mem.

Any guidance on successfully bringing in a dtbo file would be very much appreciated.

I think that blank field is a bug. I am not sure where it comes from though. What you can try is to change it to firmware-name = "sensors96.bin"; and recompile using dtc; see if that helps.

Also try the first 2 cells for your overlay. I think you need to call download(dtbo=<sth>) explicitly.