2014-11-20 02:48 AM
Hello,
i am running compile (IAR AMR) in highest optimization settting, but sometimes it does ignores my code, or even functions that does have purpose; as example, DataRx[] is loaded by DMA with data from computer, and it is used for triggering ( software based), 160 is free running mode, 168 is external triggerif((DataRx[0])==168)
{
while((GPIOA->IDR&GPIO_Pin_3)==0)
{
if(DataRx[0]==160)
{
break;
}
}
}
if i use uint8_t as my variable, this code is ignored, adding volatile uint8_t does solve problem, but then, compiler states that is problem in my other code ( but it works)
A_offset=DataRx[2]+(DataRx[3]<<8);
D_offset=(DataRx[4]+(DataRx[5]<<8))&1023;
integration=DataRx[6]+(DataRx[7]<<8);
error code says for all lines:
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
any idea how to tell compiler, that it must execute my trigger code, or should i move this code to outside main(), and create volatile function ? ( just tryed, it does work, but i should know what kind of programming error i am creating)
2014-11-20 06:46 AM
The compiler has no idea about the DMA (and ISR as well), so for it the data in DataRx never changes and it happily removes these operations as redundant.
Using of volatile qualifier is the correct way to resolve this issue. Resolving the warning could be done if you split the operation in two, so there will be only one volatile operand per operation:A_offset= DataRx[3]; A_offset=DataRx[2]+(A_offset<<8);
But volatile alone may not be enough. You should take measures to ensure that the part of the array used in the calculations will not change unexpectedly in the middle of operations. May it is not an issue if the DMA doesn't overwrite the same locations unless you restart it. And finally, it seems to me that:A_offset=DataRx[2]+(DataRx[3]<<8);
... should be:A_offset=DataRx[2]+((unit16_t)DataRx[3]<<8);
...