Development with Zynq – Part 6 – Eclipse Project for register access

This blog series describe the selection, set-up and usage of a development environment for Zynq.

Cross-Compiling an application

This instruction assume that the development environment discussed in Part2 and the PL logic from Part5 is used. Open Eclipse 4.3 and select “Cross GCC” under “File”=>”New”=>”C++ Project”. Use PL_Register as project name.EclipseCrossProject

EclipseToolChainPathUse ” arm-linux-gnueabihf-” as prefix and your absolute path to cross compiler bin folder. For me it was “/home/roy/gcc-linaro-arm-linux-gnueabihf-4.8-2013.07-1_linux/bin” All other settings pages are OK.


Delete the content of your cpp file and copy the above code to it.

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <math.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <iostream>

#define AXI4_LITE_TEST_BADDR    0x43C00000

#define REG_32WR(addr, off, val) (*(volatile unsigned int*)(addr+off)=(val))
#define REG_32RD(addr, off) (*(volatile unsigned int*)(addr+off))
#define REG_8WR(addr, off, val) (*(volatile unsigned char*)(addr+off)=(val))
#define REG_32READ(addr,off) (*(volatile unsigned int*)(addr+off))

#define STR(x)   #x
#define PRINT_REG32(Base,x) PrintReg32(Base,#x, x)

void PrintReg32(volatile unsigned int * BaseAdress, const char* defin, int Offset) {
	unsigned int RegVal = REG_32READ(BaseAdress,Offset);
	printf("%s with Offset:0x%02x  Status:0x%x(%d)",defin,Offset,RegVal,RegVal);
	int BitSize = 32;
	int i;

	char Pos[200] = "";
	char Val[200] = "";
	for (i = 0; i < BitSize; i++) {
		char buffer[6];
		if (RegVal % 2) {
			snprintf(buffer, 5, " %d", i); //%02d
			strcat(Pos, buffer);
			if (RegVal % 2)
				strcat(Val, "  1");
				strcat(Val, "   ");
		RegVal = RegVal >> 1;
	printf(" (%s)\n", Pos);
	//printf ("%s\n", Val);

int main(int argc, char *argv[]) {
	int fd = open("/dev/mem", O_RDWR | O_SYNC);
	if (fd < 0) {
		return 1;

	volatile unsigned int *register_base = (unsigned int*) mmap(0, getpagesize(),
	REG_32WR(register_base, 0, 0);
	while (1) {
		PRINT_REG32(register_base, 0);
		PRINT_REG32(register_base, 1);
		int a=REG_32READ(register_base, 0);
		REG_32WR(register_base, 0,a);
	return 0;

The project should be build without an error. It is a simple test program which reads the registers 0 and 1 and write 0,1,2,3 to register 0 to change the mode of D_OUT (LEDs). The lower part of register1 represent the state of the switches.

If you build the PL by your own it is possible  the offset address of axi4_lite_test differ. Check it in the “Address Editor” of your Vivado project. The “AdressEditor” opens with the block design. Change the AXI4_LITE_TEST_BADDR value to the value from “Address Editor”.


#define AXI4_LITE_TEST_BADDR    0x43C00000

You can copy the result via FTP to your target an start it with ./PL_Register. If you use a Crosscompiler without hard float you need to define a symbolic link.

ln -s /lib/arm-linux-gnueabihf/ /lib/

Debug the application

Create a new run configuration for a “C/C++ Remote Application” under “Run”=>”Debug Configurations”. Insert the shown values.


Use “SSH only” for connection to ZEDBOARD. For files and control transfer SSH and SFTP is used. For debugging gdb is needed and have to be compatible to the target. Currently the apt-get package of gdb for arm-linux-gnueabihf is missing therefore I use the Xilinx version.


Set the gdb debugger to “/opt/Xilinx/SDK/2013.2/gnu/arm/lin/bin/arm-xilinx-linux-gnueabi-gdb”

Now we can debug our project. Warnings appears

warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.

warning: Could not load shared library symbols for x libraries

and it is not possible to debug inside libraries, but we can debug our code.

Debug shared libraries

Often it is not needed to debug shared libraries, but if we select “Step into” a shared library the debug is stopped.
We can solve this issue by providing the target file system to the development system.

In Part4 backup and restore of the target root file system is explained. We can extract such backup on the development system. Therefore I use this desktop script. Now we have to inform the debugger about the file system. Create a new file in project folder with name gdbinit with following content.

set sysroot /home/roy/TargetFS

Change “/home/roy/TargetFS” to the path of your target file system and save the file. Open the debug configuration again and select the new file as “GDB command file”.

With these changes we can debug shared libraries and the warnings are gone.

Diskutiere über "Development with Zynq – Part 6 – Eclipse Project for register access"

  1. Markus Penzel sagt:

    ich fand ihre Tutorial rund um das Thema Zynq sehr hilfreich. Daher frage ich mich, ob Sie
    plannen, weiter fortgeschrittene Tutorials rund um Zynq/Linux zu erstellen? Interessant wäre Gebiete rund um custom IP mit Linux treibern anzusteuern.

    • Prof. Dr. Rüdiger Heintz sagt:

      Hallo Herr Penzel,

      danke für den positive Beitrag. Ich habe Quellcode für einen Gerätetreiber erstellt, welcher einen Interrupt empfängt und in ein Signal umwandelt. Das Signal kann dann im Userspace verwendet werden. Eine Artikel hierzu werde ich aber erst in 2-3 Monaten verfassen können, da ich mich zurzeit auf meine Vorlesungen konzentriere.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.