Unaligned memory access can be the result of using the attribute 'pack_mode'
. This means, for example, that a data type with a size of 4 bytes is then located
at an address which is not divisible by 4. Normally, on a 32-bit system a 32-bit data
type can be read and written with a single memory access. On some platforms, for example
on ARM platforms, this is possible only when this value is aligned in the memory.
On other platforms, it can be that the access is possible but it is performed much
more slowly.
Example
{attribute 'pack_mode':=1} TYPE DUT STRUCT by1 : BYTE; dw1 : DWORD; END_STRUCT END_TYPE
On an ARM platform, the value dw1
cannot be read with a single access. When an attempt is made to access this element
directly, the ARM processor will throw an exception.
Assumption: The following read access is performed: dwTest := dut1.dw1;
For this access to the DWORD dw1
, four memory accesses are required because each byte is read, shifted, and disjuncted
individually. The flow is somewhat the same as in the following example in which a
DWORD
is generated from an array of four bytes:
dwHelp := bytes[0]; dwResult := dwHelp; dwHelp := bytes[1]; dwHelp := SHL(dwHelp, 8); dwResult := dwResult OR dwHelp; dwHelp := bytes[2]; dwHelp := SHL(dwHelp, 16); dwResult := dwResult OR dwHelp; dwHelp := bytes[3]; dwHelp := SHL(dwHelp, 24); dwResult := dwResult OR dwHelp;
Obviously, this kind of access is much slower than access to a DWORD
, which is aligned appropriately in the memory.
pdw := ADR(dut1.dw1); dwTest := pdw^;
However, the compiler will not generate the access of the example when this kind of member is accessed by means of a pointer. This means that the following code results in an exception on an ARM platform.
pdw := ADR(dut1.dw1); dwTest := pdw^;
For performance reasons, you should therefore avoid working with structures which are not naturally aligned.
A packed structure must not contain an unpacked structure.