Messung der Anzahl der Taktzyklen im Kortex m7

Ich habe die Anzahl der Taktzyklen am Kortex m4 gemessen und möchte dies jetzt am Kortex m7 tun. Die von mir verwendete Karte ist STM32F746ZG.

Für die M4 hat alles funktioniert mit:

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;
}

Das Problem ist, dass das DWT_CTRL-Register nicht geändert wird, wenn ich auf dem m7 laufe, und 0x40000000 bleibt, anstatt zu 0x40000001 zu wechseln, sodass die Zykluszahl immer Null ist. Nach dem, was ich in anderen Posts gelesen habe, müssen Sie das FP_LAR-Register anscheinend auf 0xC5ACCE55 setzen, um DWT_CTRL ändern zu können.

Ich habe diese Definitionen hinzugefügt (habe beide FP_LAR_PTR-Adressen unten ausprobiert):

#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

und diese Funktion:

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_P,TR);
            }
        }
    }
}

Wenn ich den unkommentierten Ausdruck aufrufe, erhalte ich 0xC5ACCE55, aber wenn ich ihn nach der Rückkehr der Funktion drucke, erhalte ich 0x00000000 und ich habe keine Ahnung warum. Bin ich auf dem richtigen Weg oder ist das völlig falsch?

Edit: Ich denke, es wäre auch gut zu erwähnen, dass ich ohne den ganzen zusätzlichen Code in der Funktion versucht habe und nur versucht habe, das LAR-Register zu ändern.

BR Gustav

Antworten auf die Frage(4)

Ihre Antwort auf die Frage