Running Keil 5.1 on Freescale K64 32MHz crystal.
Trying to copy data into a two-dimensional array. Copying to an array lastRequestedHeader[3][14] from an array requestedPacket[14].
I have no problem copying into lastRequestedHeader[0] because it starts at address 0x20004514 in memory, but copying to lastRequestedHeader[1] gives me an
Stepping through the memcpy call, I see the first two bytes being copied properly in the __aeabi_memcpy function, but then getting into __aeabi_memcpy4 is where my processor stops on an unaligned access fault
Any ideas? Is there another memcpy call that I can substitute into the project?
At the initial memcpy call:
SRC = 0x20003C94 DST = 0x20004522 len = 0x0000000E Only source is 4-byte aligned.
After the first two bytes, of course, the DST is now 4-byte aligned and the source is not. The call to __aeabi_memcpy4 has R0 = 0x20004524 (destination address) R1 = 0x20003C96 (source address) R2 - 0x0000000C (length)
Then attempting to step into the __aeabi_memcpy4 hits the hard-fault, again with the unaligned access error
So - homework for Keil. They haven't done their homework - memcpy() and memmove() must work on any alignment of source and destination (assuming that there aren't some additional alignment issues for some specific parts of the processor memory region). This is a bit of a student oops if asked to implement an optimized memcpy().
Cortex-M3 and -M4 (architecture ARMv7-M) can do unaligned memory accesses (LDR/STR, LDRH/STRH. etc.). They can also be made to trap by setting CCR.UNALIGN_TRP. By default (unless all code is compiled with --no_unaligned_access) armcc/armlink will assume that unaligned accesses are enabled.
I remember that, for Cortex-M3, However, if you do a "ldm" or "stm" to load or store multiple values (where "multiple" is defined as 1 or more), unaligned addresses are never allowed.
If unaligned accesses are not allowed, then the compiler should handle the placement of variables on aligned addresses. Special care should be taken when dealing with byte arrays...but that should be a compiler/linker/library issue, not a programmer concern
This isn't a case of the compiler leaving variables on aligned or unaligned addreses.
This is about memcpy() being defined to support any alignment of the source and destination data, and the Keil implementation being designed based on false assumptions. memcpy() must always assume that the two pointers are to byte arrays of arbitrary align.