Our group are using tinyos with msp430 and find the msp430-gcc compiler can
not handle packed struct correctly. See the below code scratch and test
results. I wonder whether this will be fixed in near future.
typedef struct tTestPointer
{
uint8_t m;
uint16_t k;
uint32_t l;
} __attribute__ ((packed)) tTestPointer;
typedef struct tTestPointer_nopack
{
uint8_t m;
uint16_t k;
uint32_t l;
}tTestPointer_nopack;
implementation {
//tTestPointer will be put into TOSMsg
TOS_Msg testMsg;
TOS_MsgPtr tPtr;
TOS_Msg testMsg_nopack;
TOS_MsgPtr tPtr_nopack;
void initialize() {
tTestPointer* testMsgPtr;
tTestPointer_nopack* testMsgPtr_nopack;
//Initilize for packed
tPtr = &testMsg;
testMsgPtr = (tTestPointer*)(tPtr->data);
testMsgPtr->m = 0x12;
testMsgPtr->k = 0x3456;
testMsgPtr->l = 0x78abcdef;
//Initilize for no_packed using same values
tPtr_nopack = &testMsg_nopack;
testMsgPtr_nopack = (tTestPointer_nopack*)(tPtr_nopack->data);
testMsgPtr_nopack->m = 0x12;
testMsgPtr_nopack->k = 0x3456;
testMsgPtr_nopack->l = 0x78abcdef;
}
event result_t Timer.fired(){
uint8_t i;
uint32_t startAddr;
uint8_t* src;
uint32_t startAddr_nopack;
uint8_t* src_nopack;
tTestPointer* testMsgPtr;
tTestPointer_nopack* testMsgPtr_nopack;
testMsgPtr = (tTestPointer*)(tPtr->data);
testMsgPtr_nopack = (tTestPointer_nopack*)(tPtr_nopack->data);
startAddr = (uint32_t)(&(testMsgPtr->m));
src = (uint8_t*)(&(testMsgPtr->m));
for (i=0;i<10 ;i++ ) {
debug(DBG_SNMS,"addr %x value %x \n", startAddr+i, *(src+i));
}
startAddr_nopack = (uint32_t)(&(testMsgPtr_nopack->m));
src_nopack = (uint8_t*)(&(testMsgPtr_nopack->m));
for (i=0;i<10 ;i++ ) {
debug(DBG_SNMS,"addr %x value %x \n", startAddr_nopack+i,
*(src_nopack+i));
}
debug(DBG_SNMS,"pack.m = %x [%x]\n", testMsgPtr->m, &(testMsgPtr->m));
debug(DBG_SNMS,"pack.k = %x [%x]\n", testMsgPtr->k, &(testMsgPtr->k));
debug(DBG_SNMS,"pack.l = %x [%x]\n", testMsgPtr->l, &(testMsgPtr->l));
debug(DBG_SNMS,"nopack.m = %x [%x]\n", testMsgPtr_nopack->m,
&(testMsgPtr_nopack->m));
debug(DBG_SNMS,"nopack.k = %x [%x]\n", testMsgPtr_nopack->k,
&(testMsgPtr_nopack->k));
debug(DBG_SNMS,"nopack.l = %x [%x]\n", testMsgPtr_nopack->l,
&(testMsgPtr_nopack->l));
return SUCCESS;
}
Using the same test case above in Telosb platform, you will receive the
following results
'''(1)Packed: the output result'''
//Every byte result
addr 5c00b00a value 12
addr 5c00b00b value 00
addr 5c00b00c value 00
addr 5c00b00d value 78
addr 5c00b00e value ab
addr 5c00b00f value cd
addr 5c00b010 value ef
addr 5c00b011 value 0
addr 5c00b012 value 0
addr 5c00b013 value 0
//Value of m, k ,l
pack.m = 12 [5c00b00a]
pack.k = 0 [5c00b00b]
pack.l = 78abcdef [5c00b00d]
The 2 bytes of k (3456) are set to the wrong addresses (can't event see it
here)
'''(2)No_Packed: the output result'''
//Every byte result
addr 5c00300a value 12
addr 5c00300b value 0
addr 5c00300c value 34
addr 5c00300d value 56
addr 5c00300e value 78
addr 5c00300f value ab
addr 5c003010 value cd
addr 5c003011 value ef
addr 5c003012 value 0
addr 5c003013 value 0
//Value of m, k ,l
nopack.m = 12 [5c00300a]
nopack.k = 3456 [5c00300c]
nopack.l = 78abcdef [5c00300e]
Every byte is correct