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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren