平台网站开发可行性分析,对学院网站建设的建议,电子商务网站开发方式,做网站赚钱的点在哪里最近在MCU on Eclipse网站上看到Erich Styger所写的一篇有关通过SWD的跟踪接口SWO获取ARM Cortex-M相关信息的文章#xff0c;文章结构明晰#xff0c;讲解透彻#xff0c;本人深受启发#xff0c;特意将其翻译过来供各位同仁参考。当然限于个人水平#xff0c;有不当之处… 最近在MCU on Eclipse网站上看到Erich Styger所写的一篇有关通过SWD的跟踪接口SWO获取ARM Cortex-M相关信息的文章文章结构明晰讲解透彻本人深受启发特意将其翻译过来供各位同仁参考。当然限于个人水平有不当之处恳请指正。原文网址https://mcuoneclipse.com/2016/10/17/tutorial-using-single-wire-output-swo-with-arm-cortex-m-and-eclipse/作为一个标准过程我将一些控制台功能添加到我的嵌入式应用程序中。这样我就有了一个命令行接口可以检查和修改目标系统。ARM Cortex-M的一个有趣的硬件特性是单线输出(SWO) 它允许通过一根线路将数据(例如字符串)发送到32个不同的激励端口。ARM调试器接头上的SWO引脚
调试跟踪输出SWO我使用普通的UART/SCI作为标准的文本和命令行与目标板的接口。然而在许多板上UART被应用程序使用。
有一个Semihosting半托管但是速度非常慢而且取决于调试器和工具链/库加上需要消耗FLASH和RAM所以我不建议在任何情况下使用Semihosting。
【注】Semihosting是针对ARM目标机的一种机制它能够根据应用程序代码的输入/输出请求与运行有调试功能的主机通讯。这种技术允许主机为通常没有输入和输出功能的目标硬件提供主机资源。也有一个USB CDC但这需要一个USB接口一个USB栈和一个具有USB功能的微控制器。不适用于所有情况。还有一个Segger RTT它很小速度快最好的是不需要任何特殊的引脚。但只能工作于Segger的调试探测器。
ARM SWO但还有另一件事ARM SWO跟踪端口是由ARM为Cortexm-M定义的。从技术上讲SWO是一个单一的跟踪引脚它被用来以从CPU核心时钟中提取一个特定的时钟频率发送数据包。您可以将SWO看作是一种使用特殊格式发送数据包的UART TX引脚。可以使用多达32种包类型(或激励)。发送什么样的数据取决于应用程序并且只需要很少的CPU处理或代码。常见SWO用法是按字符串发送调试信息 记录中断的进入与退出 记录函数的进入与退出 周期性的PC值采样 事件提示 变量或内存单元修改超时最常见的用法之一就是第一种使用SWO以UART样式打印来自目标的调试消息。并且这也正是我再这篇文章中将要表达的。还有另一种编码(曼彻斯特编码)这里不做介绍。
ARM CoreSightSWO是ARM CoreSight调试功能块的一部分而ARM CoreSight则通常是Cortex-M3M4M7的一部分CoreSight功能块来自http://www.arm.com/files/pdf/AT_-_Advanced_Debug_of_Cortex-M_Systems.pdf
如上图所示通过SWO(或SWV)ITM和DWT跟踪消息可以发送。对于指令跟踪需要4个额外的跟踪引脚
SWO引脚使用SWO的前提条件是这个引脚可以在调试头中使用。这是我的TWR-K64F120M板的情况trace swo引脚来自TWR-K64F120M原理图如上图所示SWO跟踪引脚是与JTAG TDO引脚共享的。所以这就意味着SWO不能在JTAG中使用而只能在SWD中使用。
所以仔细检查你板子的原理图确定他是否支持SWO。例如FRDM-K64F是TWR-K64F120M上一个版本它的SWO是没有被引到调试头的FRDM-K64F上没有SWO
调试探针与SWO为了能够使用SWO我需要一个能够读取SWO引脚的调试探测器。例如Freescale/NXP OpenSDA在Freedom和Tower模块板载调试接口硬件就不支持SWO。然而外部的Segger J-Link却支持SWO引脚。下面我有一个J-Link EDU连接到TWR-K64F120M板的调试和跟踪端口j-link edu连接到跟踪端口
通过SWO引脚发送调试信息的源码为了通过SWO写调试消息到主机需要一小段代码。在Github上有一个可用的完整代码的例子项目
https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/TWR-K64F120M/TWR-K64F120M_Demo/Sources外部工具(比如Segger RTT查看器)可以在硬件中设置SWO。我的建议是从应用程序初始化它。因为SWO跟踪输出时钟是从CPU时钟派生而来的所以初始化函数需要这个时钟加上SWO端口号来初始化。下面是我用来初始化SWO输出的代码默认为64k波特率
/*!* \brief Initialize the SWO trace port for debug message printing* \param portBits Port bit mask to be configured* \param cpuCoreFreqHz CPU core clock frequency in Hz*/
void SWO_Init(uint32_t portBits, uint32_t cpuCoreFreqHz) {uint32_t SWOSpeed 64000; /* default 64k baud rate */uint32_t SWOPrescaler (cpuCoreFreqHz / SWOSpeed) - 1; /* SWOSpeed in Hz, note that cpuCoreFreqHz is expected to be match the CPU core clock */CoreDebug-DEMCR CoreDebug_DEMCR_TRCENA_Msk; /* enable trace in core debug */*((volatile unsigned *)(ITM_BASE 0x400F0)) 0x00000002; /* Selected PIN Protocol Register: Select which protocol to use for trace output (2: SWO NRZ, 1: SWO Manchester encoding) */*((volatile unsigned *)(ITM_BASE 0x40010)) SWOPrescaler; /* Async Clock Prescaler Register. Scale the baud rate of the asynchronous output */*((volatile unsigned *)(ITM_BASE 0x00FB0)) 0xC5ACCE55; /* ITM Lock Access Register, C5ACCE55 enables more write access to Control Register 0xE00 :: 0xFFC */ITM-TCR ITM_TCR_TraceBusID_Msk | ITM_TCR_SWOENA_Msk | ITM_TCR_SYNCENA_Msk | ITM_TCR_ITMENA_Msk; /* ITM Trace Control Register */ITM-TPR ITM_TPR_PRIVMASK_Msk; /* ITM Trace Privilege Register */ITM-TER portBits; /* ITM Trace Enable Register. Enabled tracing on stimulus ports. One bit per stimulus port. */*((volatile unsigned *)(ITM_BASE 0x01000)) 0x400003FE; /* DWT_CTRL */*((volatile unsigned *)(ITM_BASE 0x40304)) 0x00000100; /* Formatter and Flush Control Register */
}在我的主应用程序中我像这样初始化它(对于一个有24MHz核心时钟的系统)
#define CPU_CORE_FREQUENCY_HZ 120000000 /* CPU core frequency in Hz */SWO_Init(0x1, CPU_CORE_FREQUENCY_HZ);
在SWO_PrintChar()函数中完成打印
/*!* \brief Sends a character over the SWO channel* \param c Character to be sent* \param portNo SWO channel number, value in the range of 0 to 31*/
void SWO_PrintChar(char c, uint8_t portNo) {volatile int timeout;/* Check if Trace Control Register (ITM-TCR at 0xE0000E80) is set */if ((ITM-TCRITM_TCR_ITMENA_Msk) 0) { /* check Trace Control Register if ITM trace is enabled*/return; /* not enabled? */}/* Check if the requested channel stimulus port (ITM-TER at 0xE0000E00) is enabled */if ((ITM-TER (1ulportNo))0) { /* check Trace Enable Register if requested port is enabled */return; /* requested port not enabled? */}timeout 5000; /* arbitrary timeout value */while (ITM-PORT[0].u32 0) {/* Wait until STIMx is ready, then send data */timeout--;if (timeout0) {return; /* not able to send */}}ITM-PORT[0].u16 0x08 | (c8);
}上面的代码使用了一个非常简单的超时机制重要的一点是如果SWO没有启用或者SWO端口没有准备好那么应用程序就会被阻塞。为了更方便地打印字符串我使用以下函数
/*!* \brief Sends a string over SWO to the host* \param s String to send* \param portNumber Port number, 0-31, use 0 for normal debug strings*/
void SWO_PrintString(const char *s, uint8_t portNumber) {while (*s!\0) {SWO_PrintChar(*s, portNumber);}
}要通过SWO发送一个“hello”它就像这样简单
SWO_PrintString(hello world with SWO\r\n, 0);第一个参数是要发送的字符串第二个是SWO跟踪通道号。
GNU ARM Eclipse查看器要接收主机上的SWO跟踪输出GNU ARM Eclipse插件内置了Segger J-Link探测器的SWO支持。SWO仅支持SWD单线调试模式不支持JTAG模式。所以确保SWD被选为调试协议SWD调试在GNU ARM Eclipse调试配置中启用SWO并指定CPU频率和SWO频率请参见http://gnuarmeclipse.github.io/debug/jlink/上的有关频率的文档。我必须提供CPU频率在我的情况下为120 MHz并且可以将SWO频率设置为0以便J-Link自动确定速度。在端口掩码中指定使用的端口作为位掩码因此0x1用于使用端口0SWO的设置这样在目标板上运行应用程序就会在Eclipse控制台视图中显示输出Eclipse控制台视图
Segger SWO ViewerSegger有一个特殊的SWO Viewer命令行和GUI版本。在GUI版本中我指定使用的设备它可以感测跟踪时钟segger gui swo viewer在查看器中我可以打开/关闭端口并查看收到的数据segger j-link swo viewer
Telnet: Putty但是没有需要查看SWO数据的花哨的查看器或Eclipse。Segger默认使用端口2332SEGGER SWO端口我可以配置任何telnet客户端例如PuTTY在端口2332上打开会话putty telnet会话设置我在PuTTY中得到的输出SWO在PuTTY中的输出
综述ARM SWO跟踪引脚允许向主机发送跟踪消息。一个常见的用法是向主机发送调试或其他消息。SWO只需要一个引脚仅适用于SWD而不是JTAG并且在目标上需要很少的代码和资源。不幸的是许多电路板没有将SWO跟踪引脚路由到调试头因此如果您正在进行自己的设计则至少应考虑将SWO路由到调试头。虽然SWO跟踪输出很大但是限于高端Cortex-M我没有在Cortex-M0中找到它它只是输出需要一个支持它的调试探针/接口。至少与Eclipse和GNU ARM Eclipse插件结合Segger J-Link探针SWO输出对我来说非常棒。另一方面Segger RTT的功能更加多样化也非常快。它适用于所有ARM Cortex最重要的是不需要额外的引脚。然而它在目标系统上需要更多的开销和RAM资源。此外它允许发送和接收数据。所以对于串行调试消息打印Segger RTT对我来说听起来更好的解决方案。接下来就是快乐SWO中了!
相关链接SWO on Kinetishttps//community.nxp.com/thread/318058 SWO与GNU ARM Eclipse插件http : //gnuarmeclipse.github.io/debug/jlink/ Segger SWO Viewerhttps : //www.segger.com/j-link-swo-viewer.html GNU ARM Eclipse插件http : //gnuarmeclipse.github.io/debug/ Eclipse RxTx插件用于解析SWO数据http : //forum.segger.com/index.php? pageThreadthreadID1010 ARM CoreSight概述http : //www.arm.com/files/pdf/AT_-_Advanced_Debug_of_Cortex-M_Systems.pdf GitHub上的示例代码https//github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/TWR-K64F120M/TWR-K64F120M_Demo/Sources
欢迎关注