给出以下代码:
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);
}
}
我发现了 MISRA C 2012 Rule-13.2 的问题,我决定做一些研究。我在这里找到了{http://archive.redlizards.com/docs/misrac2012-datasheet.pdf):
在一个序列点内,只有一个具有volatile限定类型的读访问权
这里的事情是我无法找到一个例子或解释,说明为什么在一个序列点内不得有多于一个具有volatile限定类型的读访问权。
我需要找到违规代码的解决方案,但我不清楚该怎么做。
我现在知道在一个序列点内只有一个具有volatile限定类型的读访问权限。问题是,为什么?我需要知道为什么要实现一个解决方案,并在这里解释为什么我要更改代码。
问候。
答案 0 :(得分:5)
该规则的理由是:
(必需)表达式的值 及其持久的副作用 在所有允许的范围内应相同 评估订单
如果在序列点之间读取了多个volatile限定变量,则不指定首先读取的变量。读取volatile变量是一个副作用。
解决方案是明确地命令读取:
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);
}
}
答案 1 :(得分:2)
在获取函数调用的参数之间没有序列点。 因此,标准未定义它们被提取的顺序。 OTOH,编译器必须维护对易失性对象的访问顺序,所以这是一个矛盾。
将变量提取到非易失性temps并将其用于函数调用:
float32_t t1 = tst_mtr_dutycycle;
uint8_t t2 = tst_mtr_direction;
MTR_SetDC(t1, t2);
请注意,这实际上是标准C的问题,而不仅仅与MISRA合规性有关。
由于您似乎在标准合规方面存在多个问题,因此您可能希望将standard放在枕头下。