Guten morgen, ich soll für ein Projekt Debug-Nachrichten über CAN verschicken. Das funktioniert auch schon (Die Funktion zum senden ist ja schon vorgegeben). Diese werwartet die Adresse (an wem ich verschicke, uint8 array (mit den Daten) und die Anzahl der Daten. Aber wie kann ich Jetzt habe ich hier aber werte, welche sint16 sind. Wie kann man diese denn am besten verschicken? Für die Anderen Nachrichten habe ich ein Array welches uint16 Werte erwartet (das sind nämlich die meisten werte), welches ich dann beim Funktionsaufruf auf uint8* caste.
Sebastian schrieb: > Diese werwartet die Adresse ... und die Anzahl der Daten. > Aber wie kann ich Jetzt habe ich hier aber werte, welche sint16 sind. Wie soll man das verstehen? > Wie kann man diese denn am besten verschicken? Indem man die Bits auf mehrere Datenbytes verteilt: https://images3.programmersought.com/555/31/311da57148fbf07dcf259f58cfdb17fb.JPEG Sender und Empfänger müssen sich nur über die Reihenfolge einig sein: Lo-Byte oder High-Byte zuerst. In fertiger CAN-Software wird das Intel- und Motorola-Byte-Order genannt.
Du schreibst deinen sint16 Wert in das Array. Wenn ich deinen Text richtig interpretiere, müsste das Schreiben ausserhalb der Sendefunktion erfolgen. Du müsstest allerdings folgendes wissen: An welche Stelle im uint8 Array soll der Wert geschrieben werden? In welcher Byteoder (LSB oder MSB) wird auf dem Bus gesendet? Mal ein Beispiel: uint8 txData[8] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}; sint16 dbgValue; txData[0] = uint8((dbgValue&0xFF00)>>8); txData[1] = uint8(dbgValue&0x00FF); SendeCAN(txData, 8); Dieses Beispiel geht von Byteorder MSB aus und legt den dbg-Wert auf Byte 0 und 1 im CAN Frame.
Sebastian schrieb: > Nachrichten habe ich ein Array welches uint16 Werte erwartet (das sind > nämlich die meisten werte), welches ich dann beim Funktionsaufruf auf > uint8* caste. dann nimm halt ein sint16 Array und caste es auf uint8*
Martin schrieb: > dann nimm halt ein sint16 Array und caste es auf uint8* Das habe ich jetzt auch mal getestet und den zu sendenden wert festgelegt
1 | tmp_16 = -200; |
2 | debug_au16[0] = tmp_16; |
3 | debug_au16[1] = 200; |
4 | debug_au16[2] = 0xFF; |
5 | debug_au16[3] = 0xFF; |
6 | canSend(0x111, (uint8*)debug_au16[0], 8); |
jetzt sehe ich im CAN-Trace, dass byte[0]=0x38, byte[1]=0xFF, byte[2]=C8, byte[3]=0x00, byte[4]-byte[7]=0xFF wie kann ich denn von diesem Wert (0x38 und 0xFF) auf die -200 schließen?
Der Empfänger muß feststellen können, welches Byte im Paket welche Bedutung hat, d.h. Du brauchst ein Protokoll, was man parsen kann. Man kann sich ein Protokoll selber ausdenken oder irgendein Standardprotokoll nehmen. Gerne werden Strings genommen, da man die in einem Terminal direkt lesen kann. Da Stringnachrichten oft >8 Byte sind, braucht einen Pakettyp, der aus mehreren CAN-Nachrichten besteht.
Peter D. schrieb: > Gerne werden Strings genommen, da man die in einem Terminal direkt lesen > kann. Da Stringnachrichten oft >8 Byte sind, braucht einen Pakettyp, der > aus mehreren CAN-Nachrichten besteht. Über ein Transportprotokoll? Ich würde den einfacheren Weg gehen, die sint16 im CANdb-Tool in der gewollten CAN-Message zu definieren, damit das dann im CAN-Trace oder im CAN-Graphen korrekt skaliert angezeigt wird. Dann in der ECU bzw. PLC entsprechend dieser Definition befüllen. Den Rest erledigt INCA/CANoe/CANape/... dann von selbst. Wenn der TO einen XCP-Server auf dem Steuergerät/Industriegerät zum laufen bringt, geht es mit einem XCP-client wie z.B. eben INCA oder CANape noch einfacher. Über ein generiertes A2L bzw. aus ELF generiertem A2L kann dann Wahlfrei jede Variable angesehen und ggf. Manipuliert werden. Wie ein Debugger eben :) mfg mf
:
Bearbeitet durch User
Sebastian schrieb: > canSend(0x111, (uint8*)debug_au16[0], 8); Damit castest du den Inhalt vom Arrayeintag 0. Wenn du die Adresse vom Array haben möchtest, nimmst du nur den Namen (oder den Adressoperator für Index 0)
1 | canSend(0x111, (uint8*)debug_au16, 4 * sizeof(debug_au16[0])); |
Sebastian schrieb: > wie kann ich denn von diesem Wert (0x38 und 0xFF) auf die -200 > schließen? Gar nicht, sind ja die falschen Werte. Mach dich mal über Zweierkomplement und Endianess schlau. Dazu gibt es Wikipediabeiträge.
Sebastian schrieb: > wie kann ich denn von diesem Wert (0x38 und 0xFF) auf die -200 > schließen? Du könntest dich mal ein bissl bemühen, und dir aneignen wie Zahlen in der Digitalen Welt gespeichert werden. Stichwort Binärzahlen. Dazu gibt es viel in der Literatur und im Internet zu lesen. http://www.scalingbits.com/book/export/html/46 0xff38 hex = -200 dec 0x0000 - 1 = 0xffff 0x0000 - 2 = 0xfffe
Sebastian schrieb: > wie kann ich denn von diesem Wert (0x38 und 0xFF) auf die -200 > schließen? Mach dich mal über Zweierkomplement und Endianess schlau. Dazu gibt es Wikipediabeiträge.
Serialisierung Die dort vorgestellte µSer-Bibliothek kann signed Integer in verschiedenen Formaten kodieren/dekodieren. Peter D. schrieb: > Da Stringnachrichten oft >8 Byte sind, braucht einen Pakettyp, der > aus mehreren CAN-Nachrichten besteht. Zahlen als Strings über CAN verschicken ist nicht sehr zweckmäßig.
Niklas G. schrieb: > Zahlen als Strings über CAN verschicken ist nicht sehr zweckmäßig. Es sind ja nicht nur reine Zahlen. Meine Nachrichten sind so aufgebaut: "Befehl Parametername Wert1 [Wert2] [...]\n" Ich brauche also nur einen allgemeinen Sniffer, der CAN-Pakete zu einer Stringnachricht aneinander reiht und anzeigt. Das Aneinanderreihen geht ganz einfach. Das erste Byte kennzeichnet den Stringtyp bzw. ist die fortlaufende Nummer der zu einer Nachricht gehörenden CAN-Pakete (max 16). Ich kann dann Befehle beliebig hinzufügen oder ändern, ohne das ich jedesmal einen neuen Interpreter brauche. Wir hatten früher auch binär benutzt, aber das war fürs Debuggen ein Graus. Alles nur kryptische Hex-Bytes.
Peter D. schrieb: > Wir hatten früher auch binär benutzt, aber das war fürs Debuggen ein > Graus. Alles nur kryptische Hex-Bytes. Schon mal CANoe mit DBC-Daten benutzt? Das dekodiert alles automatisch und stellt es lesbar dar. Wenn man eine Nachricht ändert klickt man das in CANdb++ fix zusammen, da muss man keinen neuen Interpreter bauen. Im Idealfall generiert man sowieso den Code aus den DBC-Dateien, sodass man die Definition der Nachricht nur 1x machen muss. CAN ist sowieso schon langsam, das dann noch mit String-Kodierung noch weiter auszubremsen... Dann auch noch die Fehlerbehandlung, wenn einzelne Nachrichten in der Folge fehlen... Und wenn für CANoe das nötige Kleingeld fehlt: Einfach den selben Code für den Controller wie für die Analyse auf dem PC nutzen, z.B. eben in der Form der Deklarationen der µSer-Library. Dann schreibt man es 1x im Code hin und verwendet ihn für beide Seiten. Peter D. schrieb: > "Befehl Parametername Wert1 [Wert2] [...]\n" Das riecht nach dem "Inner Platform Antipattern". CAN hat bereits eine Nachrichtenkennung ("Befehl"), die ID. Noch eine weitere ID zu übertragen, die von der Hardware dann auch nicht gefiltert werden kann, ist redundant. Parameter-Namen ständig erneut zu übertragen frisst unnötig Bandbreite. CAN ist sowieso nicht Plug-And-Play, man muss sowieso alle Teilnehmer explizit anpassen oder konfigurieren.
:
Bearbeitet durch User
Niklas G. schrieb: > Wenn man eine Nachricht ändert klickt man das > in CANdb++ fix zusammen, da muss man keinen neuen Interpreter bauen. Das geht bei uns nicht. Der CAN-Bus geht nicht direkt auf den PC, sondern die Nachrichten werden per Ethernet an den PC übertragen. Daher ist das Stringformat sehr bequem. Niklas G. schrieb: > CAN ist sowieso schon langsam, das dann noch mit String-Kodierung noch > weiter auszubremsen... Das muß man schon dem Anwender überlassen, ob da was bremst. Wir haben natürlich vorher untersucht, ob das Stringformat für unsere Anwendungen schnell genug ist und das ist es.
Peter D. schrieb: > Das geht bei uns nicht. Warum? Dann baut halt einen Interpreter welcher mittels DBC-Dateien das Binärformat interpretiert, was zuvor per Ethernet verschickt wurde. Peter D. schrieb: > Wir haben > natürlich vorher untersucht, ob das Stringformat für unsere Anwendungen > schnell genug ist und das ist es. Okay, aber das ist dann eine Lösung die nur in diesem Spezialfall funktioniert. Viele Fahrzeuge und Anlagen haben sogar mehrere CAN-Netzwerke, u.a. weil ein einzelnes nicht genug Bandbreite hat. CAN-FD wurde auch deshalb erfunden. Für diese Anwendungen sollte man also lieber eine Binärkodierung verwenden. Natürlich auch, weil praktisch alle CAN-basierten Systeme auf dem Markt das eben so machen.
Peter D. schrieb: > Gerne werden Strings genommen, da man die in einem Terminal direkt lesen > kann. Dafür ist CAN aber nicht gedacht. Es kann ja auch passieren das ein anderer Client eine Nachricht dazwischen funkt und schon ist dein String futsch. In deinem speziellen Fall mag das evtl. nicht möglich sein aber das zu verallgemeinern ... hm? Ausserdem geht das ganz schön auf die Datenübertragungsrate, also bei Zeitkritischen Anwendungen auch eher nicht geeignet. Die Jungend von heute ... tztztz. Früher konnten Programmierer noch programmieren und konnten noch mit Hex und Bin umgehen. ;-)
Martin schrieb: > Die Jungend von heute ... Nö, im Alter (ü60) will man es schön bequem haben. Ich schreibe auch keine Windows-Anwendungen. Ein Kollege hat mal das UDP-Terminal geschrieben und ich benutze es nur, um die CAN-Module anzusprechen. Ich kann damit an der eigentlichen Steuerung vorbei mit den Modulen sprechen, d.h. auch im Betrieb. Das funktioniert sogar im Homeoffice.
>Sender und Empfänger müssen sich nur über die Reihenfolge einig sein: >Lo-Byte oder High-Byte zuerst. In fertiger CAN-Software wird das Intel- >und Motorola-Byte-Order genannt. Auch das wird im DBC File festgelegt, genauso wie die ID Nachrichten, sowie die Zykluszeiten. Ich bin der Meinung für dein anliegen empfiehlt es sich das TP-Protokoll aufzusetzen, falls du mit dem Payload von 8 Byte nicht auskommst. https://de.wikipedia.org/wiki/ISO_15765-2
Udo schrieb: > Du müsstest allerdings folgendes wissen: > ... > In welcher Byteoder (LSB oder MSB) wird auf dem Bus gesendet? Was spielt das für eine Rolle? Hauptsache Sender und Empfänger machen es gleich ;-)
Wolfgang schrieb: > Udo schrieb: >> Du müsstest allerdings folgendes wissen: >> ... >> In welcher Byteoder (LSB oder MSB) wird auf dem Bus gesendet? > > Was spielt das für eine Rolle? > Hauptsache Sender und Empfänger machen es gleich ;-) Naja, wenn man die beiden entwickelt, sollte man das schon wissen. Wie soll man sonst sicherstellen, dass sie es gleich machen?
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.