Ich versuche, eine LED auf einem Nucleo-L476 mit CubeMX und HAL von ST zum Blinken zu bringen. Es funktionierte perfekt unter Windows (System Workbench). Jetzt versuche ich, dasselbe unter Linux mit CubeMX und Qt Creator (meiner Lieblings-IDE) und OpenOCD zu tun . Ich bin jetzt in der Lage, das Ziel zu kompilieren und zu debuggen.
Das Programm stürzt jedoch während der HAL-Initialisierung ab. Genauer gesagt, wenn es versucht, auf die Variable zuzugreifen SystemCoreClock
. HAL_Init();
Der folgende Code wird von in aufgerufen 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;
}
Ich könnte SystemCoreClock
durch eine Konstante ersetzen, aber die Variable muss sowieso später geändert werden. ist in system_stm32l4xx.hSystemCoreClock
deklariert und in system_stm32l4xx.c definiert . Beide Dateien sind Teil des Projekts.
** Externe Variable SystemCoreClock
scheint zwei verschiedene Adressen zu haben.
Normales Zeug (ptr1 == &ticknum
und *ptr1 == ticknum)
:
(gdb) p &tickNum
$3 = (uint32_t *) 0x20017fdc
(gdb) p ptr1
$4 = (uint32_t *) 0x20017fdc
(gdb) p *ptr1
$5 = 123
Seltsames Zeug ( ptr2 != &SystemCoreClock
und *ptr2 != SystemCoreClock
):
(gdb) p &SystemCoreClock
$6 = (uint32_t *) 0x20000004 <SystemCoreClock>
(gdb) p ptr2
$7 = (uint32_t *) 0x681b4b20
(gdb) p *ptr2
$8 = 0
Wenn ich „Absturz“ sage, meine ich, dass das Programm in startup_stm32l476xx.s in eine Endlosschleife gerät:
/**
* @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
Beim Versuch, die Suche einzugrenzen, ist mir aufgefallen, dass auf eine außerhalb einer Funktion deklarierte Variable nicht richtig von innerhalb der Funktion zugegriffen wird:
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
}
Die Variable p
hier zeigt außerhalb des RAM, das bei 0x20000000 beginnt. Die nop-Anweisungen stellen sicher, p = &dummyVar;
dass sie wirklich ausgeführt werden und der Debugger mich nicht täuscht.
Irgendeine Idee?
QBS / Qt Creator fügte die Option -fPIC ( positionsunabhängiger Code ) zur gcc-Befehlszeile in meinem Rücken hinzu. Hier hat es jemand gelöst .
MathiasE
dpeng
Oldtimer
dpeng
dpeng
MathiasE
LV28