With the software and hardware labs complete, it was time for the final leg of the training which was PetaLinux. This series felt the least structured of the three and the training wheels came off as soon as possible, unlike the software and hardware series. With the software series especially, it seemed like any repeated task was walked through with almost the same level of detail as the first time it was introduced (i.e. creating new applications in SDK). This is not a bad thing, especially when learning new tools.
Lab 1: Minimal Ultra96 PetaLinux Build
The first lab walked through configuring a minimal PetaLinux build. We created a project with petalinux-create, and configured hardware settings with petalinux-config --get_hw_description=../ . In this hardware configuration step, we ensured primary SD was selected for image storage media for both the boot image and kernel image. Then we checked that primary stdin/stdout serial was set to psu_uart_1. Once these configurations were saved, the last step was to build (petalinux-build) and package the first stage boot loader, PMU firmware, bitstream and u-boot into a boot.bin file (petalinux-package).
Once done, we went through the exercise of formatting the SD card via fdisk. We created a boot and rootfs partition and burned the changes to the card. After copying the build to the SD card, we booted the board which came to a login shell. Afterwards, we could clean the build we had just done. The warning given about using the Linux command rm -rf should not be taken lightly. I have seen damage done when this command is not used with care (e.g. complete system reinstall required when critical files are accidentally deleted).
Lab 2: Updating Full Featured PetaLinux
This lab used the advanced BSP to create a PetaLinux build rather than the minimal BSP from Lab 1. There wasn't much to this lab other than building with a different (pre-made) BSP and enabling SPI device driver support in the kernel configuration. After the build was complete (or after loading the pre-built image) we also looked into customizing the root file system.
The lab conclusion gives a summary of the steps to creating a PetaLinux build:
- Start with a BSP and expand it into a project (petalinux-create -t project -n <project name> -s <BSP location>)
- Import hardware design (petalinux-config --get-hw-description)
- Configure kernel and root file system (petalinux-config -c rootfs and petalinux-config -c kernel)
- Build the project (petalinux-build)
The final portion of this lab was bonus material:
- A compact .bsp file can be generated from the build output using the petalinux-package command
- The build can be cleaned using petalinux-build -x clean
- If stopping mid-build or making a configuration change, petalinux-build -x mrproper can be used to update all dependencies. I had some issues in a later build, and must've glossed over this. It may have been worth trying to solve my issues.
Lab 3: Connect to Ultra96 Using Wi-Fi
This lab walked through some of the features available when using WiFi to connect to the Ultra96-v2 board. The PetaLinux image initially hosts a web page on its own access point at IPV4 address 192.168.2.1. The page contains different example projects, tutorials, configuration, etc. Included is a WiFi setup page which is used to connect the Ultra96-v2 to an access point with Internet access (e.g. home router). After connecting the board to an access point, the board restarts and defaults to connecting to this new access point. Now remote login, file transfer, and Internet access are possible on the board. This can also be used to transfer images to the board instead of using a USB thumb drive. Another great feature unlocked by connecting to a network access point is the ability to remotely debug an application on the board using SDK (see next lab).
Lab 4: Creating PetaLinux Applications using Xilinx SDK
This lab walked through creating an application to run on PetaLinux, as well as methods for remotely debugging the application. A notable difference here is the OS platform selected when creating a new application is now "linux", whereas it was previously "standalone" when creating a bare metal application. When creating a Linux application, the processor type is "psu_cortexa53" rather than "psu_cortexa53_0", which was used for bare metal application. The bare metal application targets a specific Zynq MPSoC+ core to run the application on.
This application is the Linux application version of interfacing with the LSM6DSL 6DOF inertial sensor. We imported example source provided with the lab and then began to set up remote application debugging. The remote debugging interface is known as a Linux TCF agent. To set this up, we configured the TCF agent with the IP address of the Ultra96-V2 board and the correct port number. Also, this is now set to the default debug target when creating a new debug configuration. Once a debugging configuration is started, the application is sent to the board remotely and the debug perspective is opened in SDK. The console tab in SDK shows stdout associated with the application, and stdin input can be sent to the application by clicking in the console text area and pressing keys. All the debug functions apply just as before via JTAG (breakpoints, play, pause, step into, step over, etc).
Lab 5: IoT Application - Log Sensor Data to IBM Bluemix
This lab walked through an application that sent data from the LSM6DSL sensor to the IBM Bluemix cloud servers via the MQTT protocol, a lightweight message protocol often used in IoT. Similar to the hardware lab that used this sensor, I wanted to read more data out, rather than just the temperature data (This is an inertial sensor, after all! Why read just temperature data?). This application uses the hardware abstraction layer (ioctl) to pass commands from the application (user space) to the physical hardware. SPIDEV is the library used for hardware abstraction of the SPI peripheral. In the hardware version of this lab, the maximum SPI command length used was 3. I was able to extend that command length in order to read out multiple registers from the inertial sensor in sequence. The inertial sensor supported a sequential read, so I just had to send the address of the first register, followed by 0x00 in every byte position after, until I read out the desired number of values. For some reason, the ioctl method for SPI access in this application had a fixed command length of 2, and I was not able to extend this to read out multiple registers sequentially. Instead I stuck with the command length 2 and read out each register with a separate 2 byte command. This was a bit less efficient, but I got it working, nonetheless. I played with delay times, but Bluemix is definitely not setup for very high data rates (not surprising). See video of my sensor data being logged on IBM Bluemix IoT servers. The interface on IBM's site was a bit clunky. It often took several clicks to start plotting a different set of streaming data.
Lab 6: Embed An Application Using Ultra96 PetaLinux
This lab walked through baking an application into a PetaLinux build so it is already installed on the system at boot. We create an app using "petalinux-create -t apps ...". This process was less automatic than I would expect. There was some dodgy editing of bit bake files to change the application filename and set the install location for the application in the PetaLinux root file system. Several other PetaLinux tools open a dialog, and it seems like this option would also be appropriate for this application rather than having to edit build files by hand. This could be used to select the location of the source to bake into the build, but that task had to be done manually, as well.
I followed the rest of the instructions, however, I had some issues during my build. The build failed when working on Chromium, similar to what happened to buffteethr here: https://www.element14.com/community/community/design-challenges/path2programmable/blog
I was able to exclude Chromium from the build (does anyone really need Chrome on an embedded computer??) by commenting and/or adding exclude commands to some of the makefiles. I could never find Chromium in the PetaLinux configuration menus in order to exclude it there. These makefiles were oddly in a completely separate directory from where the build project was created. It was somewhere similar to the path shown in the image below for webkitgtk (I had errors with this package also. Sorry the image is so small, I'm not sure why that is). The path is "/tools/petalinux-v2018.3-final/components/yocto/source/aarch64/layers/core/meta/recipes-sato/webkit/webkitgtk_2.20.5.bb:do_compile'. It looks as though the path is near where the PetaLinux tools are installed, so perhaps common recipes are stored there and anything board-specific is stored in the created project. Since these builds took so long on my machine (I had to leave them overnight), I just got a bit fed up and gave up at this point.
I'm hoping I can just use a pre-built image/BSP which will have enough features to get me going, and then I can install kernel modules or applications after the fact, as needed. It really doesn't seem worth the effort to keep re-trying builds to no avail.
That's it for the training!
I will say that PetaLinux was what I was most excited for, but what I was a bit disappointed by. It felt a bit like just being spoon-fed some PetaLinux commands without knowing what was really going on behind the scenes. I wish it had gone into a bit more detail, although I realize this course is more about learning to use the tools than learning the underlying design concepts. Perhaps to someone with more embedded Linux build experience, some of it would be a bit more familiar, and then it would just be a matter of learning the tools. I definitely hope to do some more in-depth embedded Linux courses in the future. Even so, there was still some good material covered. I did like learning about remote application debugging, which is a super handy feature. The presentation slides did elaborate and add some good information, as well. Throughout each series, I would find myself occasionally looking back at the presentation slides if I was forgetting something or it wasn't quite clear in the lab.
Hardware turned out to be my favorite series, as it felt the most hands-on, and that is the kind of work I generally like the most. It was a good primer for using Vivado, which is a bit like the backbone for the design. Most of the hardware setup is done there (configuring Zynq peripherals, clocks, I/O, and programmable logic).
Software gave a very good overview of SDK. The SW material was very detailed, and was effective in explaining how to use a hardware configuration exported from Vivado, how to create applications, add libraries, debug applications, release code, etc.
I think this training series is overall very good, with a lot of useful information. There are a few kinks to iron out here and there, but ultimately it gives a good jumping off point for Zynq MPSoC+ design. I would definitely recommend it to anyone wanting to start in on MPSoC design.
One thing I didn't realize was how great the system resource requirements are for using this toolchain. It may have been posted somewhere in advance, but I didn't realize it until starting the labs that my setup was going to be a bit underpowered. Make sure you have a modern setup with many cores, plenty of RAM and storage space!
Thanks Element 14 for putting on this program! Now we're onto the project building portion. There's not a whole lot of time left, but hopefully I'll be able to put something decent together with what time remains.