测量皮质m7上的时钟周期计数

我一直在测量皮层m4上的时钟周期计数,现在想在皮层m7上进行测量。 我使用的主板是STM32F746ZG。

对于m4,一切顺利:

volatile unsigned int *DWT_CYCCNT; volatile unsigned int *DWT_CONTROL; volatile unsigned int *SCB_DEMCR; void reset_cnt(){ DWT_CYCCNT = (volatile unsigned int *)0xE0001004; //address of the register DWT_CONTROL = (volatile unsigned int *)0xE0001000; //address of the register SCB_DEMCR = (volatile unsigned int *)0xE000EDFC; //address of the register *SCB_DEMCR = *SCB_DEMCR | 0x01000000; *DWT_CYCCNT = 0; // reset the counter *DWT_CONTROL = 0; } void start_cnt(){ *DWT_CONTROL = *DWT_CONTROL | 0x00000001 ; // enable the counter } void stop_cnt(){ *DWT_CONTROL = *DWT_CONTROL & 0xFFFFFFFE ; // disable the counter } unsigned int getCycles(){ return *DWT_CYCCNT; } 

问题是当我在m7上运行时DWT_CTRL寄存器没有改变,并且仍然是0x40000000而不是改为0x40000001,因此循环计数始终为零。 根据我在其他post中看到的内容,您似乎需要将FP_LAR寄存器设置为0xC5ACCE55才能更改DWT_CTRL。

我添加了这些定义(已尝试下面的两个FP_LAR_PTR地址):

 #define FP_LAR_PTR ((volatile unsigned int *) 0xe0000fb0) //according to reference //#define FP_LAR_PTR ((volatile unsigned int *) 0xe0002fb0) //according to guy on the internet // Lock Status Register lock status bit #define DWT_LSR_SLK_Pos 1 #define DWT_LSR_SLK_Msk (1UL << DWT_LSR_SLK_Pos) // Lock Status Register lock availability bit #define DWT_LSR_SLI_Pos 0 #define DWT_LSR_SLI_Msk (1UL << DWT_LSR_SLI_Pos) // Lock Access key, common for all #define DWT_LAR_KEY 0xC5ACCE55 

而这个function:

 void dwt_access_enable(unsigned int ena){ volatile unsigned int *LSR; LSR = (volatile unsigned int *) 0xe0000fb4; uint32_t lsr = *LSR;; //printf("LSR: %.8X - SLI MASK: %.8X\n", lsr, DWT_LSR_SLI_Msk); if ((lsr & DWT_LSR_SLI_Msk) != 0) { if (ena) { //printf("LSR: %.8X - SLKMASK: %.8X\n", lsr, DWT_LSR_SLK_Msk); if ((lsr & DWT_LSR_SLK_Msk) != 0) { //locked: access need unlock *FP_LAR_PTR = DWT_LAR_KEY; printf("FP_LAR directly after change: 0x%.8X\n", *FP_LAR_PTR); } } else { if ((lsr & DWT_LSR_SLK_Msk) == 0) { //unlocked *FP_LAR_PTR = 0; //printf("FP_LAR directly after change: 0x%.8X\n", *FP_LAR_PTR); } } } } 

当我调用未注释的打印时,我得到0xC5ACCE55,但是当我在函数返回后打印它时,我得到0x00000000,我不知道为什么。 我是在正确的轨道上还是完全错了?

编辑:我认为,如果没有函数中的所有额外代码并且只尝试更改LAR寄存器,我也很高兴。

BR古斯塔夫

再看一下这些文档,我现在非常怀疑ARM TRM中的拼写错误或复制粘贴错误。 0xe0000fb0作为ITM_LAR,DWT_LAR FP_LSR的地址给出(等效于* _LSR)。 由于所有其他ITM寄存器位于页面0xe0000000中,因此看起来非常像负责Cortex-M7文档的那部分采用Cortex-M4寄存器定义,将新的LAR和LSR添加到ITM页面,然后复制他们到DWT和FPB页面更新名称,但忽略更新地址。

我打赌我的晚餐你无意中解锁了ITM_LAR(或真正的FP_LAR),DWT_LAR实际上是0xe000 1 fb0。

由dwelch编辑

有人欠某人晚餐。

 hexstring(GET32(0xE0001FB4)); hexstring(GET32(0xE0001000)); hexstring(GET32(0xE0001004)); hexstring(GET32(0xE0001004)); PUT32(0xE000EDFC,0x01000000); hexstring(GET32(0xE0001FB4)); hexstring(GET32(0xE0001000)); hexstring(GET32(0xE0001004)); hexstring(GET32(0xE0001004)); PUT32(0xE0001000,0x40000001); hexstring(GET32(0xE0001FB4)); hexstring(GET32(0xE0001000)); hexstring(GET32(0xE0001004)); hexstring(GET32(0xE0001004)); PUT32(0xE0001FB0,0xC5ACCE55); PUT32(0xE0001000,0x40000001); hexstring(GET32(0xE0001FB4)); hexstring(GET32(0xE0001000)); hexstring(GET32(0xE0001004)); hexstring(GET32(0xE0001004)); 

产量

 00000000 00000000 00000000 00000000 00000003 40000000 00000000 00000000 00000003 40000000 00000000 00000000 00000001 40000001 0000774F 0000B311 

TRM中的表看起来很滑稽,而其他文档显示你将0xFB0和0xFB4添加到基数,Cortex-M7的其余DWT是0xE0001xxx,实际上看起来LAR和LSR是吃0xE0001FB0和0xE0001FB4 。

我建议不要在将它们定义为CMSIS的一部分时创建自己的寄存器定义 – 这样做要求文档和对它的解释都是正确的。 在这种情况下,文档似乎确实不正确,但CMSIS标题是正确的。 自动validationCMSIS标头比validation文档是否正确要容易得多,所以我每次都信任CMSIS。

我不确定FP_LAR可能引用的是什么寄存器,但是您的地址分配是指ITM_LAR ,但您似乎更倾向于使用Cortex-M4缺少的DWT_LAR

尽管我建议相信它,CMSIS 4.00省略了为DWT_LSR / SWT_LAR定义掩码,但我相信它们与相应的ITM掩码相同。

另请注意, LAR是一个只写寄存器 – 任何读取它的尝试都是没有意义的。

您使用CMSIS的代码将是:

 #include "core_cm7.h" // Applies to all Cortex-M7 void reset_cnt() { CoreDebug->DEMCR |= 0x01000000; DWT->CYCCNT = 0; // reset the counter DWT->CTRL = 0; } void start_cnt() { DWT->CTRL |= 0x00000001 ; // enable the counter } void stop_cnt() { DWT->CTRL &= 0xFFFFFFFE ; // disable the counter } unsigned int getCycles() { return DWT->CYCCNT ; } // Not defined in CMSIS 4.00 headers - check if defined // to allow for possible correction in later versions #if !defined DWT_LSR_Present_Msk #define DWT_LSR_Present_Msk ITM_LSR_Present_Msk ; #endif #if !defined DWT_LSR_Access_Msk #define DWT_LSR_Access_Msk ITM_LSR_Access_Msk ; #endif #define DWT_LAR_KEY 0xC5ACCE55 void dwt_access_enable( unsigned ena ) { uint32_t lsr = DWT->LSR;; if( (lsr & DWT_LSR_Present_Msk) != 0 ) { if( ena ) { if ((lsr & DWT_LSR_Access_Msk) != 0) //locked: access need unlock { DWT->LAR = DWT_LAR_KEY; } } else { if ((lsr & DWT_LSR_Access_Msk) == 0) //unlocked { DWT->LAR = 0; } } } }