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

G. *_*son 8 c embedded arm stm32f7

我一直在测量皮质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;
}
Run Code Online (Sandbox Code Playgroud)

问题是当我在m7上运行时DWT_CTRL寄存器没有改变,并且仍然是0x40000000而不是改为0x40000001,因此循环计数始终为零.从我在其他帖子中读到的内容看来,您需要将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
Run Code Online (Sandbox Code Playgroud)

而这个功能:

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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:我认为,如果没有函数中的所有额外代码并尝试更改LAR寄存器,我也会尝试一下.

BR古斯塔夫

Not*_*hat 6

再次查看文档,我现在非常怀疑 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));
Run Code Online (Sandbox Code Playgroud)

输出

00000000
00000000
00000000
00000000
00000003
40000000
00000000
00000000
00000003
40000000
00000000
00000000
00000001
40000001
0000774F
0000B311
Run Code Online (Sandbox Code Playgroud)

TRM 中的表格看起来很有趣,正如其他文档所示,您将 0xFB0 和 0xFB4 添加到基础中,Cortex-M7 的 DWT 的其余部分是 0xE0001xxx,实际上,LAR 和 LSR 似乎吃了 0xE0001FB0 和 0xE0001FB4 。