Modbus funktioniert in RTC Interrupt nicht

OP #6876510
Lesenswert?
• ▲
▼
Hallo,

Wir haben ein Board basierend auf dem Arduino Mkr Zero Board mit dem 
SAMD21G18 uC entwickelt. Der Arduino-Sketch wurde konvertiert und in ein 
Atmel/Microship-Studio Projekt importiert. Wir verwenden die onboard RTC 
mit der RTCZero lib für zeitbasierte Interrupts um Daten aus der 
Peripherie zu erhalten. Diese Daten stammen von i2c, ADC und so weiter - 
alle basierend auf SERCOM mit SERCOM-Handlern/Interrupts. Das 
funktioniert alles einwandfrei und ohne Probleme.

Nun wollten wir über einen MAX14840 IC und ein UART Interface (mit der 
SERCOM5-Schnittstelle) eine Modbus-Funktionalität hinzufügen. Bei der 
Ausführung in der Schleife (loop()) funktioniert alles einwandfrei, aber 
bei der Ausführung im RTC Interrupt stürzt die read Holding Registers 
Funktion der Arduino Modbus lib ab. Beim Debuggen im Microship Studio 
(break-all) scheint es, als würde der Controller in der 
Uart-Flush-Funktion warten, insbesondere in der while-Schleife. (in der 
originalen Uart.cpp-Datei)
1
void Uart::flush ()
2
{
3
while (txBuffer. available ()); // warten, bis der TX-Buffer leer ist
4
sercom->flushUART ();
5
}

Für mich sieht es so aus, als gäbe es ein Problem mit den Interrupts 
oder der Interrupt-Priorität. Hat irgendjemand ähnliche Probleme schon 
mal beobachtet? Oder eine andere Idee?

Vielen Dank!

Grüße Thomas
#6876537
Lesenswert?
• ▲
▼
Man sollte sich schon Gedanken machen, ob aller Schrunz wirklich in 
Interrupts gehört. In Interrupts sind natürlich alle anderen Handler mit 
gleichem Level gesperrt.
Typisch macht man daher nur wichtige Sachen in Interrupts, z.B. serielle 
Daten in eine FIFO packen oder aus einer FIFO senden.
Irgendwelche Warteorgien sind in Interrupts ein absolutes NoGo.
#6876682
Lesenswert?
• ▲
▼
Ein anderer Interrupt sollte generell nicht auf die UART zugreifen, da 
dann eine 2. Instanz ausgeführt wird. Die UART ist aber nicht reentrant, 
d.h. nur eine Instanz kann sie benutzen.
Vermutlich blockiert also eine Instanz in der Mainloop den Aufruf im 
RTC-Interrupt. Und da der UART-Interrupt nicht mehr ausgeführt werden 
kann, terminiert diese auch nie.
Möglich ist aber auch, der RTC-Aufruf kommt, wenn das vorherige Senden 
noch nicht beendet ist.
#6876759
Lesenswert?
• ▲
▼
Interfaces sind generell nicht reentrant und daher ruft man sie nicht 
aus anderen Interrupts heraus auf. Und da es ja knallt, werden die 
Autoren der Libs das auch gar nicht berücksichtigt haben. Wo es genau 
knallt, ist daher egal.

Man könnte zwar tricksen und dem UART-Interrupt eine höhere Priorität 
zuweisen, aber irgendwann wird es einem doch auf die Füße fallen.
Ich hab sowas schon mal gemacht und mich dann über verstümmelte 
Textausgaben gewundert.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.