Bitblöcke auslesen

OP #436605
Lesenswert?
• ▲
▼
Hallo,

ich würde gerne möglichst effizient CAN Nachrichten auswerten. Diese
bestehen immer aus 1..8 zusammenhängenden Bytes. Beispielsweise kann ein
Signal bei bit 2 starten und 10bit lang sein. Ich wollte nun
schrittweise immer zwei Byte (damit maximal 16Bit breite Worte) mit
einem Short-Zeiger auswählen und dann mit entsprechender Maskierung
verUNDen. Leider lässte der kompiler die conversion von char* zu short
int* nicht zu.

Folgendes wollte ich also tun:

short * block;
char msg[]="ABCDEFG";

/*lenght soll die länge meine wortes in bit angeben, starbit ist
selbsterklärend*/

block = &msg; // also damit sollte der short auf das untere Byte zeigen
block = block & ((short)(pow(2,length) << startbit));

nun sollte eigentlich meine nachrichtig fertig maskiert in block stehen,
sodass ich diese nur wieder um startbit in die gegenrichtung shiften
müsste.

gibt es vielleicht eine elegantere lösung, um aus einem 2er Byteblock
einen beliebig langen (max16) bitblock zu lesen?

grüße und danke für ideen,
toby
OP #436743
Lesenswert?
• ▲
▼
Danke, aber das hilft mir nicht viel weiter. Ich kann doch bits aus 
bitfelder nicht mit einem befehl beschreiben, jedenfalls steht das 
nirgends in den definitionen...

für den fall ich hätte ein bitfeld mit b0 bis b7 wäre ein befehl:

bitfeld.b0 = 0x41; recht brauchbar, wenn er die anderen bits nach b0 
überschreiben würde. funktioniert aber nicht.
Weitere tips?

gruß,
toby
#436789
Lesenswert?
• ▲
▼
2 Sachen:

1.
pow() ist eine float-Funktion, d.h. es dauert ewig lange und kostet zich 
kB Code. Beschäftige dich besser mal mit Schiebeoperatoren.

2.
Die Byteorder in mehrbytigen Variablen ist nicht definiert.
Was auf der einen CPU mit dem einen Compiler funktioniert, kann Dir mit 
ner anderen großen Mist produzieren.
Daher macht man es üblicher Weise kompatibel:
1
short val = byte_low | (byte_high << 8);



Um nun z.B. die Bits 2..9 zu extraieren, maskiert man oben und schiebt 
nach unten:
1
val9_2 = (val & (1 << 9 + 1) - 1) >> 2;


Peter
OP #436943
Lesenswert?
• ▲
▼
Hallo Peter!

Vielen Dank für die Hilfe, die Möglichkeiten der Bitoperationen habe 
ich, wie es scheint, nicht ausgenutzt.

Ich versuche gerade die Bitextraktion zu verstehen. Irgendwie steh ich 
auf dem Schlauch.

val9_2 = (val & (1 << 9 + 1) - 1) >> 2;

Wie läuft dieser Vergleich ab? wozu die -1? Welche Operation hat vorrang 
in der klammer?


vielleicht ist es einfach schon ein bisschen spät! Auf jeden Fall 
funktioniert es schon mal!

Gruß,
Toby
#436952
Lesenswert?
• ▲
▼
> Wie läuft dieser Vergleich ab

In diesem Ausdruck ist kein einziger Vergleich!

  >>  bedeutet 'bitweise nach rechts schieben'
  <<           'bitweise nach links schieben'

  i = k << 2;

der Inhalt wird also um 2 Bits nach links verschoben und das
Ergebnis wird i zugewiesen.

Zu deinem ursprünglichen Ansatz:
> leider .. char* zu short int* nicht zu.

Ja, klar. Ein Pointer auf int ist nunmal kein Pointer auf char.
Wenn du allerdings sicher bist, dass du genau das willst,
dass der Compiler so tut, als ob der Pointer auf char
einer auf int wäre, kannst du ihn immer überstimmen: mit
einem Cast

block = (short*) &msg;

Aber Vorsicht: Ein Cast ist eine Waffe. Effektiv schaltest du
damit das Typ-Prüfsystem des Compilers ab und zwingst ihn die
Zuweisung wider besseren Wissens zu akzeptieren. Der Programmierer
sollte also besser wissen was er hier tut.

Die Anmerkungen bezüglich Nicht-Portabilität gelten natürlich
weiterhin.
#437014
Lesenswert?
• ▲
▼
> aber was macht die -1?

Probiers doch einfach aus!
Hinweis: Du musst dir das binär, also auf Bitebene ansehen.

Die Fragestellung lautet: wenn du eine Binärzahl hast
die eine 2-er Potenz ist ( 1 << x liefert logischerweise
immer eine 2-er Potenz) und dann 1 davon abziehst, wie
sieht dann das Ergebnis aus, welchem Muster folgt es?

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.