Debes evitar las interrupciones cuando sea posible. Problemas:
- Desordenan el comportamiento predecible en tiempo real.
- Numerosas interrupciones pueden llevar a un uso de pila imprevisto.
- Es fácil escribir errores muy sutiles y muy graves al compartir datos entre un ISR y el programa en segundo plano.
Dicho esto, puede evitar estos problemas con un diseño cuidadoso del sistema.
1) es solo un problema para las interrupciones no cíclicas que pueden llegar en cualquier momento. Siempre que las interrupciones tengan un comportamiento determinista y se activen cíclicamente, puede usarlas. En ese caso, no son diferentes de un proceso de alta prioridad y aún puede predecir el comportamiento del sistema en tiempo real.
2) se puede evitar reduciendo el número de fuentes de interrupción en la medida de lo posible. Otras medidas de seguridad es asignar siempre una pila que sea más grande de lo necesario, y lo más importante: coloque la pila de manera que, al desbordarse, no caiga en cascada en otros segmentos de memoria RAM como .bss o .data. Aquí hay un buen artículo sobre esto .
3) es el más difícil de proteger. Cada variable compartida entre un ISR y el programa de fondo debe manejarse con mucho cuidado. Existen dos problemas: la re-entrada y los problemas del optimizador del compilador.
La reentrada debe resolverse caso por caso con acceso atómico / semáforos / mutex o inhabilitando temporalmente las interrupciones. Esto siempre es complicado y debe asegurarse de que ha considerado todos los escenarios y que el código de máquina producido realmente hace lo que piensa.
El otro problema es cuando su compilador no se da cuenta de que la MCU llama a su ISR en lugar de hacerlo desde su código y, por lo tanto, no comprende que todas las variables utilizadas por el ISR pueden actualizarse en cualquier momento. El compilador puede entonces optimizar incorrectamente el código de fondo, ya que asume que una determinada variable nunca se usa. Este error se puede evitar declarando siempre las variables compartidas con un ISR como volatile
.
Ambos de estos problemas son fuentes comunes de errores muy sutiles, pero a menudo graves. No hay una forma estándar de protegerse contra ellos, lo más cercano a una medida de seguridad es permitir que su veterano más endurecido escriba todos los ISR. Programadores con experiencia intermedia, por no hablar de principiantes, siempre escriben estos errores una y otra vez.
Debido a esto, es muy difícil justificar el uso de interrupciones en aplicaciones críticas para la seguridad. Tendría que dedicar mucho tiempo al diseño, las pruebas y la documentación para verificar que cada interrupción no esté causando problemas. Por lo tanto, puedo entender por qué algunas normas de seguridad prohíben el uso de interrupciones por completo.
En cuanto a la cuestión específica de CAN, suena un poco como si hubiera elegido la MCU incorrecta para la tarea o no estuviera utilizando el controlador CAN correctamente. Los controladores CAN más avanzados tienen buffers de rx que puede configurar para mensajes dedicados, y además un FIFO de rx donde van los demás mensajes. Estoy bastante seguro de que NXP tiene dichos controladores CAN para sus familias Cortex-M, al menos lo hacen en LPC11C.
Con este enfoque y un protocolo CAN de capa de aplicación cuidadosamente diseñado, no debería necesitar interrupciones de rx. Todas las redes CAN críticas para la seguridad deben diseñarse para enviar mensajes una y otra vez periódicamente. Si sabe que un determinado mensaje solo llega una vez cada 5 ms, simplemente debe asegurarse de que su programa en segundo plano sea lo suficientemente rápido para manejarlo antes de que llegue el siguiente mensaje.
Para SIL4, es probable que tenga más de un bus CAN: le dedicaría un bus para mensajes en tiempo real críticos para la seguridad y pondría todo lo demás en otro bus no crítico. Las soluciones de redundancia con varios buses CAN que transmiten los mismos datos críticos también se utilizan a veces.