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

3

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 ninguna respuesta proviene de la uart y del latido del corazón, lo que indica que uc está vivo o no. Y a veces los latidos del corazón parpadean y ninguna respuesta proviene de uart. Pero después de un reinicio de hardware, vuelve a funcionar, luego se bloquea de nuevo hasta que se reinicia el hardware. Implementé un perro guardián en él, pero parece que no funciona. Reajusté 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 la SRAM. ATmage8 SRAM es de 1 kb, y mis datos estáticos están usando el 71,2%. Y no estoy usando ninguna asignación de montón. Mi pregunta es: ¿Es posible que los datos estáticos y de pila se colenan?

    
pregunta LetMe

3 respuestas

7
  

¿Es posible apilar y los datos estáticos chocan?

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

Intente reducir el consumo de memoria (use los tipos de datos adecuados más pequeños para las variables, reduzca el tamaño de su matriz, etc.) Asegúrese de que no tenga 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.

PS. Como dice @Edesign, no sirve de nada darle servicio al watchdog desde una interrupción del temporizador: hacerlo protegería contra las fallas del temporizador, no las fallas del código. Debería reparar el watchdog desde su bucle principal, idealmente desde una función de comprobación de validez:

//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 watchdog ayuda con los errores que no pueden explicarse mediante programación, como fallas de energía. Usar un watchdog para restablecer un programa con errores en lugar de corregir el error no es el camino a seguir.

    
respondido por el Dmitry Grigoryev
1

El lugar donde reinicie el watchdog depende de su aplicación, pero el punto esencial es reiniciarlo inmediatamente en alguna parte antes o después de su funcionalidad crítica o de riesgo.

De esta manera, si su código nunca termina, el watchdog se apaga.

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

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

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

P.S: Una última cosa: si la cosa que está monitoreando al final su UART lo está haciendo a través de Windows, Windows tiene un manejo de puertos serie notoriamente defectuoso. Si su "reinicio de hardware" también cambia la alimentación a su adaptador serie o implica reiniciar su terminal, esto puede ser lo que solucione el problema.

    
respondido por el Brog
0

¿Comprueba que el UART está listo para enviar (TXC, transmisión completa) antes de enviar el carácter? ¿Ese "bit de transmisión completa" necesita restablecerse por software? Si es así, ¿también lo restableces antes de enviar el personaje? Si comienza a enviar el carácter primero y restablece el bit listo después, una interrupción manejada entre los dos podría demorar el software, por lo que terminará de borrar el bit TXC después de que ya se envió el carácter. Eso detendría la operación de UART porque nada volvería a establecer TXC.

    
respondido por el PkP

Lea otras preguntas en las etiquetas