NoICE Debugger

ARM Tutorials

Running NoICE for the first time

Connecting to hardware

Compiling for debugging

Source-level debugging

Home Download Purchase Tutorials FAQ NoICE Help

ARM: Source-level Debugging

This example uses ImageCraft ICCARM, as described in the previous section of the tutorial, Compiling for Source-level Debugging.

You can follow along even if you don't have this compiler. All files necessary for you to run the NoICE demo may be downloaded here: Setup for other compilers is generally similar.

Debugging hellofoo

Run NoICE. Select "File", "Load...".

By default, you will see hex files such as hellofoo.hex. You could load that, but all you would get would be disassembly, as the hex file doesn't contain any symbolic debug information.

So change the "Files of type" to"ImageCraft DBG files".

Navigate to hellofoo.dbg and press "OK".

NoICE help on LOAD

Load dialog for ImageCraft DBG files

The result looks like this.

Why don't you see the code at main? The answer is part geek and part philosophy: main is the first C code of your program, but it is not the first instruction executed by the processor after reset. That honor rests with the C startup code, which initializes the stackpointer, clears memory, and does assorted I/O initialization. After all that, it calls main.

Some debuggers hide all the low-level stuff from you and execute until main before showing you anything. My opinion is that hiding low-level stuff is not a good thing when working on embedded systems: there are times when you want to step through the startup code, or set a breakpoint in the midst of it.

So, NoICE loads the code and sets the PC to the first instruction of the startup code. If you were running without NoICE, this is where the reset vector would point.

If you want to skip over the startup code (and you usually do, once you have verified that it works), you could set a breakpoint at main, and then execute 'til there:

   B main

This should stop at main and show you the source code there.

Since you are Loading an ImageCraft DBG file, NoICE can do this automatically for you.

Select "Run", "Go until main after LOAD".

The next time you load a DBG file, NoICE will run from the start location until main (presuming that your startup code works and the program ever gets there...).

Disassembly only


Here we have also selected the option "Memory", "Watch All Locals". Thus, the values of all local variables are shown in the Watch window.

More about Watches later.

Source code at main()

Source-level Single-step

If you single-step, you will now step by lines of C code rather than by processor instruction.

Use "Step Over" or the F10 function key to step down to the call to Bar().

To step into the function Bar(), use "Step Into" or the F11 function key.

To step over the function Bar(), use "Step Over" or the F10 function key.

If you really want to step one processor instruction, use "Instruction Step" or the F9 function key.

Breakpoints work just as they do in disassembly mode.

Source-level single-step

Mixed Source/disassembly mode

To see the assembly code that corresponds to the C code, select "View", "Mixed source/disassembly".

Or click on the toolbar button that looks like a screwhead drawn by a programmer whose artistic skills never advanced past third grade.

Source-level with disassembly

Simulated UART Output

Return to source mode by selecting "View", "Mixed source/disassembly" again.

Use Step Over to step over a call to Bar(). You may observe a flash as the Output view briefly comes to the foreground, and is then replaced by the Watch view.

Click on the "Output" tab to view the characters sent by your program to the simulated UART.

If you have enough screen space, you may want to turn either the Output or the Watch view into a free-floating window. To do so, just double-click on the view's tab. Turn return the window to being a tab, just click its closer box.

NoICE help on the Output Window

UART output window

If you are running this program on real hardware rather than the simulator, you won't see anything in the Output tab. You have a real UART, and its output is being sent to a pin on the ARM chip, and from there to an RS-232 connector or whatever your hardware connects it to.

If you want to see this output, you will need to connect your target's serial port to a serial port on your PC and use a terminal emulator such as HyperTerminal to see the output.

More on Watches

We previously selected the option of watching all local variables. You can also manually add watches for static or global variables.

Double-clicking on a watch value brings up the Modify Watch dialog and allows you to change the value of the watched variable.

NoICE help on Watches

Modify a watched value

Well, that's the end of the tutorial. We hope it was useful.

The best thing to do now is to run NoICE and try things. If something doesn't make sense, or if you can't figure out how to do something, take a look at NoICE help

NoICE Debugger Copyright 2006 by John Hartman Revised 22 November 2006