Estoy tratando de hacer parpadear un LED en un Nucleo-L476 con CubeMX y HAL de ST. Funcionó perfectamente en Windows (System Workbench). Ahora, estoy tratando de hacer lo mismo en Linux con CubeMX y Qt Creator (mi IDE favorito) y OpenOCD . Ahora puedo compilar y depurar el destino.
Sin embargo, el programa se bloquea durante la inicialización de HAL. Más precisamente, cuando intenta acceder a la variable SystemCoreClock
. El siguiente código se llama desde HAL_Init();
en main()
:
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
uint32_t tickNum=123, *ptr1=NULL, *ptr2=NULL; // Added by me to debug
ptr1 = &tickNum; // Added by me to debug
ptr2 = &SystemCoreClock; // Added by me to debug
tickNum = SystemCoreClock; // Added by me to debug *** crash here ***
/* Configure the SysTick to have interrupt in 1 ms time basis */
HAL_SYSTICK_Config(SystemCoreClock/1000); // *** Crash here ***
/* Configure the SysTick IRQ priority */
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0);
/* Return function status */
return HAL_OK;
}
Podría reemplazar SystemCoreClock
por una constante, pero la variable debe modificarse aún más en la línea de todos modos. SystemCoreClock
se declara en system_stm32l4xx.h y se define en system_stm32l4xx.c . Ambos archivos son parte del proyecto.
** la variable externa SystemCoreClock
parece tener dos direcciones diferentes.
Cosas normales (ptr1 == &ticknum
y *ptr1 == ticknum)
:
(gdb) p &tickNum
$3 = (uint32_t *) 0x20017fdc
(gdb) p ptr1
$4 = (uint32_t *) 0x20017fdc
(gdb) p *ptr1
$5 = 123
Cosas extrañas ( ptr2 != &SystemCoreClock
y *ptr2 != SystemCoreClock
):
(gdb) p &SystemCoreClock
$6 = (uint32_t *) 0x20000004 <SystemCoreClock>
(gdb) p ptr2
$7 = (uint32_t *) 0x681b4b20
(gdb) p *ptr2
$8 = 0
Cuando digo 'crash', quiero decir que el programa cae en un bucle infinito en startup_stm32l476xx.s:
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
Al intentar restringir la búsqueda, noté que no se puede acceder correctamente a una variable declarada fuera de una función desde dentro de la función:
uint32_t dummyVar = 123;
void dummyFunc()
{
uint32_t loc = 123;
uint32_t *p = &loc;
p = &dummyVar; // Debugger says &dummyVar = 0x20000004 and p = 0x011a3b01
__asm("nop");
__asm("nop");
__asm("nop");
loc = dummyVar; // *** Crash here
}
La variable p
aquí apunta fuera de la RAM, que comienza en 0x20000000. Las instrucciones nop aseguran que p = &dummyVar;
se ejecute realmente y que el depurador no me engañe.
¿Alguna idea?