Una vez más, no soy un desarrollador sino un trabajador de la madera, por lo que mis preguntas podrían ser, bueno, estúpidas.

Olvidé algo realmente importante. Tengo que usar gcc-3.8 para compilar, ya que el código original con el que estoy trabajando no puede compilarse con la versión más nueva. Me olvidé por completo de hablar de eso, lo siento.

Estoy enviando datos desde una herramienta a un robot autónomo. El robot recibe datos como caracteres sin firmar * Leí mucho y parece que malloc no es seguro contra interrupciones.

Como el robot puede hacer cosas malas y peligrosas, trato de hacer que todas las partes sean seguras (al menos tanto como pueda).

Este malloc ocurre después de una interrupción provocada por los datos recibidos. Este segmento de código ahora me está dando problemas para hacerlo seguro, también mi sintaxis es probablemente mala.

char* _Xp = (char*) malloc(strlen((char*)_X)*sizeof(char));
strcpy(_Xp, (char*)_X);

1) ¿Malloc realmente no interrumpe la seguridad? La información que encontré es de 2004.

2) ¿hay una manera más eficiente de inicializar el búfer?

3) ¿por qué los caracteres sin signo son "malos"? (Lee algo sobre eso).

4) ¿la última pregunta es strcpy y tampoco interrumpe la seguridad? Las fuentes que leo difieren en ese punto.

===== respondiendo algunas preguntas:

El robot no tiene sistema operativo, el objetivo es un STR911FFM44 a 25Mhz (si ayuda)

Las matrices de entrada están terminadas en nulo.

El código no está en el controlador de interrupciones sino en el bucle infinito y se procesa solo si el IrHandler establece la bandera para ello.

No sé la velocidad del flujo de datos para "codificar" la seguridad. pero la interrupción debería estar en [500ms a 1500ms].

3
A.albin 5 abr. 2017 a las 08:27

2 respuestas

La mejor respuesta

1) ¿Malloc realmente no interrumpe segura?

malloc accede y modifica un recurso global, el conjunto de memoria común de su programa en ejecución. Si el acceso se realiza desde dos lugares no sincronizados, como el flujo normal de su programa y el ISR 1 , puede dañar el grupo. Si su ISR no llama a malloc en sí mismo, no será un problema.

Si es así, necesitaría establecer un sistema para evitar tal reingreso en malloc. Por ejemplo, envuelva la llamada a malloc en una función que desactive el manejo de interrupciones y vuelva a activarlo.

2) ¿hay una manera más eficiente de inicializar el búfer?

Si necesita un búfer con una duración de almacenamiento asignada (es decir, que decide cuándo finaliza su vida útil y no el alcance en el que está asignado), entonces no hay realmente una alternativa estándar de C. Por cierto, sizeof(char) siempre es 1, por lo que no es necesario especificarlo. Y dado que C permite la conversión implícita de tipos de puntero desde void*, la llamada puede por lo menos ser un poco prettified < sup> 2 :

char* _Xp = malloc(strlen((char*)_X));

3) ¿por qué los caracteres sin signo son "malos"?

No son malos De hecho, cuando necesita saber exactamente si el tipo de carácter está firmado o no, debe usar signed char o unsigned char. El char normal se puede firmar en una plataforma y sin firmar en otra.


1 Rutina de servicio de interrupción.
2 C tiene una noción de identificadores reservados. En particular, cualquier identificador que comience con un guión bajo seguido de una letra mayúscula siempre está reservado. Por lo tanto, cambiar el nombre de sus variables puede ayudar con la portabilidad.

4
Community 23 may. 2017 a las 10:31

En primer lugar, dice que está usando un microcontrolador de metal desnudo, por lo que malloc nunca tiene sentido. No es una PC: no comparte su RAM con nadie más. Por lo tanto, todos los peligros y desventajas de malloc ni siquiera entran en la discusión, ya que malloc no tiene sentido que lo uses.

1) ¿Malloc realmente no interrumpe la seguridad? la información que encontré es de 2004.
4) ¿la última pregunta es strcpy y tampoco interrumpe la seguridad? Las fuentes que leo difieren en ese punto.

Ninguna función que utilice recursos compartidos entre un ISR y la aplicación principal es segura contra interrupciones. Debe evitar llamar a las funciones de la biblioteca desde un ISR, deben mantenerse al mínimo.

Todos los datos compartidos entre un ISR y la persona que llama deben tratarse con cuidado. debe garantizar el acceso atómico de objetos individuales. Debe debe declarar variables como volatile para evitar errores del optimizador. Puede que tenga que usar semáforos u otros medios de sincronización. Esto se aplica a todos esos datos, ya sea que los cambie usted mismo o mediante una función de biblioteca.

Si no se hace todo lo anterior, se generarán errores muy misteriosos y sutiles, lo que provocará corrupción de datos, condiciones de carrera o código que nunca se ejecutará. En general, las interrupciones siempre son difíciles de trabajar debido a toda esta complejidad adicional. Úselos solo cuando sus requisitos en tiempo real no le den otras opciones.

2) ¿hay una manera más eficiente de inicializar el búfer?

Sí, usa una matriz. static char _Xp [LARGE_ENOUGH_FOR_WORST_CASE]; Por lo general, es una buena idea mantener dichos búferes en el segmento .data en lugar de en la pila, de ahí la palabra clave static.

3) ¿por qué los caracteres sin signo son "malos"? (Lee algo sobre eso).

No hay nada malo con ellos como tal. Sin embargo, los diferentes tipos char son problemáticos, porque en teoría podrían tener otros tamaños que no sean 8 bits. Peor aún, char sin signo / sin signo tiene firma definida por la implementación , lo que significa que podría estar firmado o sin signo, según el compilador. Lo que significa que debe nunca usar el tipo char para almacenar cualquier otra cosa que no sean cadenas de texto.

Si necesita un tipo de variable para contener bytes de datos, use siempre uint8_t de stdint.h.

Como el robot puede hacer cosas malas y peligrosas, trato de hacer que todas las partes sean seguras (al menos tanto como pueda).

Escribir software seguro para sistemas integrados es una tarea altamente calificada. No lo recomendaría a nadie con menos de 5 años de experiencia trabajando a tiempo completo con la programación de firmware incorporada para siquiera considerarlo, a menos que haya al menos un veterano de C endurecido que sea parte de su equipo y todo el código pase por una revisión por pares y un análisis estático. .

Parece que se beneficiaría mucho leyendo las pautas de codificación de MISRA-C: 2012. Es un subconjunto seguro del lenguaje C, destinado a ser utilizado en aplicaciones críticas para la seguridad, o cualquier forma de aplicación donde los errores son malos. Lamentablemente, el documento MISRA-C no es gratuito, pero se está convirtiendo en un estándar de la industria.

1
Community 13 abr. 2017 a las 12:32