Contagem do ciclo do relógio no córtex m7

Tenho medido a contagem do ciclo do relógio no córtex m4 e agora gostaria de fazê-lo no córtex m7. A placa que eu uso é STM32F746ZG.

Para o m4, tudo funcionou com:

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

O problema é que o registro DWT_CTRL não é alterado quando executo o m7 e permanece 0x40000000 em vez de mudar para 0x40000001, portanto a contagem do ciclo é sempre zero. Pelo que li em outros posts, parece que você precisa definir o registro FP_LAR como 0xC5ACCE55 para poder alterar o DWT_CTRL.

Eu adicionei essas definições (tentei os dois endereços FP_LAR_PTR abaixo):

#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

e esta função:

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

Quando chamo a impressão não comentada, recebo 0xC5ACCE55, mas quando a imprimi após o retorno da função, recebo 0x00000000 e não faço ideia do porquê. Estou no caminho certo ou isso está completamente errado?

Edit: Eu acho que também seria bom mencionar que tentei sem todo o código extra na função e só tentei alterar o registro LAR.

BR Gustav

questionAnswers(2)

yourAnswerToTheQuestion