[Tinyos-devel] nesc.xml bitoffset error
David Gay
dgay42 at gmail.com
Thu Feb 7 14:41:29 PST 2008
On Feb 7, 2008 11:57 AM, WenZhan Song <wenzhan.song at gmail.com> wrote:
> I absolutely agree with you - somewhere is wrong.
Ok, after looking at the code a little: your C code is invalid (i.e.
it depends on undefined behaviour), which is why it doesn't "work".
The compiler is not buggy.
A little explanation: on most processors (8-bit processors and x86
being exceptions...), most types have alignment restrictions - 2-byte
integers must be at even addresses, 4-byte integers must be at an
address that is a multiple of four, etc. If you take an arbitrary
pointer, cast it to something with alignment restrictions, and then
use that pointer, you will have problems (segmentation faults,
mysterious behaviour, etc).
Your example casts an arbitrary pointer (testMsg_nopack.data), which
happens to be a multiple of 2 but not 4 in your run (5c00300a) to a
pointer to something which *must* be a multiple of 4 (on ARM, the
tTestPointer_nopack structure requires a multiple of 4 because it
contains a 4-byte integer). The compiler assumes when generating code
that pointers to a type T respect T's alignment rules - if you break
that assumption, then your code won't work, as your example
illustrates...
The short version: you can't take an arbitrary pointer into an array
of bytes and make it to a pointer to an arbitrary type T, as this
violates alignment assumptions in the C compiler.
Two fixes:
* gcc's packed attribute allows you to create a structure with no
alignment restrictions, so arbitrary byte pointers *can* be cast to
pointers to packed structures. However, packed is gcc-specific and
broken on earlier gcc implementations (including the gcc version used
by TinyOS for msp430 platforms). Thus packed should not be used in any
portable TinyOS code (it was, alas, somewhat heavily abused in TinyOS
1.x, mostly to make life simpler when using tossim).
* nesC's external types (those things starting with nx_, like
nx_struct { ... }, nx_uint8_t, etc) also have no alignment
restrictions. They have been available since nesC 1.2.0, so there's no
reason to avoid them at this point. In TinyOS 2, they are used for all
packet formats in networking code. They work for all platforms, and,
unlike gcc's packed attribute, also specify endianness, so simplify
writing networking code that interoperates across different platforms.
David Gay
> On Feb 7, 2008 11:55 AM, David Gay <dgay42 at gmail.com> wrote:
>
> >
> > On Feb 7, 2008 11:25 AM, WenZhan Song <wenzhan.song at gmail.com> wrote:
> > > David,
> > >
> > > Your suggestions can correct the XML bitoffset problem of non-packed
> > > structure, but it does not solve the second problem:
> > >
> http://sensorweb.vancouver.wsu.edu/wiki/index.php/Tips#Problem2:_If_not.2C_the_initial_values_are_even_set_to_the_wrong_addresse_in_memory
> > >
> > > According to our test, without "structure_size_boundary=32", it works
> great
> > > if we always define packed structure. With it, it even has problems with
> > > "packed" structure.
> >
> > I'll look at the details later, but the nesC compiler has no influence
> > on the layout of regular C structures (as opposed to nx_structs, which
> > are layed out by nesC). If you're not getting what you expect in terms
> > of layout from a C structure, either:
> > - there's a bug in gcc
> > - you're not understanding gcc's layout rules for your architecture
> correctly
> >
> > David Gay
> >
>
>
More information about the Tinyos-devel
mailing list