If I have a struct declared like the following:
volatile struct { uint8_t foo; int16_t bar[1]; } __attribute__((packed)) foobar;
The code emitted uses LDRSH to access bar[0] and causes a hardfault at runtime. But If I were to declared it using the __packed qualifier:
__packed volatile struct { uint8_t foo; int16_t bar[1]; } foobar;
Then the compiler correctly recognizes the potential misalignment and emits LDRB instead. Is this the expected behavior? I'm using uVision v5.17 with Armcc v5.06 update 1 (build 61). Thanks.
Hello David,
Did you see this entry in the manual:
I assume you are using the --gnu or such in your Project-> Options for target -> "C/ C++ " tab, compiler control string, because based on this article:
infocenter.arm.com/.../index.jsp
It sounds like you are running into the scenario:
In GNU mode, __attribute__((packed)) has the effect of #pragma packed. Taking the address of a field covered by __attribute__((packed)) does not produce a __packed qualified pointer.
For more details, see: infocenter.arm.com/.../index.jsp
There is good stuff there, but of particular interest is the "Comparison of a __packed struct and a #pragma packed struct" section. It looks simular to the issues you are having.
A good work around may be to, rather than packing the whole struct, pack only the parts you care about (maybe just uint8_t foo;). There is a performance penalty for marking the whole struct as packed.
In my experience, packing the struct is something you only do if you are desperate for space - leaving the struct members at their natural data alignment makes it much simpler code. Also, there can be headaches when referencing pointers to pointers of a packed struct, if not done right.
infocenter.arm.com/.../index.jsp David,