c++ - working with odd bit sized unions -
i trying build rtcm sc104 v3 messages. standard requires using minumum number of bits transmit data maximum defined range can be. join data going use unions. how joint odd sized unions previous odd sized union? instance message 1002 requires 74 bits each satelite. there no padding bits untill message complete of data n number of satelites in view. can build union of previous unions?
typedef union headergps { struct { unsigned int msgno :12; // creates 12 bit wide integral field unsigned int baseid :12; //base index number unsigned int tow :30; //time of measurement unsigned int syncflg :1; //1 if gnss readings same time unsigned int no_gps :5; //number of gps readings unsigned int smoothind :1; //smoothing indicator unsigned int smoothint :3; //smoothing int rep } fields; unsigned char header[8]; } headergps; typedef union data1002 { struct //74 bits / 9.25 bytes per sv { int8u satid :6; //sat id 6 bit int8u l1ind :1; //l1 indicator 1 bit set 1 int32u l1range :24; //l1 psuedorange uint24 int diff :20; //l1 phaserange - psuedorange int20 int8u lockind :7; //l1 locktime indicator uint7 int8u ambi :8; //l1 int ambiguity uint8 int8u cnr :8; //l1 cnr uint8 }fields; int8u data[]; }data1002; bool encode1002( int basenumber, int gpsepoch , int numbergpssv, int numberglosv, int numbergalsv ) { std::string message1002; headergps h1002; //create header object h1002.fields.msgno = 1002; h1002.fields.baseid = basenumber; h1002.fields.tow = gpsepoch; if(numberglosv > 0 || numbergalsv > 0) { h1002.fields.syncflg = 1; } else { h1002.fields.syncflg = 0; } h1002.fields.no_gps = numbergpssv; h1002.fields.smoothind = 0; h1002.fields.smoothint = 0; for(int n=0; n<8; n++) { message1002 += h1002.header[n]; }//1002 header complete return true; }
ok trying setup bitset prepare data send out. using kind of staement fill bitset in needed order without filler bits being added. in "for" statement , "if channel data good" statement.
for(varpos = 0; varpos < 6; varpos ++) //start on 0, end on 5 { data_1002.set(bitpos,datastream[basenumber].channel[n].satid & (1<<varpos)); //test bit bitpos++; } data_1002.set(bitpos,1); bitpos++; for(varpos = 0; varpos < 24; varpos ++) //start on 0, end on 5 { data_1002.set(bitpos,coderange & (1<<varpos)); //test bit bitpos++; }
i want copy of bit values bitset array of bytes send out tcp/ip port using following:
int nobytes = (bitpos+7)/8; //number of data bytes copy array if(nobytes <=0) { nobytes = 0; } cout << "number of bytes process= " << nobytes <<endl; cout <<"completed bitset size= " << bitpos << endl; //convert bits bytes bitpos = 0; int bytecount; (int w=0; w<nobytes; w++) //bitpos/8 = number of bytes; w+8 because 8 bytes in header { for(int q=0; q<8; q++) { if(data_1002.test(bitpos+q) == 1) { buffer[(w+8)] = buffer[(w+8)] | (1<<q); } else { buffer[(w+8)] = buffer[(w+8)] & (0xff & (0<<q)); } } bitpos = bitpos +8; bytecount = w+8; } cout << "bytecounter= " << bytecount << endl; cout<<"number btes processed plus header= "<< nobytes+8 <<endl; for(int w=0; w<nobytes+8; w++) { output += buffer[w]; }
this seems should working if missing mistake in coding of appreciate help. there no easier way transfer bitset byte array send out? read , tried inserting bitset in stringstream inserts each bit char instead of bit.
you wrote wanted join data making union of odd sized structs? result in 2 odd sized structs referring same binary data. think wanted append, make new struct 2 unions in it; , wanted them sandwiched no padding bits?
bit packed structs of odd size aligned, either byte, word, or whatever compiler chooses. if place 2 of these in struct, padded. you'll have go different way.
so, why not put of declarations packed 1 struct? maybe because have multiple appearances of headergps , data1002? if 1 solution be: (as find preprocessor macros hack, it's way).
#define headergps(n) \ unsigned int msgno_##n :12; \ unsigned int baseid_##n :12; \ unsigned int tow_##n :30; \ unsigned int syncflg_##n :1; \ unsigned int no_gps_##n :5; \ unsigned int smoothind_##n :1; \ unsigned int smoothint_##n :3 #define data1002(n) \ int8u satid_##n :6; \ int8u l1ind_##n :1; \ int32u l1range_##n :24;\ int diff_##n :20;\ int8u lockind_##n :7; \ int8u ambi_##n :8; \ int8u cnr_##n :8 union gpsdata { struct { headergps(1); data1002(1); data1002(2); }; int8u data[]; };
note usage of append operator ##
, can add unique extensions names become satid_1
, satid_2
.
this solution bit of hack though, may confuse ide parser; eclipse did correctly suggested members me when tested.
Comments
Post a Comment