[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