2013-04-15 07:11 AM
Already posted this on Keil Website, it was tested with STM32F100, therefore:
we made some simple tests with STM32F100 Value Line Eval Board:
//------------------------------------------------------------------------------
// Variables static unsigned char sDstBuf[1024]; // 1KiB static unsigned char sSrcBuf[sizeof(sDstBuf)];printf(''Copying words from misaligned src to aligned dst buffer... '');
memset(sDstBuf, 0xcd, sizeof(sDstBuf));with optimize Level 3, optimize for time this takes
120usecwith optimize Level 0
155usecalmost the same if memcpy is used:
memcpy(sDstBuf, (const void *)0xcd, sizeof(sDstBuf));It runs into hard fault, if optimize Level >=1 and optimise for time is not set.
I think this is a compiler error..
We ran into this before with MDK 4.60, now we use 4.70A
Werner
#cross-post #memcpy2013-04-16 12:15 AM
And what is the question?
JW2013-04-16 12:25 AM
Sorry I try editing, but somehow the Forum does not let me do that..
the offending code is for (pDstWord = (unsigned int*) (sDstBuf + 0), // Aligned! pSrcWord = (unsigned int*) (sSrcBuf + 1); // Misaligned! pSrcWord < (unsigned int*) (sSrcBuf + sizeof(sSrcBuf) - sizeof(*pSrcWord)); pSrcWord++) { *pDstWord = *pSrcWord; } optimize >= 1 for size:for (pDstWord = (unsigned int*) (sDstBuf + 0), // Aligned! pSrcWord = (unsigned int*) (sSrcBuf + 1); // Misaligned! pSrcWord < (unsigned int*) (sSrcBuf + sizeof(sSrcBuf) - sizeof(*pSrcWord)); pSrcWord++) { *pDstWord = *pSrcWord; } leads to this disassembly part: 0x08002446 CC02 LDM r4!,{r1} ; >>>> after this: Hardfault occurs 0x08002448 6001 STR r1,[r0,#0x00] 372: pSrcWord 373: < (unsigned int*) (sSrcBuf + sizeof(sSrcBuf) - sizeof(*pSrcWord)); 374: pSrcWord++) 375: { 376: *pDstWord = *pSrcWord; 377: } 0x0800244A 42B4 CMP r4,r6 0x0800244C D3FB BCC 0x08002446
2013-04-16 01:12 AM
Multi-word instructions (here: LDM) must access memory word-aligned, see e.g. description of UNALIGNED bit in UFSR (part of SCB->CFSR).
I can't judge whether this could be called a compiler fault; Keil is to be consulted. Is this a library memcpy()? JW2013-04-16 01:24 AM
2013-04-16 01:26 AM
You need to set the compiler switch ''--no_unaligned_access'' in Keil.
ARM7 has the principal possibility to support access at 2-Byte addresses - but it is quite stupid, as it is not faster than two 4-Byte (=32-bit aligned) accesses. So you should switch this off in the compiler. (if you want to use it, you have to switch it on in the CPU - see the system ... .c file - best search for the keyword ''aligned'' in the ARM7 TRM / STM32F4 Programming Manual / Cortex M4 TRM).2013-04-16 01:38 AM
I can't judge whether this could be called a compiler fault; Keil is to be consulted.
I would judge it as such. The compiler should not emit such instructions if he can't ensure proper alignment. And as the address parameters are untyped (void *) and the number of elements to copy in bytes (), that is definitely not the case, so I view this as incorrect optimisation.
2013-04-16 01:43 AM
''The compiler should not emit such instructions if he can't ensure proper alignment''
But, in this case, I'm not sure that it can ensure that - given all the casting that's going on (see the Keil cross-post)''as the address parameters are untyped (void *)''
Note that the memcpy reference was a red herring - it's not occuring in the memcpy!
2013-04-16 02:17 AM
Note that the memcpy reference was a red herring - it's not occuring in the memcpy!
You are right, that would be a different case than. Forcing word-sized pointers to unaligned addresses is typically ''one's own fault''.
2013-04-16 03:16 AM
As far as the compiler is concerned...
C99, 6.3.2.3#5 An integer may be converted to any pointer type. Except as previously specified [this refers to null pointer, JW], the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation. #7 A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined. i.e. the compiler is absolutely free to emit the ''offending'' code as the result of dereferencing of cast pointers, even if it IS aware of the unalignment. JW