Forum: Mikrocontroller und Digitale Elektronik STM32 HAL Interrupt Callbacks in main.c implementieren?


von Verwirrt (Gast)


Lesenswert?

Moin,

der STM32 HAL stellt "Dummys" für Interrupt-Callbacks in Form von 
Funktionen mit __weak-Symbol in den perepheriespezifischen .c-Files 
bereit.

Das ganz sieht dann zum Beispiel wie folgt aus:
1
__weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
2
{
3
  /* Prevent unused argument(s) compilation warning */
4
  UNUSED(hcan);
5
  /* NOTE : This function Should not be modified, when the callback is needed,
6
            the HAL_CAN_RxCpltCallback can be implemented in the user file
7
   */
8
}

Meine Frage lautet nun: wie sieht die Implementierung von void 
HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan) in z.B. main.c 
korrekterweise aus?

In meinem Fall erkennt der Linker nicht, dass in main.c eine 
gleichnamige Funktion ohne __weak-Symbol vorhanden ist und diese die 
HAL-Funktion "überschreiben" sollte. Was mache ich falsch?

von C. W. (chefkoch)


Lesenswert?

Etwas mehr Input wäre nicht schlecht - zeig mal main.c komplett und die 
Fehlermeldung. Eigentlich geht das

von Stefan (Gast)


Lesenswert?

Can handler deklariert?

wird die weak aufgerufen?

Werden die Daten übertragen?

von Verwirrt (Gast)


Angehängte Dateien:

Lesenswert?

Hier ist die komplette main.c

Der Interrupt wird korrekterweise aufgerufen, wenn ich ein Signal auf 
den CAN-Bus gebe.

Eine Fehlermeldung gibt es nicht. Das Programm springt in den 
__weak-"Dummy" (sehe ich beim Debuggen mit einem Breakpoint, den ich 
dort platziert habe).


Als IDE nehme ich emBitz. Compiler ist der GCC.

von pegel (Gast)


Lesenswert?

Wo kommt der Unterstrich an Ende der Funktion her?
Selbst umdefiniert?

von Verwirrt (Gast)


Lesenswert?

Ja, mein Fehler. Das war ein schneller Test um zu sehen was passiert, 
wenn ich einen abweichenden Namen in main.c und der IRQ-Funktion 
benutze. Aber dann gibt es logischerweise einen Fehler, weil die 
HAL-generierte C-Datei kein include auf main hat und die Funktion so 
nicht finden kann.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Verwirrt schrieb:
> Aber dann gibt es logischerweise einen Fehler, weil die
> HAL-generierte C-Datei kein include auf main hat und die Funktion so
> nicht finden kann.

Was sollte es für einen Fehler geben? Der Linker findet das weak Symbol 
und verwendet dieses, es sei den der Linker findet ein Symbol mit dem 
selben Namen. Der Linker sollte ein Symbol mit dem selben Namen finden, 
wenn Du eine Funktion mit dem selben Namen definierst und gegen das 
Objekt-File, in dem das Sybol steckt linkst.

Kann es sein, dass Du einen C++ Compiler verwendest? Dann müsstest Du 
dem Compiler sagen, dass er das C ABI verwenden soll:
1
extern "C" void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
2
{
3
}

mfg Torsten

von pegel (Gast)


Lesenswert?

Im Beispiel CAN_Networking für den F1 in der HAL Lib gibt es noch ein

HAL_NVIC_EnableIRQ(CANx_RX_IRQn);

Hast du das auch?

von C. W. (chefkoch)


Lesenswert?

Wenn der _weak-Dummy angesprungen wird ist bei NVIC wohl alles bestens. 
Ich habe es auf die Schnelle mal auf einem Discovery mit einem Timer 
probiert und es geht einwandfrei:

/* USER CODE BEGIN 4 */
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef * htim)
{
  HAL_GPIO_TogglePin(LD4_GPIO_Port, LD4_Pin);
}
/* USER CODE END 4 */

Ist auch MX-generiert - nichts anderes als beim TO, nur anderer Callback 
für anderen Interrupt

von Jim M. (turboj)


Lesenswert?

Verwirrt schrieb:
> In meinem Fall erkennt der Linker nicht, dass in main.c eine
> gleichnamige Funktion ohne __weak-Symbol vorhanden ist und diese die
> HAL-Funktion "überschreiben" sollte. Was mache ich falsch?

Eventuell ist Dein GCC zu neu bzw. Dein binutils zu alt:

https://sourceware.org/bugzilla/show_bug.cgi?id=22502

Diese GCC/Binutils Kobination liegt z.B. im "GNU Tools for Arm Embedded 
Processors 7-2017-q4-major" mit drin.

von Bernd K. (prof7bit)


Lesenswert?

> Eventuell ist Dein GCC zu neu bzw. Dein binutils zu alt:
> https://sourceware.org/bugzilla/show_bug.cgi?id=22502

Ich hatte das neulich auch, aber es kam nur zum Tragen wenn die 
WEAK-Funktion aus einer Assemblerdatei kam. Also in meinem Falle die 
weak handler im Startup code wurden nicht mehr von den strong 
Implementationen im C-Code überschrieben.

Bei reinen C-Projekten konnt ich das aus irgendeinem Grund nicht 
reproduzieren.

Spontane Abhilfe war die Reihenfolge zu ändern in der sie beim 
Linkeraufruf an der Kommandozeile genannt werden, die Dateien mit 
weak-Symbolen musste ich weiter links stehen haben als die welche die 
starken Symbole enthalten, dann funktionierte es wieder.

Falls das nicht geht weil einem die IDE keine Kontrolle über den Build 
erlaubt: LTO deaktivieren oder älteren gcc installieren.

Beitrag "Re: arm gcc 7.2.1 -flto broken?"

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.