¿Qué sucede si hay un error de tiempo de ejecución en un programa? ¿Se detendrá la ejecución del programa? ¿Hay alguna forma de obtener el Arduino para decirme cuál es el error?
¿Qué sucede si hay un error de tiempo de ejecución en un programa? ¿Se detendrá la ejecución del programa? ¿Hay alguna forma de obtener el Arduino para decirme cuál es el error?
Respuestas:
Primero, veamos algunos ejemplos de lo que puede salir mal.
void setup() {
int status;
pinMode(13, OUTPUT);
digitalWrite(13, status);
}
Como señaló Edgar Bonet en los comentarios, el status
compilador de C ++ no inicializa implícitamente las variables locales como en el código anterior. Entonces, el resultado del código anterior es indeterminado. Para evitar eso, asegúrese de asignar siempre valores a sus variables locales.
Las cosas son un poco diferentes con las variables globales y estáticas:
El estándar C garantiza que las variables globales y estáticas se inicializarán a 0.
Eso significa que no debe preocuparse por inicializarlos a 0 en su código. De hecho, realmente debería evitarlo, ya que la inicialización puede desperdiciar memoria. Solo inicialícelos a valores distintos de 0.
int array[10];
int v = array[100];
array[-100] = 10;
El primer problema aquí es que no sabes qué se asignará a v, pero lo peor es que no sabes lo que arruinaste con la asignación a la posición -100 array
.
void doSomething( void ) {
for (int i = 0; i < 1000; i++);
}
void setup ()
{
void (*funcPtr)( void );
funcPtr = &doSomething;
funcPtr(); // calls doSomething();
funcPtr = NULL;
funcPtr(); // undefined behavior
}
La primera llamada a funcPtr()
será realmente una llamada a doSomething()
. Las llamadas como la segunda pueden conducir a un comportamiento indefinido.
Bueno, puedes quedarte sin RAM, por ejemplo. Qué más. En cualquier caso, creo que su programa seguirá ejecutándose, probablemente no de la manera que lo pretendía.
En los sistemas informáticos, problemas como estos generalmente se tratan en varios niveles:
Los arduinos solo tienen una protección limitada del compilador, y probablemente nada más. La buena noticia es que no son multitarea, por lo que el único programa afectado es el suyo. En cualquier caso, cualquiera de esos errores dará lugar a un comportamiento errático.
Las suposiciones son todos los problemas que mencioné anteriormente son problemas de tiempo de ejecución.
¿Qué sucede si hay un error de tiempo de ejecución en un programa?
El programa continuará y lo que ocurra dependerá de los efectos secundarios del error de tiempo de ejecución. Una llamada al puntero de función nula probablemente hará que el programa salte a una ubicación desconocida.
¿Se detendrá la ejecución del programa?
No, continuará como si nada extraordinario sucediera, probablemente haciendo lo que no tenía la intención de hacer. Se puede restablecer o actuar de forma errática. Puede convertir algunas entradas en salidas y quemar un sensor o dos (pero eso es muy poco probable ).
¿Hay alguna forma de que el Arduino me diga cuál es el error?
No lo creo. Como dije antes, los mecanismos de protección no están ahí. No hay soporte de tiempo de ejecución del idioma, no hay sistema operativo, no hay comprobaciones de hardware para acceso de memoria fuera de los límites (el gestor de arranque tampoco cuenta). Solo debe tener cuidado con su programa y probablemente establecer sus propias redes de seguridad.
La razón de la falta de protección probablemente se deba a que los controladores Arduino son demasiado baratos, tienen muy poca memoria y no deben ejecutar nada demasiado importante (sí, AVR parece haber un descargo de responsabilidad en algún lugar para que no use las MCU que normalmente usa Arduino en sistemas de soporte vital).
No hay excepciones de tiempo de ejecución. Solo hay un comportamiento indefinido.
Realmente, no hay excepciones en absoluto . Si intenta realizar una operación no válida, sus resultados serán desconocidos.
No hay comprobación de tiempo de ejecución, excepto lo que implemente. Su programa se ejecuta en hardware de metal desnudo. Es el equivalente de escritorio de correr en ring-0 todo el tiempo, porque el ATmega no tiene anillos .
Hay un mecanismo que puede obtener MCU desde un estado errático y es el temporizador de vigilancia . Si está implementando algún código que se ejecutará repetidamente en un bucle, que no se ejecutará en ningún momento más de un tiempo fijo, puede establecer este tiempo como período de vigilancia y habilitar el temporizador.
Luego, debe restablecer repetidamente el temporizador en el bucle. Si su código se congela en algún bucle de condición que nunca terminará, entonces el perro guardián contará hasta cero y eventualmente reiniciará la MCU.
De esta forma está perdiendo datos, pero si ejecuta el AVR WDT en modo de interrupción, puede almacenar algunos datos antes de restablecer la MCU.
Por lo tanto, el temporizador de vigilancia puede proteger su código de bucles interminables no deseados ocasionales.
Documentation: AVR132: Uso del temporizador de vigilancia mejorado
Necesitaría un depurador de hardware para algo como esto. Pero, por lo general, verá que el programa no se comporta como espera y tendrá que mirar esa sección del código para identificar el problema.
Una forma común / rápida / fácil de hacer esto es agregar declaraciones de impresión para imprimir los valores de las variables o simplemente cualquier cosa para que sepa que el programa llega a ese punto en el código sin ningún problema. Esto lo ayudará a aislar aún más el problema.
Creo que VisualMicro tiene alguna funcionalidad de depuración incorporada.
Supongo que la CPU AVR no tiene ninguna herramienta de detección o recuperación de errores. Puede detenerse o seguir ignorando el error y las consecuencias. Como dijo sachleen, debe agregar algunas declaraciones de depuración en su programa que impriman datos en el medio de una operación, para probar si está funcionando. Si usa un emulador y establece puntos de interrupción, podría encontrar fácilmente un problema.
Arduino se reiniciará (es decir, se reiniciará setup()
y loop()
).