使用SWO打印调试信息

    在使用STM32过程中,刚开始经常使用UART作为调试信息输出的通道,之后看到SEGGER RTT的方式搭配JLINK,直接使用SWD调试口输出调试信息,速度快,效率高但是RTT的方式存在一个问题,产品发布后,为了防止程序被恶意读出,调试口基本会被禁用掉,所以考虑使用SWO的方式作为备选。

    SWO框图如下,涉及到Coretx-M内的ITM、TPIU等

使用SWO打印调试信息

 

     在使用IDE开发时,可直接通过配置IDE使能SWO输出,程序中不需要额外设置,我的开发环境没有使用IDE,需要在程序中显示的使能SWO,

参考https://community.st.com/s/question/0D53W00000IWs2gSAD/how-to-enable-swo-with-stlink-utility-on-stm32f407gdisc1?t=1637668120413

具体程序如下:

void swoInit (uint32_t portMask, uint32_t cpuCoreFreqHz, uint32_t baudrate)
{
uint32_t SWOPrescaler = (cpuCoreFreqHz / baudrate) - 1u ; // baudrate in Hz, note that cpuCoreFreqHz is expected to match the CPU core clock

CoreDebug->DEMCR = CoreDebug_DEMCR_TRCENA_Msk; // Debug Exception and Monitor Control Register (DEMCR): enable trace in core debug
DBGMCU->CR = 0x00000027u ; // DBGMCU_CR : TRACE_IOEN DBG_STANDBY DBG_STOP DBG_SLEEP
TPI->SPPR = 0x00000002u ; // Selected PIN Protocol Register: Select which protocol to use for trace output (2: SWO)
TPI->ACPR = SWOPrescaler ; // Async Clock Prescaler Register: Scale the baud rate of the asynchronous output
ITM->LAR = 0xC5ACCE55u ; // ITM Lock Access Register: C5ACCE55 enables more write access to Control Register 0xE00 :: 0xFFC
ITM->TCR = 0x0001000Du ; // ITM Trace Control Register
ITM->TPR = ITM_TPR_PRIVMASK_Msk ; // ITM Trace Privilege Register: All stimulus ports
ITM->TER = portMask ; // ITM Trace Enable Register: Enabled tracing on stimulus ports. One bit per stimulus port.
DWT->CTRL = 0x400003FEu ; // Data Watchpoint and Trace Register
TPI->FFCR = 0x00000100u ; // Formatter and Flush Control Register

// ITM/SWO works only if enabled from debugger.
// If ITM stimulus 0 is not free, don't try to send data to SWO
if (ITM->PORT [0].u8 == 1)
{
bItmAvailable = 1 ;
}
}

通过实验发现,单纯使用上述程序初始化SWO后,调用ITM_SendChar周期发送字符,使用示波器在SWO引脚上并未测量到任何信号,

使用命令行JLinkSWOViewerCL -swoattach on -swofreq 4000000 -device xxxx -itmport 0xF可以接收到SWO输出的信息,怀疑调试器还是去配置了内部的寄存器

通过逻辑分析仪抓取SWD的信号,发现在上述命令行期间,调试器去遍历调试相关的ROM表,并没有去配置寄存器

所以猜测STM32的debug模块默认是不上电电的,在通过命令行请求其上电之后SWO的信号就可以在引脚上测量到了。

 

上一篇:38. Django 2.1.7 Admin - 注册模型、自定义显示列表字段


下一篇:netty 处理客户端连接