Hi I have some problems with struct inside a union This is my code.
union{ unsigned char id_byte[2]; struct { unsigned char DLC:4; unsigned char RTR:1; unsigned int identifier:11; }del_element; }can_descriptor;
union{ unsigned char id_byte[2]; struct { unsigned int identifier:11; unsigned char DLC:4; unsigned char RTR:1; }del_element; }can_descriptor;
The bit-fields in your struct are different types:
unsigned char DLC:4; unsigned char RTR:1; unsigned int identifier:11;
tryede that. now comes the identifier,DLC and RTR into the array. but wrong: identifier=0x0A DLC=0x04 RTR=1 gives: array[0]=0xA0 array[1]=0x0A corect is array[0]=0x64 array[1]=0x01 the identifier is the 11. higist bit, RTR bit and last 4 DLC bits. is something wrong with my order of my struct? Soren
Keil C has a somewhat non-intuitive order for bitfields. http://www.keil.com/support/docs/1948.htm Per the C standard, the "correct" storage pattern for bitfields is up the implementation. A program cannot rely on the order of bitfields within an int, nor can it depend on the signed-ness of a bitfield. For that matter, per spec all bitfields must occupy an "int" (whatever that may be), though every compiler I've ever used lets you specify other byte widths for them. In fact, I avoid using this C feature at all because the results are so different for every compiler and platform. In addition, many compilers generate poor code for bitfields. It's more portable and often more efficient just to use the & and | operators directly. If you're sending messages to another processor, you can use the same declarations without worrying about different implementation orders.
This means that I never can do what i had in intention? Soren
This means that I never can do what i had in intention? In a nutshell: yes. The language definition for C left so many details of bitfield behaviour for the implementor to specify that there's essentially nothing usable left for application like yours, trying to recreate some hardware bit addressing schemes in C structs. In short, C data structures will only ever match any pre-determined physical address layout by coincidence, but not by design. Use #define'd shifting and masking operations instead.
Actually, you can do it - but, for the reasons already discussed, it's best avoided. I don't think there's any reason to believe that bitfields will give you (significantly) better code than shifts and masks and some bitfield implementations are notoriously inefficient - so shifts and masks can actually be better! Your problem is that you have not fully understood Keil's bitfield implementation. If you really do want to use bitfields, you will have to read-up on Keil's implementation, and adapt your union to match. There are articles in the Knowledgebase that will help you with this - use the site 'Search' facility. You can always use the memory viewing facilities in the simulator to help you see what's going on... But, again, why bother? Just use shifts & masks - you know where you are with shifts & masks! And they're portable!
I tryed not to use shift and mask too much. I have now implantet the union struct, with some modifikations.....and i works. Shifting and masking, is not good if you need to convert 2 ways... Soren
"I tryed not to use shift and mask too much." Why not? It's probably how the compiler actually implements the bitfields! "I have now implantet the union struct, with some modifikations.....and i works." Be sure to test it thoroughly - you don't want any nasty surprises with the sign bit, for example... "Shifting and masking, is not good if you need to convert 2 ways..." Why not?
I uses the union struct to place bit into my SJA1000 controller. I uses the funktion to make TX id byts. and to decode RX bytes. if I shifts, I need more code, becourse I need to shift different if i have a RTR bit set. I don't have that problem in union struct. Soren
if I shifts, I need more code, becourse I need to shift different if i have a RTR bit set. I rather strongly suspect the opposite to be true. If the shift is, indeed, different depending on the status of some bits, that's impossible to model using bitfields alone, because the lengths, and thus by implication the positions, of bitfields inside a struct are fixed at compile time. It's much more transparent to have the argument of a shift operator be a variable or expression than having to do something like
if(rtr) my_union.rtr_set.somebit = 1; else my_union.rtr_clr.somebit = 1;
"if I shifts, I need more code ... I don't have that problem in union struct." It may look like more source code, but have you checked the generated object code? Does it make any difference to the amount of code that the processor actually has to run?
year ok. yes as small as passebel, no time to waste. You say that i shoud use mask and shift? dose't it give more code? Soren
"You say that i shoud use mask and shift? dose't it give more code?" Try re-reading the previous posts! Here's a reminder of what's been said so far: "many compilers generate poor code for bitfields. It's more portable and often more efficient just to use the & and | operators directly." "I don't think there's any reason to believe that bitfields will give you (significantly) better code than shifts and masks and some bitfield implementations are notoriously inefficient - so shifts and masks can actually be better!" "[shift & mask] is probably how the compiler actually implements the bitfields!" That should answer your question! And again, shifts & masks are portable; bitfields are not.
thanks i try that. soren