Continuing on with my bring up of the ZynqberryZero FPGA development board, I think it's import to follow up the base hardware design with a simple embedded C application running on the ARM-core processor of the Zynq-7000 SoC of the ZynqberryZero.
While it is possible to flash a bitstream onto the ZynqberryZero that contains a pure HDL design running in the programmable logic, I personally don't think it makes a lot of sense to do that on any FPGA board equipped with an SoC like the Zynq or ZynqMP family of chips.
(For context, I'm defining a SoC or System on a Chip here as any FPGA that has a physical processor built into its programmable logic.Andall specific parts/chip families mentioned are Xilinx, but the general concepts apply to any manufacturers.)
Aside from the obvious reason that it's-there-so-why-not-use-it, there are a couple of reasons that you should be running something on the physical ARM-core processor that's built into the Zynq chips:
1. Cost
2. Power draw
Zynq FPGAs draw more power and cost more than their purely programmable logic counterparts such as the Artix or Kintex chips. So it really doesn't make sense to go with the Zynq and not run an embedded application on the ARM-core directly (like I'll be doing in this project) or an OS such as embedded Linux or RTOS.
In my last project post with the ZynqberryZero, I covered how to setup the base hardware design in Vivado. For those not familiar, Vitis is the partner IDE to Vivado for Xilinx chips that is used to develop the software to run on any processor in the FPGA hardware (whether that be the physical ARM-core of the Zynq or a soft processor instantiated in the programmable logic like the MicroBlaze). This Vivado project and the resultant hardware package exported in the final steps of that project are what I'm starting with to base this Vitis project on. There are two ways to launch Vitis:
1. From Vivado by selecting Tools > Launch Vitis
2. From the command line in Ubuntu:
~$ source /<Vitis install path>/2019.2/settings64.sh
~$ vitis
The launch screen for Vitis will ask for a workspace directory, since this is a new project, click Browse then navigate to the desired directory where the workspace will live. I personally like to use the top level folder of the Vivado project that the hardware design for the Vitis project is coming from, and create a folder titled vitis_workspace within that directory:
Once I create the vitis_workspace directory, I navigate into it and click OK. This returns to the Vitis launch screen with confirms the selected workspace path.
After clicking Launch, Vitis will load into a new blank workspace:
Create a new platform project by selecting Create Platform Project from the blank workspace page.
Notice when the platform project is created it is out-of-date since it hasn't been compiled yet. Before moving on to create the application project from the embedded C application, build the platform project with Ctrl+B.
With the platform project compiled, create a new application project by clicking the New icon and selecting Application Project...
Give the project the desired name and leave the default option to create a new system project with it. As you click through the setup windows for the application project, be sure to select the custom platform created by the platform project done in the previous steps, the target processor core in the ARM to run the application on, you desired programming language, and the appropriate application template.
I'm writing this application in C and I selected the Hello World application template.
Now that the application project has been created, it's time to actually start writing some code. I wanted to do something more than a simple print out of "Hello World" via the UART serial terminal, but without needing to add any extra hardware. So I decided on a simply character echo from the UART.
My embedded C application starts by setting the control register for the Zynq's built-in UART and enabling the transmit and receive buffers of the UART by writing the appropriate bit masks to the control register.
Then in a while loop that is exited when it sees the ASCII character for escape, the control register bit is polled to see if there is anything in the FIFO of the receive buffer. If there is, it reads that character in, copies it into the transmit buffer, and sends it back out to the UART serial console.
After writing the C code and saving the file, build the application project by right-clicking on it in the Explorer window and selecting Build Project.
Plug in the ZynqberryZero to your PC with a Micro-USB cable. The JTAG/UART USB port is the one nearest to the corner of the board:
Next, program the bitstream onto FPGA. Again, right-click on the application project in the Explorer window and select Program FPGA. Since we selected Program FPGA from the application project, all of the fields in the window that pops up are auto-filled to the appropriate values, so you can simply click Program.
Launch a debug run of the application after the FPGA is successfully programmed. Right-click on the application project in the Explorer window and select Debug As > Launch on Hardware (Single Application Debug). Vitis will automatically switch the entire window to the Debug view and set a break-point at the first line within the main function.
To send characters to the UART of the Zynqberry and see them echoed back, a serial terminal application needs to be connected to the serial port created by the little board. You can use any serial terminal you like, but there is a built-in one in Vitis which is what I like to use just to keep things simple. If it's not already a tab open in the bottom window of the Debug view in Vitis, you can open it by selecting Window > Show View then search for/select Vitis Serial Terminal.
Connect to the serial terminal with a baud rate of 115200 (standard Zynq UART baud).
Step through code (F6) or let it run (F8) as you type characters into the serial terminal for it to process.
As you'll see, each character is pulled from the receive buffer and echoed back out. This project tutorial serves to demonstrate the overall process for creating a Vitis project for a bare-metal embedded application and how to debug it. Since permanently flashing a bitstream onto an FPGA is a little more dependent on each specific FPGA development board, I'll save that for another tutorial.
Comments