menstruación - Medición del conteo del ciclo del reloj en la corteza m7
duracion del ciclo menstrual (2)
He estado midiendo el recuento del ciclo del reloj en la corteza m4 y ahora quisiera hacerlo en la corteza m7. La placa que uso es STM32F746ZG.
Para el m4 todo funcionó con:
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;
}
El problema es que el registro DWT_CTRL no cambia cuando corro en m7 y permanece 0x40000000 en lugar de cambiar a 0x40000001, por lo que el recuento de ciclos siempre es cero. Por lo que he leído en otras publicaciones, parece que necesita configurar el registro FP_LAR en 0xC5ACCE55 para poder cambiar DWT_CTRL.
Agregué estas definiciones (he intentado ambas direcciones FP_LAR_PTR a continuación):
#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
y esta función:
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);
}
}
}
}
Cuando llamo a la impresión sin comentario obtengo 0xC5ACCE55, pero cuando lo imprimí después del regreso de la función obtengo 0x00000000 y no tengo idea de por qué. ¿Estoy en el camino correcto o está completamente equivocado?
Editar: Creo que también sería bueno mencionar que intenté sin todo el código adicional en la función y solo intenté cambiar el registro LAR.
BR Gustav
Aconsejaría no crear sus propias definiciones de registro cuando se definan como parte del CMSIS; para hacerlo, se requiere que tanto la documentación como su interpretación sean correctas. En este caso, parece que la documentación es incorrecta, pero que los encabezados CMSIS son correctos. Es mucho más fácil validar los encabezados de CMSIS automáticamente que verificar la documentación correcta, por lo que confiaría en el CMSIS en todo momento.
No estoy seguro de a qué registro se puede referir FP_LAR
, pero su asignación de dirección se refiere a ITM_LAR
, pero parece más probable que haya intentado DWT_LAR
que Cortex-M4 no tiene.
A pesar de mi consejo para confiar en él, CMSIS 4.00 omite definir máscaras para DWT_LSR
/ SWT_LAR
, pero creo que son idénticas a las máscaras de ITM correspondientes.
Tenga en cuenta también que el LAR
es un registro de solo escritura, cualquier intento de leerlo no tiene sentido.
Su código usando CMSIS sería:
#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;
}
}
}
}
Mirando los documentos nuevamente, ahora soy increíblemente sospechoso de un error tipográfico o de copiar y pegar en ARM TRM. 0xe0000fb0 se da como la dirección de ITM_LAR, DWT_LAR y FP_LSR (y equivalentemente para * _LSR). Como todos los otros registros de ITM están en la página 0xe0000000, parece mucho que quien fue responsable de esa parte de la documentación de Cortex-M7 tomó las definiciones de registro Cortex-M4, agregó el nuevo LAR y LSR a la página de ITM, luego copió a las páginas DWT y FPB actualizando los nombres pero sin tener en cuenta la actualización de las direcciones.
Apuesto mi cena a que estás desbloqueando ITM_LAR (o el FP_LAR real), y DWT_LAR está realmente en 0xe000 1 fb0.
EDITAR por dwelch
Alguien le debe una cena a alguien.
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));
salida
00000000
00000000
00000000
00000000
00000003
40000000
00000000
00000000
00000003
40000000
00000000
00000000
00000001
40000001
0000774F
0000B311
La tabla en el TRM es divertida y como la otra documentación muestra que agregas 0xFB0 y 0xFB4 a la base, el resto del DWT para el Cortex-M7 es 0xE0001xxx y de hecho parece que el LAR y el LSR son comidos 0xE0001FB0 y 0xE0001FB4 .