Ken*_*eso 10 c embedded arm stm32f7
我正在使用STM32F7-Discovery板,并且一直试图启用DWT循环计数器.从我在网上看到的,这应该足以启用它:
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= 1;
Run Code Online (Sandbox Code Playgroud)
但是,当我运行该代码时,不会更改值或跳过操作(我不太确定发生了什么).
我已经尝试过指向内存中的地址并直接修改它们,但也无济于事.例如:
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;
Run Code Online (Sandbox Code Playgroud)
目前,我获得的唯一方法是在Visual Studio中使用调试器(使用VisualGDB)时,如果我将DWT-> CTRL的值更改为ON值,则循环计数器开始.除此之外,我似乎无法获得改变代码的价值.
编辑:可能导致这些代码行没有执行任务但也没有崩溃和继续的行为.
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= 1;
Run Code Online (Sandbox Code Playgroud)
在运行这些代码行之后,这些内存位置的所有值都保持不变,并且不会随着应该执行的操作而改变.
EG:
//DWT_CTRL_CYCCNTENA_Msk = 1
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk
Run Code Online (Sandbox Code Playgroud)
应该导致DWT-> CTRL的值为0x40000001,但它保持默认值0x40000000
下面的图片是运行时期间发生的事情的示例.
小智 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;
Run Code Online (Sandbox Code Playgroud)
不知道在STM32F7上是否相同,但这是如何使用STM32F4上的CMSIS标头正确地做到这一点(实际上应在提供此模块的任何Cortex-M3 / 4(/ 7?)上工作):
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
Run Code Online (Sandbox Code Playgroud)
您还必须启用跟踪模块。注意代码不是中断安全的!通常,您应该让计数器自由运行,并拍摄快照快照以进行计时。
只要确保您的工具链不使用会干扰您的代码。OpenOCD / gdb不需要,也不知道提供手动配置功能的工具如何。
正如我在评论中已经强调的那样:不要对寄存器使用一些自制的定义。ST(和ARM)为您应使用的标准外围模块(DWT和CoreDebug实际上是ARM IP)提供了CMSIS标头。这包括不使用幻数,而是定义的常量/宏。
有关更多信息,请参见“体系结构参考手册”。警告:还有“架构应用程序级别参考手册”,这不是您想要的。
小智 5
您所做的一切都是正确的,除了您缺少解锁对 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
Run Code Online (Sandbox Code Playgroud)
需要注意的是,正如ARMv7-M架构参考手册中所述,锁定机制仅适用于软件访问。始终允许 DAP 访问(这就是您可以使用调试器启用周期计数器的原因)。
请注意,STM32F7 文档和ARM 文档都有一个拼写错误,并将 0xE0000FB0 作为锁定访问寄存器的地址(请参阅此处)。使用提供的 CMSIS 核心寄存器定义(core_cm7.h)可以避免这个问题,因为它们是正确的,当然,正如 Olaf 所说的那样,效率会更高;)