Using Xilinx SDK to Debug CMake-Defined Executables
Tags: cmake, xilinx, toolchains, embedded
Published: 2018-12-01 04:01:28

---
title: Using Xilinx SDK to Debug CMake-Defined Executables
published: true
description: 
series: AlphaAutomata
tags: cmake, xilinx, toolchains, embedded
---

# The Thing

After arduously pushing through a number of roadblocks, I can now use Xilinx SDK to debug executables defined through a CMake script.

# The Background

In the previous posts in this series, I summarized the [Alpha Automata] project and my journey towards generating Xilinx SDK projects using CMake.

I want CMake's dependency management and automation, and I want to use Xilinx SDK's debugger. Therefore, I must figure out a way to run executables compiled using CMake-generated build systems in Xilinx SDK's debugger. I have spent a lot of my free time in the past three weeks on figuring out how to do just that.

# CMake Meets Xilinx System Debugger

Three weeks ago, I had figured out how to generate a Xilinx SDK project using CMake. The last post in this series describes that journey.

### CMake Invisible

I could import the SDK project, and compile and link and `elf` file. However, Xilinx SDK would not give me the option of setting up a debugging profile for the executable.

![no_project](https://thepracticaldev.s3.amazonaws.com/i/exj96thxfmvih7ca5zo4.PNG)

As you can see, Xilinx SDK refuses to acknowledge the existence of my imported project.

I spent a long time prowling Google without getting a satisfactory answer. In fact, I didn't find many people who were even talking about mashing CMake and Xilinx SDK together. Frustrated with this lack of information, I started experimenting. I created application projects using the Xilinx SDK GUI, and compared the configurations of those projects against the configurations of my imported CMake-generated project. Almost by accident, I found the checkbox I needed to tick:

![proj_ref](https://thepracticaldev.s3.amazonaws.com/i/3yfp1llen1nd20ds98y5.PNG)

The imported project must be set to reference the target SoC's Board Support Package project in the imported project's `Project Properties`. With this one box checked, Xilinx SDK acknowledged my imported project as a candidate for a debugging profile.

![yes_project](https://thepracticaldev.s3.amazonaws.com/i/kvzntg77h3ctli7p6bct.PNG)

I could finally designate the executable compiled using the imported, CMake-generated project for debugging.

![executable](https://thepracticaldev.s3.amazonaws.com/i/sftvk5qc5hmts3ovejgn.PNG)

At this point, I was ecstatic. As is true for so many things in software, finding the solution took way too long, and the solution turned out to be way too simple.

### CMSIS vs Zynq

I happily hit the `debug` button to run my executable on the target SoC...

![load_err](https://thepracticaldev.s3.amazonaws.com/i/7gkzw1doldnd4clve1px.PNG)

...and Xilinx SDK spat in my face just as happily.

I also looked up the address called out in the error to see if it's a legal address for my particular chip to access, and the answer was a resounding "maybe".

![addr](https://thepracticaldev.s3.amazonaws.com/i/jsc93b3qva52n39x24y4.PNG)

According to the Xilinx documentation, address `0x8000_0000` marks the beginning of a programmable logic memory region. In other works, this is one of the address ranges used to read from and write to FPGA logic. Since I hadn't implemented anything in my Zynq SoC's FPGA fabric for this debugging session, my code certainly shouldn't be accessing the FPGA fabric memory range. It just so happens that the CMSIS linker script I was using designates address `0x8000_0000` as the beginning of ROM.

![cmsis](https://thepracticaldev.s3.amazonaws.com/i/w09rpapmx0nqimb9567g.PNG)

At this point, I groaned to myself. Xilinx SDK automatically generates linker scripts for application projects created using its GUI. And as many times as I hit the `Generate linker script` button for my CMake-generated project, Xilinx SDK refused to do anything of the sort. In a wild stab into the dark, I designated no linker script and just let GCC choose where it wanted to place all the binary blocks.

![debug](https://thepracticaldev.s3.amazonaws.com/i/n6df96j6wujed1ue4w8d.PNG)

And it worked. And I grew a whole new appreciation for GCC and ARM's consistent startup behavior.

*All ARM processors immediately fetch the initial stack pointer and initial program counter from a vector table at address `0x00000000` or `0xFFFF0000`, depending on the specific processor. This vector table can be moved using the Vector Base Address Register (VBAR).*

# The State of Alpha

Since last month, not much has changed. I've literally devoted three weeks to get CMake and Xilinx SDK to play nice with each other.

# Onwards and Upwards

Now that I have a debugger running on real hardware, I expect to make faster progress implementing the RTOS and to spend less time wrestling with my tools.

I said I would try really hard to post every two weeks, and I did. Things started picking up for me at my real job, and ThanksGiving conspired with my fiance to make me socialize. Hopefully, I'll make one more post before Christmas and my fiance kidnap me.

[Alpha Automata]: https://github.com/AlphaAutomata