Pregunta:
¿El temporizador de vigilancia se atasca en el ciclo de reinicio? (led verde parpadeando)
DominicM
2014-06-13 00:55:13 UTC
view on stackexchange narkive permalink

Estoy tratando de configurar una forma de reiniciar arduino en el comando. El siguiente código debería hacer eso, pero parece que mi arduino simplemente se atasca en una especie de bucle donde no puedo cargar ni obtener ninguna salida en serie. El led verde (pin 13) parpadea muy rápido. La única forma de detener esto es cortar la energía del dispositivo, incluso el botón de reinicio no funciona. Esto sucede solo cuando se recibe "R" vía serial o si se comenta la función wdt_reset ().

  #include <avr / io.h> # include <avr / wdt.h>int voidPin = 3; configuración () {MCUSR = 0; wdt_disable (); Serial.begin (57600); Serial.println ("¡ARRANQUE!"); pinMode (ledPin, SALIDA); digitalWrite (ledPin, BAJO); delay (500);} void loop () {if (Serial.available () > 0) {char cmd = Serial.read (); if (cmd == 'R') {Serial.println ("¡R recibido!"); wdt_enable (WDTO_1S); retraso (2000); Serial.println ("1 SEG."); }} wdt_reset (); digitalWrite (ledPin, HIGH);}  

¿Qué estoy haciendo mal?

Creo que me encontré con esto hace un tiempo, para cargar un nuevo boceto (sin las cosas del perro guardián) mantuve presionado el botón de reinicio hasta justo antes de que el IDE comenzara su estado de "carga".
También vea la nota al final de esta publicación: http://ariverpad.wordpress.com/2012/02/26/resetting-the-arduino-through-software-for-fun-and-profit/
@sachleen sí, seguí ese escrito pero estoy un poco confundido donde va ese código. ¿Asumo que no entra en el boceto? Preferiría no editar los archivos de origen, ya que eso afectaría a todos los programas arduino I.
Sí, eso modificaría el gestor de arranque y afectaría también a otros bocetos, pero solo si está utilizando el perro guardián.
@sachleen ¿Eso significa que el gestor de arranque debería volver a actualizarse?
Cuatro respuestas:
#1
+4
Nahkki
2014-06-13 02:03:12 UTC
view on stackexchange narkive permalink

Uno de los problemas más obvios aquí es que está habilitando el temporizador de vigilancia con un retraso de 1S y luego le pide al microcontrolador que se duerma durante 2S, imprime algo y luego vuelve al ciclo. Esto, en teoría, debería estar bien (su wdt debería activar un reinicio durante la espera de 2 segundos) pero he visto que causa problemas.

Además, algunos cargadores de arranque (notablemente el cargador de arranque Optiboot en Uno y placas más nuevas ) puede tener problemas con los temporizadores de vigilancia, lo que hace que wdt permanezca habilitado después del reinicio, aunque el ciclo de configuración lo deshabilite. Para empezar, intente aumentar el tiempo de wdt a algo mayor que 2S (debería poder hacer WDTO_8S) y vea si el problema persiste.

EDIT - El OP está usando un clon de Arduino Pro Mini. El cargador de arranque incluido en el Arduino Pro Mini no admite reinicios del sistema por parte de WDT. Esencialmente, en un dispositivo con un cargador de arranque que no admite reinicios WDT, la placa se reiniciará, pero el temporizador / reinicio no hará que la placa se reinicie continuamente al reiniciar. Existen cargadores de arranque alternativos para placas Arduino que pueden resolver este problema. Otra solución es utilizar un método diferente para reiniciar la placa.

Entonces, si puede causar problemas, ¿qué método no causa problemas? Intenté 8 segundos con un retraso de 9 segundos con los mismos resultados. De todos modos, 8 segundos serían demasiado largos, ya que en realidad no necesito ningún retraso después del comando en serie.
Una de las primeras preguntas sería: ¿qué placa es y qué cargador de arranque está ejecutando en ella? Además, ¿qué sucede con una versión más simple del código de vigilancia? Por ejemplo, uno que no lee una entrada, sino que repite una declaración de impresión n veces y luego se reinicia. Aquí (http://www.megunolink.com/how-to-detect-lockups-using-the-arduino-watchdog/) hay un ejemplo de un uso muy simple del temporizador de vigilancia: qué sucede cuando ejecuta algo como esto ?
Estoy usando arduino pro mini clone con el cargador de arranque predeterminado (no estoy seguro de qué es). Con la muestra copiada pegada del enlace, se bloquea igual después de un par de segundos después del encendido.
Un google rápido en su producto muestra a otros con el mismo problema. El cargador de arranque del Arduino Pro Mini no admite reinicios del sistema admitidos por el temporizador de vigilancia. Básicamente, reinician el sistema pero no reinician el temporizador, lo que hace que la placa se reinicie continuamente al reiniciar. No he usado un Arduino Pro mini ni he tenido mucha suerte con marcas desconocidas (no tienen nada de malo, solo mala suerte de mi parte), así que no puedo recomendar otro gestor de arranque de improviso, pero una búsqueda rápida en Google muestra que hay personas que tienen encontró un cargador de arranque en funcionamiento para el dispositivo que admite WDT.
¿Es necesario el gestor de arranque para el perro guardián? ¿Podría deshacerme del gestor de arranque por completo, siempre que pueda programarlo a través de bluetooth, esa sería la mejor opción para mí?
Eso probablemente no resolverá su problema. No es que el cargador de arranque sea el problema, es la implementación del WDT en el cargador de arranque y cómo el cargador de arranque está manejando eventos WDT lo que es el problema. Deshacerse del gestor de arranque no elimina el problema, solo lo cambia para que tenga que implementar el manejo de WDT por su cuenta. Ciertamente es posible grabar un boceto en un arduino sin el gestor de arranque ([Aquí] (http://www.arduino.cc/en/Hacking/Programmer) hay cierta documentación al respecto.) Pero sin un gestor de arranque no estará capaz de cargar un boceto a través de bluetooth.
¿Hay alguna razón en particular por la que estás usando un WDT para reiniciar el arduino? Hay varios otros métodos ([aquí] (http://www.instructables.com/id/two-ways-to-reset-arduino-in-software/?ALLSTEPS) es un instructivo que detalla estos métodos) que podría usar que solucionaría esto.
WDT es la única solución de software, pero supongo que usaré uno de los pines para activar el reinicio.
#2
+2
Chupo_cro
2017-10-04 07:11:43 UTC
view on stackexchange narkive permalink

Habilitar el reinicio del sistema del temporizador de vigilancia y esperar en un bucle hasta que se restablezca es una forma legítima de que SW restablezca el µC, al igual que usar el mecanismo de vigilancia para detectar el mal comportamiento de µC, que puede deberse a varias razones.

Sin embargo, algunos Se deben tomar precauciones al usar el reinicio del sistema de vigilancia porque en todos los AVR que también tienen una interrupción de vigilancia, el mecanismo de vigilancia con el preescalador establecido en 0000 = 16 ms permanece activo después de la condición de reinicio del sistema de vigilancia. Por lo tanto, es responsabilidad de un programador borrar MCUSR y desactivar el temporizador de vigilancia tan pronto como sea posible después de que ocurra tal condición. Dado que las rutinas LPM para inicializar las secciones .data y .bss pueden durar más que el intervalo de tiempo de espera del perro guardián, el código para deshabilitar el perro guardián debe colocarse en la sección .init3 y el contenido de MCUSR opcionalmente se puede guardar para un examen posterior de la fuente de reinicio. Aquí está el código que hace lo descrito:

  uint8_t mcusr_copy __attribute__ ((section (".noinit"))); void disable_wdt (void) \ __attribute __ ((desnudo)) \ __attribute __ ((sección (". init3"))); void disable_wdt (void) {mcusr_copy = MCUSR; MCUSR = 0x00; wdt_disable ();}  

Sin embargo, el problema puede surgir cuando se usa un cargador de arranque que no tiene en cuenta la posibilidad de una condición de reinicio del sistema de vigilancia. Si ese es el caso, el tiempo de espera de vigilancia ocurrirá dentro del cargador de arranque (que se ejecuta el primero) antes de que el código anterior tenga la oportunidad de deshabilitar el temporizador de vigilancia y µC se bloqueará en un ciclo de reinicio sin fin. Dado que restablecer el µC no borrará la marca WDRF en el registro MCUSR (solo se puede borrar en el software o mediante el reinicio de encendido), el único La forma será entonces apagar y encender un nuevo código cuando el temporizador de vigilancia aún no esté activado por el código anterior. WDRF en el registro MCUSR debe borrarse antes que wdt_disable () porque WDE no se puede borrar si WDRF todavía está configurado, por lo que el orden de las instrucciones en el código anterior es muy importante. La función ubicada en la sección .init3 no se debe llamar desde un código posterior.

#3
  0
geometrikal
2014-06-15 02:51:53 UTC
view on stackexchange narkive permalink

Puede reiniciar Arduino con este comando:

  asm volatile ("jmp 0");  
Esto solo realiza un restablecimiento parcial y no lo restablecerá a los valores predeterminados por completo.
#4
  0
Albertobozal
2018-10-16 18:43:46 UTC
view on stackexchange narkive permalink

Eliminar la bandera de los perros guardianes en init es una solución. Estoy usando optiboot 8.0 y funciona perfectamente.

  // Función Pototypevoid wdt_init (void) __attribute__ ((naked, used, section (". Init3"))); // Function Implementationvoid wdt_init (vacío) {MCUSR = 0; wdt_disable (); return;}  


Esta pregunta y respuesta fue traducida automáticamente del idioma inglés.El contenido original está disponible en stackexchange, a quien agradecemos la licencia cc by-sa 3.0 bajo la que se distribuye.
Loading...