[Tinyos-devel] nesc.xml bitoffset error
David Gay
dgay42 at gmail.com
Thu Feb 7 15:59:09 PST 2008
On Feb 7, 2008 3:29 PM, WenZhan Song <wenzhan.song at gmail.com> wrote:
> Well, I do not agree the code is invalid - this used often in tinyos-1.x
> networking code.
And that code is broken on any platform with alignment restrictions.
When we wrote it, we knew it was broken, but it was convenient on
8-bit platforms (the rene and mica motes). It also ran "ok" on x86
because x86 supports unaligned accesses. When people wrote the first
msp430 ports (which requires ints to have 2-byte alignment), they
hacked the TOSMsg structure to guarantee that data was aligned to a
multiple of 2, but this was very much a hack.
We liked this style of programming so much that we invented a language
feature (external types) to support it in a non-broken, portable
way... (see below)
> For instance, we frequently see MultihopMsg *netMsg =
> (MultihopMsg *)msg->data; while the "data" offset in TOS_Msg is 10. We can
> not assume a user pre-knows the pointer is pointing to an address multiple
> of 2 but not 4.
Which is why you can't do the cast to a type with alignment restrictions.
> At least, we see packed attribute works fine in iMote2 according to our
> preliminary test. Thanks for reminding gcc of MSP430 though. We will verify
> that with MicaZ and TelosB later.
Just use external types (nx_struct and co). They are precisely
designed to address this issue. You just need to write:
typedef nx_struct tTestPointer_nx
{
nx_uint8_t m;
nx_uint16_t k;
nx_uint32_t l;
} tTestPointer_nx;
and your code will work on all platforms.
David Gay
> On Feb 7, 2008 2:41 PM, David Gay <dgay42 at gmail.com> wrote:
>
> >
> > 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