¿Cómo encontrar y superar la corrupción de RAM en tiempo de ejecución en un microcontrolador? [cerrado]

¿Cómo puedo encontrar y superar cualquier corrupción de RAM en un microcontrolador (ARM Cortex M0) durante el tiempo de ejecución? Por ejemplo, qué pasa si dos o tres ubicaciones están dañadas, digamos 0x2E 0x2F, 0x30. ¿Cómo puedo dejar que el sistema funcione superando o ignorando esta corrupción?

¿Quiere decir en el campo durante la operación o en su banco porque quiere ahorrar dinero y usar un chip defectuoso de todos modos?
¿Error de corrección? Obtener corrupciones de RAM no es tan común en aplicaciones terrestres. ¿Cuál es tu entorno?
@PlasmaHH En el campo durante la operación. En caso de tales errores, ¿cómo encontrarlos y superarlos?
Checksuming y copias de seguridad de datos. Almacene una suma de verificación del área crítica, así como una segunda copia de los datos y una suma de verificación para eso. Si una suma de verificación resulta incorrecta, copie los datos de la otra copia.
¿Qué pasa si los registros del procesador se corrompen?
@Jasen, esa pregunta es idéntica a "¿qué pasa si algo que es realmente crítico para el funcionamiento de mi dispositivo semiconductor falla?" y la respuesta es: entonces su dispositivo está irreparablemente roto. Para algunos registros de propósito general, es posible que pueda modificar su compilador lo suficiente como para simplemente no usar ese registro. Pero: si, entre todas las cosas, falla un registro , entonces ya no puede confiar en que nada suceda dentro de la CPU. Deseche su IC.
La corrupción de datos globales en la RAM suele ser una indicación de desbordamiento de pila.
@filo no, no en general. Especialmente no en un microcontrolador que bien podría programarse en ensamblaje sin el uso de marcos de pila, aunque normalmente tiene mecanismos elegantes de manejo de pila cuando se trata de interrupciones.
@filo, ¡veo lo que hiciste allí!
si no está fallando, sino corrupto: por ejemplo, por rayos cósmicos, y la dirección de retorno en la pila está dañada, no hay solución de software, pero escribir código que desconfíe de todo el contenido de RAM (por lo tanto, no use la pila para direcciones de retorno a menos que pueda trabajar de una manera redundante), pero entonces, ¿qué tan diferentes son los registros de la CPU de la RAM estática?
"ARM Cortex M0... ubicaciones 0x2E 0x2F,0x30". - estas son ubicaciones reservadas en la tabla de vectores de interrupción, por lo que puede ignorar cualquier 'corrupción' en ellas porque no deberían contener ninguna información útil (si RAM existe allí ).

Respuestas (7)

Debe elegir la MCU correcta que tenga las funciones que necesita. Aquí hay un ejemplo del chip Cortex M0 que tiene EDAC (corrección de errores de un solo bit) y Scrub (actualización periódica del contenido de la memoria que evita la acumulación de errores).

Si no tiene funciones de hardware de corrección de errores, lo mejor que puede hacer es verificar periódicamente el contenido de la memoria que no se esperaba que cambiara y reiniciar si se detecta un cambio.

¿Cómo puedo dejar que el sistema funcione superando o ignorando esta corrupción?

En un Cortex M0 general: probablemente no del todo. Si bien esto se vuelve más fácil (no fácil) si tiene una MMU que puede mapear la memoria, es muy probable que su microprocesador ARM no tenga eso. Por lo tanto, tendría que escribir su software y los scripts del enlazador de una manera que evite específicamente estas direcciones, compilarlas y ejecutarlas en el µC.

Cómo puedo encontrar ...

Por lo general, ese es el trabajo de los mecanismos de hardware de validación de memoria. En el mundo de la computación estilo PC/Servidor/Estación de trabajo/Cluster, elegiría la memoria ECC y posiblemente incluso la redundancia de memoria. En las aplicaciones espaciales, posiblemente tenga controladores de memoria que tengan una Corrección de errores de reenvío (FEC) mucho más elaborada en la RAM, el mismo tipo de pensamiento que usa el almacenamiento masivo de estado sólido para evitar errores de bits, o su receptor de TV digital.

El problema aquí es: no tiene un controlador de memoria que pueda hacer eso en un Cortex M0. Por supuesto, primero puede verificar cada región de RAM con una suma de verificación antes de acceder a ella a menudo en el software, pero eso será una tarea enorme y tampoco ayudará realmente si la corrupción de la memoria ocurre durante la lectura repetida o una escritura.

Entonces, si un Cortex M0 tiene memoria rota, está rota y necesita ser reemplazada.

Lo bueno es que este tipo de chip definitivamente no tiene tanta RAM, por lo que la probabilidad de error de bit debido a la distribución de Bernoulli causada por "o" mucho "¿está roto este bit?" probabilidades no es tan alto. Lo que significa aún más que debe reemplazar el chip en el campo si tiene RAM rota: hay algo mal con el chip y es difícil predecir qué fallará a continuación.

Cortex M0 no tiene características específicas de detección de fallas o confiabilidad como ECC. Hay microcontroladores (basados ​​en Cortex-M7, por ejemplo) que tienen algunas de estas características, que podrían ayudarlo a mejorar la confiabilidad.

Dejando de lado la causa de los errores (un entorno operativo de alta radiación sería un caso razonable), debe lograr al menos dos cosas. Detección de la falla antes de que se haya hecho demasiado daño a su estado guardado y recuperación del sistema. Estos no son triviales, y el mejor enfoque depende de su aplicación. Las cosas que puedes considerar son:

  • Perro guardián
  • Sumas de comprobación ejecutables
  • Duplicación de regiones de datos y sumas de verificación
  • Subprocesos o núcleos replicados
  • Validación de datos (repetidamente)

Una vez que se detecta una falla, lo más sensato es reiniciar el núcleo y comenzar de nuevo. Simplemente restablecer el núcleo con un temporizador externo de vez en cuando podría ayudar.

La sobrescritura de RAM puede ser un síntoma de un error de software en lugar de una falla o falla del hardware. Las dos causas más comunes en los programas C incrustados se deben a punteros y accesos a matrices fuera de los límites. A menudo, las herramientas de depuración le permiten establecer puntos de interrupción en las escrituras de memoria en ubicaciones específicas, por lo que es posible que pueda encontrar la línea de código C responsable de la sobrescritura y luego determinar por qué ocurrió este error.

Incluso sin ese soporte, es posible que pueda reducir las líneas sospechosas averiguando qué variables o matriz se han asignado justo antes de estas direcciones, ya que eso proporciona una pista. Por ejemplo, si hay una matriz de 8 elementos, y cada elemento es de 1 byte, y comienza en 0x2E-0x08=0x26, entonces si algún código está escribiendo en esta matriz pero el índice es 9, sobrescribirá 0x2E. (Tal vez tenga una matriz de estructuras, cada una de las cuales tiene 3 bytes, por lo que los "datos incorrectos" podrían darle una pista de dónde proviene esto).

Sin embargo, si se trata de un puntero no inicializado que se está utilizando, es poco probable que el diseño de la memoria sea de ayuda. Pero aún puede buscar en su código el uso de punteros o usar verificadores de código estático, o los niveles de advertencia de su compilador para buscar punteros que se estén usando antes de inicializarlos con una dirección válida.

Finalmente, si puede producir esta sobrescritura repetidamente pero no puede determinar qué línea de código es la causa, un enfoque de fuerza bruta es eliminar secciones de código que sospecha hasta que las encuentre. Sin embargo, esto corre el riesgo de perturbar tanto el resto del código que el error se mueve.

En el caso de un error de software, no desea encontrar una manera de permitir que el sistema siga funcionando con tal corrupción; usted debe encontrar y corregir el error. Si tuviera que configurar las opciones del enlazador para evitar esta área de la memoria, es probable que el error se mueva a otra parte (siempre que no tenga hardware defectuoso).

donde se necesita una alta confiabilidad, a menudo se ejecutan varios sistemas en paralelo y votan sobre las decisiones.

Nunca he visto redundancia basada en votos en la implementación de RAM de MCU. ¿Tienes un ejemplo?
@DmitryGrigoryev: No harías que la memoria RAM sola sea redundante; tendría núcleos informáticos redundantes y votaría en sus conexiones de E/S.

Al final, simplemente no puede protegerse contra todas las fallas de memoria. Afortunadamente, estos son extremadamente raros a menos que su dispositivo vaya al espacio.

Puede, utilizando ciclos adicionales, protegerse de la corrupción en ciertas partes específicas de la memoria. Por ejemplo, podría mantener varias copias de una estructura de datos crítica, cada una con su propia suma de verificación. Tendría que acceder a los datos en esta sección a través de subrutinas que actualizan las copias múltiples, calculan las sumas de verificación y tratan las discrepancias.

Muchas de las cosas que escuchas por ahí como estrategias, particularmente para lidiar con fallas en la memoria del programa, en realidad empeoran las cosas. Por ejemplo, si su código ocupa 1 kB, pero con la verificación de errores toma 2 kB, acaba de duplicar la posibilidad de que le dé un error aleatorio. Cualquier verificación que haga ahora tiene que superar eso solo para alcanzar el punto de equilibrio. ¿Y cómo revisas el corrector? Como dije al principio, simplemente no puedes protegerte contra todos los fracasos.

Una estrategia más realista es minimizar la posibilidad de fallar en primer lugar. Podría usar un microcontrolador antiguo con un tamaño de función más grande. Eso hace que sea menos probable que ciertos eventos cambien un poco. Los subsistemas de memoria externa pueden tener corrección y detección de errores, hasta cierto nivel de errores.

Si algo cambia un poco en la ALU o en uno de los registros clave del procesador, estará jodido. En algunos casos, un perro guardián puede ayudar. Cuando el código ya no borra el temporizador de vigilancia regularmente, el procesador se reinicia y puede comenzar de nuevo.

Básicamente, si necesita una confiabilidad extra alta, se logrará mejor con múltiples sistemas redundantes a un nivel más alto que con trucos lindos en un microcontrolador.

Puede utilizar la codificación de corrección de errores (ECC) para corregir o detectar errores de memoria. Esto aumentará significativamente el tamaño de la utilización de RAM e introducirá gastos generales de procesamiento.

ECC funciona utilizando solo un conjunto de palabras disponibles. Como ejemplo, establezca 000 y 111 como palabras válidas. Si lees 101, sabes que esta no es una palabra válida. ECC es un tema amplio con muchos esquemas diferentes de diversa complejidad. El esquema anterior, por ejemplo, se denomina código de repetición.

Aunque aumenta la probabilidad de obtener un error, debido al mayor uso de la memoria, su capacidad para corregir los errores aumenta más rápidamente. La pregunta es qué tasa de error de bit (BER) puede tolerar mientras se mantiene dentro de sus otras restricciones. Puede seguir aumentando la palabra clave para lograr el BER deseado, sacrificando la eficiencia de la memoria.

Bueno, el problema con eso en los microcontroladores es: por qué puede decidir codificar con ECC todo lo que almacena en la RAM, por lo general no puede obligar a su controlador DMA a hacerlo, por lo que si bien esto ciertamente ayuda contra los errores en la memoria que controla su programa , no ayuda en la memoria escrita por hardware.
@MarcusMüller, obviamente necesitaría deshabilitar DMA para los periféricos. Alternativamente, puede obtener un controlador DMA que admita ECC. O tal vez solo una sección de RAM tiene un BER alto. Puede apuntar los periféricos a la sección más segura. El OP no especificó la fuente de su preocupación, por lo que es imposible saberlo.