Ozone Debug and Trace with RAM Functions

From SEGGER Wiki
Jump to: navigation, search

A target application might execute certain (or all) function from RAM instead of from Flash memory. Because RAM is not initialized after power up, these functions need to be written to RAM, which is usually done by the startup code before the main application executes.

Standard toolchains, such as GCC, store a copy of the RAM functions, i.e. the initialization image, in Flash and simply copy the image to the destination RAM area. With advanced linkers, such as the SEGGER Linker, the initialization image can also be compressed, which saves some Flash memory, and the RAM function is decompressed and written to RAM.

Because the exact content, i.e. instructions, of a RAM function is not known from the Elf Application File, Ozone does not have all information about the function in the beginning. Therefore it is necessary to tell Ozone when the RAM functions are initialized, so that it can create the disassembly and get the missing information.

After Ozone got all information about the RAM functions, it can display the (inline) disassembly and also use it for instruction trace analysis.

Initializing RAM Function Information

After the RAM functions are initialized, which they usually are at main(), the command Debug.ReadIntoInstCache() with the RAM area(s) in which RAM functions are, needs to be called.

Example: Debug.ReadIntoInstCache(0x20000000, 0x2000);

It can be called manually from the Console, or automated from the project, such as in OnTargetHalt() or in a breakpoint handler for a Breakpoint at main.

Example Project


This project executes functions from Flash and RAM. On startup all RAM functions are initialized before reaching main(). The startup, main() and MAIN_FlashFunc() execute from Flash, all other functions, including ISRs, execute from RAM.

To debug and trace this example, the RAM Function Information needs to be initialized as discussed above. In this project it is done automatically from a callback on the breakpoint.

void OnProjectLoad(void) {
  Break.SetCommand("main.c:87", "cbBreakMain");

void cbBreakMain (void) {                                       
  Debug.ReadIntoInstCache(0x20000000, 0x2000);

The project is configured to run on the emPower Board, but the application can run on any Cortex-M4 device with Flash at 0x00000000 and RAM at 0x2000000000.

The application outputs a simple message:

Executing main() from Flash @ 0x00000410.
Executing APP_Main() from Flash @ 0x200009B8.
Tick Count: 1500    Tick Count squared: 2250000
Tick Count: 2000    Tick Count squared: 4000000