我正在使用STM32F7-Discovery板并且一直试图启用DWT循环计数器。从我在网上看到的,这应该足以启用它:
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= 1;
但是,当我运行该代码时,不会更改值或跳过操作(我不太确定发生了什么)。
我已经尝试过指向内存中的地址并直接修改它们,但也无济于事。例如:
volatile uint32_t *DWT_CONTROL = (uint32_t *) 0xE0001000;
volatile uint32_t *DWT_CYCCNT = (uint32_t *) 0xE0001004;
volatile uint32_t *DEMCR = (uint32_t *) 0xE000EDFC;
*DEMCR = *DEMCR | 0x01000000;
*DWT_CYCCNT = 0;
*DWT_CONTROL = *DWT_CONTROL | 1;
目前,我获得的唯一方法是在Visual Studio中使用调试器(使用VisualGDB),如果我将DWT-> CTRL的值更改为ON值,则循环计数器开始。除此之外,我似乎无法在代码中获得改变的价值。
编辑:可能导致这些代码行未执行任务而且不会崩溃并继续执行的行为。
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= 1;
运行这些代码行后,这些内存位置的所有值保持不变,并且不会因应执行的操作而改变。
E.G。 :
//DWT_CTRL_CYCCNTENA_Msk = 1
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk
应该导致DWT-> CTRL的值为0x40000001,但它仍保持默认值0x40000000
下面的图片是运行时期间发生的事情的一个示例。
答案 0 :(得分:7)
可能缺少解锁dbg regs(DWT-> LAR = 0xC5ACCE55): 以下序列为我解决了pb:
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->LAR = 0xC5ACCE55;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
答案 1 :(得分:6)
不确定STM32F7上是否相同,但这是如何使用STM32F4上的CMSIS标头正确执行的(实际上应该在提供此模块的任何Cortex-M3 / 4(/ 7?)上工作):
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
您还必须启用跟踪模块。注意代码不是中断安全的!一般情况下,您应该让计数器自由运行,并将快照的差异用于计时。
确保您的工具链不会干扰您的代码。 OpenOCD / gdb没有,不确定提供手动分析功能的工具如何。
正如我在评论中已经强调的那样:不要对寄存器使用一些自制定义。 ST(和ARM)为标准外设模块(DWT和CoreDebug实际上是ARM IP)提供CMSIS标头,您应该使用它们。这包括不使用幻数,而是使用定义的常量/宏。
更多信息可在“架构参考手册”中找到。 警告:还有一个“架构应用程序级别参考手册”,这不是您想要的。
答案 2 :(得分:3)
你正在做的一切正常,除了你缺少解锁对DWT寄存器的访问权限(霍华德指出)。 在您的代码中,它将类似于:
volatile uint32_t *DWT_CONTROL = (uint32_t *) 0xE0001000;
volatile uint32_t *DWT_CYCCNT = (uint32_t *) 0xE0001004;
volatile uint32_t *DEMCR = (uint32_t *) 0xE000EDFC;
volatile uint32_t *LAR = (uint32_t *) 0xE0001FB0; // <-- added lock access register
*DEMCR = *DEMCR | 0x01000000; // enable trace
*LAR = 0xC5ACCE55; // <-- added unlock access to DWT (ITM, etc.)registers
*DWT_CYCCNT = 0; // clear DWT cycle counter
*DWT_CONTROL = *DWT_CONTROL | 1; // enable DWT cycle counter
请注意,如ARMv7-M架构中所述 参考手册,锁定机制仅适用于软件访问。始终允许DAP访问(这就是使用调试器启用循环计数器的原因)。
请注意,STM32F7 documentation和ARM documentation都有拼写错误,并将0xE0000FB0作为锁定访问寄存器的地址(请参阅here)。 使用提供的CMSIS核心注册表定义(core_cm7.h)可以避免这个问题,因为它们是正确的,当然可以像Olaf所说的那样更高效;)
答案 3 :(得分:-1)
这对我有用:
//address of the register
volatile unsigned int *DWT_CYCCNT = (volatile unsigned int *)0xE0001004;
//address of the register
volatile unsigned int *DWT_CONTROL = (volatile unsigned int *)0xE0001000;
//address of the register
volatile unsigned int *DWT_LAR = (volatile unsigned int *)0xE0001FB0;
//address of the register
volatile unsigned int *SCB_DEMCR = (volatile unsigned int *)0xE000EDFC;
...
*DWT_LAR = 0xC5ACCE55; // unlock (CM7)
*SCB_DEMCR |= 0x01000000;
*DWT_CYCCNT = 0; // reset the counter
*DWT_CONTROL |= 1 ; // enable the counter
...
x = *DWT_CYCCNT;
...正在测试的代码:
y = *DWT_CYCCNT;
x = (y - x); // Elapsed clock ticks, at SystemCoreClock