[Tinyos-devel] TinyOS-2.x platform independent types?
Matti Öhman
mohman at cc.hut.fi
Fri Sep 8 02:24:12 PDT 2006
On Thu, 7 Sep 2006, David Gay wrote:
> Mixing bit-fields of different endianness doesn't quite work, because
> the endianness of bit-fields actually implies two things:
> 1) if a bitfield spans multiple bytes, which bytes contain the most
> significant bits (for big-endian that's the lowered numbered bytes,
> for little-endian the higher numbered ones).
> 2) at what end of the byte do you start using bits (for little-endian,
> you start at the least significant bits, for big-endian you start at
> the most significant bits)
> Also remember that fields are allocated in order of declaration
>
> Rule 1 isn't a problem, but rule 2 is: what does
> nx_struct {
> nx_uint8_t a : 2;
> nxle_uint8_t b : 2;
> }
> mean? Rule 2 would seem to imply there's a 4-bit hole in the middle of
> the byte this structure takes. It gets more fun if you then do:
> nx_struct {
> nx_uint8_t a : 2;
> nxle_uint8_t b : 2;
> nx_uint8_6 c : 3;
> }
> Where does c live? In the next byte? In the hole? What if c is 5 bits
> (so bigger than the hole)?
>
> It gets worse from here. So, to avoid any very mysterious behaviour,
> bitfields in external types are only big-endian.
>
> Btw, there is actually one consistent way of mixing big and little
> endian bit fields. But it means that you have to reverse the bits for
> one of those within bytes. No thanks :-)
>
> David Gay
Thank you for your quick response.
I did not consider the implications of mixing bit-fields of different
endianness. However, that is not what I am proposing here. I think that is
should be possible to use either little-endian or big-endian bit-fields -
not both at the same time.
Currently it is possible to mix little-endian and big-endian types (not
bit-fields) in the same structure:
nx_struct {
nx_uint16_t a;
nxle_uint16_t b;
}
which is laid out as:
[a8a9a10a11a12a13a14a15][a0a1a2a3a4a5a6a7] ...
[b0b1b2b3b4b5b6b7][b8b9b10b11b12b13b14b15]
Mixing little-endian and big-endian types this way seems unambiguous and
easy to implement, but it still feels like a bad idea.
Is anyone using this feature?
It might be more appropriate to have separate structures for
little-endian and big-endian bit-fields:
nx_struct {
nx_uint8_t a:4;
nx_uint8_t b:4;
}
nxle_struct {
nxle_uint8_t a:4;
nxle_uint8_t b:4;
}
How does this sound?
Currently it is possible to write, say:
nx_struct {
nx_uint16_t a:12;
nxle_uint16_t b;
nx_uint8_t c:4;
}
and get some mysterious behaviour ("holes"):
[a4a5a6a7a8a9a10a11][()()()()a0a1a2a3][b0b1b2b3b4b5b6b7] ...
[b8b9b10b11b12b13b14b15][()()()()c0c1c2c3]
Garbage in, garbage out, but this is the right way of doing it: as b is
an ordinary field (not a bit-field) it is possible to take its address
which means that it has to be aligned to a byte boundary. The following
structure could be laid out in the same way by aligning adjacent
bit-fields with different endianness at byte boundaries:
nx_struct {
nx_uint16_t a:12;
nxle_uint16_t b:14;
nx_uint8_t c:4;
}
the structure is terrible and so is the layout:
[a4a5a6a7a8a9a10a11][()()()()a0a1a2a3][b0b1b2b3b4b5b6b7] ...
[b8b9b10b11b12b13()()][()()()()c0c1c2c3]
You get what you pay for, I guess. Even though it can be done, I am not
saying it should be done. It might be better to just have separate
structures for little-endian and big-endian types.
Btw, I really like the idea of platform independent types. But they need
to be a bit more flexible. Not having any kind of support for
little-endian bit-fields is a major shortcoming. Get them right and the
platform independent types are probably the best invention since
electricity :-)
Cheers,
Matti
More information about the Tinyos-devel
mailing list