Forum: Mikrocontroller und Digitale Elektronik Arbitrierung CAN / CANopen


von dirk (Gast)


Lesenswert?

Hallo Experten,

Ich habe eine grundsätzliche Frage zur Arbitrierung des CAN-Bus 
Protokolls.
Hier steht folgendes:
"Message IDs must be unique on a single CAN bus, otherwise two nodes 
would continue transmission beyond the end of the arbitration field (ID) 
causing an error."
http://en.wikipedia.org/wiki/CAN_bus
Das bedeutet für mich, dass "lediglich" die COB-ID für die Arbitrierung 
verwendet wird, oder?

Nehmen wir mal an, 2 Clients (CANopen) versuchen gleichzeitig einen 
SDO-Zugriff auf das OD (Channel 1) von Node 1.
Gleicher Index, gleicher Subindex, COB-ID ist sowieso gleich (601). Wie 
klappt das dann ohne Kollision?
Wenn die Arbitrierung über das gesamte CAN-Frame läuft (bis auf den 
letzten Teil / ACK, natürlich), dann sollte das ja kein Problem sein.
Wenn auch noch die gleichen Daten gesendet werden: Fein, keine 
Kollision. Und beide Clients werten (die gleiche) positive Antwort aus.

Was ist nun aber, wenn alles gleich ist, bis auf die Daten?

Ich hoffe, ich konnte mein Problem verständlich erklären (und 
hoffentlich kann mich einer von euch aufklären;)

Viele Grüße,
Dirk.

von Jeffrey L. (the_dude)


Lesenswert?

kann nicht vorkommen da jeder CAN-Knoden eine individuelle NodeID als 
Alleinstellungsmerkmal haben MUSS.

Bei der Cob-ID entscheidet dann die NodeID welcher der beiden Knoten die 
Bitarbitrierung gewinnt.

von Jeffrey L. (the_dude)


Lesenswert?

achso, ja ne, jetzt verstehe ich!

Die Bitarbitrierung ist nicht auf die CobID begrenzt! - in Deinem 
beschriebenen Fall greift die Bitarbitrierung in den Nutzdatenbytes

von dirk (Gast)


Lesenswert?

;)
Die Antwort habe ich vor 2 Stunden auch schon von nem ehem. IXXAT 
Mitarbeiter bekommen. Der Wiki-Artikel hat mich dann aber stutzig 
gemacht, weil da eben "transmission beyond the end of the arbitration 
field (ID) causing an error" steht.
Bei CAN reicht das ja aus, da definiere ich als "Systemdesigner" alle 
COB-IDs, "wie's mir passt" und bin entsprechend dafür verantwortlich, 
aber CANopen mit seinem SDO-Service an 600 + ID führt da bei mir eben 
zum Verständnisproblem.

von Heinz (Gast)


Lesenswert?

Jeffrey Lebowski schrieb:
> in Deinem beschriebenen Fall greift die Bitarbitrierung in den
> Nutzdatenbytes

Nein.

Es gibt z. B. Telegramme mit 11-Bit Identifier (CAN 2.0A). Die 
Arbitrierung wird über 11 Bits durchgeführt. Die Bits sind (CANOpen) 
aufgeteilt: 4 Bits sind der COB-ID, 7 Bits NODE-ID.

von dirk (Gast)


Lesenswert?

Sorry, ich hab's noch nicht kapiert.
Folgendes Szenario (wie ich es momentan verstehe):
Node ID 1 hat einen SDO-Server (Channel), dieser ist 0x600 + Node-ID = 
0x601 (für Rx) und 0x580 + Node-ID = 0x581 (für Tx).
Ein weiterer Knoten mit ID 2 hat auch einen SDO-Server und zwar an 
0x602/0x582.
Somit weiß jeder der Knoten 1 und 2 wann er (sein SDO-Service) 
angesprochen wird.
Jetzt gibt es 2 Clients mit den IDs 3 und 4.
Beide Clients fangen nun gleichzeitig an, einen SDO-Request an Knoten 1 
zu senden. Beide "konsultieren" COB-ID 0x601, die eigene Knoten-ID wird 
im Anfrage-Telegramm ja nicht irgendwie "integriert" ...
Was passiert jetzt? Kollision oder nicht? Vertändnisfehler?
Viele Grüße,
Dirk, der Verwirrte ;)

von hbl333 (Gast)


Lesenswert?

Das knallt dann halt in den Daten, wenn diese unterschiedlich sind.
Wenn beide Nodes den selben Index/Subindex anfragen fällt es nicht
auf. Macht aber auch nix, weil ja beide die richtige Antwort bekommen.
Wenn sich die Datenbereiche unterscheiden gibt es entweder eine Form-
Fehler oder einen CRC Fehler,

von dirk (Gast)


Lesenswert?

Ja, das wäre der eine Fall (wobei ich nicht verstehe, warum du das vom 
Index/Subindex abhängig machst, meiner Meinung nach kracht es schon, 
wenn der Index sich unterscheidet, da die Arbitrierung nach den 11 Bit 
COB-ID aufhört). Dagegen spricht aber, was ich bis jetzt beobachten, bzw 
praktisch ausprobieren konnte:
Ich habe hier 2 Knoten, die einen Blocktransfer durchführen (2 PIC32, 
einer mit einem Stack von Systec, der andere mit einem "selbst 
gebastelten").
Wenn ich nun mit einem dritten Knoten (IXXAT CAN-Karte mit Software 
"Canalyzer") an den "beschäftigten Server" einen SDO-Request schicke, 
dann sehe ich keine Kollision. Der SDO-Request vom "Canalyzer" wird 
ordentlich zwischen 2 Segmente vom Blocktransfer "dazwischengeschoben". 
Die Arbitrierung scheint also irgendwie zu funktionieren...
Viele Grüße,
Dirk.

von Mirko (Gast)


Lesenswert?

Hallo,

ich fasse das Szenario noch einmal zusammen:

Es gibt einen SDO-Server (Node-ID = 1), auf den zwei SDO-Clients (die 
sich auf Knoten mit der Node-ID 3 und 4 befinden - die Node-ID der 
Clients spielt übrigens keine Rolle) zugreifen.

1.) Client(3) und Client(4) senden den SDO-Request gleichzeitig.
Damit sind schon mal die CAN-Identifier der Request-Nachrichten.

1a.) Die Dateninhalte (Inhalte der übertragenen Datenbytes) der Requests 
sind gleich (z.B. bei SDO-Lese-Zugriff auf den jeweils gleichen 
Index/Sub-Index).

Ergebnis: Hier gibt es kein Problem. Der Server merkt nichts davon, dass 
er zwei (überlagerte) Requests bekommen hat und antwortet entsprechend.

1b.) Die Dateninhalte (Inhalte der übertragenen Datenbytes) der Requests 
sind unterschiedlich (z.B. SDO-Schreib-Zugriff mit unterschieldichen 
Inhalten).

Ergebnis: Hier gibt es eine schöne Kollision (Bitfehler bei der 
Übertragung der Datenbytes). Mit dem CANanalyzer kann man die einzelnen 
Error Frames sehen. Zuguterletzt wird aber der Request dann doch 
ausgesendet und der Server antwortet.

2.) Client(3) und Client(4) senden den SDO-Request nicht gleichzeitig.

Ergebnis: Hier erkennt der Server zwei SDO-Requests. Wenn die Requests 
gepuffert (i.d.R. in einem Wechselpuffer oder direkt im CAN-Controller 
oder auch in einer Software-Queue) werden und es sich um einen Expedited 
Transfer (Segemented oder Block-Transfer würde gar nicht gehen. Da kämen 
die SDO-Protokoll-Zustandsmaschinen völlig durcheinander) handelt, gibt 
es wohl auch zwei SDO-Responses. Allerdings werden die SDO-Clients 
(vermutlich) nur die erste Response entgegennehmen. Hier können viele, 
schwer zu lokalisierende Probleme auftreten (da kann einem der CANalyzer 
mit der CANopen Option helfen - OK, er detektiert die Probleme, aber 
kann sie natürlich nicht verhindern ;-) ).


Also, das Szenario 1a würde gehen (ist aber eher Zufall, da Client(3) 
und Client(4) synchronisiert werden müssten). Grundsätzlich ist es aber 
eine Todsünde bei CAN (nicht nur bei CANopen) die gleiche Nachricht von 
unterschiedlichen Knoten aus zu senden.

von dirk (Gast)


Lesenswert?

Hallo Mirko,

Danke für deine ausführliche Antwort.

> Transfer (Segemented oder Block-Transfer würde gar nicht gehen. Da kämen
> die SDO-Protokoll-Zustandsmaschinen völlig durcheinander) handelt, gibt

Volltreffer, genau das Problem hatte ich nämlich mit dem "selbst 
gebastelten Stack" ;) Ich war bis jetzt nur der Meinung, dass es möglich 
sein sollte, an einen SDO-Server einen Request zu senden, auch während 
er einen Blocktransfer mit einem weiteren Client durchführt. Dass der 
Request negativ beantwortet wird oder der Blocktransfer wiederholt 
werden muss, hätte ich mir vorstellen können.
Ich wollte das demnächst noch mit dem Systec-Stack ausprobieren, bin 
aber noch nicht dazu gekommen (im Moment ist der selbst gebastelte der 
Server und der Systec der Client).

> Also, das Szenario 1a würde gehen (ist aber eher Zufall, da Client(3)
> und Client(4) synchronisiert werden müssten). Grundsätzlich ist es aber
> eine Todsünde bei CAN (nicht nur bei CANopen) die gleiche Nachricht von
> unterschiedlichen Knoten aus zu senden.

Ich habe einen "Displaycontroller-Knoten", der an 0x5000 geschriebene 
Strings auf dem LCD ausgibt. Dieser "Service" wird von mehreren 
(erweiterbaren) Clients benötigt. Muss ich in dem Fall für jeden 
potentiellen Client einen eigenen Channel einrichten?

Viele Grüße,
Dirk.

von Christian B. (casandro)


Lesenswert?

Knallen kann das nie, da beim CAN Bus Kollisionen selbstständig gelöst 
werden. Die Arbitrierung bestimmt nur die Reihenfolge der Pakete. 
Übrigens gehen d natürlich alle Bits mit ein, nicht nur die Bits des 
Identifiers.

von (prx) A. K. (prx)


Lesenswert?

Könnte es sein, dass hier die ID mit einer Zieladresse verwechselt wird? 
Tatsächlich ist die ID so gesehen eher eine eindeutige Absenderadresse.

Wenn man einer Node einen ID-Bereich verpasst auf den sie reagieren und 
irgendwas tun soll, und diese Node von mehreren anderen Nodes in 
gleicher Weise angesprochen wird, dann muss man auch die sendende Node 
irgendwie in die ID reincodieren. Damit die ID eindeutig wird. Die 
empfangende Node kann diese Bits dann per Maske ignorieren.

von Peter D. (peda)


Lesenswert?

Wenn 2 Teilnehmer den gleichen Identifier senden, gewinnen beide die 
Arbitrierung und es gibt einen Error in den Daten. Das Retry erfolgt 
dann auch wieder gleichzeitig und irgendwann schalten dann die 
Errorcounter gleichzeitig beide ab.

Daher muß durch ein Protokoll vermieden werden, daß 2 Teilnehmer den 
gleichen Identifier senden können.

Ein einfaches Protokoll dazu ist ein Single-Master Protokoll. 
Nachrichten können nur vom Master zum Slave gesendet werden oder 
umgekehrt. Nachrichten zwischen 2 Slave sind verboten.
Der Master sendet die Slaveadresse mit gelöschtem Slavebit und ein Slave 
sendet seine eigene Adresse mit gesetztem Slavebit.
Somit hat die Arbitrierung immer Erfolg und der Master Priorität.

Eine andere Möglichkeit ist CAN2.0b und der Identifier (29 Bit) enthält 
beide Adressen, die des Senders und die des Empfängers.


Peter

von Steffen - emtas (Gast)


Lesenswert?

Hi,

als erstes sollte man sagen, dass es in einem CANopen Netzwerk nur einen 
aktiven SDO Client je Server geben darf. SDO ist einen Punkt-zu-Punkt 
Verbindung. Daher muss man, wenn man mit Diagnose-Tools ins Netzwerk 
auch aufpassen und korrekterweise den Master ausschalten (ist meist der 
einzige mit SDO Clients).

Insofern darf es den beschriebenen Zustand - 2 Clients schreiben auf 
einen Server - nicht geben. Und ja, dieser Vorgang führt zu Problemen. 
Meist merkt man dies anfangs nicht, da beide Clients genau gleichzeitig 
senden müssen. Dies ist erst später der Fall, wenn der Bus mit 
höherprioren Nachrichten recht voll ist. Es kracht daher erst bei der 
Inbetriebnahme.

Meist führt dies zu einem einmaligen Busoff, der häufig automatisch 
aufgelöst wird. Dann fängt sich das ganze System wieder bis zum nächsten 
Schluckauf.

bye
Steffen

von dirk (Gast)


Lesenswert?

Hallo miteinander,

Ich fasse mal kurz zusammen, was ich herausgelesen habe:

1) Die Arbitrierung geht "nur" über die COB-ID (so wie auch in den 
meisten "offiziellen" Docs beschrieben.

2) Ein SDO-Server benötigt für jeden potentiellen Client einen Channel.

Wenn man sich an 2) hält ist 1) kein Problem.
Wenn man aber mit mehreren Clients den selben Server/Channel anspricht 
(wie in meinem Fall mit dem "Display-Server"), kommt es praktisch zu 
Kollisionen.

Vielen Dank an euch alle.
Gruß, Dirk.

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.
Lade...