How to …¶
Use peripherals¶
LEDs¶
The TDK’s all have 1 or more general purpose LEDs. They are registered (via the devicetree)
to the Linux OS as LED devices. Device files for them are created at /sys/devices/platform/<group-label>/leds/<label>
For example to turn on a LED run the following command (replace the labels with the actual values):
echo 1 > /sys/class/leds/<label>/brightness
EEPROM¶
The TDK’s all have a I2C EEPROM memory device that can (partly) be used by the user. The first part of this memory is used by TOPIC for production data as serial numbers and MAC address
To find the EEPROM device run the following ‘search’ command on target:
find /sys/bus/nvmem -name nvmem
The search result is the path to the EEPROM device
To view its content:
hexdump -C <path_to_eeprom_device>
To write something to it:
echo "Hello World" > <path_to_eeprom_device>
RTC (Real Time Clock)¶
To configure the RTC, first sync time with internet once using ntpd
echo "server 2.nl.pool.ntp.org" >> /etc/ntp.conf
echo "server 1.us.pool.ntp.org" >> /etc/ntp.conf
ntpd -d -n -q
The output should be something like:
ntpd: '2.nl.pool.ntp.org' is 149.210.142.45
ntpd: '1.us.pool.ntp.org' is 64.142.54.12
ntpd: sending query to 64.142.54.12
ntpd: sending query to 149.210.142.45
ntpd: reply from 149.210.142.45: offset:+54013.704436 delay:0.007460 status:0x24 strat:2 refid:0xca4f43c1 rootdelay:0.001831 reach:0x01
ntpd: reply from 64.142.54.12: offset:+54013.700510 delay:0.151523 status:0x24 strat:3 refid:0x4c4037ce rootdelay:0.089906 reach:0x01
ntpd: sending query to 149.210.142.45
ntpd: reply from 149.210.142.45: offset:+54013.704544 delay:0.008119 status:0x24 strat:2 refid:0xca4f43c1 rootdelay:0.001831 reach:0x03
ntpd: setting time to 2021-03-30 09:08:45.282092 (offset +54013.704544s)
To sync the HW clock with the system clock run the following:
hwclock -w
After executing the above commands, the system clock should stay intact after a reboot.
Ethernet¶
Wired ethernet is supported on the TDKZ(U) and TDPZU boards. This interface is registered as the eth0 interface. This can be displayed/configured using the ifconfig command:
ifconfig eth0
eth0 Link encap:Ethernet HWaddr 02:12:78:AB:95:12
inet addr:192.168.80.81 Bcast:192.168.80.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1311 errors:0 dropped:0 overruns:0 frame:0
TX packets:593 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:127745 (124.7 KiB) TX bytes:627085 (612.3 KiB)
Interrupt:13
A command like ping
can be used to test the connection:
ping -c 1 google.com
Display¶
On most of the TDKs a display interface is present as a HDMI output. This display is
present as a linux framebuffer device in /dev/fbX
where X is a sequential number
starting at 0.
When running the desktop-image, the framebuffer device is used by that desktop. When running with the minimal-image, the framebuffer can be ‘tested’ by running:
cat /dev/urandom > /dev/fbX
WiFi¶
WiFi is supported on the XDPZU board. To check/configure it run:
ifconfig wlan0
wlan0 Link encap:Ethernet HWaddr C0:EE:40:61:9F:58
inet6 addr: fe80::c2ee:40ff:fe61:9f58/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:54 errors:0 dropped:0 overruns:0 frame:0
TX packets:17 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:6164 (6.0 KiB) TX bytes:3501 (3.4 KiB)
When running the desktop-image the GUI can configure the WiFi network.
When running with the minimal-image a connection to a WiFi network can be made using
a wpa supplicant file. This file is located (or should be created) at /etc/wpa_supplicant.conf
and can be ‘filled’ by using the following command:
wpa_passkey MY-SSID MY-PASSWORD >> /etc/wpa_supplicant.conf
Change the contents of the file to look like the following:
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
update_config=1
network={
ssid="SSID-of-network"
psk="Password-of-network"
}
Replacing SSID-of-network
and Password-of-network
with the SSID and password of the network
you are connecting to.
Bluetooth¶
Bluetooth is supported on the XDPZU board.
Scan for bluetooth devices using bluetoothctl
.
Running bluetoothctl
will open a bluetooth console.
In that console, run the following commands:
power on
scan on
discoverable on
Now the device should show up, type devices
in bluetooth console to show a list
devices
Device 7D:51:A8:F6:3B:9A 7D-51-A8-F6-3B-9A
Device 0C:43:10:1D:B5:43 0C-43-10-1D-B5-43
Device 1D:46:AA:40:F6:DC 1D-46-AA-40-F6-DC
Device 47:A6:EB:66:2E:D3 47-A6-EB-66-2E-D3
Device 00:D1:EB:ED:86:CF 00-D1-EB-ED-86-CF
Use SWUpdate¶
SWUpdate is a software package for embedded Linux systems to update the contents of non-volatile memories holding the software components like a bootloader, kernel and rootfs.
The SWUpdate service can be reached in several ways but the most convenient way is via a network connection.
The board runs a webserver hosting a webpage. Use a browser or program like curl
to upload a software update
package file (.swu) through this webpage.
This .swu file contains the new software and also the location of where it should go and other meta-data.
There are several ways to update a board using SWUpdate:
- SWUpdate webpage:
- Can be reached by typing its hostname/IP-address + a port number into a browser.
The portnumber defaults to 8080. This requires a network connection (ethernet, USB or WiFi). Example URL: http://192.168.100.1:8080
- USB (memory device):
On the desktop images, an USB stick with a .swu file on it can be inserterd. This will then be automativally installed.
- Command line:
Execute the following command on the target device:
swupdate -v -i <path_to_swu_file>
. This is particularly useful to debug issues with an SWU file.
- SWUpdate API:
SWUpdate also comes with an API to control it.
For more information check the SWUpdate website.
Update scheme¶
Most setups use an A/B update scheme. There are two copies of the whole filesystem present, called A and B. When the system is running from A, the update process will write the new image to the B partition. On success, the system will mark B as bootable and reboot. This makes the upgrade almost atomic, a failure during the upgrade will have no effects on the running system.
By default, for SD/eMMC we use A/B scheme for all devices using 4 partitions:
boot
Hold the FSBL/u-bootx-rootfs-a
andx-rootfs-b
Where x is eithersd
oremmc
These partitions are the ones being updated by SWUpdate. Either a or b is the ‘active’ partition.
data
General data partition. Can be used to hold persistent data, SWUpdate will not touch this partition. By default it is empty.
The following will happen when providing a new SWUpdate package for eMMC.
The non-active will be mounted (lets say B)
SWUpdate writes the Update to non-active partition
Copy peristent files from A to B (see Persistent files)
SWUpdate moves the bootable flag from A to B
SWUpdate triggers a reboot
The boot loader will detect bootable flag is now on B, and will use that one to boot from.
When there is not enough space on the media for two copies, a single update scheme can be used. This allows an atomic update only by booting from another device, for example one can upgrade the QSPI while running from eMMC. When running from QSPI, it is still possible to upgrade the image in QSPI but failure during the upgrade will result in the system being unable to boot. In this case the user will have to manually repair this, for example by booting from an SD card instead.
The following configs use a single scheme instead:
XDP with QSPI
TDKZ with QSPI
Persistent files¶
Some files can be left untouched when updating the board’s software with SWUpdate, like for example the WiFi configuration.
- See for full list:
meta-topic-platform/recipes-support/swupdate/swupdate/swu-transfer-list
After writing the new copy of the filesystem, the upgrade process will copy the files in this list (if they exist) to the newly installed copy. At the moment, this is not available on QSPI using ubifs.
Create your own Vitis app¶
Xilinx’ Vitis SDK can be used to create applications for the TOPIC boards. To create a platform project, import the .XSA file generated by Vivado. Check FPGA technical reference designs (TRDs) for more information about this .XSA file.
Standalone (bare-metal) application¶
Linux application¶
Create and use an SDK¶
In order to generate the SDK in the petalinux project folder run
petalinux-build --sdk
This command will create a sdk.sh script in the folder images/linux.
To create the SDK, run the petalinux-package command:
petalinux-package --sysroot -s images/linux/sdk.sh
This will create an sdk folder in images/linux which contains the SDK. This directory can also be changed by passing the -d or –dir flag to the petalinux-package command.
For more information on how to use the SDK, see the UG1144 Petalinx Reference Guide.
Use a custom FPGA image¶
By default the TLD will fetch a prebuild FPGA image from downloads.topic.nl The following steps describe how to use a custom build FPGA image.
Create your Vivado project (it is recommended to use the TRD as a starting point, see FPGA technical reference designs (TRDs).)
Note
The TLD 2020.2 release only supports the use of Vivado 2020.2.
Build your FPGA image
- Export the build results: choose
File -> Export -> Export hardware
(Use default settings in wizard) This exports a .xsa file which is needed in the next step.
- Export the build results: choose
Import the results into the petalinux project by running the following command in the petalinux workspace:
petalinux-config --silentconfig --get-hw-description ${XSA_FILE}
- Generate new device tree based on new FPGA image (by default the TLD does not do this, as it is not reliable)
- Enable the devicetree generation by running the following command:
petalinux-config
In the menu change the following:DTG Settings -> DEselect “Remove PL from devicetree”
Save the configuration -> default location
Exit the menu
- Rebuild the design
Clean the project (sometimes old build results are not cleaned automaticaly) and then rebuild:
rm -rf components/ build/ petalinux-build -c device-tree -x do_compile
Now petalinux has generated a device tree based on the new FPGA image. Unfortunately this can not be used as is but it can be used as a starting point / reference.
- Create a new device tree file at
project-spec/meta-user/recipes-bsp/device-tree/dtb-example-custom.bb
An example of the contents of this file is shown below:
SUMMARY = "Devicetree overlay for FPGA image" require ../../../topic-platform/meta-topic/recipes-bsp/device-tree/dtb-overlay.inc COMPATIBLE_MACHINE = ".*" BITSTREAM = "fpga-image-example-custom"
- Create a new device tree file at
- Create a new folder to hold the new devicetree files:
project-spec/meta-user/recipes-bsp/device-tree/dtb-example-custom/
- Copy the device tree from the reference design to
project-spec/meta-user/recipes-bsp/device-tree/dtb-example-custom/pl.dts
Check Appendix A - Topic boards for the location of the reference device tree file of your board.
- Update the reference device tree with the new components.
- The auto generated version is located here:
components/plnx_workspace/device-tree/device-tree/pl.dtsi
It is recommended to only copy/overwrite the changed parts into the new device treeproject-spec/meta-user/recipes-bsp/device-tree/dtb-example-custom/pl.dts
- Disable the device tree generation again by running the following command:
petalinux-config
- In the menu do the following:
DTG Settings -> select “Remove PL from devicetree”
Save the configuration -> default location
Exit the menu
The device tree part is done now.The next steps show how to generate a recipe for the new FPGA image. This to include the FPGA image into the build.
- Disable the device tree generation again by running the following command:
- Create a new folder
project-spec/meta-user/recipes-bsp/fpga
and create a new file in there:fpga-image-example-custom.bb
. An example of the content is shown below. Change the
${FPGA_BITFILE}
variable with the correct filename.SUMMARY = "FPGA image" require recipes-bsp/fpga/fpga-image.inc LICENSE = "CLOSED" COMPATIBLE_MACHINE = ".*" FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" PV = "1" FPGA_BITFILE = "fpga-image-example-custom.bit" BOARD_DESIGN_NAME = "fpga-image-example-custom" BOARD_DESIGN_URI = "file://${FPGA_BITFILE}" PKGV = "${PV}" S = "${WORKDIR}/${BOARD_DESIGN_PATH}" B = "${S}" # Nothing to build do_compile() { cp ${FPGA_BITFILE} fpga.bit }
- Create a new folder
- Copy the .bit file to
project-spec/meta-user/recipes-bsp/fpga/fpga-image-example-custom/
Make sure to use the same filename as provided in the recipe
${FPGA_BITFILE}
. The recipe created in the previous step will pick up the .bit file and copy it into the build.
- Copy the .bit file to
- Update the
project-spec/meta-user/recipes-core/images/user-config.inc
to include new FPGA image. Do this by adding the name of the new recipe to the
IMAGE_INSTALL_append
list and adding the original dtb recipe to theIMAGE_INSTALL_remove
list. See example below:IMAGE_INSTALL_append = " \ dtb-example-custom \ " IMAGE_INSTALL_remove = "dtb-miami-florida-gen-reference" # login by default inherit autologin
- Update the
Now we can build again and the new FPGA image will be built and included into the image:
petalinux-build