Event Recorder RAM Allocation Exceeds Expected Size on STM32F0
When configuring the Event Recorder on an STM32F0 microcontroller using ARM-MDK 5.27, the RAM allocation for the Event Recorder exceeds the expected size. Specifically, setting the record count to 64U, which should theoretically require 1,024 bytes (16 bytes per record), results in a linker error indicating that the allocated 1,024 bytes in the IRAM2 region is insufficient. The actual size required is 1,252 bytes, which is 228 bytes more than expected. This discrepancy persists regardless of the record count, forcing developers to allocate larger IRAM2 regions (e.g., 2,048 bytes) to avoid linker errors, leading to inefficient RAM usage.
The Event Recorder is a debugging tool that captures runtime events and stores them in a buffer for later analysis. Each event record is 16 bytes, and the total buffer size is calculated as 16 * Number_of_Records. However, the Event Recorder also requires additional memory for internal data structures, padding, and alignment, which are not accounted for in the simple calculation. The linker map file reveals that the extra 228 bytes are used for padding, a single byte for timer state, and other internal data structures such as EventFilter and EventStatus.
The padding is introduced to ensure proper alignment of data structures in memory. For example, the EventBuffer is aligned to a 6-byte boundary, which may result in additional padding bytes. The SysTimerState variable, which is only 1 byte, also contributes to the overall memory usage. Additionally, the EventFilter and EventStatus structures consume 128 bytes and 36 bytes, respectively. These internal data structures are necessary for the Event Recorder to function correctly but are not explicitly documented in the RAM size calculation formula provided by Keil.
To summarize, the extra 228 bytes are used for the following purposes:
- Padding for alignment (e.g., 63 bytes of padding after
SysTimerState). - Internal data structures such as
EventFilter(128 bytes) andEventStatus(36 bytes). - A single byte for
SysTimerState.
This explains why the RAM allocation exceeds the expected size and why increasing the IRAM2 region is necessary to avoid linker errors.
SysTick Handler Multiple Definition Conflict in Event Recorder
Another issue arises when configuring the Event Recorder to use SysTick as the time stamp source. This configuration results in a linker error due to multiple definitions of the SysTick_Handler function. The conflict occurs because both the Event Recorder and the STM32F0 standard peripheral library (or other libraries such as RTX/RTX5) define their own versions of the SysTick_Handler. The Event Recorder attempts to redefine the SysTick_Handler to integrate its time stamping functionality, but this conflicts with the existing definition in stm32f0xx_it.o or other files.
The SysTick_Handler is a critical interrupt service routine (ISR) that handles the SysTick timer interrupts. In the STM32F0 standard peripheral library, this handler is typically defined in the stm32f0xx_it.c file. When using an RTOS like RTX or RTX5, the RTOS may also define its own SysTick_Handler to manage task scheduling and timing. The Event Recorder, when configured to use SysTick, introduces its own version of the handler to capture time stamps for recorded events. This results in a multiple definition error during linking.
The conflict can be traced to the following scenarios:
- The Event Recorder defines
SysTick_Handlerin its source files. - The STM32F0 standard peripheral library defines
SysTick_Handlerinstm32f0xx_it.c. - An RTOS like RTX/RTX5 defines
SysTick_Handlerin its kernel files.
To resolve this issue, developers must ensure that only one definition of SysTick_Handler is present in the final binary. This can be achieved by either modifying the Event Recorder configuration to use a different time stamp source or by integrating the Event Recorder’s time stamping functionality into the existing SysTick_Handler.
Resolving RAM Overrun and SysTick Handler Conflicts
Addressing RAM Overrun in Event Recorder Configuration
To address the RAM overrun issue, developers must account for the additional memory required by the Event Recorder’s internal data structures and padding. The following steps can help optimize RAM usage and avoid linker errors:
-
Calculate the Total RAM Requirement: Use the formula provided by Keil,
164 + 16 * Number_of_Records, as a baseline. However, add an additional buffer to account for padding and internal data structures. For example, if the record count is 64, the baseline requirement is 1,028 bytes (164 + 16 * 64). Allocate at least 1,300 bytes to account for padding and other overhead. -
Analyze the Linker Map File: Examine the linker map file to identify the exact memory usage of the Event Recorder. Look for sections such as
.bss,.bss.noinit, and.constdatato understand how memory is allocated and padded. -
Adjust IRAM2 Allocation: Increase the size of the IRAM2 region to accommodate the total RAM requirement. For example, if the baseline requirement is 1,028 bytes and the linker map file shows an additional 228 bytes of overhead, allocate at least 1,256 bytes in the IRAM2 region.
-
Optimize Record Count: If RAM usage is critical, reduce the record count to minimize the buffer size. For example, reducing the record count from 64 to 32 reduces the baseline requirement to 676 bytes (164 + 16 * 32), with an additional overhead of approximately 228 bytes, resulting in a total requirement of 904 bytes.
-
Use Conditional Compilation: Surround the Event Recorder code with pre-processor directives to exclude it from production builds. This ensures that the additional RAM is only used during debugging.
Resolving SysTick Handler Conflicts
To resolve the SysTick_Handler multiple definition conflict, developers can choose one of the following approaches:
-
Use DWT Cycle Counter as Time Stamp Source: Configure the Event Recorder to use the Data Watchpoint and Trace (DWT) cycle counter instead of SysTick. The DWT cycle counter is a hardware feature available on Cortex-M processors that provides a high-resolution time stamp source. Although the Cortex-M0 does not have a native DWT, it is emulated in software. This approach avoids the need to redefine
SysTick_Handlerand eliminates the multiple definition conflict. -
Integrate Event Recorder Time Stamping into Existing SysTick Handler: Modify the existing
SysTick_Handlerto include the Event Recorder’s time stamping functionality. This requires merging the Event Recorder’sSysTick_Handlercode with the existing handler instm32f0xx_it.cor the RTOS kernel. For example:void SysTick_Handler(void) { // Existing SysTick handler code HAL_IncTick(); // Example for STM32 HAL osSystickHandler(); // Example for RTOS // Event Recorder time stamping code EventRecorderClockUpdate(); } -
Exclude Event Recorder from Production Builds: Use conditional compilation to exclude the Event Recorder from production builds. This ensures that the
SysTick_Handlerconflict only occurs during debugging and does not affect the final application. -
Modify Event Recorder Configuration: Edit the Event Recorder configuration files to prevent it from defining
SysTick_Handler. This may require modifying theEventRecorderConf.hfile or other source files to remove or conditionally compile the handler definition.
Summary of Solutions
| Issue | Solution | Implementation Details |
|---|---|---|
| RAM Overrun | Calculate total RAM requirement and adjust IRAM2 allocation | Use formula 164 + 16 * Number_of_Records and add buffer for padding and overhead. |
| RAM Overrun | Analyze linker map file to identify memory usage | Examine .bss, .bss.noinit, and .constdata sections for detailed memory layout. |
| RAM Overrun | Optimize record count to reduce RAM usage | Reduce record count and allocate sufficient IRAM2 region to avoid linker errors. |
| SysTick Handler Conflict | Use DWT cycle counter as time stamp source | Configure Event Recorder to use DWT and avoid redefining SysTick_Handler. |
| SysTick Handler Conflict | Integrate Event Recorder time stamping into existing SysTick_Handler |
Merge Event Recorder code with existing handler in stm32f0xx_it.c or RTOS kernel. |
| SysTick Handler Conflict | Exclude Event Recorder from production builds | Use conditional compilation to remove Event Recorder code in production builds. |
By following these steps, developers can effectively resolve the RAM overrun and SysTick_Handler conflicts when using the Event Recorder on STM32F0 microcontrollers. These solutions ensure efficient RAM usage and seamless integration of the Event Recorder into the application.