Почему в пределах одной точки следования должно быть не более одного доступа на чтение с типом volatile-qualified?

Учитывая следующий код:

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 – 13.2 и решил провести небольшое исследование. Я нашел здесь (http://archive.redlizards.com/docs/misrac2012-datasheet.pdf) что:

в пределах одной точки следования должно быть не более одного доступа для чтения с типом volatile-qualified

Дело в том, что я не смог найти пример или объяснение, объясняющее, почему в пределах одной точки последовательности должно быть не более одного доступа на чтение с типом, квалифицируемым как volatile.

Мне нужно найти решение для нарушения кода, но мне не совсем понятно, что делать.

Теперь я знаю, что в пределах одной точки следования должно быть не более одного доступа на чтение с типом, квалифицируемым как volatile. Вопрос в том, почему? и мне нужно знать почему, чтобы реализовать решение и объяснить всем здесь, почему я меняю код.

С Уважением.


person m4l490n    schedule 06.08.2015    source источник


Ответы (2)


Обоснование правила:

(Обязательно) Значение выражения и его постоянные побочные эффекты должны быть одинаковыми во всех разрешенных порядках оценки.

Если между точками последовательности считывается более одной переменной с квалификатором 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);
    }
}
person ecatmur    schedule 06.08.2015
comment
Идеальный!! Спасибо! Этот ответ может помочь мне и с другими проблемами. Мне не хватало части правила о побочных эффектах. - person m4l490n; 06.08.2015
comment
Что-то мне не очень понятно. Почему чтение volatile переменной является побочным эффектом? - person m4l490n; 06.08.2015
comment
@ m4l490n, потому что для этого предназначен volatile - он указывает, что записи и чтения не могут быть кэшированы или переупорядочены. Примером может служить аппаратный регистр, где операции чтения могут возвращать разные значения при последовательных чтениях и приводить к произвольным действиям. - person ecatmur; 06.08.2015
comment
@ecatmur: на самом деле в стандарте этого не сказано. Это относится только к переупорядочению компилятором в отношении абстрактной машины. Кэширование и буферизация или переупорядочивание внешним оборудованием не рассматриваются, если только сама программа не получает правильные значения. Это одна из причин, по которой volatile недостаточно при использовании потоков или мультипроцессоров с прерываниями. Здесь в игру вступают атомики, которые включают в себя барьеры/заборы и прочую общесистемную синхронизацию. - person too honest for this site; 07.08.2015

Между получением аргументов вызова функции нет точек последовательности. Таким образом, порядок их извлечения не определен стандартом. OTOH, компилятор должен поддерживать порядок доступа к volatile-объектам, так что это противоречие.

Извлеките переменные в энергонезависимые временные файлы и используйте их для вызова функции:

float32_t t1 = tst_mtr_dutycycle;
uint8_t t2 = tst_mtr_direction;
MTR_SetDC(t1, t2);

Обратите внимание, что на самом деле это проблема стандартного C, а не только связанная с MISRA-соответствием.

Поскольку у вас есть несколько проблем с соблюдением стандартов, вы можете сохранить стандарт под подушкой.

person too honest for this site    schedule 06.08.2015
comment
Спасибо за разъяснение, что между выборкой аргументов вызова функции нет точек последовательности. - person m4l490n; 06.08.2015
comment
Спасибо, я проверю это. - person m4l490n; 06.08.2015