Forum: Mikrocontroller und Digitale Elektronik CAN Bus Vorteile Mailbox-Mode?


von Asterix (Gast)


Lesenswert?

Hallo,

ich würde gerne erfahren, was denn der Vorteil der Mailbox gegenüber 
eines FIFO beim Empfang von CAN Messages ist. Beim Renesas Synergy habe 
ich nur die Mailbox zur Verfügung, welche aber nur eine Nachricht 
jeweils aufnehmen kann. Wie geht man damit um, dass keine Nachrichten 
verloren gehen, wenn diese einmal schneller eintreffen, als sie 
verarbeitet werden? Ich habe das Problem, dass die Nachricht, welche 
noch nicht verarbeitet wurde, einfach überschrieben wird. Damit ist die 
erste Nachricht für den sendenden CAN Controller angekommen, aber sie 
kann nicht mehr vom Programm auf der Empfangsseite gesehen werden. Ich 
habe, um das zu vermeiden, die gesamte CAN Bus Auswertung in der ISR für 
den Empfang einer Message implementiert, was aber nicht im Sinne des 
Erfinders sein kann.

von Jim M. (turboj)


Lesenswert?

Du könntest im Interrupt Handler auch einfach die komplette CAN Message 
in einen FIFO packen, um dessen Daten später in der Hauptschleife zu 
verarbeiten.

von Soul E. (Gast)


Lesenswert?

Mailbox ist für zyklische Nachrichten, wo immer der aktuelle Status 
gesendet wird. Deine SW guckt da in gewissen Abständen vorbei und findet 
immer den neuesten Zustand vor. Nachgucken und Aktualisieren sind 
unabhängig und müssen nicht mit der gleichen Abtastrate erfolgen. Hast 
Du im Auto für Zustandvariablen wie "Licht an" oder "Gaspedal 25% 
getreten".

Fifo ist für Nachrichten wo keine verpasst werden soll. Die kommen der 
Reihe nach rein und werden der Reihe nach abgearbeitet. Hast Du im Auto 
für Diagnosebotschaften, Firmwareupdates und das Krypto-Geraffel.

Wenn Du kein Fifo in HW hast musst Du das in SW machen. D.h. beim 
Befüllen der Botschaft einen Interrupt erzeugen, und in dessen Routine 
die Daten in Deine Liste umkopieren. Die Liste abarbeiten macht dann die 
SW in Ruhe im Hauptprogramm.

von Asterix (Gast)


Lesenswert?

Dann werde ich wohl um einen Fifo nicht herumkommen. Die Frage ist nur, 
wie ich den am besten implementiere. Ganz kapiert habe ich das Prinzip 
noch nicht. Ich muss ja ein struct, welches die ID, die Daten und die 
Länge des Datenwortes enthält, erstellen. Kann ich ein Array aus structs 
erstellen? Die Größe des Puffers wird durch die Anzahl structs 
vorgegeben. Die Nachricht muss jedesmal soweit wie es geht nach vorne 
geschoben werden wie es geht, und zwar auch dann, wenn keine Nachricht 
nachkommt. Das heißt, jedesmal, wenn eine Nachricht aus dem Puffer 
gelesen wird, muss alles eine Position nach vorne rücken. Wenn nichts 
nachkommt, muss trotzdem geschoben werden und die ausgelesenen 
Datenfelder werden als unbelegt gekennzeichnet. Dazu bräuchte ich wohl 
ein weiteres Element im struct. Dann muss ich irgendeine 
Fehlerbehandlung haben, wenn der Puffer voll ist. Ich habe noch nie mit 
Puffern gearbeitet und weiß deshalb nicht, ob ich mit meinem 
Gedankengang auf dem richtigen Weg bin. Vielleicht hat ja hier jemand 
schon einmal genau diese Aufgabe gelöst. Ich wäre sehr dankbar, wenn mir 
jemand hilft, dass der Knoten endlich platzt.

von GL (Gast)


Lesenswert?

Guck dir mal an wie Ringbuffer implementiert werden. Da werden nur 
Zeiger geschoben, keine riesen Datenmengen umkopiert.

von Heinz (Gast)


Lesenswert?

Der mailboxmode wird meist bei Echtzeisystemen benutzt.
Im Automobilbereich z.B.
Da ist die Software in Zeitscheiben aufgeteilt, die alle 10ms
 oder alle 20ms laufen. Somit wird in einem festen Interval gesendet
und auf Empfängerseite ebenfalls in einem festen Interval in der mailbox 
nachgesehen. Da Sender/Empfänger nicht synchron laufen, kann hin und 
wieder mal eine Nachricht verloren gehen. Die Systeme können damit aber 
umgehen.

Wenn Datenprotokolle laufen sollen (ISO15765, ISO11783...) wäre der 
Ringbuffer mode besser, weil Datenverlust zum Protokollabbruch oder 
Paketwiederholung führt.


Viele Prozessoren haben die mailboxes gleich eingebaut. Den 
Ringbuffermode
unterstützt bspw. der SJA1000, ein externer CAN Controller. Der kann 
aber soweit ich erinnere nur den Ringbuffer mode.

Ich weiß nicht, ob es Prozessoren gibt, die beides parallel können, 
mailbox mode und ringbuffer mode.

von Heinz (Gast)


Lesenswert?

Im Mailbox mode konfiguriert man die mailbox so, dass sie
eine bestimmte Botschaft empfängt oder eben eine bestimmte Gruppe.
Die Gruppe wird anhand von CAN-ID & AcceptanceMask festgelegt.
So weiß der Controller sofort, was er mit der Botschaft in Mailbox X 
machen muss.

Im Ringbuffer mode kann man das theoretisch zwar auch machen, aber der 
Ringbuffer mode wird meist benutzt, um erstmal im Interrupt alles zu 
empfangen, und später die empfangenen Daten den entsprechenden Kanälen 
zuzuordnen. Mit diesem Modus kann man bspw. dynamisch zur Laufzeit 
beliebig virtuelle CAN Kanäle gemäß OSI Schichtenmodell instanziieren.

von Asterix (Gast)


Lesenswert?

Soweit, so gut. Die Mailbox ist also eine Art Filter, wo eine Vorauswahl 
getroffen wird anhand der ID, sodass für jede Mailbox eine eigene ISR 
die Verarbeitung der eingegangenen Messages übernimmt. Trotzdem sehe ich 
Probleme, wenn Messages für eine Mailbox direkt hintereinander 
eintreffen, sodass entweder die erste Nachricht überschrieben wird oder 
die letzte verworfen wird. Wenn ich jetzt richtig liege, gilt eine 
Message für den sendenen CAN-Controller aber dann trotzdem als 
übermittelt. In dem Moment habe ich keinen Puffer, welcher die Messages 
bis zur Verarbeitung sicher aufbewahrt. Ich frage mich, wo das Geheimnis 
liegt, dass die Nachrichten lückenlos erfasst werden und das Programm 
trotzdem performant läuft.

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

CAN in seiner Ursprungsidee (vor über 30 Jahren) sollte die dicken 
Kabelbäume im KfZ ersetzen. Es wurden also dazu verwendet Signale (z.B. 
Drehzahl, Blinker, Hupe usw.) auf einer Leitung zu multiplexen. Es wird 
vereinbart das auf dem Identifier 0x123 in Bytes 6-7 die Drehzahl 
übertragen wird. Man konfiguriert also die Mailbox einmal auf diesen 
Identifier und kann dann immer in den Bytes 6-7 die aktuelle Drehzahl 
abholen ohne sich um den CAN-Controller kümmern zu müssen. Es gibt dann 
kein "Nachricht verpassen" weil die Information immer die gleiche ist. 
Das gleiche System kann man heute bei CANOpen noch erkennen. PDOs haben 
dort auch eine fest Zuordnung von CAN-ID zu Daten wenn der Bus fertig 
konfiguriert ist.

CAN wird heute natürlich für weitaus mehr benutzt wo der Mailboxbetrieb 
nicht immer passt. Desswegen haben neuere CAN-Controller eben einen FIFO 
Mode.

Matthias

von Thomas F. (igel)


Lesenswert?

Asterix schrieb:
> Beim Renesas Synergy habe ich nur die Mailbox zur Verfügung, welche aber
> nur eine Nachricht jeweils aufnehmen kann.

Das Datenblatt des kleinen S124 sagt auf Seite 723:

Message box: 32 mailboxes, with two selectable mailbox modes:

Normal mode: 32 mailboxes independently configurable for either 
transmission or reception

FIFO mode: 24 mailboxes independently configurable for either 
transmission or reception, with remaining mailboxes used for receive and 
transmit 4-stage FIFOs.

Es gibt also reichlich davon, da kann man eigentlich keine Nachricht 
verpassen.

von Asterix (Gast)


Lesenswert?

Μαtthias W. schrieb:
> 0x123 in Bytes 6-7 die Drehzahl
> übertragen wird.

Vielleicht ist die Drehzahl hier ein unkritisches Beispiel. Trotzdem 
wird dieses Signal regelmäßig übertragen und da sind wir wieder an dem 
Punkt, dass zwei hintereinander eintreffende Nachrichten kollidieren 
könnten. Interessanter wären z.B. Steuerbefehle oder sogar ein 
kritisches Stop-Signal (bspw. für eine Maschinensteuerung), welches 
keinesfalls ausgelassen werden darf; was sofort zuverlässig verarbeitet 
werden muss, egal wie schnell nachfolgende Nachrichten eintreffen.

von Rolf M. (rmagnus)


Lesenswert?

Μαtthias W. schrieb:
> Es gibt dann kein "Nachricht verpassen" weil die Information immer die
> gleiche ist.
> Das gleiche System kann man heute bei CANOpen noch erkennen.

Das ist auch im Fahrzeug noch weitgehend so.

Asterix schrieb:
> Vielleicht ist die Drehzahl hier ein unkritisches Beispiel. Trotzdem
> wird dieses Signal regelmäßig übertragen und da sind wir wieder an dem
> Punkt, dass zwei hintereinander eintreffende Nachrichten kollidieren
> könnten.

Das stört aber nicht, da mich eine frühere Drehzahl nicht interessiert, 
sondern nur der aktuelle Wert.

> Interessanter wären z.B. Steuerbefehle oder sogar ein kritisches Stop-
> Signal (bspw. für eine Maschinensteuerung), welches keinesfalls
> ausgelassen werden darf; was sofort zuverlässig verarbeitet
> werden muss, egal wie schnell nachfolgende Nachrichten eintreffen.

Das würde ja nur zum Problem führen, wenn danach nochmal die gleiche 
Nachricht kommt, wo aber das Stop-Signal nicht mehr gesetzt ist.
Davon abgesehen könnte auch einfach so (z.B. durch ein externes 
Störsignal) eine Botschaft ausfallen. Den Fall, dass mal eine Botschaft 
fehlt, muss man  also sowieso berücksichtigen.

von Asterix (Gast)


Lesenswert?

Rolf M. schrieb:
> Den Fall, dass mal eine Botschaft
> fehlt, muss man  also sowieso berücksichtigen.

Wie würdest Du das sinnigerweise anstellen?

von Rolf M. (rmagnus)


Lesenswert?

Asterix schrieb:
> Rolf M. schrieb:
>> Den Fall, dass mal eine Botschaft
>> fehlt, muss man  also sowieso berücksichtigen.
>
> Wie würdest Du das sinnigerweise anstellen?

Kommt drauf an. Bei dem Beispiel mit der Drehzahl oder dem Stop-Signal 
kann man die Daten einfach zyklisch senden, mit einer Zykluszeit, die 
kurz genug ist, dass ein Ausfall unkritisch ist. Im Automobilbereich ist 
das üblich.
Wenn man dagegen keine Signale an festen Stellen in der Botschaft hat, 
sondern andere Daten übertragen will, wie z.B. eine Firmware, dann muss 
man noch ein Transportprotokoll drauf setzen, das eine korrekte und 
vollständige Übertragung sicherstellt, wie das schon genannte ISO15765. 
Auch das wird im Automobilbereich genutzt.

: Bearbeitet durch User
von Asterix (Gast)


Lesenswert?

Das mit der Zykluszeit sollte hinzubekommen sein.

Rolf M. schrieb:
> Im Automobilbereich ist
> das üblich.

Es hat sich für mich herausgestellt, dass gerade im Bereich der 
Automobiltechnik viel Geheimniskrämerei herrscht und ich finde, dass es 
nicht einfach ist, an konkrete Informationen oder Codebeispiele zu 
kommen, anhand derer die sichere Funktionsweise nachvollziehen lässt. 
Gibt es dazu beispielhaften (oder realen) Code, um diese Zusammenhänge 
und die dahintersteckende Komplexität, gerne auch im Zusammenspiel mit 
einem RTOS, besser zu vestehen?

von Soul E. (Gast)


Lesenswert?

Asterix schrieb:

> (...) Interessanter wären z.B. Steuerbefehle oder sogar ein
> kritisches Stop-Signal (bspw. für eine Maschinensteuerung), welches
> keinesfalls ausgelassen werden darf; was sofort zuverlässig verarbeitet
> werden muss, egal wie schnell nachfolgende Nachrichten eintreffen.

Auf dem CAN werden keine Steuerbefehle übertragen, sondern Zustände. Da 
hast Du irgendwo eine Information, die die Zustände "Maschine läuft" und 
"Maschine stop!" enthält. Diese Information wird regelmäßig gesendet.

Deine Software guckt in gewissen Zeitabständen in die Mailbox und findet 
da immer den neuesten Zustand vor. Wieviele Nachrichten in der 
Zwischenzeit angekommen sind interessiert keinen, nur die neueste 
(aktuelle) ist relevant.

Deine Armbanduhr sagt Dir auch nicht immer Bescheid wenn der Controller 
eine neue Zeitanzeige berechnet hat. Sie zeigt einfach den neuesten Wert 
an. Und wenn Du irgendwann mal draufguckst siehst Du den aktuellen 
Zustand, ungeachtet der Vorgeschichte.


Wenn man mit so einem System Daten übertragen will, wo jede einzelne 
Botschaft zählt, dann geht das nur mit einem geeigneten Handshake. Dafür 
sind Transportprotokolle da. Wie bei besseren Stoppuhren mit 
Zwischenzeit-Anzeige: "ja, ich habe den Wert gesehen, gib mit bitte den 
nächsten".

von Asterix (Gast)


Lesenswert?

Dann liege ich mit meinem Ansatz scheinbar gar nicht so falsch. Dann 
könnte ich doch die ankommenden Nachrichten anhand ihrer ID in ein 
jeweils entsprechendes Struct kopieren, welches auch ein Flag enthält, 
ob die Nachricht neu oder schon abgearbeitet ist. Jedesmal, wenn die 
selbe Nachricht erneut eintrifft, wird der Inhalt überschrieben und das 
Flag gesetzt, welches von der entsprechenden Funktion ausgewertet wird 
und nach Bearbeitung der Nachricht zurückgesetzt wird. Dann habe ich 
zumindest die Nachrichten auf verschiedene Speicherstellen verteilt und 
vor Überschreiben durch "artfremde" Nachrichten geschützt. Könnte mein 
Vorhaben funktionieren?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.