Comptage du cycle d’horloge sur cortex m7

J’ai mesuré le nombre de cycles d’horloge sur le cortex m4 et voudrais maintenant le faire sur le cortex m7. Le conseil que j’utilise est STM32F746ZG.

Pour la m4, tout a fonctionné avec:

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

Le problème est que le registre DWT_CTRL n’est pas modifié lorsque j’exécute sur le m7 et rest 0x40000000 au lieu d’être remplacé par 0x40000001, de sorte que le nombre de cycles est toujours égal à zéro. D’après ce que j’ai lu dans d’autres articles, il semble que vous deviez définir le registre FP_LAR sur 0xC5ACCE55 pour pouvoir modifier DWT_CTRL.

J’ai ajouté ces définitions (j’ai essayé les deux adresses FP_LAR_PTR ci-dessous):

 #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 

et cette fonction:

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

Je reçois 0xC5ACCE55 lorsque j’appelle l’impression non commentée, mais lorsque je l’ai imprimée après le retour de la fonction, j’obtiens 0x00000000 et je ne sais pas pourquoi. Suis-je sur la bonne voie ou est-ce complètement faux?

Edit: Je pense qu’il serait également bon de mentionner que j’ai essayé sans tout le code supplémentaire dans la fonction et n’ai essayé que de changer le registre LAR.

BR Gustav

En regardant à nouveau la documentation, je suis maintenant extrêmement méfiant vis-à-vis d’une erreur de frappe ou de copier-coller dans le TRM ARM. 0xe0000fb0 est donné comme adresse de ITM_LAR, DWT_LAR et FP_LSR (et de manière équivalente pour * _LSR). Etant donné que tous les autres registres ITM sont dans la page 0xe0000000, cela ressemble beaucoup à celui qui était responsable de cette partie de la documentation Cortex-M7 a pris les définitions de registres Cortex-M4, ajouté les nouveaux LAR et LSR à la page ITM, puis copié les sur les pages DWT et FPB mettant à jour les noms mais oubliant de mettre à jour les adresses.

Je parierais que je débloque involontairement ITM_LAR (ou le vrai FP_LAR), et que DWT_LAR est à 0xe000 1 fb0.

EDIT par dwelch

Quelqu’un doit un dîner à quelqu’un.

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

sortie

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

La table dans le TRM est amusante et comme l’autre documentation indique que vous ajoutez 0xFB0 et 0xFB4 à la base, le rest de la DWT pour le Cortex-M7 est 0xE0001xxx et en effet, il apparaît que le LAR et le LSR sont consommés 0xE0001FB0 et 0xE0001FB4. .

Je vous déconseille de créer vos propres définitions de registre lorsqu’elles sont définies dans le cadre du système CMSIS – pour cela, vous devez disposer de la documentation et de son interprétation correctes. Dans ce cas, il semble que la documentation soit effectivement incorrecte, mais que les en-têtes de CMSIS sont corrects. Il est beaucoup plus facile de valider automatiquement les en-têtes de CMSIS que de vérifier que la documentation est correcte. Je me fie donc à chaque fois à CMSIS.

Je ne suis pas sûr de savoir à quoi le registre FP_LAR pourrait faire référence, mais votre affectation d’adresse fait référence à ITM_LAR , mais il semble plus probable que vous ayez voulu DWT_LAR dont Cortex-M4 manque.

En dépit de mon conseil de lui faire confiance, CMSIS 4.00 omet de définir des masques pour DWT_LSR / SWT_LAR , mais je pense qu’ils sont identiques aux masques ITM correspondants.

Notez également que le LAR est un registre en écriture seule – toute tentative de lecture est dénuée de sens.

Votre code utilisant CMSIS serait:

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