I've covered a few times in the past how to create a custom application in Linux and integrate it into a PetaLinux project using the PetaLinux command line tools in combination with the PetaLinux ASCII GUI for configuring the root filesystem (see my PetaLinux 2019.2 custom application example here, the core principles/commands still remain the same through PetaLinux 2021.1).
While it's pretty straightforward to create and add your custom application using the PetaLinux command line tools with ASCII GUI, there isn't a great way to debug your application, leaving you to just add a bunch of print statements and rebuild the whole project every time you make a change.
This is where Vitis comes in, with access to debugging tools and it's capabilities to also create/support Linux applications alongside bare-metal applications it becomes the ideal environment to work in through the development stage of custom Linux applications.
PetaLinux ProjectThis method of debugging Linux applications in the Vitis IDE still requires a working base PetaLinux project with the proper hardware system configuration and kernel drivers enabled for the Linux application being developed/debugged. The embedded Linux image itself is still being generated in PetaLinux using the FPGA's board support package (BSP) or hardware definition file exported from Vivado and only the custom Linux application is going to be done in Vitis now.
Once the PetaLinux project for the target FPGA board is successfully built, package a boot binary for it, and upload the image to the board (ie - flash the QSPI, or prep the SD card; whatever Linux root filesystem type you chose). In my case I'm using the Linux image I generated for my Arty Z7 in PetaLinux 2020.2 as outlined in my previous project post here.
Boot the target FPGA board with the Linux image from PetaLinux and log in.
Again, I'm starting right where I left off at the end of my previous project post with the Arty Z7 running my base Linux image.
Create New Domain in VitisWhether starting from an existing Vitis project where a standalone domain already exists, or no other domains exist, a new Linux domain must be added.
Since I'm starting with a Vitis project with a standalone domain that already exists, I opened platform.spr file in the Platform Project from the Explorer window, and selected the green + button to add a new domain.
Name the domain as desired, select 'linux' for the OS, select the target processor the application will be running on (the built-in ARM processor of the Arty Z7's Zynq FPGA in my case), C/C++ for the supported runtimes, and 32-bit for the architecture. The fields for Bif file, Boot Components Directory, and Linux Image Directory can be left blank for now.
Once created, take note of how the new Linux domain is completely separate from the Zynq first stage bootloader (FSBL), board support package (BSP), etc. that currently exists from the creation of the bare-metal application, as all of this is going to be provided from the PetaLinux project which is targeted to booting/supporting embedded Linux versus a bare-metal application.
Re-build the platform project as you'll notice it goes out-of-date when the new domain is added.
With the Linux domain added to the Vitis platform project, the embedded Linux application can now be created in Vitis. Click New > Application Project from the top left corner of the screen.
Select the current platform being used in the Vitis workspace, then on the next screen give the application the desired name and select the processor with SMP specified in its name as the target processor for the application.
To run a single OS like Linux and allow for it to utilize all of the cores in the processor (which in the case of the Arty Z7, it is a dual-core ARM Zynq), the processor must be put in SMP mode (symmetric multiprocessing mode). So you'll notice that when selecting the target processor, the SMP option doesn't specify ps7_cortexa9_0 or ps7_cortexa9_1, but instead specifies ps7_cortexa9 SMP, denoting the fact that the application will have access to both ARM cores of the Arty's Zynq chip.
After naming the application and selecting the target processor, click next. This next screen is where you'll select the Linux domain created in the platform project. Leave the Application settings blank, and click next.
Finally select the desired application template and click Finish, I just chose the Linux Hello World application template for simplicity.
With the Linux application now added to the project, open the main file (helloworld.c in the case of the Linux Hello World application template) and add your desired code.
For me, I have a simple DMA application that I'm developing (which will be it's own project post soon) that I wanted to step through with using the TCF debugger to verify I was writing to the proper memory locations.
Build the application project once your code is ready to run.
In order to run your custom Linux application on the target FPGA running embedded Linux, Vitis needs a channel that allows for your custom Linux application to be downloaded onto the target FPGA.
This is where the TCF agent comes in (TCF = Target Communication Framework). The TCF is a vendor-neutral, lightweight, extensible network protocol that was developed for communicating with embedded system targets. Eclipse-based IDEs such as Vitis use it as a communication channel with embedded/FPGA targets to download applications onto them to run and debug.
The TCF Agent must also be built into the embedded Linux image running on the target FPGA. PetaLinux enables the TCF agent by default in all new projects, so unless you specifically disabled it, it's already running on the FPGA's Linux image, as it is configured in PetaLinux to launch at boot.
For bare-metal applications, the TCF agent doesn't need any extra configuration, but for a Linux application, we do need to tell Vitis how to talk to the target FPGA's TCF agent.
Using your serial terminal application of choice (I like to use the built in one in Vitis, but you can use Putty, TeraTerm, etc.), connect to the target FPGA and verify it's network connection. You can either plug it straight into your router or into the host PC (plugging into a router is much easier, as it doesn't require any extra configuration if you have DHCP enabled in the PetaLinux project for the kernel & root filesystem). Specifically, make note of the target FPGA's IP address.
Next, from the toolbar at the top of the Vitis window, select Window > Show view... and search for Target Connections. Select it to open that window.
Double-click on Linux Agent[default] under Linux TCF Agent in the Target Connections window to open the configuration editor.
Specify the target FPGA's IP address in the Host field and leave the Port set to whatever it auto-populated to. Click Test Connection to validate that Vitis is able to talk to the target FPGA and open that channel for the TCF agent.
Finally, we're ready to run the debugger and step through the Linux application, right-click on the Linux application's name from the Explorer window and select Debug Configurations... under Debug As.
Select Debugger_[application name]-Default under TCF Single Application Debug and validate that the Debug Type is set to Linux Application Debug, Connection is set to Linux Agent, and the port number in the note is the same as what auto-populated the the target connection configuration window in the last step.
Click Debug and Vitis will launch the debugger, switch over to the debug view and a breakpoint will pause the execution at the first line in the main function, allowing you to step through it as you would normally in any debugger.
After you've validated the settings the first time the debugger is run, it can be easily relaunched by right-clicking on the Linux application's name from the Explorer window and selecting Launch on Hardware (Single Application Debug) under Debug As.
And there you have it, a full debugging setup for your custom Linux application.
Once you've successfully debugged your Linux application in Vitis, copy & paste the code back into the source file for the custom application in the PetaLinux project.
After adding the code back to the source file in the PetaLinux project, rebuild the root filesystem:
~$ petalinux-build -c rootfs
Then rebuild the PetaLinux project.
~$ petalinux-build
Now your debugged (and assumed working) custom Linux application is built back into the embedded Linux image for your FPGA. Simply re-package the boot binary for it and re-upload it onto the FPGA to deploy it!
Comments