Main Page | Modules | File List | Globals | Examples

bfemu - Blackfin emulation library Documentation

Version:
0.11
Author:
Martin Strubel
Date:
1.09.2005

Overview

The in circuit emulation library libbfemu for the Blackfin series from Analog Devices is a library helping to access the built in debugging and testing features of the Blackfin via its JTAG port. It allows to completely 'remote control' the Blackfin via JTAG and to monitor the system as non-intrusively as possible, thus no existing kernel or monitor/bootloader is required.

For hardware developer, this provides the following functionality:

bfemu currently only supports one blackfin CPU in the JTAG chain. If your chain is longer, please contact section5 (http://www.section5.ch).

The libbfemu is partial OpenSource, meaning, that some driver specific bottom layers may not be disclosed. However, full OpenSourcing of this library is planned for the near future.

JTAG hardware support

bfemu is optimized for stability and speed to run on the ICEBEAR USB JTAG adapter which can be ordered via http://www.section5.ch/icebear. Support for parallel port JTAG adapters is available in the OpenSource version.

bfemu has been heavily tested on the following platforms:

When designing your own Blackfin hardware, make sure to read Analog Devices' JTAG application note EE-68. section5 can also support you in getting your embedded system tested and set up using JTAG.

Blackfin remote debugging with GDB

When debugging under the GDB environment, the debugger needs to know what target to connect to. This target is a tiny server daemon, typically running on the local computer. It is equivalent to a gdbserver, although it does not run on the target hardware. This server is called gdbproxy and is derived from rproxy-0.7. This is the procedure you normally start with:

The Blackfin will now halt and you can:

To load an ELF binary into memory and execute:

(gdb) load blink.dxe
Loading section .text, size 0x1b8 lma 0xffa00000
Start address 0xffa00000, load size 440
Transfer rate: 3520 bits in <1 sec, 440 bytes/write.
(gdb) c
Continuing.

More commands: see GDB help

Note that the above examples assume, that the peripheral hardware has been properly initialized. GDB does not initialize anything on start, since it has no knowledge about the current state of the system. Before you load a program into the Blackfin, make sure you have done the correct initialization - read more hints below.

For different system configurations, GDB scripts are used. GDB scripting is a very powerful feature and helps to automatize different system configurations.

Initializing the Blackfin

When loading the very first program onto a Blackfin, you will very likely have to initialize your SDRAM before you can actually execute a 'load'. Not doing so can cause a hardware error which may require a 'monitor reset' command to recover -- see JTAG internals.

The following example initializes the SDRAM controller for the memory configuration found on the BF533 STAMP:

source mmr.gdb    # load the memory register definitions
set *$EBIU_SDGCTL = 0x80111149
set *$EBIU_SDBCTL = 0x00000037
set *$EBIU_SDRRC  = 0x00000817

For tested hardware, please see init-* scripts in the scripts/ subdirectory of the Blackfin-JTAG GDB distribution.

It is recommended, to add the initialization commands into the .gdbinit file residing in your hardware development directory -- see also GDB manual.

Catching exceptions

By default, GDB does not catch any of the Blackfin core exceptions to not interfere with kernel or user code whatsoever. When the core stalls ("CORE FAULT") while debugging, it is very likely that an exception got fired but not handled. Reasons for this can be uninitialized SDRAM or illegal memory accesses. To facilitate debugging of programs, make sure your program contains exception handling code.

Then, you can use the GDB script 'catch_exc.gdb' to make GDB react to hardware exceptions. This basically sets a breakpoint inside the initialized exception handlers.

Note:
'catch_exc.gdb' takes only effect after your program has initialized the exception handlers!
Example output on illegal memory access:

-----------------------------------------------------------------
-- Exception !!
-- EXCAUSE: 24
-- Reason: "Address error / misalignment"
-- Instruction: 0x12e0 <savecall+32>:   [p0++] = r0;
-----------------------------------------------------------------

For example, check out the .gdbinit script from the shell demo (which is found in the Blackfin Software download section at the section5 website). The catch_exc.gdb script is run after the initialization of the exception handlers. We will cause the above Address misalignment exception by dumping memory from an odd address (which is not caught in the shell demo). These are the steps to reproduce such an error:

In some cases, when it is very hard to catch an error, you can also use a loop, for example, to find out, when a hardware error is latched to the IRQ controller:

source mmr.gdb
while (!(*$ILAT & 0x20))
si
end

This will single step until the hardware error occurs.

Useful scripts

Sometimes it is not obvious, why an exception was caused. Especially, when certain interrupts are disabled but latched, errors or program interrupts can happen at an unexpected location.

To display the interrupt status, there are several userdefined commands in the dump.gdb script. You must load the file mmr.gdb beforehand.

Using the bfemu API

The bfemu API is documented under the modules section. Please see the examples on usage.

Note that currently only one Blackfin device is supported in the JTAG chain.

All emulation functions require a valid CPU handle to be passed as first argument. This handle is acquired via calling jtag_init().

Error handling

If not specified, an API function always returns 0 on success and a negative error code on failure. See "Error Handling" in the modules section for meaning of the error codes.

See also the Troubleshooting section of the ICEBEAR short manual.

Accessing the Blackfin's memory

When accessing the on-chip L1 program memory via the function set_memory(), or get_memory(), there is one important thing to note: Since access can not happen directly, the L1 data memory is used as an auxiliary buffer to transfer the data blocks via DMA. The DMA context and the auxiliary buffer are NOT preserved!

The user must either:

When accessing the SDRAM, make sure that the PLL and the SDRAM controller are correctly configured. Otherwise, the core may stall.

JTAG internals

Resetting

The command
 monitor reset 
resets the Blackfin core and system. The program counter is set and executed at the address which is depending on the boot mode (see Boot Mode switches of your platform hardware manual) or the SYSCR register.

Doing a single step ('si' command) after a 'monitor reset' shows the location after a reset, which is normally:

0x20000000: external Flash/Async memory
0xef000000: Blackfin Boot ROM

Depending on the silicon revision, the program counter may already be a few instructions ahead of the above listed location. This can not be avoided.

Breakpoints

There are two kind of supported breakpoints, software and hardware breakpoints. Software breakpoints are realized by writing the EMUEXCPT instruction into the desired location. For hardware breakpoints and watchpoints, the watchpoint unit of the blackfin is used. The behaviour of the watchpoint unit seems to differ from the documentation and does not produce reliable results on silicon revisions < 0.3. See also wpu_init().

Library and Software Components

This is a short summary of the components needed to get a full test and debugging system running:

Known issues and bugs


Generated on Thu Sep 1 15:02:53 2005 for bfemu - Blackfin emulation library by  doxygen 1.4.3-20050530