I have an unsigned char array with values as below:
u_char *t_header[4]; //filled with values 0x00000047,0x00000004,0x00000093,0x00000012
I have a struct as below:
#pragma pack(push, 1)
typedef struct th_struct {
unsigned s_byte : 8;
unsigned t_e_indicator : 1;
unsigned p_u_s_indicator : 1;
unsigned t_priority : 1;
unsigned id : 13;
unsigned t_s_control : 2;
unsigned a_f_control : 2;
unsigned c_counter : 4;
}th_struct;
#pragma pack(pop)
I am trying to fill the struct fields as below:
const struct th_struct *tsh;
tsh = (struct th_struct*)(t_header);
It fills the tsh->s_byte
with 71
= 0x47
in hex as expected but the rest of the fields are all 0
.
What i have to do to fill struct th_struct *tsh
with the u_char *t_header[4]
values correctly as below?
0100 0111 .... .... .... .... .... .... = (0x00000047) tsh->s_byte
.... .... 0... .... .... .... .... .... = 0 tsh->t_e_indicator
.... .... .0.. .... .... .... .... .... = 0 tsh->p_u_s_indicator
.... .... ..0. .... .... .... .... .... = 0 tsh->t_priority
.... .... ...0 0100 1001 0011 .... .... = (0x00000493) tsh->id
.... .... .... .... .... .... 00.. .... = (0x00000000) tsh->t_s_control
.... .... .... .... .... .... ..01 .... = (0x00000001) tsh->a_f_control
.... .... .... .... .... .... .... 0010 = 2 tsh->c_counter
Thank you!
You can do something like this:
struct th_struct t_header = {
.s_byte = 0x47,
.t_e_indicator = 0,
.p_u_s_indicator = 0,
.t_priority = 0,
.id = 0x00000493,
.t_s_control = 0,
.a_f_control = 1,
.c_counter = 2 };
and then:
const struct th_struct* tsh = &t_header;
I think it's easier.
You must change the way you assing for sometinh like this:
u_char t_header[4];
t_header[0] = 0x47; // s_byte
t_header[1] = (u_char)
(0x00 // t_e_indicator
| (0x00 << 1) // p_u_s_indicator
| (0x00 << 2) // t_priority
| (0x493 << 3)); // id[0..4]
t_header[2] = (u_char) ((0x493 << 3) >> 8); // id [5..12]
t_header[3] = (u_char)
(0x00 // t_s_control
| (0x01 << 2) // a_f_control
| (0x02 << 4)); // c_counter
const struct th_struct* tsh = (th_struct*)t_header;
Or change the struct order:
#pragma pack(push, 1)
typedef struct th_struct2 {
unsigned s_byte : 8;
unsigned id1 : 5;
unsigned t_e_indicator : 1;
unsigned t_priority : 1;
unsigned p_u_s_indicator : 1;
unsigned id2 : 8;
unsigned c_counter : 4;
unsigned a_f_control : 2;
unsigned t_s_control : 2;
}th_struct2;
#pragma pack(pop)
where id1 is the higher part od id, and id2 the lower part.
First of all you have a problem here:
u_char *t_header[4];
That is 4 pointers - not 4 u_char. You probably want:
u_char t_header[4];
Next problem is that the layout of bit fields is implementation-dependent.
Consequently, it is a bad idea (in general) to write code that assumes a specific layout. Such code will only be able to run on the specific system used when writing the code, i.e., the code is non-portable.
I recommend that you use the shift operator >>
and bitwise and operator &
to pick exactly the bits needed:
unsigned char t_header[4] = {0x47, 0x04, 0x93, 0x12};
th_struct tsh;
tsh.s_byte = t_header[0];
tsh.t_e_indicator = (t_header[1] >> 7) & 0x1;
tsh.p_u_s_indicator = (t_header[1] >> 6) & 0x1;
tsh.t_priority = (t_header[1] >> 5) & 0x1;
tsh.id = ((unsigned)(t_header[1] & 0x1f) << 8) + t_header[2];
tsh.t_s_control = (t_header[3] >> 6) & 0x3;
tsh.a_f_control = (t_header[3] >> 4) & 0x3;
tsh.c_counter = t_header[3] & 0xf;
printf("s_byte=%x\n", tsh.s_byte);
printf("t_e_indicator=%x\n", tsh.t_e_indicator);
printf("p_u_s_indicator=%x\n", tsh.p_u_s_indicator);
printf("t_priority=%x\n", tsh.t_priority);
printf("id=%x\n", tsh.id);
printf("t_s_control=%x\n", tsh.t_s_control);
printf("a_f_control=%x\n", tsh.a_f_control);
printf("c_counter=%x\n", tsh.c_counter);
Then you can also avoid having a packed struct.
User contributions licensed under CC BY-SA 3.0