ARM CoreSight ETR(Embedded Trace Router)是CoreSight调试架构中的关键组件,负责高效路由和缓冲来自多个源的跟踪数据。作为SoC调试基础设施的核心部分,ETR通过内存映射寄存器提供对硬件功能的精细控制。这种设计允许开发人员直接通过处理器地址空间访问和控制ETR,无需专用调试接口。
ETR的主要功能包括:
在典型的调试场景中,ETR位于跟踪源(如处理器核心的ETM)和跟踪接收器(如外部跟踪端口或系统内存)之间,构成完整的数据通路。理解ETR的寄存器编程模型对于构建可靠的调试解决方案至关重要。
内存映射寄存器(Memory-Mapped Registers,MMR)是嵌入式系统中硬件控制的基石。其核心思想是将物理寄存器映射到处理器的地址空间,使软件可以通过标准的内存访问指令(如LDR/STR)来读写这些寄存器。
ETR的寄存器访问具有以下特点:
ETR寄存器按照功能分组分布在不同的偏移地址处。典型布局如下:
| 寄存器组 | 基地址偏移 | 关键寄存器示例 |
|---|---|---|
| 控制寄存器 | 0x000-0x0FF | MODE, FFCR, CTL |
| 状态寄存器 | 0x300-0x3FF | FFSR, STS |
| 数据指针寄存器 | 0x010-0x01F | RRP, RWP, RURP |
| 配置寄存器 | 0xFC0-0xFFF | DEVID, DEVID1, DEVTYPE |
这种布局设计考虑了功能分区和扩展性,相似的寄存器被组织在相邻地址区域,便于软件管理和访问。
DEVID(Device Configuration Register)是ETR的核心配置寄存器,提供设备发现和功能描述信息。其32位字段定义如下:
code复制31 30 29 28 27 25 24 23 17 16 15 14 10 8 7 6 5 4 0
+---------------+---------------+---------------+---------------+---------------+
| IRQ | CACHETYPE | MODES |NOSCAT| AW |V|R| MEMWIDTH |
+---------------+---------------+---------------+---------------+---------------+
| WBUF_DEPTH | MEMWIDTH (cont)| CONFIGTYPE |CLK|ATBINPORTCOUNT|
+---------------+---------------+---------------+---------------+
关键字段说明:
IRQ (bits [31:30]) - 中断控制类型:
MODES (bits [27:25]) - 实现的操作模式:
AW (bits [23:17]) - 地址宽度:
DEVID1寄存器仅包含一个有效位:
DEVTYPE寄存器标识设备类型:
这些寄存器共同构成了ETR的"身份证明",软件在初始化阶段通过读取这些寄存器来确认设备能力和配置参数。
MODE寄存器控制ETR的核心操作行为,其字段布局如下:
code复制31 7 6 5 4 3 2 1 0
+---------------+---------------+---------------+
| Reserved |IRQOnReady|IRQOnFull|Stall|R|MODE|
+---------------+---------------+---------------+
关键功能位:
MODE (bits [1:0]) - 操作模式选择:
IRQOnFull (bit 5) - 缓冲区满中断:
StallOnStop (bit 4) - 停止状态行为:
重要提示:修改MODE寄存器必须在ETR处于Disabled状态(CTL.TraceCaptEn == 0)时进行,否则行为不可预测。
不同模式适用于不同场景:
环形缓冲模式:
c复制MODE &= ~0x3; // 清除模式位
MODE |= 0x0; // 设置为环形缓冲
软件读FIFO模式1:
c复制MODE &= ~0x3;
MODE |= 0x1; // 设置为FIFO模式1
软件读FIFO模式2:
c复制MODE &= ~0x3;
MODE |= 0x3; // 设置为FIFO模式2
BUFWM = FIFO_SIZE - WATERMARK; // 设置水位阈值
FFCR控制ETR的数据格式化行为,主要字段包括:
code复制15 14 13 12 11 10 8 7 6 5 4 3 2 1 0
+---------------+---------------+---------------+---------------+---------------+
|EmbedFlush|R|StopOnTrigEvt|StopOnFl|R|TrigOnFl|R|FlushMan|FOnTrigEvt|FOnFlIn|R|EnFmt|
+---------------+---------------+---------------+---------------+---------------+
关键控制位:
EnFmt (bits [1:0]) - 格式化模式:
FlushMan (bit 6) - 手动刷新控制:
StopOnTrigEvt (bit 13) - 触发事件停止:
FFSR反映格式化器的当前状态:
code复制5 4 3 2 1 0
+---------------+---------------+-------+
|BypassNoPad|FtNotPresent|FtNonStop|TCPresent|FtStopped|FInProg|
+---------------+---------------+-------+
状态位解读:
ETR支持三种中断机制:
中断配置流程示例:
c复制// 配置MSI中断
if (DEVID.IRQ == 0b10) {
IRQCR0.ADDR = MSI_ADDRESS; // 设置MSI地址
IRQCR1.DATA = MSI_DATA; // 设置MSI数据
IRQCR2.MSIEN = 1; // 使能MSI
}
// 使能缓冲区满中断
MODE.IRQOnFull = 1;
状态检查顺序:
c复制void ETR_IRQ_Handler(void) {
if (STS.Full) {
// 处理缓冲区满情况
handle_buffer_full();
}
if (STS.TMCReady) {
// 处理设备就绪情况
handle_device_ready();
}
}
性能优化技巧:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 无法写入寄存器 | 1. ETR处于锁定状态 | 检查LSR.SLK位 |
| 2. 未解锁软件锁 | 向LAR写入0xC5ACCE55 | |
| 中断不触发 | 1. 中断未正确配置 | 检查DEVID.IRQ和MODE寄存器 |
| 2. MSI地址未正确设置 | 验证IRQCR0.ADDR值 | |
| 数据丢失 | 1. 缓冲区溢出 | 增大缓冲区或提高读取频率 |
| 2. StallOnStop未启用 | 设置MODE.StallOnStop=1 |
内存对齐优化:
c复制// 根据DEVID.MEMWIDTH设置对齐
size_t alignment = 1 << (DEVID.MEMWIDTH + 1);
buffer = aligned_alloc(alignment, buffer_size);
批处理操作:
电源管理考量:
c复制// 低功耗场景下的配置
if (low_power_mode) {
MODE.StallOnStop = 1; // 避免数据丢失
FFCR.EnFmt = 0; // 禁用格式化器节省功耗
}
c复制void etr_init(void) {
// 1. 验证设备类型
if (DEVTYPE.SUB != 0x2 || DEVTYPE.MAJOR != 0x1) {
return ERROR_WRONG_DEVICE;
}
// 2. 配置缓冲区
uint32_t memwidth = DEVID.MEMWIDTH;
size_t alignment = 1 << (memwidth + 1);
etr_buffer = aligned_alloc(alignment, ETR_BUFFER_SIZE);
// 3. 设置基地址和大小
DBA = (uintptr_t)etr_buffer;
RSZ = ETR_BUFFER_SIZE / 4; // 转换为32位字数
// 4. 配置中断
if (DEVID.IRQ == 0b10) { // MSI支持
IRQCR0.ADDR = MSI_ADDR;
IRQCR1.DATA = MSI_DATA;
IRQCR2.MSIEN = 1;
}
MODE.IRQOnFull = 1;
// 5. 选择操作模式
MODE.MODE = 0x0; // 环形缓冲模式
FFCR.EnFmt = 0x1; // 普通格式化模式
// 6. 启用跟踪
CTL.TraceCaptEn = 1;
}
c复制void etr_capture(void) {
// 1. 准备阶段
MODE.StallOnStop = 1; // 避免数据丢失
FFCR.FlushMan = 1; // 触发手动刷新
// 2. 等待刷新完成
while (FFSR.FInProg);
// 3. 读取数据
if (MODE.MODE == 0x0) { // 环形缓冲
uint32_t wp = RWP;
uint32_t rp = RRP;
uint32_t size = (wp >= rp) ? (wp - rp) : (ETR_BUFFER_SIZE - rp + wp);
memcpy(capture_buf, (void*)rp, size);
} else { // FIFO模式
// ... FIFO特定读取逻辑
}
// 4. 清理状态
STS.Full = 0; // 清除满状态
}
在嵌入式系统开发中,深入理解ARM CoreSight ETR的寄存器编程模型是构建高效调试系统的关键。通过合理配置DEVID、MODE和FFCR等寄存器,开发人员可以实现精确的跟踪控制,满足从简单的调试到复杂的性能分析等各种需求场景。实际应用中,建议结合具体硬件实现参考手册,并充分利用状态寄存器提供的信息进行错误检测和性能优化。