For the majority of this blog, we will be using the Xilinx Software Development Kit (SDK). However, there is one last thing we need to do within PlanAhead first, and that is to export the hardware to the SDK. (Note that we will need to do this each time we make a change to the hardware.)
Actually, it might be worth taking a moment to explain this in a little more detail, because this is the sort of thing that can sneak up and bite you on the bottom later if you don’t fully understand what’s going on, so let’s take a small step back…
As we know, the Zynq-7000 All Programmable SoC powering the ZedBoard is composed of two distinct sections: the programmable logic (PL) section and the processing system (PS) section. What we’ve done in my previous blogs is to define the hardware portion of the system — specifically, we’ve established some simple functionality in the programmable logic that will drive some LEDs in the outside world; we’ve specified what we want to use in the processor subsystem (the ARM Cortex-A9, the DDR RAM, the SPI, etc.); and we’ve set up an AXI bus linking the PS and PL sections. Finally, we’ve generated the configuration bit-file that will be used to set up the hardware portion of the system.
When I say that we need to use PlanAhead to “export the hardware to the SDK,” I’m talking about informing the SDK as to the nitty-gritty details of our hardware configuration, including such things as the address ranges of any external memories and the register maps associated with any peripheral functions and hardware accelerators implemented in the programmable fabric (we don’t have any hardware accelerators at this time, but we may add some later).
OK, so we select the “Export Hardware to SDK…” menu item, as illustrated in the screenshot below.
This BSP will be specific to our hardware implementation. In addition to containing drivers for any of the peripherals we are using, it will also include a number of hardware-specific C header files, such as “xparameters.h,” which defines the memory map of the system along with other system configuration parameters. In the case of our example, when creating this BSP, we must make sure to select the target processing system and CPU0.
Now we are at the stage when we can finally start to create our software project, which will use the imported hardware and BSP, as illustrated in the screenshot below.
For the purposes of my first test case, I decided to create a very simple C application to send a message over the UART to the console and flash a pattern on the LEDs connected to the AXI port in the programmable logic side of the device. In order to do this, I selected the “Xilinx C Project” option, as illustrated in the screenshot below
The next step allows you to name the project and select if you want a basic template for a project. Since none of the provided templates offered what I was intending to implement, I opted to go with a blank template, as illustrated below
My goals for this first project were very simple. As I mentioned earlier, all I want to do is to send a message up to the console and flash a pattern on the LEDs, thereby proving to myself that I know how to get PS portion of the Zynq to communicate with its PL counterpart.
If you are unsure of the peripheral drivers within the system — or if you are not sure how to drive them — take a look at the “system.mss” file under your BSP within the project explorer. This also provides a list of helpful links to documentation and examples.
Next, we need to include a number of C header files that contain parameters and functions that can be used by the software developer. The header files I included in my project were as follows:
- Stdio.h — Defines the standard Input and Output (this should be familiar to anyone who has worked with C).
- Platform.h — Defines basic functions for the implementation and platform initialization and clean-up.
Xil_types.h — Defines a number of types needed for Xilinx IP cores.
- Xgpio.h — Defines the drivers for the AXI bus driving the general purpose input/output (GPIO) module we have connected to the LEDs in the outside world.
- Xparameters.h — Defines the hardware architecture and configuration for this implementation.
With these files included, I next wrote a small bit of C code to achieve my aims (click here to download a compressed ZIP file containing this C source code). Having written our code and having successfully compiled it, we next wish to download the application into our ZedBoard. In order to do this, we first need to create a linker file script that will specify where the executable is placed in the system memory. My program was tiny and would easily fit in the on-chip memory; however, I decided to place my executable in the external DDR memory so as to demonstrate that this interface was also configured correctly. We can create our linker script by right-clicking on our project and selecting the “Generate Linker Script” option, as illustrated in the screenshot below
We’re almost there. The next task we have to perform is to set up the run configurations using “Project Explorer -> Project -> Run -> Run” in the right-click menu. This is where we can define our STDIO connection to the serial port we are using for the STDIO. Once we are happy, we can apply the configuration and then close the dialog. (Do not click “Run” as we are not quite ready for that.) The final stage is to connect the ZedBoard board to our PC using both the UART USB cable and the programming USB cable. We should now be able to program the ZedBoard via the SDK, as illustrated in the screenshot below
Always make one last check that you are using the correct configuration bit-file (which tells you that I’ve slipped up myself on at least one occasion) and then program the device, as illustrated in the screenshot below
Once the configuration has completed successfully, you will see the “Done LED” illuminate on the ZedBoard. Having completed the configuration, you can now download the ELF file and try out your program. Doing this is as simple as selecting your project within the project explorer, right-clicking “Run As,” and then selecting the “Launch on Hardware” option, as illustrated in the screenshot below.