El microcontrolador no funciona como se esperaba o falla después de unos días

Estoy usando Atmel AVR ATmega8 en mi proyecto de monitoreo, que mide el voltaje trifásico y envía datos a través de un uart. Funciona muy bien en 1 o 2 días. Pero después de esa cantidad de tiempo, no funciona como se esperaba, y no hay respuesta del uart y del latido del corazón, lo que indica que la uc está activa o no. Y, a veces, el led de latido del corazón parpadea y no hay respuesta de uart. Pero después de un reinicio de hardware, vuelve a funcionar y luego se vuelve a bloquear hasta que se reinicia el hardware. Implementé un perro guardián en él, pero parece que no funciona. Restablecí el contador de vigilancia en la rutina de interrupción del temporizador de 8 bits. ¿Debo restablecerlo en mi código principal, no en una rutina de interrupción?

Supongo que está saliendo de SRAM. ATmage8 SRAM es de 1 kb, y mis datos estáticos utilizan el 71,2% de la misma. Y no estoy usando ninguna asignación de montón. Mi pregunta es: ¿es posible apilar y colisionar datos estáticos?

Definitivamente debería restablecer el perro guardián en su bucle principal, porque para eso es. Se supone que el perro guardián verifica que el programa esté procesando el ciclo principal regularmente (porque reinicia el temporizador del perro guardián cada vez que pasa por el comienzo del ciclo). En su caso, si el programa se atasca en un bucle infinito, el perro guardián no se activará porque su rutina de interrupción del temporizador lo reinicia regularmente.
Sí, pensé lo mismo, y supuse que era falta de sram. Hice esa suposición a partir de un programa de 1 o 2 días que funcionó como se esperaba.
En general, parece que estás cometiendo algunos errores clásicos de principiante. Debe dejar que un programador experimentado eche un vistazo a su proyecto. Con respecto a la pila, lea esto .
@LetMe: "Supongo que se está saliendo de SRAM" Aunque no hay suficiente información para excluir esa posibilidad, no haría esa suposición, al menos, no en la información proporcionada hasta ahora. Veo otras opciones posibles que se ajustan a la historia. Según las pruebas que haya realizado y los resultados de esas pruebas (especialmente las pruebas en un banco de trabajo, etc.), esa información puede ayudar a confirmar o negar otras hipótesis. No puedo obligarlo a considerar otras posibilidades (:-)), pero si proporciona detalles de sus otras pruebas y esos resultados (edite su pregunta y agréguelos al final), esa información sería útil.

Respuestas (3)

¿Es posible apilar y colisionar datos estáticos?

Sí, eso es completamente posible. Atmega no tiene espacio de pila dedicado, por lo que si usa demasiado, se desbordará y colapsará sus datos estáticos.

Intente reducir su consumo de memoria (utilice los tipos de datos adecuados más pequeños para las variables, reduzca el tamaño de su matriz, etc.) Asegúrese de no tener ninguna recursión o árboles de llamadas inusualmente largos bajo ciertas condiciones.

Si puede obtener un mejor hardware, intente ejecutar su programa en una versión 2K del controlador. Si se ejecuta sin problemas, puede confirmar que es un problema de memoria insuficiente sin tener que hacer ningún esfuerzo de programación adicional.

PD. Como dice @Edesign, dar servicio al perro guardián desde una interrupción del temporizador es inútil: hacerlo protegería contra fallas del temporizador, no fallas del código. Debe dar servicio al perro guardián desde su bucle principal, idealmente desde una función de verificación de cordura:

//main loop
while(1) {
  uart_task();
  sensor_task();
  wdg_task();
}

void wdg_task(void) {
  if(uart_ok() && sensor_ok()) do_wdg_reset();
}

Tenga en cuenta que se supone que el perro guardián ayuda con los errores que no se pueden contabilizar mediante programación, como fallas en el suministro eléctrico. Usar un perro guardián para restablecer un programa defectuoso en lugar de corregir el error no es el camino a seguir.

El lugar donde restablezca el perro guardián depende de su aplicación, pero el punto esencial es restablecerlo en algún lugar inmediatamente antes o después de su funcionalidad crítica o riesgosa.

De esta manera, si su código nunca termina, el perro guardián se agota.

Su pila puede colisionar con los datos estáticos, pero a menos que tenga llamadas de función recursivas con una profundidad que aumenta muy lentamente, parece poco probable aquí.

¿Es siempre "1 o 2 días"? A menudo, los bloqueos lentos están relacionados con desbordamientos de variables de tiempo, pero entonces el período sería muy estable.

De lo contrario, su lógica principal podría quedar atrapada en algún caso raro y extraño. Mira tu código. ¿Realmente no hay forma de que la cosa se atasque?

PD: una última cosa: si lo que al final monitorea su UART lo hace a través de Windows, Windows tiene un manejo de puerto serie notoriamente fallido. Si su "restablecimiento de hardware" también cambia la alimentación de su adaptador en serie o implica restablecer su terminal, esto puede ser lo que realmente resuelva el problema.

¿Verifica que el UART esté listo para enviar (TXC, transmisión completa) antes de enviar el carácter? ¿Ese "bit completo de transmisión" necesita ser reiniciado por softare? Si es así, ¿también lo reinicia antes de enviar el personaje? Si comienza a enviar el carácter primero y restablece el bit listo después, una interrupción manejada en el medio podría retrasar el software para que termine borrando el bit TXC después de que el carácter ya se haya enviado. Eso detendría la operación UART porque nada volvería a configurar TXC.

Sí, lo comprobé y funcionó unos días. Creo que está relacionado con la falta de memoria. Gracias por tu preocupación.