STM32 HAL_GetTick() in Interrupt nutzen / nested Interrupts?

1 Antwort

Vom Fragesteller als hilfreich ausgezeichnet

Die Funktion "HAL_getTick" sollte nur einen Integer-Wert mit einer Anzahl Clock-Ticks zurückgeben, das dürfte unproblematisch sein (zumal es keine Interrupt-Service-Routine, ISR ist).

Dein Grundkonzept solltest du aber überarbeiten. In einer ISR sollte man keine großen Funktionen ausführen, um das Programm nicht zu blockieren. Lieber mit Flags arbeiten und dann in einer zyklischen Funktion deine weiteren Schritte ausführen.

Aber haben sich schon Probleme geäußert oder vermutest du es nur?

Woher ich das weiß:Studium / Ausbildung – Masterstudium Elektrotechnik - Schwerpunkt Embedded Systems
AOMkayyy 
Fragesteller
 06.08.2022, 17:09

(Kleine Voranmerkung, ich bin "fortgeschrittener" Novize, sowohl im Bereich C/C++ als auch im embedded Bereich bzw. STM32, kenne mich als nicht wirklich aus.)

Also es kam zu Problemen, ich kommuniziere praktisch über UART mit einem C# Script auf dem PC mit meinem MCU und immer wenn ich gewisse Funktionen aufgerufen habe, dann kam in meine Computerkonsole (die ich zum Auslesen der Kommunikation verwendet habe) keine Antwort. Meine Vermutung (wohlgemerkt nur Vermutung) war, dass HAL_GetTick auch in irgendeiner Weise mit einem seperaten Interrupt zusammenhängt (keine Ahnung ob das stimmt) und dass es wegen falsche Priorisierung der Interrupts zu Problemen kommt.

Ich baue auf Code auf, den jemand anderes begonnen und nicht wirklich kommentiert hat, dieser funktioniert auch nicht und ich bin ständig auf Fehlersuche. Ich hab das ganze dann auch mit Polling ohne Interrupts versucht und auch da gehts nicht wirklich, ich glaube aber, dass ich den Fehler dort entdeckt habe.

Die Funktionen die ich in den Interrupts aufrufe sind nicht wirklich groß, ich glaube nicht, dass es deswegen zu wirklichen Problemen kommt, zumal die Interrupts nichts kritisches unterbrechen. Gibt HAL_getTick nicht in ms anstatt ticks zurück?

Wie arbeitet man da am besten mit Flags? Also was wäre da so die grundsätzliche Struktur?

Vielen Dank für deine Antwort!

0
Gehilfling  10.08.2022, 10:27
@AOMkayyy
 Gibt HAL_getTick nicht in ms anstatt ticks zurück?

Scheinbar doch, hab mir eben die Funktionsbeschreibung angesehen. Es wird jede Millisekunde inkrementiert (interruptbasiert). Allerdings sollte die Priorität recht hoch liegen, also wärst du mit dem UART-Callback noch drunter und solltest das nicht unterbrechen können.

Schematisch könnte das Arbeiten mit Flags so aussehen:

boolean boUART_Received

// Funktion bei UART Interrupt
void ISR_UART_RX_Callback()
{
  boUART_Received = TRUE;
}

// Zyklische Funktion, z.B. alle 5-10 ms
void Cyclic_5ms()
{
  if(boUART_Received == TRUE)
  {
    // Hole die Daten und setze Flag zurück
    Buffer = UART_GetData();
    boUART_Received = FALSE
  }
}

Man muss natürlich dahingehend optimieren, dass man mit diesem Ansatz im Zweifel UART-Daten verliert, sofern diese schneller als alle 5 ms kommen. Alternativ ließe sich auch ein eigener Buffer einführen, in den man die UART-Daten in der ISR reinschiebt und in der zyklischen Funktion ausliest - reduziert die Verlustgefahr.

Aber wenn du sagst, deine UART-Routine ist eh nicht sonderlich üppig, dann sollte der Fehler ggf. wo anders liegen.

1
AOMkayyy 
Fragesteller
 10.08.2022, 14:25
@Gehilfling

Vielen Dank! Wird die Cyclic (oder beliebige andere Funktion die die UART Flag nutzt) dann einfach wiederholt in der main bzw. while(1) abgefragt oder läuft das dann wieder über einen Timer Interrupt? Läuft man im ersten Fall nicht Gefahr, dass die "Abtastrate" durch weitere Inhalte in der Main die 5 ms übersteigt?

0