The following steps enable the MDK debugger views for static information and dynamic events.
For User Code:
- Add the Event Recorder to the project.
- Place Event Recorder in uninitialized memory to avoid overwriting the entries on program reset.
- Add Event Annotations in the C source to be able to stream dynamic event information.
- Create an SCVD file to Format Event Information that matches with application code.
For MDK Middleware and Keil RTX5:
The software packs for MDK Middleware and CMSIS already contain the *.SCVD files and the related event annotations in the C source code.
- Enable Event Recorder to the project.
- Select the required software component variant to enable event information.
Enable Event Recorder
To use the Event Recorder in an application, you need to:
- Select the software component Compiler:Event Recorder using the RTE management dialog.
- Include the EventRecorder.h header file and add the event recorder initialization function to the source code:
:
:
int main (void) {
:
HAL_Init();
SystemClock_Config();
MemoryBus_Config();
:
}
- Note
- By default, the Event Recorder is using the DWT Cycle Counter as a time reference. This is not available on all targets. Change the configuration to use an alternative timer instead.
- If you are using Keil RTX5 (version 5.4.0 and above), you should not call EventRecorderInitialize in the main function, but use the Global Initialization available from the RTX_Config.h file. Refer to the Keil RTX5 user's manual for more information.
Place Event Recorder in uninitialized memory
To be able to run without interruptions from program reset, the Event Recorder component has to be placed inside a memory region that is not initialized during reset. This can be either achieved using a linker script, or from within uVision using the Options for Target dialog:
- Prepare a RAM memory region that can be left uninitialized. For that, open the Options for Target dialog or press Alt+F7. On the Target tab, locate your read/write memory. For example, you might have an IRAM1 starting at 0x20000000 with a size of 0x20000.
- To calculate the required memory for the Event Recorder, use this formula: 128 + 36 + 16 x Number_of_Records. The number of records corresponds to the #define EVENT_RECORD_COUNT in the EventRecorderConf.h file. The default number is 64. This equates to a total required memory of 1188 bytes. Let's continue with 2048 bytes for easier calculation which translates to 0x800.
- In the memory layout dialog, reduce the size of IRAM1 by 0x800 and create an IRAM2 starting at 0x2001F800 with a size of 0x800. Enable the NoInit for this region.
- Note
- If you do not place your Event Recorder component in uninitialized memory, you will see a warning in the Command window of the uVision debugger: "Warning: Event Recorder not located in uninitialized memory!".
- Knowledgebase article 4012 explains how to create custom memory areas in uVision.
Event Annotations
To to stream dynamic event information, insert calls to the Event Data Recording functions on relevant code locations:
These Event Data Recording functions receive as first parameter an id event identifier used for filtering and displaying. The macro EventID may be used to compose id values to include level
and component
numbers.
Example:
int some_error = 0;
char string[10] = "MyTest";
void MyFunction (int parameter) {
;
if (some_error) {
return;
}
return;
}
int main (void) {
MyFunction (0x10);
some_error = 1;
MyFunction (0x60);
}
When executing this example in the µVision debugger, use the menu command View - Analysis Windows - Event Recorder to open the Event Recorder window. This should show the following output:
Output shown in Event Recorder window
Format Event Information
You may create an *.SCVD (Software Component View Description) file to format the event output so that matches the application. The event output is created using the /component_viewer/events.
SCVD file example
<?xml version="1.0" encoding="utf-8"?>
<component_viewer schemaVersion="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd">
<component name="MyExample" version="1.0.0"/> <!-- name and version of the component -->
<events>
<group name="My Events Group">
<component name="MyApp" brief="My Application" no="0x00" prefix="EvrNetMM_" info="Network - System - Dynamic Memory Management"/>
</group>
<event id="1" level="API" property="MyFunction" value="parameter=%x[val1]" info="Event on start of MyFunction" />
<event id="2" level="Error" property="MyFunctionError" info="Event on error in MyFunction" />
<event id="3" level="Op" property="MyFunctionProcess" value="string=%t[val1]" info="Event on operation in MyFunction" />
</events>
</component_viewer>
In the µVision debugger, this *.SCVD file is specified in the dialog Options for Target -> Debug -> Manage Component Viewer Description Files. Click on Add Component Viewer Description File and add the related .SCVD file.
Manage *.SCVD files
The Event Recorder displays the events as shown below.
Event Recorder output formatted with *.SCVD file
The described groups and events also show up in the filter dialog.
Event Recorder Filter dialog
Software Component Variants
The software packs for MDK Middleware and CMSIS already contain SCVD files that match the related event annotations in the C source code. However, you need to select the right component Variant. For MDK Middleware, you need to select the Debug variants, whereas for Keil RTX5, you need to add the Source variant.
The example below enables event recording for the MDK-Middleware File System component:
Redirecting printf output
The Event Recorder can be used to retarget printf output. This is especially interesting for targets without ITM, such as Cortex-M0/M0+/M23. Steps to enable this:
- In the Manage Run-Time Environment window, set the component Compiler:I/O:STDOUT to use Variant EVR.
- Select the component Compiler:Event Recorder or use the Resolve button.
- In the user code, include
EventRecorder.h
and call the EventRecorderInitialize()
function in main().
Refer to the example Retarget STDOUT via Event Recorder in "I/O Retargeting".
Event filtering
Filtering for events reduces the amount of data transmitted from the target to the debugger. To filter for events, use the button Configure Target Event Recording:
A new window opens up that lets you filter for events that you are interested in:
Filtering events