Hallo Gemeinde!
Ich komme grad nicht recht weiter, ich habe hier ein Integerfeld der
Länge 8, dass etwa folgendermaßen ausschaut:
xxxx 1101 0101 1001 | 1001 1111 0101 0010 | xxxx ....
soll heißen: die hochwertigsten vier Bits jedes zweiten Integers sind
immer hinfällig, dann kommen 12 Nutzbits, dann der nächste Integer mit
16 Nutzbits und dann wieder einer mit nur 12.
Alle Nutzbits hintereinander sind vom Typ
Label(4bits) | Daten (0-16bits) | Label(4bits) | Daten(0-16bits) ...
Die Länge und der Typ der Datenfelder ist durch das vorhergehende Label
bestimmt. Ich hol mir also das Label, weiß dann was für Daten darauf
folgen, hole mir diese und kann diese dann dekodieren. Hier komme ich
ins Straucheln, da ja wie gesagt die Länge der Datenbereiche variiert.
Natürlich könnte ich das ganze in einer ewigen if-else - Anweisung
abarbeiten, aber es müsste doch auch eleganter gehen.
Ich hoffe es hat jemand einen Tipp für mich,
Danke und Gruss
luggi.
Danke,
in Richtung Struct hab ich auch schon nachgedacht, aber wie soll ich
denn die Bits in den Struct packen?
Ich seh´s irgendwie noch nicht so recht...
luggi wrote:
> Die Länge und der Typ der Datenfelder ist durch das vorhergehende Label> bestimmt. Ich hol mir also das Label, weiß dann was für Daten darauf> folgen, hole mir diese und kann diese dann dekodieren. Hier komme ich> ins Straucheln, da ja wie gesagt die Länge der Datenbereiche variiert.
Schreibe als erstes mal eine Funktion, die aus dem Integerfeld die
jeweils nächsten Bits extrahiert, und zwar abhängig von einem Parameter:
1
uint16_tGetBits(uint8_tanzahl){
Dann kannst du erstmal 4 Bits "abholen", und dann jeweils entscheiden,
wie viele du als nächstes brauchst.
luggi wrote:
> in Richtung Struct hab ich auch schon nachgedacht, aber wie soll ich> denn die Bits in den Struct packen?
Mit einer Struct geht das nicht wirklich gut, da ja die Datenfelder eine
variable Länge haben.
Stefan Ernst wrote:
> luggi wrote:>>> in Richtung Struct hab ich auch schon nachgedacht, aber wie soll ich>> denn die Bits in den Struct packen?>> Mit einer Struct geht das nicht wirklich gut, da ja die Datenfelder eine> variable Länge haben.
Ist zwar eigentlich nicht erlaubt, aber was solls.
So wie ich das verstanden habe, sind zwar die Datenfelder zwar variabel
lang, aber nur in Bezug auf den Labeltyp.
Man könnte also für jeden Labeltyp eine eigene Struct definieren und die
mit einem Cast über die Daten stülpen.
Je nach label, wird dann der Datenpointer zurechtgecastet und auf die
Daten zugegriffen.
Bitfelder:
struct a
{
unsigned int Dummy : 4;
unsigned int Label : 4;
unsigned int Data : 12;
}
Dummy belegt 4 Bits, Label ebenfalls und Data besteht aus 12 Bits.
Herausfinden musst du noch, ob dein Compiler bei der Bitnummerierung
beim MSB oder beim LSB anfängt. Gegebenenfalls die Reihenfolge umdrehen
und beten, dass sich das nie ändern wird.
Nun, ich habe das etwas anders verstanden:
Die Rohdaten liegen in 28-Bit-Gruppen vor (in jeweils 4 Byte). Mehrere
dieser Gruppen zusammen bilden die eigentlichen Nutzdaten. Und in diesen
liegen dann mehrere dieser Label/Data-Paare direkt hintereinander. D.h.
die genau Bitposition des zweiten Paares in den Nutzdaten hängt davon
ab, wie lang das erste Paar war. Ich sehe nicht, wie das einfach mit
Struct/Union zu handhaben wäre. Man müsste das ganze schon erst seriell
"aufsplitten".
Danke schonmal für die Mühen!
Stefan hat recht,
es ist ein Feld aus 8 x 16bit Integer, zB.:
feld[0] = xxxx 0001 0010 0011 0111
feld[1] = 0101 0110 0111 1000 1001
feld[3] = xxxx 1010 1011 1100 1101
usw.
Bei den geraden Indizies sind die hochwertigsten 4bit Müll, bei den
ungeraden nicht.
hier im Beispiel schauts also so aus:
Label_1 = 0001 --> Data_1 ist 3bit lang: 001
Label_2 = 0 001 --> Data_2 ist 3bit lang: 1 01
Label_3 = 11 01 --> Data_3 ist 16bit lang: 01 0110 0111 1000 10
usw.
Ich denke ich werde mal anfangen, die insgesamt(max.) 112Nutzbits in ein
7 x 16bit Feld zu schreiben und dabei den 4bit-Müll zu entsorgen.
luggi wrote:
> Ich denke ich werde mal anfangen, die insgesamt(max.) 112Nutzbits in ein> 7 x 16bit Feld zu schreiben und dabei den 4bit-Müll zu entsorgen.
Würde ich nicht machen. Schreibe die von mir oben genannte Funktion. Das
wegwerfen der 4 Füllbits kannst du dort ganz einfach "nebenbei" machen.
Ein Glück, andere kommen auch ins straucheln... die Beschreibung da oben
ist echt mies.
Was ist ein Integer der Länge 8? 8 Byte, oder was?
> Chris (Gast)> Soweit ich verstanden habe, 32bit Integer
Das passt aber nicht zu "ich habe hier ein Integerfeld der Länge 8".
Außer er zählt in Oktetten.
> Ich komme grad nicht recht weiter, ich habe hier ein Integerfeld der> Länge 8, dass etwa folgendermaßen ausschaut:> xxxx 1101 0101 1001 | 1001 1111 0101 0010 | xxxx ....>> soll heißen: die hochwertigsten vier Bits jedes zweiten Integers sind> immer hinfällig, dann kommen 12 Nutzbits, dann der nächste Integer mit> 16 Nutzbits und dann wieder einer mit nur 12.
Bitmaske für die ersten zwei Bytes:
1111 1111 0000 1111
> Alle Nutzbits hintereinander sind vom Typ
Nutzbits waren bitte was? Das was nach den ersten zwei Bytes kommt?
> Label(4bits) | Daten (0-16bits) | Label(4bits) | Daten(0-16bits) ...>> Die Länge und der Typ der Datenfelder ist durch das vorhergehende Label> bestimmt. Ich hol mir also das Label, weiß dann was für Daten darauf> folgen, hole mir diese und kann diese dann dekodieren. Hier komme ich> ins Straucheln, da ja wie gesagt die Länge der Datenbereiche variiert.> Natürlich könnte ich das ganze in einer ewigen if-else - Anweisung> abarbeiten, aber es müsste doch auch eleganter gehen.
Nach den obigen 16 Bit (oder 2 Byte) kommen also maximal 2 * 20 Bits?
Also 2,5 Bytes?
Am besten löst man sowas auf einem Blatt Papier...
luggi wrote:
>> feld[0] = xxxx 0001 0010 0011 0111> feld[1] = 0101 0110 0111 1000 1001> feld[3] = xxxx 1010 1011 1100 1101> usw.>> hier im Beispiel schauts also so aus:>> Label_1 = 0001 --> Data_1 ist 3bit lang: 001> Label_2 = 0 001 --> Data_2 ist 3bit lang: 1 01> Label_3 = 11 01 --> Data_3 ist 16bit lang: 01 0110 0111 1000 10> usw.
Ah. OK also doch ein fortlaufender Bitstrom.
Ich dachte, dass bei den xxxx immer ein neuer Datensatz anfängt.
Stefan hat recht. Eine Funktion die die nächsten n Bits extrahiert
(unter Berücksichtigung deiner Füllbits) ist die einfachste Variante.
Artet zwar in dieser Funktion in ein Bitgepfriemel und -geschiebe aus
aber es wird sich nur in dieser Funktion konzentrieren. Darüberliegende
Funktionen haben dann schon 'schöne' Daten, mit denen sie arbeiten.
> Artet zwar in dieser Funktion in ein Bitgepfriemel und> -geschiebe aus
Ach, so schlimm ist das gar nicht. ;-)
Die Funktion sieht etwa so aus (ungetestet!):
1
uint16_tGetBits(uint8_tanzahl){
2
3
staticuint8_tint_index=0;
4
staticuint16_tbit_mask=0x0800;
5
6
uint16_tbits=0;
7
8
while(anzahl--){
9
10
// Bit eintragen
11
bits<<=1;
12
if(feld[int_index]&bit_mask)
13
bits|=1;
14
15
// nächstes Bit
16
bit_mask>>=1;
17
18
if(!bit_mask){// war letztes Bit, also nächster Int
> Artet zwar in dieser Funktion in ein Bitgepfriemel und -geschiebe aus
das war ja das wovor ich mich drücken wollte, aber naja, der Nachmittag
dauert ja noch ein wenig... ;-)
Ok, ich mache eine Funktion, die mir in Abhängigkeit von meinem
Parameter "Anzahl" Anzahl Bits extrahiert. Der Ablauf in der aufrufenden
Funktion wäre dann der:
- hole 4 bit (Label)
- werte Label, zB. "Aha, das Label = 4, dann ist mein Datenblock 8 bit
lang"
- hole 8 bit (Daten)
- werte die Daten aus
- hole 4 bit (das nächste Label)
usw.
Aber wie mache ich meiner Funktion dann klar, an welcher Stelle sie n
bits auslesen soll. Ich dachte daran, die ausgelesen Bits zu löschen,
bzw. noch nicht gelesene dann drüber-zu-shiften und immer von vorne zu
lesen. Schön geht das zwar nicht, da ich ja über die Grenzen der
einzelnen Variablen drüber schieben muss, aber was muss...
Danke für die Anstöße!
PS:
Das Ganze wird ja wahrscheinlich mehrfach gebraucht, also ist auch noch
eine Neuinitialisierung von int_index und bit_mask nötig. Könnte man in
der Funktion machen, z.B. bei anzahl=0.
@ Stefan
Vielen Dank, das hast du jetzt also mal schnell hingezaubert, ok! Weiß
jetzt zwar noch nicht obs im Detail so geht, aber die Idee mit dem
static-Index kam mir Amateur mal wieder nicht, so sollte das
Positionsproblem zu beheben sein - freufreu - danke.
Ja das mit der Neuinitialisierung ist klar, muss ich noch an geeigneter
Stelle mit einbauen. Es kommt eh noch hinzu, das es nicht immer die
vollen 112bits sind, bei bestimmten Labeln muss ich vorher abbrechen -
aber das ist das kleinere Übel.
Guten Morgen,
also Stefans Funktion - mit kleinen Änderungen - hab ich erfolgreich
eingebaut, passt jetzt wunderbar!
Vielen Dank nochmal, wäre da alleine sicher noch ein gutes Stück
drangehangen!
Schöne Grüße,
Luggi.
Ich würde für jeden Datensatztyp eine struct definieren
und diese structs mit einer union auf einen gemeinsamen
Speicherbereich legen. Die union kann dann auch noch
den Speicherplatz für die Eingangsdaten enthalten.
Beim ersten Zugriff auf die Union kann man die Daten-
satzart ermitteln und dann über die richtige struct
auf die Daten zugreifen.
@Gast:
Danke für die Mühe aber das Problem ist schon erschlagen.
Aber trotzdem: Mit Union und Struct wäre es - glaub ich - nicht wirklich
hübsch, da ich im Vorfeld nicht weiß, wie der Bitstrom ausschaut:
- er kann zwischen 28 und 4 x 28 = 112 bit lang sein
- es können zwischen 1 und 16 Label-Daten-Paare darin enthalten sein
- die Label-Daten-Paare können zwischen 4 und 20bit lang sein
das sind mir zuviele Unbekannte für feste Strukturen.
Ich denke die Lösung mit obiger Funktion triffts ganz gut.
Danke und Gruß,
Luggi.
Achja, vielleicht beschäftigt sich mal jemand anderes auch damit und
dann sollte die Such-Funktion auch richtig anschlagen:
Das Ganze dient der Auswertung des
Optional Message Content, der in den
Free Format Bits der
RDS-TMC Multigroup - User - Messages
verpackt ist.
Schöne Grüße,
Luggi.