Ich kämpfe mit dem Konzept, wie ich meine Aufgaben planen soll.
Mein Setup: STM32F103 an CAN angeschlossen. Das Messen mit einem Lidar V3-Modul kommuniziert über I2C und verteilt diese Messung dann auf dem CAN
Interrupt 1 ist ein 1-ms-Timer-Interrupt, um das Senden von Nachrichten auf CAN zu initiieren
Interrupt 2 ist beim Empfang einer CAN-Nachricht aktiv
Ich muss auch ein Register über I2C auf der LIDAR-Einheit abfragen, um sicherzustellen, dass die Messung abgeschlossen ist, bevor ich dann I2C verwenden kann, um das Entfernungsregister zu lesen, Codeausschnitt unten gezeigt
status = CheckLidarStatus();
while ((status & LIDAR_BUSY) == LIDAR_BUSY)
{
status = CheckLidarStatus();
}
Was meiner Meinung nach der richtige Ablauf ist, den mein Programm nehmen sollte, wird unten gezeigt:
Meine Hauptanliegen sind:
Erscheint der Flow als logischer Weg, um dies anzugehen?
Wenn ich den Timer-Interrupt (statt RX int) für die CAN-Übertragung priorisiere, wirkt sich dies negativ auf das CAN-Netzwerk aus, dh die empfangenen CAN-Nachrichten werden nicht rechtzeitig genug behandelt?
Wenn einer der Interrupts während der I2C-Kommunikation aktiv ist, führt dies dazu, dass die I2C-Kommunikation "umfällt"?
Ist es akzeptabel, in einer While-Schleife zu sitzen und darauf zu warten, dass der Checklidar-Status als nicht beschäftigt zurückkommt, oder gibt es einen besseren Weg, dies zu tun?
Ja, erscheint mir logisch. Wie lange darf das Lidar-Peripheriegerät jedoch maximal beschäftigt sein? Wenn das länger als 1 Millisekunde ist, könnten Sie eine Sendegelegenheit verpassen. Vielleicht sollte der Busy-Fall einfach die gelesenen Daten überspringen, anstatt zurück zu schleifen, um den Status abzufragen.
Ja, der Interrupt-Handler mit niedrigerer Priorität wird abgeschaltet, während der Interrupt-Handler mit höherer Priorität läuft. Wenn der Timer-Interrupt-Handler mit höherer Priorität länger läuft, als das CAN-Peripheriegerät benötigt, um genügend Nachrichten zum Überlaufen zu erhalten, würden Sie Nachrichten verlieren. Deshalb ist es eine gute Faustregel, Interrupt-Handler kurz zu halten. Und wenn Ihr Timer-Interrupt nur ein Flag setzt, bezweifle ich, dass Sie ein Problem haben werden.
Eine andere Möglichkeit, dies zu berücksichtigen, ist die Strafe, wenn einer der Interrupt-Handler durch den anderen verzögert wird. Wenn der CAN-Interrupt durch den Timer-Interrupt verzögert wird, würden Sie der CAN-Antwort eine Verzögerung hinzufügen oder im schlimmsten Fall eine Nachricht verwerfen. Wenn der Timer-Interrupt durch den CAN-Interrupt verzögert wird, würden Sie dem Timer-Interrupt Jitter hinzufügen. Im schlimmsten Fall würde eine Millisekunde ausfallen, aber dafür müsste der CAN-Interrupt länger als eine Millisekunde laufen. Was ist also weniger wünschenswert für Ihre Anwendung, ein wenig Verzögerung oder ein wenig Jitter?
Es ist zweifelhaft, dass jeder Interrupt die I2C-Kommunikation unterbrechen würde. Sie verwenden wahrscheinlich ein I2C-Controller-Peripheriegerät, das Bits größtenteils unabhängig von der CPU sendet / empfängt. Der I2C-Controller taktet weiterhin nach Bedarf Bits ein und aus, ohne von den Interrupts beeinflusst zu werden. (Wenn Sie jedes Bit bit-bangen würden, hätte dies eine größere Auswirkung, da einzelne Takte durch einen unabhängigen Interrupt gedehnt werden könnten. Aber selbst das ist aufgrund der synchronen Natur von I2C nicht unbedingt ein Problem. Das Slave-Gerät sollte dies nicht tun ' Es ist egal, ob die I2C-Taktimpulse verlängert werden.)
Es kann akzeptabel sein, den LIDAR-Status abzufragen. Wenn Sie nichts anderes für die CPU zu tun haben, was schadet es dann? Wenn das Lidar-Peripheriegerät jedoch über eine Art "Daten bereit" -Interrupt verfügt, können Sie diesen Interrupt aktivieren und auf den Interrupt warten, anstatt den Status abzufragen.
Es liegt in der Natur von CAN, dass beim Versuch, eine Nachricht zu senden, Kollisionen mit Nachrichten mit höherer Priorität auftreten können, die Sie empfangen und verarbeiten müssen.
Ihr Vorschlag zeigt extrem einfache ISRs, die lediglich Flags setzen, wobei die gesamte eigentliche Arbeit in einem einzigen Hintergrundthread (Nicht-ISR) ausgeführt wird.
Ich kenne die Details des CAN-Controllers des STM32 nicht und insbesondere nicht, wie autonom er sein könnte, aber Ihr Vorschlag scheint in Bezug auf dieses Problem unzureichend zu sein.
Jeroen3
Pop24
Jeroen3
Pop24
Lundin
Jeroen3