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.
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.
achso, ja ne, jetzt verstehe ich! Die Bitarbitrierung ist nicht auf die CobID begrenzt! - in Deinem beschriebenen Fall greift die Bitarbitrierung in den Nutzdatenbytes
;) 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.
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.
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 ;)
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,
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.
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.
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.
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.
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.
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.