Quizás, cada desarrollador de programas para microcontroladores probablemente haya escuchado al menos una vez sobre estándares especiales de codificación diseñados para ayudar a aumentar la seguridad y la portabilidad de su código. Uno de esos estándares es MISRA. En este artículo examinaremos con más detalle qué es este estándar, cuál es su filosofía y cómo usarlo en sus proyectos.
Muchos de nuestros lectores han escuchado que PVS-Studio admite la clasificación de sus alertas de acuerdo con el estándar MISRA. Actualmente PVS-Studio
cubre más de 100 reglas MISRA C: 2012 y MISRA C ++: 2008.
Este artículo tiene como objetivo matar tres pájaros de un tiro:
- Indique qué es MISRA para quienes no están familiarizados con este estándar;
- Recordar al mundo incrustado de lo que somos capaces;
- Para ayudar a profundizar en el curso de los negocios para los nuevos empleados que también desarrollarán aún más nuestro analizador MISRA;
Espero poder hacerlo interesante. ¡Entonces comencemos!
Historia de MISRA
La historia de MISRA comenzó hace mucho tiempo. Luego, a principios de los años 90, el programa del gobierno del Reino Unido bajo el nombre indicativo "Safe IT" asignó fondos para varios proyectos, de una forma u otra relacionados con la seguridad de los sistemas electrónicos. El proyecto MISRA (Asociación de Fiabilidad de Software de la Industria del Motor) en sí fue fundado para crear una guía para desarrollar software para microcontroladores en vehículos terrestres, en automóviles, en general.
Después de recibir fondos del estado, el equipo de MISRA se puso a trabajar y, en noviembre de 1994, lanzó su primera guía: "
Directrices de desarrollo para software basado en vehículos ". Esta guía aún no se ha vinculado a un lenguaje específico, pero debo admitir: el trabajo fue impresionante y probablemente se refería a todos los aspectos concebibles del desarrollo de software embebido. Por cierto, los desarrolladores de esta guía
celebraron recientemente
el 25 aniversario de una fecha tan importante para ellos.
Cuando terminaron los fondos del estado, los miembros de MISRA decidieron continuar trabajando juntos de manera informal, esto continúa hasta nuestros días. De hecho, MISRA (como organización) es una comunidad de partes interesadas de diversas industrias de fabricación de automóviles y aviones. Ahora estas fiestas son:
- Bentley automóviles
- Ford Motor Company
- Jaguar land rover
- Sistemas diésel de Delphi
- HORIBA MIRA
- Protean electric
- Servicios de ingeniería de Visteon
- La universidad de leeds
- Ricardo reino unido
- ZF TRW
Jugadores de mercado muy fuertes, ¿no? No es sorprendente que su primer estándar relacionado con el lenguaje, MISRA C, haya sido ampliamente aceptado entre los desarrolladores integrados de misión crítica. MISRA C ++ apareció un poco más tarde. Gradualmente, las versiones de los estándares se actualizaron y refinaron para cubrir las nuevas características de los idiomas. Al momento de escribir este artículo, las versiones actuales son MISRA C: 2012 y MISRA C ++: 2008.
Filosofía y ejemplos de reglas
Las características más distintivas de MISRA son su increíble atención al detalle y su meticulosidad extrema para garantizar la seguridad. Los autores no solo reunieron en un lugar todos los "agujeros" C y C ++ que se les ocurrieron (como, por ejemplo, los autores del CERT), sino que elaboraron cuidadosamente los estándares internacionales de estos idiomas y anotaron todas las formas concebibles e inconcebibles de cometer errores. Y luego tomaron y agregaron las reglas sobre la legibilidad del código desde arriba: esto es para dificultar la introducción de un nuevo error en el código ya limpio.
Para comprender el grado de seriedad, considere algunas reglas tomadas de la norma.
Por un lado, hay muchas reglas buenas y adecuadas que siempre se deben seguir en todo momento, independientemente de para qué se destine su proyecto. En su mayor parte, están diseñados para eliminar el comportamiento indefinido / no especificado / dependiente de la implementación. Por ejemplo:
- No use el valor de una variable no inicializada
- No use el puntero ARCHIVO después de cerrar la secuencia
- Todas las funciones no nulas deben devolver un valor.
- El contador de bucle no debe tener un tipo de punto flotante
- ... etc.
Por otro lado, hay reglas, cuyos beneficios se encuentran en la superficie, pero que (desde el punto de vista de los proyectos ordinarios) no son tan pecaminosos para romper:
- No use goto y longjmp
- Cada interruptor debe terminar con el valor predeterminado
- No escriba código inalcanzable
- No use funciones variables
- No use aritmética de direcciones (excepto [] y ++ )
- ...
Dichas reglas tampoco son malas, y en combinación con las anteriores ya dan un aumento tangible en la seguridad, pero ¿es esto suficiente para sistemas integrados altamente responsables? Se utilizan no solo en la industria automotriz, sino también en la fabricación de aeronaves, aeroespacial, militar y médica.
No queremos, debido a un error de software, que algunas máquinas de rayos X
irradien pacientes con una dosis de 20,000 rad , por lo que las reglas habituales "cotidianas" ya no son suficientes. Están en juego vidas humanas y enormes cantidades de dinero, y debe incluirse meticulosidad. Aquí el resto de las reglas de MISRA entran en escena:
- El sufijo 'L' en el literal siempre debe estar en mayúscula (la pequeña 'l' se puede confundir con la unidad)
- No use el operador de coma (aumenta la posibilidad de cometer un error)
- No utilice la recursividad (una pila pequeña de microcontroladores puede desbordarse fácilmente)
- Los cuerpos de las declaraciones if , else , for , while , do , switch deben estar entre llaves (puede potencialmente cometer un error si el código no está alineado correctamente )
- No use memoria dinámica (porque existe la posibilidad de asignarla sin éxito del montón, especialmente en microcontroladores)
- ... y muchas, muchas de esas reglas.
A menudo, las personas que se encuentran con MISRA tienen la opinión de que la filosofía de la norma es "prohibir esto y prohibir esto". De hecho, esto es así, pero solo en parte.
Sí, el estándar tiene muchas reglas similares, pero su propósito no es prohibir todo lo posible, sino enumerar todas las formas de violar la seguridad del código. Para la mayoría de las reglas, eliges si seguirlas o no. Explicaré esto con más detalle.
En MISRA C, las reglas se dividen en tres categorías principales: obligatorio, obligatorio y consultivo. Obligatorio: estas son reglas que no deben violarse bajo ningún pretexto. Por ejemplo, esta sección incluye la regla "no use el valor de una variable no inicializada". Las reglas requeridas son menos estrictas: permiten la posibilidad de rechazo, pero solo si estas desviaciones están cuidadosamente documentadas y justificadas por escrito. El resto de las reglas se incluyen en la categoría de Asesoramiento; estas son reglas que no se deben seguir.
MISRA C ++ es un poco diferente: falta la categoría obligatoria, y la mayoría de las reglas pertenecen a la categoría obligatoria. Por lo tanto, de hecho, tiene derecho a violar cualquier regla; solo recuerde documentar las desviaciones. También hay un documento de categoría: estas son reglas obligatorias (no se permiten desviaciones), que están asociadas con prácticas comunes como "Cada uso de ensamblador debe documentarse" o "la biblioteca de complementos debe cumplir con MISRA C ++".
Que mas hay
De hecho, MISRA no solo consiste en un conjunto de reglas. De hecho, este es un manual para escribir código seguro para microcontroladores y, por lo tanto, está lleno de todo tipo de utilidades. Echemos un vistazo a ellos en detalle.
En primer lugar, el estándar contiene una descripción bastante detallada de los antecedentes: en aras de lo que se creó el estándar, por qué se eligió C o C ++, las ventajas y desventajas de estos lenguajes.
Somos conscientes de las virtudes de estos idiomas. Sí, y sobre las deficiencias, en general, también :) ¿Cuáles son la alta complejidad, la especificación incompleta del estándar y la sintaxis que hace que sea muy fácil cometer un error y luego buscar un error largo? Por ejemplo, podrías escribir esto accidentalmente:
for (int i = 0; i < n; ++i); { do_something(); }
Aún así, existe la posibilidad de que una persona no note un
punto y
coma extra , ¿verdad? También puedes escribir
así :
void SpendTime(bool doWantToKillPeople) { if (doWantToKillPeople = true) { StartNuclearWar(); } else { PlayComputerGames(); } }
Es bueno que tanto el
primer como el
segundo caso sean fácilmente detectados por las reglas de MISRA (el primero es MISRA C: 13.4 / MISRA C ++: 6.2.1, el segundo es MISRA C: 13.4 / MISRA C ++: 6.2.1).
Además de describir los problemas, el estándar contiene una gran cantidad de consejos sobre lo que necesita saber antes de comenzar: sobre cómo configurar el proceso de desarrollo de MISRA, sobre el uso de analizadores estáticos para verificar el cumplimiento del código, qué documentos debe conservar y cómo llenar, y así sucesivamente.
También al final hay aplicaciones que contienen: una lista corta y una tabla resumen de reglas, una pequeña lista de vulnerabilidades C / C ++, un ejemplo de documentación de desviaciones de la regla, así como varias listas de verificación diseñadas para ayudarlo a no perderse en toda esta burocracia.
Como puede ver, MISRA no es solo un conjunto de reglas, sino casi una infraestructura completa para escribir código seguro para sistemas integrados.
Úselo en sus proyectos
Imagine una situación: va a escribir un programa para un sistema integrado muy necesario y responsable. O ya tiene un programa, pero necesita "transferirlo" a MISRA. ¿Cómo verificar que su código cumpla con el estándar? ¿Realmente tienes que hacerlo manualmente?
La verificación manual del código no es una tarea fácil y potencialmente imposible. No solo cada revisor tendría que mirar cuidadosamente cada línea de código, sino que también tendría que conocer el estándar de memoria. Horror!
Por lo tanto, se recomienda a los propios desarrolladores de MISRA que utilicen análisis estáticos para probar su código. De hecho, de hecho, el análisis estático es un proceso de revisión de código automatizado. Simplemente ejecute el analizador en su programa y en unos minutos recibirá un informe sobre posibles violaciones del estándar. Lo que necesitas, ¿verdad? Solo tiene que ver el registro y corregir la respuesta.
Siguiente pregunta: ¿en qué momento comienza a usar MISRA? La respuesta es simple: cuanto antes mejor. Idealmente, incluso antes de comenzar a escribir código, porque MISRA asume que sigue el estándar durante toda la vida de su código.
Por supuesto, no siempre es posible escribir MISRA desde el principio. Por ejemplo, a menudo sucede que un proyecto ya se ha implementado parcial o totalmente, pero el cliente deseaba que el proyecto cumpliera con el estándar. En este caso, deberá realizar una refactorización exhaustiva del código existente.
Aquí es donde surge la trampa. Incluso diría que aparece una roca submarina. ¿Qué sucede si toma un analizador estático y verifica que el proyecto "ordinario" cumpla con el estándar MISRA? Spoiler: puedes asustarte.
Por supuesto, el ejemplo en la imagen es exagerado. Aquí puede ver el resultado de verificar un proyecto suficientemente grande, que de hecho nunca se pensó para trabajar en microcontroladores. Sin embargo, al verificar un código existente, es muy posible que vea una, dos, cinco o incluso diez mil operaciones del analizador. Y en todo este montón se perderán nuevas operaciones que se emitieron al código que se acaba de escribir o cambiar.
¿Qué hacer al respecto? ¿Es realmente necesario dejar de lado todas las cosas y sentarse para arreglar todos los viejos aspectos positivos?
Sabemos que la primera vez que se verifica un proyecto, aparecen muchos aspectos positivos con bastante frecuencia y hemos desarrollado una solución que lo ayudará a obtener el beneficio del analizador de inmediato, sin detener el trabajo. Esta solución se llama "base de supresión".
Suppress-bases es el mecanismo PVS-Studio que permite la supresión masiva de mensajes del analizador. Si está revisando el proyecto por primera vez y descubre varios miles de aspectos positivos allí, simplemente los agrega a la base de supresión, y la próxima vez que ejecute el analizador, le dará cero advertencias.
Por lo tanto, puede continuar escribiendo y modificando el código de la manera habitual, y al mismo tiempo verá advertencias solo sobre aquellos errores que se acaban de introducir en el proyecto. Al mismo tiempo, obtendrá el máximo beneficio del analizador aquí y ahora, sin distraerse con rastrillar los viejos errores. Unos pocos clics, ¡y el analizador está implementado! Puede leer instrucciones detalladas sobre esto
aquí .
Probablemente podría preguntar: "Espere, ¿qué hacer con las respuestas ocultas?" La respuesta es bastante simple: no se olvide de ellas y corríjalas en silencio. Puede, por ejemplo, colocar la base de supresión en el sistema de control de versiones y permitir solo aquellas confirmaciones que no aumentan el número de operaciones. Por lo tanto, gradualmente, su "roca submarina" tarde o temprano se drena y no habrá rastros de ella.
Bien, el analizador está implementado y ahora estamos listos para continuar. ¿Qué hacer a continuación? Negocio claro: trabajar con el código. Pero, ¿qué se necesita para poder declarar el cumplimiento de la norma? ¿Cómo demostrar que su proyecto cumple con MISRA?
El hecho es que no hay un "certificado" especial de que su código cumpla con MISRA. Como lo estipula el estándar, el seguimiento del código de cumplimiento debe ser realizado por dos partes: el cliente del software y el proveedor del software. El proveedor desarrolla software que cumple con el estándar y completa los documentos necesarios. El cliente, por su parte, debe asegurarse de que los datos de estos documentos sean verdaderos.
Si usted mismo es un cliente y un desarrollador de su propio software, la responsabilidad de cumplir con el estándar solo recaerá sobre sus hombros :)
En general, para demostrar la conformidad de su proyecto, necesitará documentos de prueba. La lista de documentos que los desarrolladores de proyectos deben preparar puede variar, pero MISRA ofrece algunos como referencia. Consideremos este conjunto con más detalle.
Para reclamar el cumplimiento del estándar, necesitará algunas cosas:
- En realidad, un proyecto cuyo código cumple con las reglas obligatorias y obligatorias
- Plan de aplicación de la guía
- Documentación de todas las advertencias del compilador y del analizador estático.
- Documentación de todas las desviaciones de las reglas requeridas.
- Resumen de cumplimiento de la directriz
El primero es un plan de cumplimiento. Esta es su tabla más importante, y será la que enviará al examinador a todos los demás documentos. En su primera columna hay una lista de las reglas de MISRA, en el resto se observa si se han identificado desviaciones de estas reglas. Esta tabla se ve así:
El estándar recomienda construir su proyecto con varios compiladores, así como también usar dos o más analizadores estáticos para verificar el cumplimiento de su código. Si el compilador o el analizador genera algún tipo de advertencia asociada con la regla, debe tener esto en cuenta en la tabla y el documento: por qué no se puede eliminar la operación, si es falsa, etc.
Si alguna de las reglas no puede verificarse con un analizador estático, entonces debe llevar a cabo el procedimiento de revisión del código. Este procedimiento también debe documentarse, después de lo cual se debe agregar un enlace a esta documentación al plan de cumplimiento.
Si el compilador o el analizador estático resultan correctos, o si se encontraron violaciones reales del código en el proceso de revisión del código, debe corregirlos o documentarlos. Nuevamente, adjuntando un enlace a la documentación en la tabla.
Por lo tanto, un plan de cumplimiento es un documento mediante el cual puede encontrar documentación para cualquier desviación identificada en su código.
Ahora un poco sobre la documentación de las desviaciones de las reglas. Como ya mencioné, dicha documentación es necesaria solo para las Reglas requeridas, porque no puede violar las Reglas de nivel obligatorias, y las Reglas de asesoramiento no pueden seguirse sin ninguna documentación.
Si decide desviarse de la regla, la documentación debe contener:
- Número de regla rota
- Lugar de desviación exacta
- La validez de la desviación.
- Evidencia de que la desviación no compromete la seguridad.
- Posibles implicaciones para el usuario
Como puede ver, este enfoque de la documentación le hace pensar seriamente si la violación vale la pena. Esto se hace específicamente para violar las reglas requeridas no era bueno :)
Ahora sobre el resumen del cumplimiento de las normas. Este documento es quizás el más fácil de completar:
La columna central se llena antes de comenzar a trabajar con el código, y la columna de la derecha está después de que su proyecto esté listo.
Es bastante razonable hacer una pregunta: ¿por qué necesita especificar categorías de reglas, si ya están especificadas en el estándar mismo? El hecho es que el estándar permite el "aumento" de la regla en una categoría más estricta. Por ejemplo, un cliente puede pedirle que mueva una regla de asesoramiento a una categoría. Dicho "aumento" debe realizarse antes de trabajar con el código, y un resumen del cumplimiento de las reglas permite que esto se note claramente.
Con la última columna, todo es simple: es suficiente simplemente observar si se usa la regla, y si es así, entonces hay desviaciones de ella.
Toda esta tabla es necesaria para que pueda ver rápidamente qué prioridades tienen las reglas y si el código coincide con ellas. Si de repente se interesa por conocer el motivo exacto del rechazo, siempre puede consultar el plan de cumplimiento y encontrar la documentación que necesita.
Entonces, escribiste el código cuidadosamente siguiendo las reglas de MISRA. Hizo un plan de cumplimiento y documentó todo lo que podía documentar, y completó un resumen de cumplimiento. Si esto es cierto, entonces ha recibido un código muy limpio, muy legible y muy confiable que ahora odia :)
¿Dónde vivirá su programa ahora? En una máquina de resonancia magnética? ¿En un sensor de velocidad ordinario o en el sistema de piloto automático de algún satélite espacial? Sí, pasaste por un camino burocrático serio, pero estos son pequeños. ¿Cómo puede uno no ser meticuloso cuando están en juego vidas humanas reales?
Si logró y logró alcanzar un final victorioso, entonces lo felicito sinceramente: usted escribe un código seguro de alta calidad. Gracias
El futuro de las normas.
Finalmente, quiero hablar un poco sobre el futuro de los estándares.
MISRA actualmente está viviendo y desarrollándose. Por ejemplo, a principios de 2019, se anunció “La tercera edición de MISRA C: 2012 (primera revisión)”, un estándar actualizado y complementado por las nuevas reglas de 2012. Al mismo tiempo, anunciaron el próximo lanzamiento de MISRA C: 2012 Enmienda 2 - C11 Core, el estándar de 2012, en el que se agregarán reglas que cubrirán las versiones del lenguaje C para 2011 y 2018 por primera vez.
No se detiene y MISRA C ++. Como saben, el último estándar MISRA C ++ se remonta a 2008, por lo que la versión más antigua del lenguaje que cubre es C ++ 03. Debido a esto, hay otro estándar, similar a MISRA, y se llama AUTOSAR C ++. Originalmente fue concebido como una continuación de MISRA C ++ y estaba destinado a cubrir versiones posteriores del lenguaje. A diferencia de su cerebro, AUTOSAR C ++ se actualiza dos veces al año y actualmente es compatible con C ++ 14. Se planea una actualización adicional a C ++ 17, y luego a C ++ 20, y así sucesivamente.
¿Qué comencé sobre algún otro estándar? El hecho es que hace poco menos de un año, ambas organizaciones anunciaron la unificación de sus estándares en uno solo. Ahora MISRA C ++ y AUTOSAR C ++ se convertirán en un único estándar, y ahora se desarrollarán juntos. Creo que esta es una gran noticia para los desarrolladores que escriben bajo microcontroladores C ++, y no menos buenas noticias para los desarrolladores de analizadores estáticos. ¡Todavía hay mucho trabajo favorito por delante! :)
Conclusión
Hoy hemos aprendido mucho sobre MISRA: leemos la historia de su ocurrencia, estudiamos ejemplos de reglas y la filosofía del estándar, consideramos todo lo que necesita para usar MISRA en sus proyectos e incluso miramos un poco hacia el futuro. ¡Espero que ahora entiendas mejor qué es MISRA y cómo cocinarlo!
Según la antigua tradición, dejaré un enlace aquí a nuestro analizador estático PVS-Studio. Es capaz de encontrar no solo desviaciones del estándar MISRA, sino también una
gran variedad de errores y vulnerabilidades. Si está interesado en probar PVS-Studio usted mismo,
descargue la versión demo y verifique su proyecto.
Esto concluye mi artículo. ¡Les deseo a todos los lectores un feliz año nuevo y un feliz fin de semana!
Enlaces de sitio
- Georgy Gribkov - " Seguridad a la velocidad máxima: cómo escribir código C / C ++ confiable para sistemas embebidos ".
- PVS-Studio es un analizador de código estático .
- PVS-Studio y KEIL 5 colaboración .

Si desea compartir este artículo con una audiencia de habla inglesa, utilice el enlace a la traducción: George Gribkov.
Qué es MISRA y cómo cocinarlo .