大多数工程师只知道 DWT 能做微秒级延时,但它真正的 “杀手锏” 是硬件数据监视 / 断点—— 不用修改业务逻辑、不侵入代码,就能实时捕捉指定变量被篡改、指定函数被调用,瞬间触发 DebugMonitor 中断,帮你抓住最难查的 “野指针、踩内存、函数莫名调用” 问题。
ST 官方 LAT1256 应用笔记,把 STM32 DWT 监控内存 / 函数的用法讲得非常直白,看完就能上手,专治各种疑难杂症。
资料获取:【应用笔记】LAT1256 使用STM32的DWT单元监控内存
1. DWT 到底是什么?
DWT(Data Watchpoint and Trace)是 Cortex‑M 内核自带的硬件调试单元,除了计时,还能做:
- 监控数据地址读写(变量被改立刻抓)
- 监控指令地址(函数被调用立刻抓)
- 匹配后触发 DebugMonitor 中断
- 不占定时器、不占中断、完全硬件实现
你可以把它理解为:硬件版的隐形断点 + 内存访问记录仪。
2. 本文实现的两个最强功能(直接可用)
LAT1256 基于 STM32U575 实现了两套实战监控:
- 监控变量 test_var:只要代码修改它 → 立即进中断
- 监控函数 HAL_Delay:只要代码调用它 → 立即进中断
所有动作都能在 DebugMon_Handler 里精准捕捉。
3. DWT 配置只需 4 步(极简)
- 使能 TRACE 调试时钟
- 使能 DebugMonitor 异常
- 配置 DWT_COMPn = 监控地址
- 配置 DWT_FUNCTIONn = 监控模式(读 / 写 / 执行)
核心开启代码:
// 使能追踪 + 调试中断
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk | CoreDebug_DEMCR_MON_EN_Msk;
4. 中断服务函数:一看就知道谁触发了
void DebugMon_Handler(void)
{
if (DWT->FUNCTION0 & DWT_FUNCTION_MATCHED_Msk) {
printf("变量 test_var 被修改!\r\n");
}
if (DWT->FUNCTION1 & DWT_FUNCTION_MATCHED_Msk) {
printf("函数 HAL_Delay 被调用!\r\n");
}
}
触发时会精准打印,谁动了变量、谁调用了函数,一目了然。
5. 典型应用场景(工程师救命神器)
- 变量莫名被改(野指针 / 栈溢出):用 DWT 监视它,一改就断,直接定位凶手。
- 函数不该调用却被执行:监视函数地址,调用即触发,快速定位调用路径。
- 硬件不在线调试、只想 log 记录:用 DebugMon 打印 log,不用暂停程序。
- 查时序异常、调用异常、标志被篡改:比单步调试快 10 倍。
6. LAT1256 重点总结
- DWT 是内核硬件,所有 STM32 基本都支持
- 可同时监控多个变量 / 函数(COMP0~COMP3 等)
- 监控写数据:
Data Address Write - 监控函数执行:
Instruction Address Match - 触发后进入 DebugMon_Handler,不影响正常业务
- 零侵入、不占定时器、不占 DMA、不占 GPIO
DWT 不是只能计时,它是 STM32 最强硬件调试器:变量一改就断、函数一调就抓,专治各种隐形 BUG。
阅读全文
289