3 votos

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

Estoy usando Atmel AVR ATmega8 en mi proyecto de monitorización, que mide la tensión trifásica y envía los 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 está funcionando como se esperaba, y no hay respuesta viene de la uart y el latido del corazón LED, lo que indica uc está vivo o no. Y a veces el led de heartbeat parpadea y no hay respuesta del uart. Pero después de un reinicio de hardware, funciona de nuevo, luego se bloquea de nuevo hasta el reinicio de hardware. He implementado un watchdog en él, pero parece que no funciona. He reiniciado el contador del watchdog en la rutina de interrupción del temporizador de 8 bits. ¿Debo reiniciarlo en mi código principal, no en una rutina de interrupción?

Supongo que está saliendo de SRAM. La SRAM de ATmage8 es de 1 kb, y mis datos estáticos están usando el 71,2% de ella. Y no estoy usando ninguna asignación de heap. Mi pregunta es: ¿Es posible que la pila y los datos estáticos colisionen?

7voto

Mark0978 Puntos 495

¿Es posible que la pila y los datos estáticos choquen?

Sí, es totalmente posible. El Atmega no tiene espacio de pila dedicado, por lo que si usas demasiado, te desbordarás y bloquearás tus datos estáticos.

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

Si puedes conseguir un hardware mejor, intenta ejecutar tu programa en una versión 2K del controlador. Si se ejecuta sin problemas, puedes confirmar que es un problema de memoria insuficiente sin tener que hacer ningún esfuerzo extra de programación.

PS. Como dice @Edesign, dar servicio al watchdog desde una interrupción del temporizador es inútil: hacerlo protegería contra fallos del temporizador, no contra fallos del código. Deberías dar servicio al watchdog desde tu bucle principal, idealmente desde una función de control de sanidad:

//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 el perro guardián se supone que ayuda con los errores que no se pueden tener en cuenta mediante la programación, como los fallos de alimentación. Usar un perro guardián para reiniciar un programa con errores en lugar de arreglar el error no es la manera de hacerlo.

1voto

Jörgen Lundberg Puntos 753

El lugar donde se reinicia el watchdog depende de la aplicación, pero lo esencial es reiniciarlo en algún lugar inmediatamente antes o después su funcionalidad crítica o de riesgo.

De esta forma, si tu código no termina nunca, el watchdog se agota.

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, eso parece poco probable aquí.

¿Siempre son "1 o 2 días"? A menudo las caídas lentas están relacionadas con desbordamientos de la variable temporal, pero entonces el periodo sería muy estable.

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

P.D.: Una última cosa: Si la cosa al final que monitorea su UART lo hace a través de windows, windows tiene un manejo de puerto serial notoriamente chocante. Si su "reinicio de hardware" también cambia la alimentación de su adaptador de serie o implica reiniciar su terminal, esto puede ser lo que resuelve el problema.

0voto

Dror Puntos 745

¿Comprueba que la UART está lista para enviar (TXC, transmisión completa) antes de enviar el carácter? ¿Ese "bit de transmisión completa" necesita ser reiniciado por el softare? Si es así, ¿también lo restablece antes de ¿enviar el personaje? Si comienzas a enviar el carácter primero y restableces el bit de preparado después, una interrupción manejada en el medio podría retrasar el software de manera que termines borrando el bit TXC después de el personaje ya ha sido enviado. Eso detendría el funcionamiento de la UART porque nada volvería a establecer el TXC.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X