Debug using Event Recorder

Event Recorder (EVR) provides an API (function calls) for event annotations in the application code or software component libraries. It uses CoreSight DAP to output data from the target (memory reads/writes). This means any debug adapter can be used. MDK-Middleware , Keil RTX5 , and CMSIS-FreeRTOS are already annotated. EVR requires a certain amount of system RAM.

printf without a UART

μVision provides a simple printf utility using the Event Recorder. It does not require a UART and it is much faster. Text is displayed in the Debug (printf) Viewer window.

Configure Event Recorder

  1. If it is running, Image Alt Text:Stop stop the application and Image Alt Text:Start/Stop Debug exit debug mode (Ctrl+F5).
  2. Image Alt Text:Manage Run-Time Environment Go to Project - Manage - Run-Time Environment.
  3. Expand Compiler and enable Event Recorder:DAP and I/O:STDOUT:EVR as shown: Image Alt Text:Manage Run-Time Environment Window
  4. The Validation Output window should be empty. If not, click on the Resolve button to enable other missing software components.
  5. Click OK to close this window.
  6. retarget_io.c, EventRecorder.c, and EventRecorderConf.h will be added to your project under the Compiler group in the Project window:
    Image Alt Text:New compiler component
  7. Right click near the top of Blinky.c (at line 7), choose Insert ‘#include file’, and select:
        
    
            
            
                #include "EventRecorder.h"
            
        
    
  8. In the main() function (near line 39), just after SystemCoreClockUpdate();, add these lines:
        
    
            
            
                EventRecorderInitialize(EventRecordAll,1);
    EventRecorderStart();
            
        
    

Use Event Recorder

Now, create a global variable named counter whose value will be printed on Debug (printf) Viewer window.

  1. In Blinky.c, near line 14, declare the global variable counter:
        
    
            
            
                uint32_t counter = 0;
            
        
    
  2. Add these two lines just after the Delay(1000) statement at line 46:
        
    
            
            
                counter++;
    if (counter > 0x0F) counter = 0;
            
        
    
  3. Near the top of the file (around line 80), add:
        
    
            
            
                #include "stdio.h"
            
        
    
  4. Near line 48, just after the statement if (counter > 0x0F…), add:
        
    
            
            
                printf("Hello %d\n", counter);
            
        
    
  5. Go to Image Alt Text:Save All File - Save All.
  6. Go to Image Alt Text:Build Project - Build Target (F7).
  7. Image Alt Text:Build Start a Debug Session (Ctrl+F5) to enter the µVision debugger.
  8. Image Alt Text:Run Run (F5) the application.
  9. Image Alt Text:Debug (printf) Go to View - Serial Windows and select Debug (printf) Viewer.
  10. The values of counter are displayed as seen here:
    Image Alt Text:Output in the Debug (printf) Viewer window
  11. Go to View - Analysis Windows and select Event Recorder to see information about the printf statements:
    Image Alt Text:printf information in the Event Recorder window
  12. Image Alt Text:Stop Stop the program and Image Alt Text:Start/stop debug exit debug mode (Ctrl+F5).
Notes
  • When using real hardware, select the ::Compiler:Event Recorder:DAP variant.
  • The FVP model supports semihosting. It requires the following entry in the configuration file (already done in the example project):
    cpu0.semihosting-enable=1

Run EVR in Non-initialized Memory

In the Command window, you will see Warning: Event Recorder not located in uninitialized memory!. This can be safely ignored for the purpose of this tutorial.

In general, it can be important to preserve the EVR data located in the target’s RAM in the event of a crash and/or reset. Creating and using non-initialized memory is implemented by modifying the scatter file. Knowledge base article KA003868 explains how to modify your project to do so.

Code Annotation with Event Recorder

With Event Recorder, you can also annotate your source code which can be displayed in various information windows.

Configure Event Recorder

  1. Confirm that the configuration steps in the previous section were completed.
  2. To add an event, insert this function call at the top of the while(1) loop (around line 47):
        
    
            
            
                EventRecord2(3, 44, counter);
            
        
    
  3. Go to Image Alt Text:Save All File - Save All.
  4. Go to Image Alt Text:Build Project - Build Target (F7).
  5. Image Alt Text:Build Start a Debug Session (Ctrl+F5) to enter the µVision debugger.
  6. Go to View - Analysis Windows and select Image Alt Text:Event Recorder Event Recorder to see the event coming in.
  7. Image Alt Text:Run Run (F5) the application.
  8. Events will start to display in the Event Recorder window as shown below:
    Image Alt Text:Events shown in the Event Recorder window
  9. You can see the results of the EventRecord2(3, 44, counter); event.
  10. printf frames (stdout) are also displayed with the printf data in hexadecimal form.
Notes
  • Hover your mouse over Event Property entries to gain more information.
  • Stop the recording by unselecting Enable in the upper left corner.
  • When you re-enable it, events that were collected in the background as the program ran will be displayed.

Determine Relative Timing Values

  1. Unselect Enable in the Event Recorder window to stop the collection of data.
  2. Right-click on the first in a sequence of stdout frames and select Set Time Reference. The selected frame will turn from blue to green.
  3. Position your mouse pointer on the Time (sec) column on the next event frame.
  4. A box will open displaying the elapsed time. It took about one second from the start of this printf to the next one:
    Image Alt Text:Time reference in the Event Recorder window
  5. Enable the Event Recorder so the frames continue to be captured and displayed.
  6. You can use this feature to time many different events in your code.
Notes
  • Using event annotations provides a useful time link to your source code.
  • Using printf with a 9600 baud/8 characters UART requires about 80,000 CPU cycles or about 8 msec. Using Event Recorder, it takes only ~500 CPU cycles. Event Recorder is 10 times faster than a UART running at highest speeds. Using an Event such as StartB(1) with 8 bytes is even faster: only ~250 CPU cycles.

Filter the Event Recorder Window

It is possible to filter the window contents. Modify the information displayed in the Event Recorder window using the funnel icon which will open the Show Event Levels window. You can specify what elements are collected and displayed in the Event Recorder window.

  1. If running, Image Alt Text:Stop stop the program if necessary but stay in debug mode.
  2. In the Event Recorder window, select Image Alt Text:Configure Target Event Recording Configure Target Event Recording. The Show Event Levels window opens up:
    Image Alt Text:Filter event levels
  3. Unselect all boxes opposite STDIO as shown above.
  4. Click OK to close this window.
  5. Click Image Alt Text:Clear Clear to make it easier to see what is happening.
  6. Image Alt Text:Run Run (F5) the application.
  7. The Event Recorder window no longer contains printf frames as shown below:
    Image Alt Text:Filtered Event Recorder window
    In this case, you only need to unselect the Op column. The other frames do not exist in this simple example.

Save Filter Settings

You can save and recall the filter settings. In the Command window, execute:

    

        
        
            ER SAVE path\filename
ER LOAD path\filename
        
    

Event Statistics

You can add start and stop events to your source code to collect information about execution counts and times. If you are using a ULINKplus debug adapter, information can also include voltage, current, and total charge (Q) consumed. Individual and aggregate times are provided in the Event Statistics window. This information will be collected between the start and stop event tags including the execution of any exception handlers or program branches.

  • Start: The basic function calls are EventStartX(slot) and EventStartX(slot, v1, v2).
  • Stop: The basic function calla are EventStopX(slot) and EventStopX(slot, v1, v2).
  • These calls are arranged in four groups (X = A, B, C, D). v is for data value.
  • Each group has 15 slots (0 to 15). Stop events for slot = 15 creates a global stop for all slots of a group.
  • Examples:
        
    
            
            
                EventStartA(2);
    EventStopA(2);
    EventStartB(4,34, counter);
            
        
    

Set Core Clock for Timing Measurements

For correct timing information when working with real hardware, the core clock needs to be set up correctly.

  1. Go to Image Alt Text:Options for Target Project - Options for Target… (Alt+F7) and select the Debug tab.
  2. Select the Settings icon to the right of this window.
  3. Select the Trace tab.
  4. Enter the correct Core Clock: value. μVision uses this setting to calculate timing values displayed in some windows.
  5. Click OK twice to return to the main μVision menu.
Note

The above is not required in simulation!

Add the EventStart and EventStop Events

  1. If running, Image Alt Text:Stop stop the program and Image Alt Text:Start/stop debug exit debug mode (Ctrl+F5).
  2. Add this code near line 47:
        
    
            
            
                EventStartA(11);
            
        
    
  3. Add this code near line 51:
        
    
            
            
                EventStopA(11);
            
        
    
  4. Go to Image Alt Text:Save All File - Save All.
  5. Go to Image Alt Text:Build Project - Build Target (F7).
  6. Image Alt Text:Build Start a Debug Session (Ctrl+F5) to enter the µVision debugger.
  7. Go to View - Analysis Windows and select Image Alt Text:Event Statistics Event Statistics to see the event coming in.
  8. Image Alt Text:Run Run (F5) the application.
  9. The Event Statistics window displays timing data between the start and stop function calls:
    Image Alt Text:Event Statistics window
  10. Event Group A is displayed, showing slot 11 as indicated.
  11. The execution time statistics are displayed for minimum, maximum, and average execution times (do not differ in simulation). This makes it easy for you to determine these statistical values for locations in your sources.

This provides a good method to determine timings relative to your source code. Event Statistics is easy to configure and interpret. You can create up to 64 start/stop events.

Notes
Back
Next