为什么在一个序列点内只有一个具有volatile限定类型的读访问权限?

时间:2015-08-06 15:53:36

标签: c volatile misra

给出以下代码:

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限定类型的读访问权限。问题是,为什么?我需要知道为什么要实现一个解决方案,并在这里解释为什么我要更改代码。

问候。

2 个答案:

答案 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放在枕头下。