Given the following code:
static volatile float32_t tst_mtr_dutycycle;
static volatile uint8_t tst_mtr_direction;
static volatile uint32_t tst_mtr_update;
void TST_MTR_Task(void)
{
if (tst_mtr_update == 1U)
{
tst_mtr_update = 0;
MTR_SetDC(tst_mtr_dutycycle, tst_mtr_direction);
}
}
I found problems with MISRA C 2012 Rule-13.2 and I decided to make some research. I found here (http://archive.redlizards.com/docs/misrac2012-datasheet.pdf) that:
there shall be no more than one read access with volatile-qualified type within one sequence point
The thing here is that I haven't been able to find an example or explanation that makes clear why there shall be no more than one read access with volatile-qualified type within one sequence point.
I need to find a solution for the violating code but is not really clear to me what to do.
I know now that there shall be no more than one read access with volatile-qualified type within one sequence point. The question is, why? and I need to know why in order to implement a solution and to explain everybody here why I am changing the code.
Regards.
The justification for the rule is:
(Required) The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders
If more than one volatile-qualified variable is read between sequence points, then it is unspecified which is read first. Reading a volatile variable is a side effect.
The solution is to explicitly order the reads:
void TST_MTR_Task(void)
{
if (tst_mtr_update == 1U)
{
tst_mtr_update = 0;
float32_t dutycycle = tst_mtr_dutycycle;
uint8_t direction = tst_mtr_direction;
MTR_SetDC(dutycycle, direction);
}
}
There are no sequence points between fetching the arguments of a function call. So the order they are fetched is undefined by the standard. OTOH, the compiler has to maintain the order of accesses to volatile objects, so this is a contradiction.
Fetch the variables to non-volatile temps and use those for the function call:
float32_t t1 = tst_mtr_dutycycle;
uint8_t t2 = tst_mtr_direction;
MTR_SetDC(t1, t2);
Note this is actually an issue for standard C and not just related to MISRA-compliance.
As you appear to have multiple problems regarding standard compliance, you might want to keep the standard under your pillow.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With