Motorola zu Intel konvertieren ....
-
Ich hab nen 32 bit integer, der kommt ueber unsere Messtechnik (auf Intel abgestimmt) im Motorola Format an (der Bus uebertraegt das zeug bitweise, Nur gibts dafuer keinen standard, ob die most signifikanten bytes zuerst oder zuletzt gesendet werden). Nun hab ich den wert in nem UINT liegen, allerdings genau spiegelverkehrt. Bit 0 muss an stelle von bit 31, bit 1 an stelle von 30 .... usw
Gibts dafuer ne fertige funktion ? das ganze soll natuerlich auch noch performant sein, da es zur Laufzeit die signale dekodieren muss .... WIll da ned erst mit nem Bitset anfangen oder was kompiliziertes schreiben wenns dafuer schon was gibt ...
Kennt da wer was ?
Ciao ...
-
man hton
und co.ciao,
jenz
-
Die Shiftoperatoren sollten helfen können.
Ist zwar schon ein wenig peinlich (die ersten Gehversuche in C) der Code aber vllt. hilft der Dir weiter:
-
sind bei dir wirklich alle bits verdreht? normalerweise sind nur die bytes anders herum, so dass man (z.b. 16-bit werte) mit a = b>>8 | b<<8 wieder in's passende format kriegt. ansonsten guckst du hier: http://graphics.stanford.edu/~seander/bithacks.html
-
wie gesagt, die Bits sind wirklich verdreht.
Der Bus ueber den das geht, spezifieziert das ned. Bisher hatten wir nur den Fall, das an so nem Bus nur Steuergeraete hingen die die daten nach Intel spezifaktion verschicken. Unsere messtechnick iss auch auf Intel aufgebaut.
Seit neuseten haben wir aber einen Bus, wo nur Motorola zeugs dran ist, und die schicken das zeugs wirklich bitverkehrt uebern bus.
Wir setzen auf teilweise unterschiedlicher Hardware auf un bieten da ne einheitliche oberflaeche. Bei einigen Treibern kann man einstellen, welche HW da dranhaengt (motorola, Intel .. und noch paar zwischenformen). Aber einige koennen nur Intel. Also muessen wir es selber machen ....
@jenz
hton und co tauscht nur die byteorder, nicht die bitorder. bei tcp/ip (oder eher bei den darunter liegenden protokollen) ist definiert, an welcher stelle das most signifikante bit kommt, also wandelt es da die HW bzw die treiber scho ...Ciao ...
-
RHBaum schrieb:
Seit neuseten haben wir aber einen Bus, wo nur Motorola zeugs dran ist, und die schicken das zeugs wirklich bitverkehrt uebern bus.
na, dann musste die dinger nur richtig herum anschliessen...
-
hm, wenn die wirklich verdreht sind habe ich natürlich mal wieder nicht geholfen.
dann würde ich vorschlagen, dass die einleseroutine verändert wird ich stelle mir das mit meiner glaskugel mal so vor:unsigned int read_from_bus() { unsigned int erg(0); unsigned int mask(1); for (unsigned int i(0);i<32;++i) { if (bit_from_bus()) { erg += mask; } mask <<= 1; } return erg; }
oder man fängt mit der maske beim höchsten bit an und schiebt es dann immer runter.
so kann man sich die reihenfolge der bits doch schon beim einlesen einstellen.
wahrscheinlich habt ihr das doch auch so gemacht, oder?jetzt bin ich gespannt, wie klar meine glaskugel wirklich sieht
ciao,
jenz
-
jenz schrieb:
...ich stelle mir das mit meiner glaskugel mal so vor:
die glaskugel hat aber lange keinen staublappen mehr gesehen. schön immer 32 additionen und shifts pro datenwort, das ist ja in puncto speed nicht mehr zu toppen...
-
und was schlägst du dann vor, wenn die daten bitweise eintrudeln?
-
jenz schrieb:
und was schlägst du dann vor, wenn die daten bitweise eintrudeln?
naja, z.b. einlesen wie's kommt und dann (am besten wenn nix auf dem bus los ist) einen der bitverdreher-algos aus dem link da oben einsetzen. oder vielleicht 'ne hardware davorbasteln (irgendwas mit schieberegistern o.ä.) so als konverter zwischen dem motorola und intel bussystem...
-
Ich wollt eigentlich nur wisssen ob es da ne fertige funktion in irgend ner öffentlichen schon fuer gibt .. weil kann ja sein das ich ned der einzige bin der das Problem hat.
Ok, aber scheinbar werd ichs selber schreiben muessen.
wegen der performane werd ich das zeugs in bytebloecke zerhacken und die bytes erst mal tauschen ... danach die bits.
Da ich mir das rumgeschleife zur laufzeit ned antun will, werd ich wohl nen 256 byte grosses array bauen, wo ich uebern index das spiegelverkehrte byte auslesen kann. das array brauch ich dann nur einmal zu initialisieren ....da beim initialisieren die laaufzeit nimmer so kritisch ist, kann ich da bitset<8> fuer nehmen.
oder hat jemend noch ne bessere Idee ?
Ciao ...
-
naja, z.b. einlesen wie's kommt und dann (am besten wenn nix auf dem bus los ist) einen der bitverdreher-algos
okay, es kommt bitweise... was machst du da um die nacheinander in einen int reinzubekommen
additionen oder nicht?
auch 32 aber eben in der falschen richtung und ne maske brauchst du auch.und hardware davor ist ja auch ganz nett, aber das geht immer...;-)
die einleserouting sollte natürlich nicht blockieren. insbesondere
bit_from_bus())
sollte die rechenzeit wieder an andere prozesse abgeben.
aber sonst sehe ich da jetzt keinen riesen vorschlagejenz
-
mich würde wirklich noch mal das Einlesen der Daten interessieren.
Falls du das mal posten könntest...danke,
jenz
-
jenz schrieb:
okay, es kommt bitweise... was machst du da um die nacheinander in einen int reinzubekommen
additionen oder nicht?
auch 32 aber eben in der falschen richtung und ne maske brauchst du auch.nö, selbst wenn man's nacheinander, sozusagen 'online' macht, braucht man nur ein paar 'oders' mit 'ner lookuptable in der die bits umgedreht sind.
btw: aber wir wissen ja nicht wie schnell's ein soll. vielleicht trudeln die bits nur mit ein paar kHz ein, dann ist das ja alles egal
-
Das einlesen geht ueber unterschiedliche API's die ich vom hersteller bekomme ....
bei einem muss ich pollen .... beim anderen muss ich dem nen zeiger aufn Event geben, der setzt das event wenn ne nachricht eintrifft, und dann dann kann ich mir nen Array mit daten abholen ....
die API's geben die Daten schon telegrammorinetiert raus ... also ich bekomm nen array von ner Struct.
In der struct stehen
zeitstempel (64bit int),
telegrammID(16 bit Int),
DLC(laenge der nutzdaten in byte, 8bit int),
und nen char[8] array (8 ist max laenge)TelegramID ist spezifiziert, die kommt auch richtig rum an .... weil die telegrammID auch was mit der Prioritaet aufn Bus zu tun hat (iss nen serieller Bus mit 1 oder 2 leitungen)
DLC kommt auch richtig rum an (istd spezifiziert), weil die auch fuer die uebertragung und stopbits usw wichtig ist.Nur bei den Datenbytes ist es nicht spezifiziert ...
Die telegramme Sind in Signale aufgeteilt. diese signale werden in ner Zentralen DB gepflegt. Da steht dann drinn, das bspweise am telegram 0x116 das bit 8 - 15 nen Signal X enspricht ... fuer das Signal gibts dann Offset und Aufloesung so dass man sich den realen wert mit offset + x*aufloesung errechnen kannwie gesagt bei den Motorola buss iss nu alles verkehrt rum ... waehrend ich in der DB wenigstens schon mal die Startbits der signale umrechnen kann, kommen am treiber die Bytes nun aber bitverdreht an ...
Das nur zur allgemeinen Info ... wer jetzt wegen den 8 Byte laenge an CAN denkt, liegt auch genau richtig ...
die ganze anbindung an den CAN-Bus der Stg's wird von industriellen CAN-Controllern uebernommen, da sind also TelegrammID und laenge spezifiziert. Aber was in den Daten drinnesteht, intressiert die controller nich, sondern das wird von den FPGA's oder CPU der STG's befuellt. wenn da nun einige Motorola Teile verwenden, schreiben die einfach die eigenen Speicherbereiche in die puffer der CAN Controller, und die sind gegenueber Intel bitverdreht ... intressiert aber nich, weil alle stg's am buss (monentan noch) dann motorola sprechen.
Nur wir muessen die Daten interpretieren ... und die meisten karten schieben eh nur den puffer der CANController in den Speicher des PC's (Intel) und voila, alles ist verdreht ^^Willst wirklich noch ne ausleseroutine sehen ? ^^
btw: aber wir wissen ja nicht wie schnell's ein soll. vielleicht trudeln die bits nur mit ein paar kHz ein, dann ist das ja alles egal
eigentlich human .... 500kbit bei extrem schlechter nutzdatenrate ^^ (CAN halt)
im schnitt max 3800 Nachrichten = 2+1+8 byte pro sekunde ... der zeitstempel wird beim empfang generiert.
Problem ist, dass unsere SW auch auf mobilen industrierechnern laufen muss, die haben zwar windows drauf, aber die rechenleistung ist ... urks ^^ glaub die miesesten haben nen 500Mhz cyrix prozessor oder so. Da kommts eben halt auch extrem aufn stromverbrauch und temperatur / ruettelfestigkeit an ....
Ciao ...
-
@net ich will ja jetzt nicht drauf rumreiten, aber auch wenn du oderst brauchst du eine maske...
und ein oder ist auch nicht schneller als ein add vielleicht früher mal.bitte pseudocode mir das doch mal "online" bitweise ohne maske.
das umdrehen per lookuptable kann man sich dann auch gleich schenken..wenn man die daten natürlich von nicht änderbarem code bekommt, dann kann man natürlich nichts machen. aber ob dann der umdrehen per lookuptable schneller ist, als ein bitweises übertragen von register zu register, das wage ich dann doch zu bezweifeln.
aber das bezweifel ich auch einfach aus der lust heraus.nicht, dass es wirklich wichtig wäre
vielleicht hat ja trotzdem jemand lust, das mal auszumessen. bestimmt ne ganz gute anfänger übung...ciao,
jenz
-
jenz schrieb:
bitte pseudocode mir das doch mal "online" bitweise ohne maske.
ganz einfach, so ungefähr
unsigned long table[32] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, ... ... ... 0x20000000, 0x40000000, 0x80000000, } ... unsigned long result = 0; int s; for (s=0; s<32; s++) { if (read_bit() == 1) // hi-bit kommt als erstes result |= table[s]; } // result enthält nun umgedrehtes bitmuster ...
@RHBaum
was habt ihr denn für'n adapter am pc der die can-messages bitweise abliefert? sowas ist doch eher ungewöhnlich
-
das geht dann allerdings auch ohne LUT, indem wir die maske als laufvariable der schleife missbrauchen (vorausgesetzt, der entsprechende typ ist exakt 32bit breit):
unsigned result = 0; for (unsigned mask=1; mask!=0; mask<<=1) { if (read_bit() == 1) // hi-bit kommt als erstes result |= mask; }
-
@net, na da hast du ja mal eine richtig tolle lösung gefunden.
du schreibst also lieber die ganzen masken hin, anstatt die zu schiften?
so ganz kann ich das leider nicht akzeptieren.zumal der nächste auch gleich wieder die maske vorschlägt. natürlich ein bisschen cleverer implementiert als ich aber mit maske...
ciao,
jenz
-
jenz schrieb:
@net, na da hast du ja mal eine richtig tolle lösung gefunden.
du schreibst also lieber die ganzen masken hin, anstatt die zu schiften?
so ganz kann ich das leider nicht akzeptieren.toll ist das alles nicht (wegen der 32 schleifendurchläufe). aber lookuptables sind immer ein tickchen schneller. kannst es ja mal testen (beide versionen einige millionen mal aufrufen und zeit messen).