Go Down

Topic: Communication "Packet" design by using "union" (Suggestion required) (Read 1 time) previous topic - next topic

Cybernetician

Apr 15, 2013, 08:53 am Last Edit: Apr 15, 2013, 09:05 am by Cybernetician Reason: 1
Hello Everyone,

Story start from this thread ref:http://arduino.cc/forum/index.php/topic,159519.0.html.

To feel "union in c" I tested it in real (not only for Arduino base system) Wireless Sensor Network application. This is the format of packet

Code: [Select]

union uPacket{
 struct packet{
   char sDelimeter; //To mantian Backward Compatibilty
   uint8_t id;
   uint8_t payload[10];
   char mDelimeter; //To mantian Backward Compatibilty
   uint16_t msgId;
   char eDelimeter; //To mantian Backward Compatibilty
 }
 sPac;
 uint8_t asBytes[16];
}
uRx, uTx;


Quote
Cycle of Communication


                           NODE 1                                                    NODE 2
Fill(struct) -->Send(uTx.asBytes) -... ...- Recv(&buffer) -->copy(uRx.asBytes) -->extract(struct)


Suggestion required (anything need to keep in mind?).
Thanks in advance.

Literature Links:
http://forums.codeguru.com/showthread.php?306399-Visual-C-Network-How-do-I-transfer-structure

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=115140&postdays=0&postorder=asc

http://lxr.linux.no/linux+v3.1.5/+search

http://nrqm.ca/nrf24l01/driver/

Edit: Sorry for last time posting in wrong section
From Idea To Invention

Erdin

One suggestion:

A union is used if data is used in different ways in the same sketch.

If you transmit and receive data, you often don't have to use an union.
A transmit function is typical: transmit( char * buffer, int size);
You can call that function with the structure: transmit( (char *) myStruct, sizeof( myStrut));

Cybernetician


One suggestion:

A union is used if data is used in different ways in the same sketch.

If you transmit and receive data, you often don't have to use an union.
A transmit function is typical: transmit( char * buffer, int size);
You can call that function with the structure: transmit( (char *) myStruct, sizeof( myStrut));


Thanks. Actually this is the simplest form of (testing)message. In actual application union contain multiple stuctures for specific purpose. e.g. [header][ver][Application][][]...
From Idea To Invention

Nick Gammon


Suggestion required (anything need to keep in mind?).


Don't use a union. It doesn't give you anything here.

Cybernetician



Suggestion required (anything need to keep in mind?).


Don't use a union. It doesn't give you anything here.


It's mean i am doing some thing wrong?
From Idea To Invention

Nick Gammon

You are posting a snippet. Why do you want the union? Show the rest of your code.

How to use this forum

Cybernetician


Why do you want the union?


Because it is the part of K&R and i am trying to feel(practice) it.



You are posting a snippet. Show the rest of your code.


It's too long...

Thanks.
From Idea To Invention

Nick Gammon


Because it is the part of K&R and i am trying to feel(practice) it.


Right.

But the real reason?

Cybernetician

#8
Apr 15, 2013, 12:36 pm Last Edit: Apr 15, 2013, 12:38 pm by Cybernetician Reason: 1

But the real reason?


By using union lots of (heavy)function replaced by few lines of code e.g. conversion steps ,extracting different parameter, error-detecting, and performing action on them.

In short, I just wanted to make sure that use of union is not harmful for embedded systems in this case.
From Idea To Invention

pYro_65

Quote
In short, I just wanted to make sure that use of union is not harmful for embedded systems in this case.

It depends in what way you intend to use the members.
What you are really doing by defining data as one type and aliasing it as another is type-punning.

As GCC supports its use ( mostly ) you can use it here in Arduino land, however:
* The C99 and C11 standards allow it.
* The C++99  and C++11 standards do not.

As you are using a char type as the second member things are different. C++ explicitly allows type-punning to a char type, whereas the other way around is undefined behaviour.

So if you write to the struct member, then read/write the array member its fine. But writing the array, then reading the struct can break strict-aliasing rules.

This makes your union usage more or less implementation defined, and therefore cannot really be considered portable: Even through future revisions. GCC currently says this:

Quote
*A member of a union object is accessed using a member of a different type.
The relevant bytes of the representation of the object are treated as an object of the type used for the access. See Type-punning. This may be a trap representation.


What this means is you can use your union fine as you have it laid out there, but consider this example:

Code: [Select]
union a{
 uint16_t b;
 uint32_t c;
 char d[ 4  ];
};

a A = { 0xFFFF };


Initialising the smaller type of a union with unequal sized members means you can only safely access d upto d[sizeof(b)-1], and c cannot be touched at all.
Whereas if c or d is the active member, reading the others is fine.

The active member is the last written to member:
Quote from: C++99: 9.5 class.union
In a union, at most one of the non-static data members can be active at any time, that is, the value of at
most one of the non-static data members can be stored in a union at any time.



Cybernetician

This seems me what i am excepting to study BTW at this time i am considering the C99 only.

Thanks pYro_65.
From Idea To Invention

Go Up