STM32L4 SystemCoreClock access bloquea el programa durante la inicialización HAL

0

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?

    
pregunta dplamp

1 respuesta

1

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

    
respondido por el dplamp

Lea otras preguntas en las etiquetas