El acceso STM32L4 SystemCoreClock bloquea el programa durante la inicialización de HAL

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 objetivo.

Sin embargo, el programa falla durante la inicialización de HAL. Más precisamente, cuando intenta acceder a la SystemCoreClockvariable. 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 reemplazarlo SystemCoreClockpor una constante, pero la variable debe modificarse más adelante de todos modos. SystemCoreClockse declara en system_stm32l4xx.h y se define en system_stm32l4xx.c . Ambos archivos son parte del proyecto.

** la variable externa SystemCoreClockparece tener dos direcciones diferentes.

Cosas normales (ptr1 == &ticknumy *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 != &SystemCoreClocky *ptr2 != SystemCoreClock):

(gdb) p &SystemCoreClock
$6 = (uint32_t *) 0x20000004 <SystemCoreClock>
(gdb) p ptr2
$7 = (uint32_t *) 0x681b4b20
(gdb) p *ptr2
$8 = 0

Cuando digo 'bloqueo', me refiero a 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 tratar de reducir la búsqueda, noté que no se accede 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 paquí apunta fuera de la RAM, que comienza en 0x20000000. Las instrucciones nop se aseguran de que p = &dummyVar;realmente se ejecuten y el depurador no me engañe.

¿Alguna idea?

¿De qué se trata el accidente? puede encontrar información sobre el accidente leyendo el registro SCB. Ver este enlace: Manual de programación . Primero puede mirar el registro SHCSR para ver qué tipo de error detectó la CPU.
La memoria en 0xE000ED24 lee 0x00000000. Consulte la sección 'Editar 2' en la publicación sobre el 'bloqueo'.
¿Es esto un duplicado de la pregunta de stackoverflow?
La memoria en 0xE000ED24 lee 0x00000000. Consulte la sección 'Editar 2' en la publicación sobre el 'bloqueo'.
Noté en el seguimiento que se activó el controlador de interrupciones WWDG (perro de vigilancia de la ventana del sistema). Hay un alias del controlador WWGD IRQ al controlador predeterminado (bucle infinito).
Asegúrese de que su función que maneja el incremento de ticks funcione correctamente. La función predeterminada para esto se llama HAL_IncTick() y la variable que se debe incrementar se llama uwTick. Verifique que su puntero de pila sea correcto (probablemente debería ser 0x2004FFFF). También verifique que sus tablas vectoriales estén configuradas correctamente.
Si está buscando ayuda, puede hacer su pregunta sobre STM32 aquí: st-microelectronics.jiveon.com

Respuestas (1)

QBS / Qt Creator estaba agregando la opción -fPIC ( código independiente de posición ) a la línea de comando gcc en mi espalda. Alguien lo resolvió aquí .