Re: [Hampshire] [Slightly OT] Arduino coding help - pointers…

Top Page
Author: Hugo Mills
Date:  
To: paul, Hampshire LUG Discussion List
Subject: Re: [Hampshire] [Slightly OT] Arduino coding help - pointers tostructs

Reply to this message
gpg: failed to create temporary file '/var/lib/lurker/.#lk0x570ec100.hantslug.org.uk.14384': Permission denied
gpg: keyblock resource '/var/lib/lurker/pubring.gpg': Permission denied
gpg: Signature made Tue Aug 3 14:24:46 2010 BST
gpg: using DSA key 20ACB3BE515C238D
gpg: Can't check signature: No public key
On Tue, Aug 03, 2010 at 02:12:16PM +0100, paul@??? wrote:
> I'm writing a piece of code for an Arduino to process short data blocks received
> over a serial link.
>
> I've made a struct to hold the input data block which is something like:
>
> struct received_data {
>     unsigned int start:1;
>     unsigned int address:4;
>     unsigned int command:5;
>     unsigned int flags:4;
>     unsigned int padding:1;
>     unsigned int parity:1;
>     }

[snip]
> In the function I define a pointer to the struct: struct received_data *messagedata;
>
> I do a type-cast on the pointer to char: messagedata=(struct received_data*)message;

[snip]
> I've not written C for a long time and would appreciate it if someone could show
> me the correct way to do this. Am I barking up the wrong tree by trying to be
> elegant and cast rather than writing statements to bit-slice the chars up?


In a word, yes.

Bit-packed structs are deeply non-portable, and have any number of
issues with bit-alignment, all quite heavily compiler-dependent (in
some cases, even down to nearby versions of the same compiler).

You should probably define some macros to do the slicing:

#define RD_START(_x) (((_x)[0]) & 0x1)
#define RD_ADDRESS(_x) ((((_x)[0]) >> 1) & 0xf)
#define RD_COMMAND(_x) (((((_x)[0]) >> 5) & 0x3) | ((((_x)[1])<< 3) & 0x18))
...

decodedaddress = RD_ADDRESS(message);

Be careful, though, as the RD_COMMAND definition evaluates _x
twice, so you can't use anything with side-effects in it. (There's a
hack to get around that limitation, I believe).

Alternatively, short (inline) functions to do the same job would
work.

Hugo.

-- 
=== Hugo Mills: hugo@... carfax.org.uk | darksatanic.net | lug.org.uk ===
  PGP key: 515C238D from wwwkeys.eu.pgp.net or http://www.carfax.org.uk
   --- Nothing wrong with being written in Perl... Some of my best ---   
                      friends are written in Perl.