Getting unknown addresses in instruction trace

From SEGGER Wiki
Revision as of 08:37, 27 September 2022 by Nino (talk | contribs) (Examples with Ozone)
Jump to: navigation, search

Under certain circumstances it is possible that debug software outputs instruction trace packets as "unknown address". This article will describe why this could be happening and how to fix the issue.

Introduction

The reason for getting unknown addresses is that to be able to reconstruct instruction trace the J-Link software needs to have cached the contents of the executed memory area. Per default only readonly memory, such as Flash, is cached on download. Already present flash content, e.g. a bootloader, is not read back, nor is RAM cached automatically.

Main causes

The main causes for this are:

  • The application is running from RAM which is not cached by default
  • The target device already has something (e.g. a bootloader) programmed to Flash, so when a new additional application gets downloaded only the newly added memory are will be cached.
  • The user attaches to a running program. In this case no memory at all is cached as no application has been downloaded for J-Link to know which memory areas are affected.
  • The application is executed from another location than it is downloaded to.

How to get correct trace output

To enable trace cache for one of the aforementioned scenarios the exec command ReadIntoTraceCache needs to be used. The syntax is as follows: ReadIntoTraceCache <Addr> <NumBytes>

How to use exec commands is described in the J-Link User Manual (UM08001).

Note:

This command causes an immediate read from the target, so it should only be called

at a point where memory contents at the given area are known to be valid.

Examples with Ozone

Adding Bootloader to Tracecache

The following steps assume that you have a bootloader or some other application already programmed (e.g. softdevice) that is not downloaded with Ozone.

When a new Ozone project has been created and saved you will find the following entry in the .jdebug file:

/*********************************************************************
*                                                                     
*      AfterTargetDownload                                            
*                                                                     
* Function description                                                
*   Event handler routine.                                            
*                                                                     
* Notes                                                               
*   This sample implementation demonstrates the application           
*   initialization on a Cortex-M target.                              
*   If no initialization can be done, Target.Reset() may be called.   
*                                                                     
**********************************************************************
*/                                                                     
//void AfterTargetDownload (void) {                                   
//                                                                    
//  unsigned int SP;                                                  
//  unsigned int PC;                                                  
//  unsigned int VectorTableAddr;                                     
//                                                                    
//  VectorTableAddr = Elf.GetBaseAddr();                              
//                                                                    
//  if (VectorTableAddr != 0xFFFFFFFF) {                              
//                                                                    
//    Util.Log("Initializing PC and SP.");                          
//                                                                    
//    SP = Target.ReadU32(VectorTableAddr);                           
//    Target.SetReg("SP", SP);                                      
//                                                                    
//    PC = Target.ReadU32(VectorTableAddr + 4);                       
//    Target.SetReg("PC", PC);                                      
//  }                                                                 
//}  

Edit it to include the exec command and uncomment the function block so it looks like this:

/*********************************************************************
*                                                                     
*      AfterTargetDownload                                            
*                                                                     
* Function description                                                
*   Event handler routine.                                            
*                                                                     
* Notes                                                               
*   This sample implementation demonstrates the application           
*   initialization on a Cortex-M target.                              
*   If no initialization can be done, Target.Reset() may be called.   
*                                                                     
**********************************************************************
*/                                                                      
void AfterTargetDownload (void) {                                                                                                    
  Exec.Command("ReadIntoTraceCache 0x00000000 0x1000");
}  

Alternatively function Debug.ReadIntoInstCache() can also be used.

Note:
Please adjust the values for address and size fitting to your target device and setup. ReadIntoTraceCache can be called multiple times for different memory areas. As long as the memory areas are not overlapping the new memory area will be added to the existing cache.

Adding RAM functions or remapped code to Tracecache

The following steps assume that your application changes during startup of your device (e.g. bootloader remaps application or RAM functions are copied to RAM).

When a new Ozone project has been created and saved you will find the following entry in the .jdebug file:

/*********************************************************************
*                                                                     
*       OnStartupComplete                                             
*                                                                     
* Function description                                                
*   Called when program execution has reached/passed                  
*   the startup completion point. Optional.                           
*                                                                     
**********************************************************************
*/                                                                    
//void OnStartupComplete (void) {                                     
//}

Edit it to include the exec command and uncomment the function block so it looks like this:

/*********************************************************************
*                                                                     
*       OnStartupComplete                                             
*                                                                     
* Function description                                                
*   Called when program execution has reached/passed                  
*   the startup completion point. Optional.                           
*                                                                     
**********************************************************************
*/                                                                    
void OnStartupComplete (void) {                                                                                                                           
  Exec.Command("ReadIntoTraceCache 0x00000000 0x1000");
}  

Alternatively function Debug.ReadIntoInstCache() can also be used if you need to make Ozone aware of the program change to e.g. show the correct disassembly for the uncached regions.

Note:
Please adjust the values for address and size fitting to your target device and setup. ReadIntoTraceCache can be called multiple times for different memory areas. As long as the memory areas are not overlapping the new memory area will be added to the existing cache.