Forum: Mikrocontroller und Digitale Elektronik CAN-Bus: Nachrichtenfilter berechnen?


von Steffen Hausinger (Gast)


Lesenswert?

Hallo zusammen

Ich arbeite mit dem mcp2515. Der Baustein hat zwei Empfangsregister für
die CAN-ID. Vor diese zwei Registern kann man maskierbare Filter
schalten, die nur die Nachrichten durchlassen, die für den Baustein
auch bestimmt sind.

Soweit so gut. Nun habe ich meine Knoten aber so programmiert, dass man
die IDs der Nachrichten verändern kann. D.h., es gibt eine Nachricht,
die eine bestimmte ID auf einen anderen Wert umbenennt. Leider bedeutet
das konsequenterweise auch, dass sich meine Filter mit jeder ID-Änderung
auch ändern müssen.

Deshalb möchte ich nun eine Routine schreiben, die mir die maskierbaren
Filter so einstellt, dass eine möglichst große Übereinstimmung
herauskommt.

Beispiel für 4 Nachrichten und 2 Filter:

ID Nachricht 1: 0b001100
ID Nachricht 2: 0b001101
ID Nachricht 3: 0b110110
ID Nachricht 4: 0b110010

=> Filter 1: 0b0011xx
=> Filter 2: 0b110xxx

Das wäre logischerweise die günstigste Kombination. Von Hand auch
relativ leicht rauszufinden. Nur - wie kann man sowas am Besten in
einer Routine automatisch berechnen? Alle IDs mit XOR verknüpfen und
dann alle Abweichungen ausrechnen? Hat jemand von Euch sowas schon mal
gemacht und weiß eine gute Lösung?

Grüsse,
Steffen

P.s.: Spricht eigentlich etwas gegen eine Neuverteilung von IDs? Ich
halte das für eine gute Idee, oder macht man sowas grundsätzlich nicht?

von Michael W. (mictronics) Benutzerseite


Lesenswert?

Schau Dir mal die folgende Seite an:
http://www.vassfamily.net/ToyotaPrius/CAN/CAN232/index.html

Dort gibts es Sourcecodes mit denen man Werte für das AMR und ACR eines
SJA1000 berechnen kann. Entweder anhand von ID's die Registerwerte oder
anhand des Registerwertes die ID's.
Die Sourcecodes geben Dir vielleicht eine Grundlage.

Die Codes hab ich auch als fertige EXE compiliert falls Du probieren
möchtest.

/Michael

von Steffen Hausinger (Gast)


Lesenswert?

Hallo Michael,

super, das ist genau das, was ich gesucht habe! Danke Michael!

Wie macht man das überhaupt in der Praxis? Nimmt man da auch
veränderbare IDs? Oder legt man die nur einmal fest und behält sie
dann?

Denn so ganz trivial ist die Berechnung offensichtlich ja doch nicht.
Der mcp hat auch noch, je nach Empfangsregister, neben der Maske nicht
nur einen, sondern gleich 2 bzw. 4 Filter. Wenn ich da das Optimum
finden möchte, brauche ich Unmengen an Code :-(

Grüsse,
Steffen

von Michael W. (mictronics) Benutzerseite


Lesenswert?

Der Sinn von ID's besteht wohl darin, das ein Frame eindeutig
identifiziert werden kann, und somit auch der Inhalt der Daten.
Eine geänderte ID macht vielleicht Sinn, wenn man den Dateninhalt von
zwei Frames in einem neuen Frame zusammenfasst.
Wenn Du das aus Sicht der Daten betrachtest müsste jede CAN Node
mitplotten welche ID sich gerade auf eine neue geändert hat, damit die
Node weis hinter welcher ID sich beim nächsten Transfer die Daten
befinden.

Vielleicht kannst Du mehr Details zu Deinem Vorhaben liefern damit man
sich was darunter vorstellen kann was Du überhaupt machen willst.

/Michael

von Steffen Hausinger (Gast)


Lesenswert?

Das System besteht aus ungefähr 30 Busknoten und vernetzt Sensor-Aktor
in meinem, vorher CAN-Bus freien, Pkw. Das fängt an beim
Innenlichtdimmer und endet bei der Ladedruckregelung. Das Ganze findet
also in meinem Hobby Anwendung und ist (natürlich) nicht kommerziell.

Die ID dient ja nicht nur zur Identifizierung, sondern legt ja auch die
Priorität der Nachricht fest. Ich befürchte, dass ich mich jetzt auf
Prioritäten festlege, die sich hinterher verschieben. Bei 30 Knoten
vielleicht noch nicht so das Problem, aber eine gewisse Flexibilität
ist doch generell nützlich. Weiterhin ging ich bisher davon aus, dass
man das in der gängigen Praxis genauso löst. An die würde ich mich
nämlich gerne halten.

Naja, bis zur Berechnung der Masken/Filter war der Programmcode ja auch
nicht schwer (IDs im EEPROM abspeichern, eine Nachricht ReadIDs, eine
SetID). Aber wenn ich jetzt an jedem Knoten noch aufwändig die Filter
berechnen muss, sieht das schon wieder anders aus...

Grüsse,
Steffen

von Michael W. (mictronics) Benutzerseite


Lesenswert?

Es macht vielleicht Sinn, sich dann an bestehenden Standards zu
orientieren.
zB. an der SAE J2178-2 diese Beschreibt zwar die J1850 Class B
Netzwerke, aber dort ist die Aufteilung der Frames geregelt nach
Systemen. Jedes System enthält wieder Sub-Systeme. Siehe Anhang.

Für CAN Bus gibt es bestehende Specificationen die Du vielleicht
anschauen solltest, die ISO11898,ISO14229,ISO15765 und ISO15031-5(noch
nicht veröffentlicht)

Was ich immer noch nicht verstanden habe warum sollen sich die ID's
der Frames für ein und den selben Dateninhalt dynamisch ändern?
Wenn Du schon ein solches Projekt anfängst, dann must Du dir vorher
auch ein Konzept ausdenken das Beschreibt, welche Daten, mit welcher
Priorität(somit ID) in welchem Zeitzyklus (oder azyklisch) gesendet
werden sollen.
Wie willst Du den Überblick behalten wenn sich dein Bustraffic ständig
ändert. Wie willst Du den Traffic analysieren? Du brauchst ja dann ein
PC Tool, das genau das selbe macht wie Deine Nodes, nämlich
rauszufinden, welche Daten sich gerade hinter einer empfangenen ID
verbergen.

Als Beispiel (wenn ich dich richtig verstanden habe):
Eine Node sendet die Motordrehzahl auf ID 112. Eine andere Node
empfängt diese und setzt die Motordrehzahl auf ID 126 um. Wenn jetzt
noch eine dritte Node die Motordrehzahl braucht, dann muss diese wohl
wissen, das die sich entweder hinter 112 oder 126 verbirgt.
Das macht überhaupt kein Sinn, wenn sich alle 30 Nodes auf dem selben
Bus befinden. Sowas macht nur Sin wenn du zwischen zwei oder mehreren
verschiedenen CAN's die Daten umsetzen must, zB. Motor-CAN und
Cockpit-CAN, jeder mit anderer Geschwindigkeit.

Aber auch dann wäre die ID Umsetzung nicht dynamisch sondern folgt
einem vorgegebenen Schema, ähnlich einer Look-up Table.
Und diese Umsetzung muss ja dann auch nur eine Node machen, und nicht
jede.

Freue mich auf mehr Details ;-)

/Michael

von Michael W. (mictronics) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hmm, Anhang vergessen, hier ist er.

von Steffen Hausinger (Gast)


Lesenswert?

Perfekt! Das sind genau die Tipps, die mir gefehlt haben. Vielen Dank,
Michael! Ich hab's bisher nur geschafft, die Informationen zu den
Normen kurz zu überfliegen. Da werd ich mich am Wochenende genauer mit
beschäftigen.

Mit den "dynamischen" IDs hatte ich es übrigens anders gemeint:
Angenommen ich habe einen Knoten zur Temperaturmessung entwickelt. Nun
baue ich diesen Sensor als Geber für die Motortemperatur ein. Einige
Wochen später möchte ich auch die Kühlwassertemperatur messen und bau
den gleichen Sensor nochmal ein => Konflikt! Ausserdem hatte ich die
Befürchtung, dass mir irgendwann die IDs mit hoher Priorität ausgehen
und das System dann nicht mehr weiterentwickelbar ist. (Was mir selbst
im Nachhinein bei der Anzahl möglicher IDs eher unwahrscheinlich
vorkommt.)

Meine Idee: Ich kann eine Broadcast-Nachricht über den Bus verschicken,
die für alle Knoten gilt. Mit der benenne ich die alte ID des Knoten für
die Motortemperatur um. Es bekommen alle Knoten diese Nachricht und alle
Knoten übernehmen diese neue ID. Nun kann ich meinen neuen Knoten für
die Kühlwassertemperatur anschliessen. Das Ganze dient also der
"In-System" Konfiguration. Ich spare mir so die Liste, in der ich mir
sonst für jeden Knoten die ID notieren müsste.

Ich habe eine Frage zu Deiner angehängten SAE Norm: Ist die auf CAN
gemünzt? Die IDs sind 21stellig...

von Michael W. (mictronics) Benutzerseite


Lesenswert?

Das heist, eine ID Änderung würde nur dann stattfinden wenn sich etwas
am Gesamtsystem ändert.
Aber selbst sowas läst sich einfacher lösen als mit aufwendigen
Filterberechnungen. Du könntest zB. Jumper/DIP-Schalter in Deiner
Hardware nutzen, mit der sich eine ID Range leicht von aussen ändern
läst, ohne umzuprogrammieren.
Aber vorrausschauend könntest Du auch eine 29bit ID aufteilen in
Bitgruppen, mit deren Hilfe sich das System, Subsystem, Knotentyp,
Datentyp usw. klassifizieren läst.

Das Dir die ID's ausgehen halte ich auch für sehr unwahrscheinlich,
zumal Du pro CAN Frame 8 Byte Daten senden kannst. Ein Datenwert wird
aber wohl niemals alle 8 Bytes belegen. Du kannst also mehrere
Datenwerte in einer ID übertragen. Als 8bit, 16bit oder 32bit Wert, je
nachdem welche Auflösung Du brauchst.
Auch hier kann ich Dir nur empfehlen bestehende Standards anzuschauen.
Das eben beschriebene Verfachen wird in SAE J2178-2 behandelt.

>>Ich spare mir so die Liste, in der ich mir sonst für jeden Knoten die
ID notieren müsste.
Wohl kaum, wie willst Du den Überblick behalten ohne Dokumentation?
Auch muss jeder Knoten der Daten empfängt und verarbeitet eine Liste
gespeichert haben, wo drin steht hinter welcher ID sich die Daten
verbergen. Der Unterschied ist nur die Art der ID Änderung bei einer
Systemmodifikation.

>>Ich habe eine Frage zu Deiner angehängten SAE Norm: Ist die auf CAN
gemünzt?
Nein, wie in vohergehenden Post schon angemerkt ist/sind die SAE Spec
für  SAE J1850 Bussysteme, wie sie zB. in Chrysler Fahrzeugen verwendet
werden (ab 2006 auch durch CAN ersetzt).

/Michael

von Steffen Hausinger (Gast)


Lesenswert?

Je länger wir über diese ID-Geschichte reden, desto ungünstiger
erscheint sie mir auch. Von Jumpern halte ich zwar nicht viel,
besonders bei kleinen Sensoren (große Bauform, benötigt I/O). Aber die
kann ich ja durch einen Wert im EEPROM ersetzen.

Ok, dann schaue ich mir heute Abend die von Dir geposteten ISO Normen
und die SAE J2178-2 an. Leider ist das Thema für mich noch relativ
unbekannt, in seinem Hobby interessiert einen ja meist mehr die
technische als die organisatorische Seite. Allerdings, so ganz neu ist
es mir auch wieder nicht (ich erinnere mich an einige langweilige(?)
Vorlesungen dazu).

Danke! Damit hast Du mir ein ordentliches Stück weitergeholfen,
Michael!

Steffen

von Rahul (Gast)


Lesenswert?

Warum verpasst du deinen CAN-Knoten nicht eine eindeutige Nummer (so wie
die MAC-Adresse beim Ethernet oder die Chip-ID beim 1-Wire)?
Dann könntest du über einen Broadcast ("ID-Set-Message") über die
Datenbytes einem Knoten im laufenden Betrieb seine ID zuweisen.
Die "MAC-Adresse" könnte man beim Flashen entweder ins EEPROM oder
mit ins FLASH schreiben; sie sollte einfach nur einmalig vorhanden
sein.
Ansosnten sollte man sich schon einig sein, welcher Sensor/Aktor welche
Priorität bekommt.

von Michael W. (mictronics) Benutzerseite


Lesenswert?

>>in seinem Hobby interessiert einen ja meist mehr die technische als
die
>>organisatorische Seite.

Mag sein, aber bei Deinem Vorhaben wirst Du ohne vernünftige
Dokumentation nicht auskommen. Das wird Dir besonderst dann auffallen,
wenn Du über einen längeren Zeitraum dich nicht damit beschäftigt hast
und wieder etwas dran machen willst.

/Michael

von Steffen Hausinger (Gast)


Lesenswert?

@Rahul: Es geht weniger um eine ID des Knotens. CAN ist ja
nachrichtenorientiert, also die ID gibt keinen Absender an (höchstens
implizit), sondern wovon die Nachricht handelt. Damit sendet ein Knoten
nicht nur eine ID, sondern soviele, wie er Nachrichten erzeugt.
Ausserdem ist das Problem, dass nicht nur der sendende Knoten die ID
der Nachricht ändern muss, sondern auch alle empfangenden. Und mit
dieser Situation bin ich dann bei meiner ursprünglichen Frage
angelangt... Meintest Du das so? (Sorry, kenne mich mit
Ethernet-Protokollen nicht sonderlich aus.)

Inzwischen sehe ich auch keinen richtigen Sinn mehr, die IDs variabel
zu machen. Erst Recht nicht, wenn sowas schon standardisiert wurde. Und
mit der Aufteilung in Gruppen und Untergruppen bekommt die Sache ja auch
eine klare Struktur...


Viele Grüsse,
Steffen

von MNR (Gast)


Lesenswert?

>> CAN ist ja nachrichtenorientiert, also die ID gibt keinen Absender an
(höchstens implizit), sondern wovon die Nachricht handelt.

Das ist interessant. Bis jetzt war ich ja der Meinung, CAN definiert
bestenfalls den physikalischen Layer. Das Protokoll, dass du dann
darauf implementierst, ist ja wohl absolut deine Sache.
In meinem Protokoll hat z.B. jeder Knoten seine eigene AbsenderID(8bit)
 in die Extended CAN-ID codiert.
Des weiteren entscheidet dein Protokoll, ob es Nachrichten oder
Adressenorientiert arbeitet.

BTW, in meinem Netz benutze ich weder Filter noch Masken, der Knoten
(also die SW des Knotens) entscheidet selber, ob er die Nachricht
gebrauchen kann. Da die Zuordnung frei wählbar ist, hält der Knoten
eine Liste von (Sub)IDs, die sich dynamisch ändern kann.

Gruß,
Matthias

von Steffen Hausinger (Gast)


Lesenswert?

Hallo Matthias,

wie ich schon oben schrieb: ich kenne mich wenig mit organisatorischen
Dingen aus. Trotzdem: auch wenn CAN nur den physikalischen Layer
definiert, ist es trotzdem nachrichtenorientiert. Was man in einer
Schicht darüber daraus macht, ist natürlich eine andere Sache. Da
überlasse ich aber Dir das Feld.

Wenn Dein Knoten alle Nachrichten empfängt, hast Du natürlich massig
Traffic zu verarbeiten. Wieso benutzt Du keine Filter?

von Dietmar (Gast)


Lesenswert?

@Steffen Hausinger:

Ja ja, ich weiß, CAN Bus soll ja eigentlich für viele ein Hobby sein!!!
Und da ist es auch eine sehr sehr feine Sache !!!

Zur Zeit staune ich aber nur noch darüber, wie manche Menschen aus
einfachen Dingen gerne was noch komplizierteres machen möchten. Der
CAN-Bus ansich ist doch schon kompliziert genug, oder?

Warum ist eine dynamische Identifier-Generierung notwendig?

Dynamische ID-Vergaben gibt es bei CANopen, aber das ist dann auch
streng organisiert, und für standardisierte Industrie-Anwendungen in
der Automatisierungstechnik.

Kannst du dann auch mit einem CAN Analyzer Tool noch Statistiken
aufzeichnen bzw. verwerten? Eher nicht. Ist die Strategie immer
zuverlässig?

Allgemein, stellt man die Akzeptanzfilter eines Knotens so ein, daß er
nur Nachrichten empfangen darf, die er auch empfangen soll. Das macht
ein- und die selbe Software für verschiedene Knoten und ist kein
Problem, habe ich beim Philips LPC2129 so gemacht: Eine Baugruppe mit
einem Steckplatz in einem Racksystem, in dem der Steckplatz mit ein
paar Pins auf der Backplane binär kodiert ist und die Steckplatznummer
darstellt, die so in den Identifier eingeht? Die Steckplatznummer wird
per Software gelesen, und danach die Akzeptanzfilter eingestellt.

Weiter, stellt man diese Knoten so ein, daß sie nur Identifier senden,
die kein sonstiger Knoten mehr senden darf.

Dann ist man schon im grünen Bereich.

Das ist das interessante am CAN Bus: Man kann dort wegen der Strategie
einen Knoten hinzufügen oder wegnehmen, ohne den anderen zu schaden.

Über das Identifier Vergabeschema sollte man sich vorher einen genauen
Plan machen (Lastenheft, Pflichtenheft): Normale Messages erhalten
einen mittleren Identifier (etwa ab 0x200), Fehlermessages einen sehr
kleinen (ab 0x000, meist wichtig), weniger wichtige Messages einen
höheren (vielleicht ab 0x400), o.ä.. Das muß nicht zwangsläufig einer
Norm entsprechen.

Mit dem Identifier wird es zudem komplizierter, wenn dieser durch
Bitgruppen wie z.B. Line-Nummer, Gruppe, Stern, durch ein
komplizierteres Leitungssystem nach der Leitungstopologie kodiert bzw.
bestimmt wird.

Ansonsten: Den Möglichkeiten der Nutzung von ID, Hierarchien und
Datensätzen, sind beim CAN-Bus grundsätzlich keine Grenzen gesetzt: Die
sind unendlich. Wer nur gerne einen Audio-Stream life über den CAN-Bus
übertragen möchte: Bitte, gerne, mit 1 Mbit/s gut denkbar.

Eine ältere Auswertestruktur ist die so genannte Multiplexed ID, indem
man z.B. das Byte 0 des Datenfeldes noch als erweiterten Identifier zur
Auswertung heranzieht.

Literatur und Sourcen:

Für Philips LPC 2000 Serien (ARM7) gibt es hier CAN Beispielsoftware:

http://www.keil.com/download/docs/291.asp

Buchvorschläge:

Horst Engels: CAN-Bus
Franzis Verlag
ISBN 3-7723-5146-8

Wolfhard Lawrenz: CAN Controller Area Network
Hüthig Verlag
ISBN 3-7785-2780-0

Gruß

Dietmar

von MNR (Gast)


Lesenswert?

>>Wenn Dein Knoten alle Nachrichten empfängt, hast Du natürlich massig
Traffic zu verarbeiten. Wieso benutzt Du keine Filter?

Weil mein Protokoll sowohl Event- als auch Adressorientiert arbeitet.
Und Events können potentiell jeden interessieren. Der Knoten ist dazu
da, Traffic zu verarbeiten, das ist schon ok so. Theoretisch müßte ich
die Filter auch recht aufwendig berechnen, wollte ich welche verwenden,
aber ich sehe keinen Sinn darin. Der Knoten verarbeitet die Events
anhand von Listen, und gut ist. Dazu herrscht auf meinem Bus auch nicht
viel Traffic, da Hausbus...

Gruß,
Matthias

von Steffen Hausinger (Gast)


Lesenswert?

Ja, inzwischen bin ich ja davon schon ab, die IDs dynamisch zu
verteilen. Michael hatte mich doch schon überzeugt.

Nur, ich sitze hier an meinem Schreibtisch, denk mir irgendwelche
Aufgaben aus und programmiere sie dann. Von den ganzen Normen weiß ich
nichts und ein Lasten- oder Pflichtenheft mache ich mir auch nicht. Und
ohne diese Vorgedanken kommt es häufig vor, dass man im Nachhinein etwas
ändern muss. Aus dieser Situation entstand die Idee mit den dynamischen
IDs und - ehrlich gesagt - nahm ich auch an, dass man in der Praxis es
auch so macht. Schließlich wird doch sonst auch kaum etwas konstant und
unveränderbar gelassen.

Jetzt, im Nachhinein, bin ich froh hier Tipps von Euch zu bekommen. Und
mit einer klaren Struktur bei den IDs lebt es sich garantiert einfacher.
Darüber war ich im vorher gar nicht mal im Klaren.

Danke für Deine Tipps und die Literaturvorschläge (die Bücher sind ja
sogar auf deutsch!).

Steffen

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.