top of page

MicroZed Chronicles: Embedded Software, working with Peripherals.

In this third blog recapping the basics of working with the Zynq MPSoC, we are going to examine how we can work with peripherals within the programable logic and interact with the real world.

 

We are going to start simply, in the design we created for the ZU Board recently we added a AXI GPIO which is connected to a LED on the board.

With the exported hardware design, imported into Vitis, with a platform and application created for a simple hello world we are going to expand on that to show how we can drive the AXI GPIO.

 

The first thing we need to understand is the role of the platform, the platform contains all of the board support packages and hardware abstraction necessary for us to create our software application. The platform is customised to by the XSA which is exported from Vitis, as such any peripheral we add in Vivado which is memory mapped will appear in the Vitis Platform.

 

We can examine the peripherals and their addresses by clicking on Vitis-Comp.json under the platform settings and clicking on hardware specification.

This will show you a list of all the hardware (much of which is fixed in the processing system), its address, access type and security zone.

 

When we create the platform we stated we wanted to target the Cortex A53 0 processors, as such under the sources directory in the platform we will see a psu_cortexa53_0 folder under this folder we will find the standalone BSP source which is compiled to make the BSP.

 

We cannot change any of this code but it is exceptionally useful for referencing. One of the most important files is under the includes and is the xparameters.h file. This file contains definitions for all of the hardware within the design, it should align with the previous hardware specification. However being a C header it allows is to easily interact with out peripherals in the design.

 

For example the xparameters.h entry for the AXI GPIO we added shows, the number of GPIO instances in the design. The high and low addresses, if the GPIO is a dual channel and the width of the GPIO. It also shows the compatible driver for the GPIO.

Along with the xparameters.h when the platform is built all of the drivers necessary are also compiled into the BSP provided by the platform. The drivers included in the BSP library can be seen under libsrc folder.

For the AXI GPIO the source for the drivers can be found under the GPIO folder, not the GPIOPS which relates to the PS GPIO.

Within these header files are the functions we can call from our software application to initialise and configure the GPIO.

 

The most important of these files is the xgpio.h which defines most of the functions we will need.

Using this library we can configure the AXI GPIO instance correctly, and then interact with it in our software application.

 

Lets take a look at how to do that, coming back to the original hello world application, the first thing we need to do is include the xgpio.h header and xparameters.h

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"

The next step is declare a GPIO instance, I made this a global variable.

XGpio LED_OP;

With all the necessary declaration in place we are then able to initialise the AXI GPIO in the program main. To do this we can use the XGpio_Initialize function, pass the address of the XGpio instance and the base address of the AXI GPIO we wish to work with, this is defined in the xparameters.h file.

XGpio_Initialize(&LED_OP, XPAR_XGPIO_0_BASEADDR);

The next step is then to make the LED toggle, we will do this within a continual loop in the maim program. We will call the functions XGpio_DiscreteSet and XGpio_DiscreteClear to set and clear bits in the AXI GPIO output.

 

The set and clear functions need a mask defining to show which bits to set and clear, along with being passed the address of the GPIO instance which is to be set or cleared.

     while(1){

    XGpio_DiscreteSet(&LED_OP, 1, 0x11);
    usleep(1000000);
    XGpio_DiscreteClear(&LED_OP, 1, 0x11);
    usleep(1000000);

    }

To ensure the flashing could be seen I used the usleep to create a 1 second delay.

 

Once this is built and downloaded we can see the flashing LED as would be expected.


 

Of course this is a simple introduction to working with the peripheral like the AXI GPIO, but the approach is similar for all peripherals if he interaction is does get more involved with more complex peripherals.

 

Helpfully Vitis does provide a list of example applications which can be accessed from within Vitis showing how to interact with a specific peripheral.  


UK FPGA Conference


FPGA Horizons - October 7th 2025 - THE FPGA Conference, find out more here.


Workshops and Webinars:


If you enjoyed the blog why not take a look at the free webinars, workshops and training courses we have created over the years. Highlights include:



Boards


Get an Adiuvo development board:


  • Adiuvo Embedded System Development board - Embedded System Development Board

  • Adiuvo Embedded System Tile - Low Risk way to add a FPGA to your design.


Embedded System Book   


Do you want to know more about designing embedded systems from scratch? Check out our book on creating embedded systems. This book will walk you through all the stages of requirements, architecture, component selection, schematics, layout, and FPGA / software design. We designed and manufactured the board at the heart of the book! The schematics and layout are available in Altium here   Learn more about the board (see previous blogs on Bring up, DDR validation, USB, Sensors) and view the schematics here.


Sponsored by AMD 

bottom of page