Showing results for 
Show  only  | Search instead for 
Did you mean: 
Registered: ‎10-29-2020

API's to acess AXI registers under Petalinux for read and write.


I am new to the Petalinux .we have defined  some  AXI registers , which we need to access for read write on our application from PS side is there any API's available for to do read/write to these registers.

If API's are not available how we can access these registers for read/write.

Tags (2)
0 Kudos
2 Replies
Registered: ‎05-28-2013

Ultimately your registers will appear in the memory map of the CPU. In other words, there is a specific physical address, which will access your AXI registers. If you are writing in baremetal C code, it would look like this:

volatile int *addr = (volatile int *)0x12345000;
printf("register value is %08x\n", *addr);  // read the register
*addr = 0x55;                               // write the register

Determining the physical address requires knowing:
- how the AXI registers are connected to the CPU. There are several PS-PL interfaces ("bridges") available in the Zynq. Each one has a base address.
- each register in your AXI block has a fixed address offset from the base. Typical 32-bit registers would have offsets 0x0, 0x4, 0x8, 0xc, 0x10 and so on.
The vivado/vitis tools typically will handle most of this for you, so consult with the FPGA designer.

Once you know the physical address, there are various was you can use to perform access for testing purposes:
- in u-boot the commands "md" (memory dump") and "mw" (memory write) can be used directly with the physical address. Assuming of course that the FPGA has been configured, and the bridge is active
- once Linux/Petalinux has booted, the command-line utility "devmem" or "devmem2" can be used to similarly perform read/write of physical address.

Note that Linux/Petalinux use virtual memory. So unlike the baremetal code example above, you cannot directly access a physical address. Instead it is necessary to map the physical region into the virtual address range. The "devmem" program does this, and you can also do the same in your own code.

You will find mention of UIO (userspace I/O). This provides a device ("/dev/uio0") which your application can open, and then request physical-to-virtual mapping ("mmap"). This is is very similar to what devmem does. The main reason to use UIO is to allow your application to respond to hardware interrupts. For basic register read/write, you do not need UIO.

Moving further up the complexity curve, you could write a real device driver that operates in Linux kernel space, as opposed to application (user-space). This gives more control, and more options such as using DMA for data transfer.

In the opposite direction, there are any number of 'convenience' wrappers around the basic memory-mapped I/O concept. I have no direct experience, but "Pynq" ( seems to be quite popular method. And there are countless others in different languages.

0 Kudos
Registered: ‎08-02-2019

Hi @jagadiswar ,

As @rfs613 mentioned there is a /dev/uio way, that I'm using it to catch interrupts from ZYNQ to Petalinux.

If you need only write & read, then easier way for you is using /dev/mem.

By using this you can map some blocks of your FPGA by setting an start address and length.

As an example:


    fd = open("/dev/mem", O_RDWR|O_SYNC);

    if (fd < 0) {

        fprintf(stderr, "open(/dev/mem) failed (%d)\n", errno);

        return 1;



    if (mm == MAP_FAILED) {

        fprintf(stderr, "mmap64(0x%x@0x%x) failed (%d)\n",

                (uint32_t)PAGE_SIZE, (uint32_t)(COMM_BASE), errno);

        return 1;


//to read a val
int buffer1_current_val = *(volatile uint32_t *)(mm + COMM_SERVO_BUFFER1_CURR_VAL);
//to wrote a val
*(volatile uint32_t *)(mm + COMM_SERVO_BUFFER1_CURR_VAL) = an_int_value;




<--- If reply is helpful, please feel free to give Kudos, and close if it answers your question --->
0 Kudos