I'm using an AT91SAM7 uC and have inherited some C code which is giving me fits. When I run this code I get a data abort error. I've tracked down the offending line of code, and it appears to be caused by something like this:
n = (UINT8) ((UINT16*)(pObject->pVar))[0];
pObject->pVar points to an instance of a structure like this:
typedef __packed struct{ UINT16 v1; UINT32 v2; UINT32 v3; UINT32 v4; UINT32 v5; }OBJTYPE; OBJTYPE xxx = {0,0,0,0,0};
When I stop the debugger on the line that causes the data abort error, I can see that pObject->pVar is pointing to 0x00200173. Is the data abort error happening because that object is not on a 32-bit boundary in memory? If so, how can I [easily] fix that? I've been going through all the online doc's reading about __packed, #pragma pack(n), adding unions to typedefs, etc.; but all the things I've been trying have not fixed the problem.
Is there an easy way (besides the __at__ attribute) to get variables like the above structure to be aligned on 32-bit boundaries?
Can anyone give me a suggestion for how to resolve this problem?
Help... Dave.
Thanks Dan.
According to the map file, the variable that this pointer is supposed to be pointing to is located at 0x00200173. When I stop on the line of code that's trying to access this variable via the pointer, the pointer is pointing to 0x00200173. That makes me think it really is pointing to the right structure. I don't see how that address is 32-bit aligned though.
If I use the debugger to look at the RAM the pointer points to, the right data is there.
If I make the pointer point to an address that is 32-bit aligned (although it doesn't point to the start of the structure anymore), the data abort error goes away.
If I remove __packed from the struct's typedef and rebuild the code, the map file shows that the var then does get aligned on a 32-bit boundary; and the data abort error goes away too.
I'm still confused. I don't see how this code can work if these structures don't get aligned on 32-bit boundaries when I use __packed in their typedef's.
Dave.
have you tried to patch the structure?
Hi David,
I believe you shoud remove the casting of the pointer: (UINT16*)(pObject->pVar). It appears that the cast removes the __packed qualifier from the pointer, so the compiler uses an aligned memory access instead of unaligned one. If the code in question tries to access a structure member, why wouldn't it just do it: n = (UINT8)(pObject->pVar->v1) ?
"I'm still confused. I don't see how this code can work if these structures don't get aligned on 32-bit boundaries when I use __packed in their typedef's."
You never did show pObject's declaration. Is it an 'OBJTYPE*' (i.e., points to a __packed structure)? I sounds like the compiler does not agree that it's pointing to unaligned data.