Dado el siguiente código:
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); } }Encontré problemas con MISRA C 2012 Rule-13.2 y decidí investigar un poco. Encontré aquí ( http://archive.redlizards.com/docs/misrac2012-datasheet.pdf ) que:
no habrá más de un acceso de lectura con tipo calificado volátil dentro de un punto de secuencia
Lo que pasa aquí es que no he podido encontrar un ejemplo o una explicación que aclare por qué no debe haber más de un acceso de lectura con tipo calificado como volátil dentro de un punto de secuencia.
Necesito encontrar una solución para el código que infringe, pero no tengo muy claro qué hacer.
Ahora sé que no habrá más de un acceso de lectura con tipo calificado volátil dentro de un punto de secuencia. La pregunta es, ¿por qué? y necesito saber por qué para implementar una solución y explicar a todos aquí por qué estoy cambiando el código.
Saludos.
La justificación de la regla es:
(Obligatorio) El valor de una expresión y sus efectos secundarios persistentes serán los mismos en todas las órdenes de evaluación permitidas
Si se lee más de una variable calificada como volátil entre puntos de secuencia, no se especifica cuál se lee primero. Leer una variable volátil es un efecto secundario.
La solución es ordenar explícitamente las lecturas:
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); } }No hay puntos de secuencia entre la obtención de los argumentos de una llamada de función. Entonces, el orden en que se obtienen no está definido por el estándar. OTOH, el compilador tiene que mantener el orden de los accesos a los objetos volátiles, por lo que esto es una contradicción.
Obtenga las variables a temperaturas no volátiles y utilícelas para la llamada a la función:
float32_t t1 = tst_mtr_dutycycle; uint8_t t2 = tst_mtr_direction; MTR_SetDC(t1, t2);Tenga en cuenta que esto es realmente un problema para el estándar C y no solo relacionado con el cumplimiento de MISRA.
Como parece tener múltiples problemas con respecto al cumplimiento de los estándares, es posible que desee mantener el estándar bajo la almohada.