I'm trying to do execution profiling (or the nearest available equivalent) for an STM32F407, using a ULINK PRO and SWD + SWO (I don't have the available GPIO for the full parallel ETM function without chopping up the unit under test).
I have set up Keil uVision 5.40 with the ULINK PRO, and I have all the normal SWD functionality running.
I have set up the debug configurations in the dbgconf and trace.ini files, and configured the target driver for the correct clock rate and data format per the ULINK PRO user guide. I have also freed the SWO pin from other usage.
When I run a debug session, I get a "Trace: Data Overrun" error that I cannot seem to configure my way around.
Note that I am not trying to send printf data through the SWO port, just trying to get whatever level of performance analysis that SWO will support.
Any clues here? What additional information would I get through the SWV function that I cannot already see, and what other steps might I be missing?
Thanks,
Steve Hersey
Here are my trace.ini and debugconf settings:
TRACE.INI:
/*-------------------------------------------------------------------
** Define the function to enable the trace port**-----------------------------------------------------------------*/FUNC void EnableTPIU(void) {
_WDWORD(0xE0042004, 0x00000027); // Set asynchronous communication via DBGMCU_CR}
/*-------------------------------------------------------------------** Invoke the function at debugger startup**-----------------------------------------------------------------*/EnableTPIU();
DEBUGCONF:
// File: STM32F405_415_407_417_427_437_429_439.dbgconf// Version: 1.0.0// Note: refer to STM32F405/415 STM32F407/417 STM32F427/437 STM32F429/439 reference manual (RM0090)// refer to STM32F40x STM32F41x datasheets// refer to STM32F42x STM32F43x datasheets
// <<< Use Configuration Wizard in Context Menu >>>
// <h> Debug MCU configuration register (DBGMCU_CR)// ENABLE TRACESWO// <o.2> DBG_STANDBY <i> Debug Standby Mode// <o.1> DBG_STOP <i> Debug Stop Mode// <o.0> DBG_SLEEP <i> Debug Sleep Mode// </h>DbgMCU_CR = 0x00000027;
// <h> Debug MCU APB1 freeze register (DBGMCU_APB1_FZ)// <i> Reserved bits must be kept at reset value// <o.26> DBG_CAN2_STOP <i> CAN2 stopped when core is halted// <o.25> DBG_CAN1_STOP <i> CAN2 stopped when core is halted// <o.23> DBG_I2C3_SMBUS_TIMEOUT <i> I2C3 SMBUS timeout mode stopped when core is halted// <o.22> DBG_I2C2_SMBUS_TIMEOUT <i> I2C2 SMBUS timeout mode stopped when core is halted// <o.21> DBG_I2C1_SMBUS_TIMEOUT <i> I2C1 SMBUS timeout mode stopped when core is halted// <o.12> DBG_IWDG_STOP <i> Independent watchdog stopped when core is halted// <o.11> DBG_WWDG_STOP <i> Window watchdog stopped when core is halted// <o.10> DBG_RTC_STOP <i> RTC stopped when core is halted// <o.8> DBG_TIM14_STOP <i> TIM14 counter stopped when core is halted// <o.7> DBG_TIM13_STOP <i> TIM13 counter stopped when core is halted// <o.6> DBG_TIM12_STOP <i> TIM12 counter stopped when core is halted// <o.5> DBG_TIM7_STOP <i> TIM7 counter stopped when core is halted// <o.4> DBG_TIM6_STOP <i> TIM6 counter stopped when core is halted// <o.3> DBG_TIM5_STOP <i> TIM5 counter stopped when core is halted// <o.2> DBG_TIM4_STOP <i> TIM4 counter stopped when core is halted// <o.1> DBG_TIM3_STOP <i> TIM3 counter stopped when core is halted// <o.0> DBG_TIM2_STOP <i> TIM2 counter stopped when core is halted// </h>DbgMCU_APB1_Fz = 0x00000000;
// <h> Debug MCU APB2 freeze register (DBGMCU_APB2_FZ)// <i> Reserved bits must be kept at reset value// <o.18> DBG_TIM11_STOP <i> TIM11 counter stopped when core is halted// <o.17> DBG_TIM10_STOP <i> TIM10 counter stopped when core is halted// <o.16> DBG_TIM9_STOP <i> TIM9 counter stopped when core is halted// <o.1> DBG_TIM8_STOP <i> TIM8 counter stopped when core is halted// <o.0> DBG_TIM1_STOP <i> TIM1 counter stopped when core is halted// </h>DbgMCU_APB2_Fz = 0x00000000;
// <<< end of configuration section >>>
Update: I have managed to clear the trace overrun error by unchecking ALL the ITM stimulus ports; now the trace status is "data streaming." Of course, I still have no idea what data I can get from it.
I have not yet tried it on an F4 (it's on my ToDo list), but I captured this image from some old F1 projects I did. This allowed me to send data to the PC using ITM_SendChar(). There are some tutorials online for using this for plotting graphs and such. Anyway, this may at least get you going with moving data to and fro. I don't know why you are not getting more help with this because it certainly must be a well traveled path...
Possibly helpful link:
Retargeting printf: use Serial Wire Output (SWO) with printf
https://blog.embeddedexpert.io/?p=800
Thanks for the suggestions.
The printf() redirection certainly sounds useful, but what I'm really hoping to do is to benchmark the time spent in each RTOS task so I know where all that CPU time is going. (Our printf redirection solution was to add a Telnet shell and print to the Telnet console; this is useful for mostly higher-level diagnostics, but that seems to be good enough).
I get some lovely charts from the task view pane showing when various DMA and peripherals are active, as well as SysTick interrupts, and I can see stack usage stats for my tasks when I pause execution (this has already proven VERY useful), but the hoped-for time in each task remains elusive. I may actually have to do some surgery on my controller board to free the parallel ETM lines to get that.
Steve Hersey said:I have set up the debug configurations in the dbgconf and trace.ini files, and configured the target driver for the correct clock rate and data format per the ULINK PRO user guide.
The trace.ini files were necessary at a time when we did not have 'debug description' information in the Device Family PACK. This is not needed anymore when you enable the 'Enable' checkbox in the dialog 'Options for Target - Debug - ULINKpro Cortex Debugger - Settings - Pack'. With the *.dbgconf file in the same dialog, you can make further adjustments, what you previously did in the trace.ini file.
Steve Hersey said:When I run a debug session, I get a "Trace: Data Overrun" error that I cannot seem to configure my way around.
Steve Hersey said:Update: I have managed to clear the trace overrun error by unchecking ALL the ITM stimulus ports; now the trace status is "data streaming."
You can overload the SWO trace easily, although you're already using a 144 MHz SWO clock. When disabling all the ITM Stimulus Ports helped, your application must have sent out lots of data via ITM trace. You could route the printf data through channel 0 if you like, but you could also do that via Event Recorder (see below).
You should enable the 'Exception Tracing' Trace Events to see all the interrupts.
Steve Hersey said:Note that I am not trying to send printf data through the SWO port, just trying to get whatever level of performance analysis that SWO will support.
You can't get any performance analysis data via SWO trace (ETM trace would be ideal here).
If you want to see which thread is executed at which time, you should use the Event Recorder. Please see:
https://developer.arm.com/documentation/101451/0100/-Vision-Windows/System-Analyzer
https://developer.arm.com/documentation/101407/0542/Debugging/Debug-Windows-and-Dialogs/Event-Recorder
The Event Recorder is not based on any trace information, but it shows you all task switches and you could even route the printf output through it. The Event Recorder and its configuration is fully implemented in RTX5.
Thank you for the reply; this looks like it may be very useful. Of course, now I'll have to upgrade my application from RTX 4.73 to RTX 5, but if this stuff were easy, everyone would be doing it, right? (And RTX 5 does have wrappers for the old API, so I might just get lucky...)
Regards,
Steve