I'm developing an programm running on Atmel AT90CAN128. Connected to this controller there are 40 devices, each with a status (on/off). As I need to report the status of each of this devices to a PC through Serial Communication, I have 40 bits, which define whether the device is on or off. In addition, the PC can turn any of this devices on or off.
So, my first attempt was to create the following struct:
typedef struct {
unsigned char length; //!< Data Length
unsigned data_type; //!< Data type
unsigned char data[5]; //!< CAN data array 5 * 8 = 40 bits
} SERIAL_packet;
The problem with this was that the PC will send an unsigned char address
telling me the device to turn on/off, so accessing the bit corresponding to that address
number turned out to be rather complicated...
So I started looking for options, and I stumbled upon the C99 _Bool
type. I thought, great so now I'll just create a _Bool data[40]
and I can access the address
bit just by indexing my data
array. Turns out that in C (or C++) memory mapping needs an entire byte for addressing it. So even if I declare a _Bool
the size of that _Bool
will be 8 bits which is a problem (it needs to be as fast as possible so the more bits I send the slower it gets, and the PC will be specting 40 bits only) and not very efficient for the communication. So I started looking into Bit Fields, and tried the following:
typedef struct {
unsigned char length; //!< Data Length
unsigned data_type; //!< Data type
arrayData data[40]; //!< Data array 5 bytes == 40 bits
} SERIAL_packet;
typedef struct {
unsigned char aux : 1;
} arrayData;
And I wonder, is this going to map that data[40]
into a consequent memory block with a size of 40 bits (5 bytes)?
If not, is there any obvious solution I'm missing? This doesn't seem like a very complicated thing to do (would be much simpler if there were less than 32 devices so I could use a int
and just access through a bit mask).
Assuming the addresses you get back are in the range 0 - 39 and that a char
has 8 bits, you can treat your data
array as an array of bits:
| data[0] | data[1] ...
-----------------------------------------------------------------
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| 13| 14| 15|
-----------------------------------------------------------------
To set bit i
:
packet.data[i/8] |= (1 << (i%8));
To clear bit i
:
packet.data[i/8] &= (1 << (i%8)) ^ 0xff;
To read bit i
:
int flag = (packet.data[i/8] & (1 << (i%8)) != 0;