Here:
s2 strobe_s * 0x800a497 <_fflush_r+66>
s2is a flash (read-only) address. Copying to read-only memory is both semantically erroneous and may trigger an MPU fault if the region were set to read-only.
It is not clear to me how the original code worked or indeed how:
*s1 = ss->strobe;
is not causing a problem too however. Certainly it won't work as intended even if there were no exception.
Answer from Clifford on Stack OverflowFast memcpy
memcpy crashes with NEW_LIBC on stm32 cortex m7 with debugger attached
Several problems:
DMA buffers need to be
volatilequalified or otherwise the compiler might go bananas when generating the code accessing them.You use
memcpyincorrectly, should have beenmemcpy(Wave_Active , Wave_High, sizeof Wave_Active);The use of
memcpyto begin with is often incorrect when it comes to hardware-related programming. Copying 256 bytes takes a lot of time. Worst case, your DAC might even request new data before you are done copying.The correct way to write such code would be to have several allocated buffers, then swap an "active" pointer to point at the one used. With the disclaimer that I don't understand the purpose of these arrays, something like this would be an immense speed optimization:
volatile uint32_t Wave_Low[NS] = {2048,[...],2047}; # lookup table 1 volatile uint32_t Wave_High[NS] = {4096,[...],4067}; # lookup table 2 volatile uint32_t* Wave_Active = Wave_High; ... if(DMA_flag) { Wave_Active = (Wave_Active==Wave_Low) ? Wave_High : Wave_Low; /* you might have to tell the DMA which array to use next time here */ }
@ 0___________ suggested a solution with the right approach. He suggested overwriting one half of the lookup table while the DMA reads the other half. This would avoid reading a byte while it's getting read. The problem with this is that I'm sampling faster than memcpy can write the values.
Therefore I've tried the simple approach and bluntly overwrite the array with memcpy no matter what. This partly causes funny signal patterns (you can actually see which part of the lookup table ges overwritten first) but over all it works. This causes a signal transition within around 20 µs which is sufficient. As I can live with the imperfect signal pattern that will be my solution. Below is an oscilloscope screenshot of the signal transition from low to high.
Thanks for your help!

Hello,
I've read a lot about fast memcpy, type punning and strict aliasing rule in C99 and I feel a bit confused and would like to make sure that my understanding is correct. So, as far as I understand, the safest way of implementing a memcpy that works with chunks of data bigger than one byte is to use assembly, because:
Accessing a uint8_t buffer with an uint32_t pointer is undefined behavior (due to strict aliasing, not only address alignment):
if (pu8Buffer % 4 == 0)
* (uint32_t *) pu8Buffer = u32Array[szIndex];
2) Type punning with unions is specified behavior only with gcc extensions:
union {
uint8_t * p8;
uint32_t * p32;
} uPointer;
uPointer.p8 = pu8Buffer;
*uPointer.p32 = u32Array[szIndex];
Is there really no standard way of implementing a faster memcpy in C99?