LabVIEWForum.de
Timing von CAN-Nachrichten auf cRIO-9014/9112 und 9853 - Druckversion

+- LabVIEWForum.de (https://www.labviewforum.de)
+-- Forum: LabVIEW (/Forum-LabVIEW)
+--- Forum: LabVIEW Module (/Forum-LabVIEW-Module)
+---- Forum: LabVIEW FPGA (/Forum-LabVIEW-FPGA)
+---- Thema: Timing von CAN-Nachrichten auf cRIO-9014/9112 und 9853 (/Thread-Timing-von-CAN-Nachrichten-auf-cRIO-9014-9112-und-9853)

Seiten: 1 2


Timing von CAN-Nachrichten auf cRIO-9014/9112 und 9853 - bjoerne - 24.04.2015 11:59

Hallo, seit kurzem bin ich in meiner Firma an einem Prüfstand, bei dem Messsignale auf einem CAN-Bus ausgegeben werden sollen. Als Hardware liegen mir eine cRIO-9014, cRIO-9112 und das 9853 CAN-Modul vor.

An sich habe ich es bereits geschafft, dass alle Nachrichten in ihrem jeweiligen vorgesehenen Intervall rausgeschickt werden. Ich habe auf die Frame bzw. Channel-API verzichtet und mir die Nachrichten als Array selbst aufgebaut.

Die VI für den FPGA ist im als Ausschnitt im Bild zu sehen. Die äußere Sequenz initialisiert im ersten Rahmen die Module und im zweiten befinden sich dann die einzelnen Schleifen zum generieren der Nachrichten.
Für jede CAN-ID und den entsprechenden Port habe ich eine FPGA I/O Node erstellt. Das innere Wait gibt das Intervall vor, wobei das erste Intervall in der Gesamtsequenz eine Art Verzögerung vorgibt, damit die Nachrichten mit einem zeitlichen Versatz am Port herausgeschickt werden. Nicht schön, aber es funktioniert.

Jetzt bin ich aber das "Problem" gestoßen, dass die Größe der Bitfiles nach der Synthese fast an der Grenze liegt. Also wollte ich das Generieren und das Intervall der CAN-Nachrichten dem Real-Time Controller überlassen. Im Groben sollte das Timing dabei auch stimmen, das einzige worüber ich gerade stolpere ist die "Abtastung" des FPGAs.
Wenn ich in der Host-VI also alle 20ms eine Nachricht generiere und dem FPGA übergebe, dann versucht doch dieser in der Zwischenzeit die ganze Zeit die Message am Port rauszuschicken. Also angenommen ich würde den Schleifentimer im FPGA auf 1ms setzen, dann sollte die Nachricht jede Millisekunde auf dem CAN-Bus erscheinen.

Ist mein Anliegen oder Problem verständlich? Leider tue ich mich mit der grafischen Programmierung etwas schwer. Das ganze in C würde mir irgendwie leichter fallen, wobei doch eine Menge an Arbeit abgenommen wird.

Danke und
Björn


RE: Timing von CAN-Nachrichten auf cRIO-9014/9112 und 9853 - GerdW - 24.04.2015 12:11

Hallo Björn,

Zitat:Wenn ich in der Host-VI also alle 20ms eine Nachricht generiere und dem FPGA übergebe, dann versucht doch dieser in der Zwischenzeit die ganze Zeit die Message am Port rauszuschicken. Also angenommen ich würde den Schleifentimer im FPGA auf 1ms setzen, dann sollte die Nachricht jede Millisekunde auf dem CAN-Bus erscheinen.
Gegenfrage: Wieso musst du auf dem FPGA ständig CAN-Botschaften abschicken? Das macht der FPGA doch nur, wenn du es so programmierst…

Ich mache das meist so:
RT-Host:
- Generiere neue Botschaft und schreibe sie in ein FPGA-Control (Array aus 6 U32-Werten).
- setze ein "New Message"-Flag auf TRUE

FPGA:
Code:
WHILE
  IF NewMessage THEN
     send CAN-Message
     NewMessage := FALSE
  ENDIF
  wait(1ms)
WEND

Hat es einen Grund, dass du zwei FALSE verODERn musst, um eine Schleife endlos laufen zu lassen? Wink


RE: Timing von CAN-Nachrichten auf cRIO-9014/9112 und 9853 - bjoerne - 24.04.2015 12:31

(24.04.2015 12:11 )GerdW schrieb:  Ich mache das meist so:
RT-Host:
- Generiere neue Botschaft und schreibe sie in ein FPGA-Control (Array aus 6 U32-Werten).
- setze ein "New Message"-Flag auf TRUE

FPGA:
Code:
WHILE
  IF NewMessage THEN
     send CAN-Message
     NewMessage := FALSE
  ENDIF
  wait(1ms)
WEND

So in der Art hatte ich mir das auch mal überlegt, bin dann aber nicht so recht auf die Lösung gekommen. Natürlich brauch ich dann ja für jede ID ein eigenes Flag. Kann ich in dem Fall statt dem FPGA-Control gleich eine globale Variable nehmen, in die ich aus der Host-VI schreibe und welche ich dann im FPGA zurücksetze?

Habe mal schnell etwas zusammengeklickt, wie ich es jetzt versuchen würde. Das ganze dann natürlich für die weiteren Nachrichten. In der Host-VI soll jetzt also die Nachricht generiert werden, nachdem eine bestimmte Zeit gewartet wurde. Das Array und das Flag sollen dann dem FPGA übergeben werden.

(24.04.2015 12:11 )GerdW schrieb:  Hat es einen Grund, dass du zwei FALSE verODERn musst, um eine Schleife endlos laufen zu lassen? Wink

Doppelt hält besser, oder wie war das Wink? Wusste, dass die Frage kommt. Ist noch ein Überbleibsel, eigentlich war der Status mit der Konstante verODERt, damit im Fehlerfall die Schleife beendet wird.

Danke für deine Antwort!

Gruß
Björn


RE: Timing von CAN-Nachrichten auf cRIO-9014/9112 und 9853 - GerdW - 24.04.2015 12:37

Hallo Björn,

Zitat:Natürlich brauch ich dann ja für jede ID ein eigenes Flag.
Wieso? Warum? Weshalb?
Du hast einen CAN-Port und auf diesem einem CAN-Port kann man nicht gleichzeitig zwei Botschaften schicken. Sowas geht immer nur "eine nach der anderen"!
Also: Dein RT-Host generiert eine Botschaft nach der anderen. Jedesmal, wenn du eine Botschaft für den FPGA vorbereitet hast, setzt du das Flag und der FPGA verschickt die Botschaft…

Zitat:Kann ich in dem Fall statt dem FPGA-Control gleich eine globale Variable nehmen, in die ich aus der Host-VI schreibe und welche ich dann im FPGA zurücksetze?
Nein: Der FPGA hat keinen Zugriff auf den Speicher des RT-Hosts.

Du kannst mit dem FPGA nur über
- Controls
- FIFOs
- IRQ
kommunizieren!


RE: Timing von CAN-Nachrichten auf cRIO-9014/9112 und 9853 - bjoerne - 24.04.2015 12:57

(24.04.2015 12:37 )GerdW schrieb:  
Zitat:Natürlich brauch ich dann ja für jede ID ein eigenes Flag.
Wieso? Warum? Weshalb?
Du hast einen CAN-Port und auf diesem einem CAN-Port kann man nicht gleichzeitig zwei Botschaften schicken. Sowas geht immer nur "eine nach der anderen"!
Also: Dein RT-Host generiert eine Botschaft nach der anderen. Jedesmal, wenn du eine Botschaft für den FPGA vorbereitet hast, setzt du das Flag und der FPGA verschickt die Botschaft…

Klar. Denkfehler von mir. Deshalb hatte ich auch überlegt für jede Message ein FPGA-Control zu haben und im FPGA für jede ID eine eigene FPGA I/O Node zu behalten. Wenn ich jetzt aber schon ein gemeinsames Flag setze, dann wäre es ja sinnvoll im FGPA nur eine I/O Node für einen CAN-Port zu haben. Mein Problem dabei: Wie führe ich die Arrays zu einem FPGA-Control zusammen? Die Flags der einzelnen Sequenzen habe ich verODERt...

edit: Gerade gesehen. Natürlich sollte das Flag bei der Botschaft auf TRUE gesetzt werden. Wird korrigiert.


RE: Timing von CAN-Nachrichten auf cRIO-9014/9112 und 9853 - GerdW - 24.04.2015 13:12

Hallo Björn,

Zitat:Mein Problem dabei: Wie führe ich die Arrays zu einem FPGA-Control zusammen?

Ich wiederhole aus meinem letzten Beitrag:
Zitat:Du hast einen CAN-Port und auf diesem einem CAN-Port kann man nicht gleichzeitig zwei Botschaften schicken. Sowas geht immer nur "eine nach der anderen"!

Daraus ergibt sich die Frage: Wieso willst du auf dem RT-Host nun mehrere Botschaften parallel erstellen - du kannst sie NICHT parallel verschicken!

Lösung:
Statt mehrere paralleler Sequenzen eine Case-Struktur mit je einem Case je Botschaft. In einer Schleife dann nacheinander die Cases durcharbeiten…

Hier mal ein Bild dazu (die eben besprochene Case-Struktur steckt im subVI in der unteren Schleife):
[attachment=52914]


RE: Timing von CAN-Nachrichten auf cRIO-9014/9112 und 9853 - bjoerne - 24.04.2015 13:33

(24.04.2015 13:12 )GerdW schrieb:  Lösung:
Statt mehrere paralleler Sequenzen eine Case-Struktur mit je einem Case je Botschaft. In einer Schleife dann nacheinander die Cases durcharbeiten…

Eine Case-Struktur hatte ich auch bereits zuvor. Gut, da lag es auch an einer andere Sache, dass es nicht so funktioniert hat, wie es soll. Mich stört daran nur, dass fast jede Nachricht ein anderes Intervall hat. Die erste wird bspw. mit 10ms (x10) und die anderen beiden (x20, x30) mit 20ms gesendet. Bei anderen Nachrichten wird es unter Umständen noch "wilder".

Jetzt könnte ich in jedem Case 5ms warten und 4 Fälle erstellen: x10, x20, x10, x30.
Ich habe damit die Nachricht x10 zweimal und das find ich irgendwie unschön. Bin mir noch nicht ganz sicher, ob ich dein Programm richtig verstehe, aber vielleicht umgehst du das Problem ja auch.

Werde mal weiter versuchen da durchzublicken. Das ist aber auch verdammt gewöhnungsbedürftig Big Grin.

Danke nochmal für die super Unterstützung!


RE: Timing von CAN-Nachrichten auf cRIO-9014/9112 und 9853 - GerdW - 24.04.2015 13:37

Hallo Björn,

Zitat:Jetzt könnte ich in jedem Case 5ms warten und 4 Fälle erstellen: x10, x20, x10, x30.
Du schickst also 3 verschiedene Botschaften/IDs im 5ms-Raster - ist doch perfekt.
Also muss das Timing nicht "in jedem Case", sondern nur in der Schleife drumherum sein…

Sowas mache ich im Bild in der unteren Schleife: ich habe 3 Botschaften (die IDs links in der Arraykonstante), die hier jeweils im 33ms-Raster erzeugt werden. In der Schleife wird das Array mit den IDs immer um eine Position weiter rotiert und die Botschaft für die dann jeweils erste ID erzeugt…

Zitat:Mich stört daran nur, dass fast jede Nachricht ein anderes Intervall hat. Die erste wird bspw. mit 10ms (x10) und die anderen beiden (x20, x30) mit 20ms gesendet.
Du musst auch immer daran denken, dass du über den CAN-Port immer nur eine Botschaft nach der anderen senden kannst. Du musst sie also zeitlich verteilen, in deinem Beispiel auf einem 5ms-Raster.

Zitat:Bei anderen Nachrichten wird es unter Umständen noch "wilder".
Entweder wird dein Raster kleiner - oder es kommt zu Konflikten. Irgendwann ist der CAN-Bus ausgelastet, abhängig von Baudrate und Anzahl anderer Talker/Listener auf dem Bus…


RE: Timing von CAN-Nachrichten auf cRIO-9014/9112 und 9853 - bjoerne - 24.04.2015 13:47

Ich habe irgendwie immer die Schwierigkeit darin gesehen, dass die Nachricht zum Teil noch nicht 100%ig fix sind was das Timing angeht. Das heißt, dass die Reihenfolge der IDs und das Timing der Schleife jedes mal angepasst werden muss, wenn doch wieder etwas geändert wird. Nur deshalb bin ich den Weg gegangen, die Nachrichten parallel mit je einem eigenen Wait zu erzeugen. Nur die einmalige Verzögerung davor sollte dafür sorgen, dass es eben doch keine richtige Parallelität ist.

Mal angenommen ich habe Nachrichten die alle 10ms, 2ms, 5ms und 30ms gesendet werden. Jetzt werden aus einem bestimmten Grund die Zeiten auf 1ms, 2ms, 5ms und 35ms geändert. Jetzt muss doch die gesamte Reihenfolge, d.h. die Arraykonstante neu erstellt werden.

Ich sehe gerade noch nicht so richtig, wo du deine Daten für jede Nachricht in Abhängigkeit von der ID "erzeugst"?


RE: Timing von CAN-Nachrichten auf cRIO-9014/9112 und 9853 - GerdW - 24.04.2015 13:48

Hallo Björn,

Zitat:Ich sehe gerade noch nicht so richtig, wo du deine Daten für jede Nachricht in Abhängigkeit von der ID "erzeugst"?
wie ich oben schrieb: im subVI in der unteren Schleife, direkt nach dem indexArray…

Das subVI bekommt die gewünschte ID und geht damit direkt auf den Case-Selektor.
Hier noch ein Bild davon:
[attachment=52915]
(6 Messwerte werden entsprechend einer vereinbarten CAN-DBC skaliert und in ein U64=8×U8 gepackt.)