目录
序言
在实际项目中,如果没有提供串口等硬件资源又不想单步调试时,我们怎么调试程序?这时,多数人都会想到使用printf函数,幸好MDK提供了这样一个功能Debug printf Viewer,这就非常的nice!有些同学就会问:MDK是如何实现硬件打印的呢?这就是本篇文章的重点,MDK通过Cortex-M3的调试组件,实现了这样一个功能,具体操作实现参考以下链接https://blog.csdn.net/weixin_41080308/article/details/109637470。废话不多说,那就开启抄袭之路吧。
简介
在CM3内核中,有好多调试组件。使用它们可以执行各种调试功能,包括断点、数据观察点、闪存地址重载以及各种跟踪。这就非常的方便软件开发人员观察数据以及查找bug。在这些所有的调试组件及跟踪组件,以及FPB,都可以经由CM3的私有外设总线来编程。
Cortex-M3的跟踪系统
CM3的跟踪系统基于CoreSight架构的,跟踪数据被打包成数据包,它们的长度可变。跟踪组件使用高级跟踪总线ATB来发送这些数据包给TPIU,TPIU则把它们格式化,转换成符和“跟踪总线接口协议”的数据包。格式化的数据包发到片外,可以使用跟踪端口分析仪(TPA)之类的设备捕获它们。这个数据流动的路线如下图所示:
从上图可见,在CM3中可以有3种跟踪源:ETM、ITM和DWT。其中,ETM是一个可选的组件,这里不做详解。在操作中,每个跟踪源都被赋予一个7为的ID号(ATID),跟随它所发出的数据包一起送出。在归并数据流中还原各原始的数据流时,就可以使用ATID作为识别的手段。在使用跟踪系统之前,必须把DEMCR.TRCENA置位(具体控制寄存器如下表)。
跟踪系统:数据观察点与跟踪(DWT)
DWT提供的调试功能包括:
- 包含4个比较器,在配置成发生比较匹配时,只要是产生硬件观察点,通过ETM触发发出一个数据并汇入跟踪数据流中
- 作为计数器,对以下项目进行计数:
- 时钟周期
- 被折叠指令
- 对加载/存储单元(LSU)的操作
- 睡眠的时钟周期
- 每指令周期数
- 中断的额外开销
- 固定周期采样PC的值
- 中断事件跟踪
具体详细了解可以去查看CM3权威指南
跟踪组件:指令跟踪宏单元(ITM)
ITM有如下功能:
- 软件可以直接把控制台消息写到ITM stimulus端口,从而把它们输出成跟踪数据。
- DWT可以产生跟踪数据包,并通过ITM把它们输出。
- ITM可以产生时间戳数据包并插入到跟踪数据流中,用于帮助调试器求出各事件的发生事件。
ITM使用条件
如果使用ITM功能跟踪数据,必须有TPIU单元,否则无法使用这是一个必要条件。同时,必须把DEMCR.TRCENA位置位,否则ITM处于失能状态,无法使用。另外,在ITM寄存器中还有一个锁。在编程ITM之前,必须写入一个访问钥匙值0xC5AC_CE55进行解锁操作。否则,所有对ITM寄存器的写操作都被忽略。
ITM的软件跟踪
基于ITM软件跟踪具体有哪些软件,比如MDK、IAR等。回归正题继续讲解ITM用途,其主要用途就是支持调试消息的输出(例如,prinf格式输出)ITM包含了32个刺激(stimulus)端口,可以把数据流输出到不同的端口,可以非常方便的让调试主机读取数据流输出信息。与USRT不同的是,使用TIM输出不会对应用程序造成很大的延迟,这就非常方便在高频触发中非常有用。
ITM硬件跟踪
与DWT相比,ITM也能输出硬件跟踪数据,这些数据由DWT产生(不理解看CM3跟踪系统图),ITM则担任跟踪数据包的归并单元,如下图所示。欲使用DWT跟踪,需要在ITM寄存器中置位DWTEN位,其余操作设置由DWT完成。
ITM时间戳
ITM还附带有一个时间戳的功能:当新的跟踪数据包进入ITM的FIFO时,TIM会把一个差分时间数据包插入到跟踪数据流中。这样方便跟踪捕获设备捕获跟踪数据之间的的时间相关信息。
跟踪组件:嵌入式跟踪宏单元
ETM功能块用于提供指令跟踪(即指令执行的历史记录),不一定出现在所有的CM3产品中。ETM为了减少产生数据量,ETM并不会一直精确地输出处理当前正在执行的地址。具体地使用过程:
- 把DEMCE.TECENA位置位
- 解锁ETM,往ETMLOCK_ACCESS寄存器中写入0xC5AC_CE55
- 编程ATBID寄存器,赋予ETM唯一标识
- ETM的NIDEN输入信号必须为高电平
- 编程ETM控制寄存器组以产生数据
跟踪组件:跟踪端口接口单元(TPIU)
从CM3跟踪系统框图可知,ITM、DWT和ETM的跟踪数据都汇聚在TPIU处。TPIU的作用是把跟踪数据格式化并输出到片外,提供跟踪端口分析仪之类的设备接收使用。
TPIU输出模式
- 带时钟模式,使用最多4位并行数据输出端口。在该模式下,数据输出端口位数可编程。
- 串行线观察器模式,使用单一位的SWV输出。通过使用SWV协议,它可以减少所需的输出信号数,但是跟踪输出的最大的带宽也减少。
欲使用该模块的功能,需要先把DECMT.TRCENA置位,还要编程"协议选择寄存器"和“跟踪端口尺寸寄存器”,才能实现TPIU的功能。
总结
关于CM3内核调试组件就讲解到这里,希望大家通过本篇文章对读者有用。