(Actualizado) Extraño comportamiento de reinicio con el procesador ARM9

Estoy trabajando para depurar un problema de arranque con una placa Atmel AT91SAM9G20. Todo va muy bien durante los primeros 700 ms aproximadamente. Parece que unos 700 ms después del reinicio, el procesador se congela. Lo curioso es que la CPU impulsa la línea de reinicio después de que suelte el botón de reinicio.

Aquí hay una toma de alcance que muestra lo que está pasando. El rastro amarillo es la línea de reinicio. La primera caída es el momento en que estoy manteniendo presionado el botón de reinicio. La segunda caída es, creo, generada por la CPU.

El rastro azul son datos en serie que salen de la CPU. Las dos primeras ráfagas provienen del gestor de arranque inicial. La tercera ráfaga es el arranque en U. La CPU deja de enviar caracteres cuando finaliza la tercera ráfaga azul.

Si estoy interpretando los rastros correctamente, esto significa que la línea de reinicio está baja durante casi exactamente el tiempo que el procesador está cargando U-boot desde NAND flash.

dos trazos de osciloscopio

Tengo algunas preguntas:

  • ¿Es normal este tipo de reinicio controlado por la CPU?
  • ¿Alguna sugerencia sobre cómo depurar esto?

Algunos detalles más: debo agregar que he mirado los rieles de alimentación y se ven limpios. El comportamiento siguiente es reproducible. Puedo variar la duración de la inmersión de reinicio inicial (en amarillo) por unos segundos, y el resto del comportamiento ocurre de la misma manera. Si conecto el cable JTAG, el comportamiento cambia: a veces arranca, a veces no, pero después de unos segundos, JTAG se hace cargo y el procesador se detiene.

Bajo JTAG, puedo arrancar con éxito. Así es como se ve un arranque exitoso controlado por JTAG:

otra captura de pantalla de alcance, pero con más datos en serie evidentes

Tenga en cuenta que la escala de tiempo es diferente, y no estoy presionando el botón de reinicio, está controlado por software. Se produce el mismo dip de reinicio. En ambos casos, la duración ronda los 500 ms.

Actualización (todavía desconcertado)

Impulsado por la sugerencia del Sr. Taffey a continuación, investigué el temporizador de vigilancia y el controlador de reinicio con más detalle. De hecho, el temporizador de vigilancia está deshabilitado por el primer gestor de arranque; Estoy bastante seguro de que el código se está ejecutando porque ocurre antes de que se envíe el texto al puerto serie de depuración y puedo leer el texto correctamente.

Al leer sobre los detalles del controlador de reinicio, aprendí que se supone que el procesador debe tomar el control del pin de reinicio y bajarlo durante un período corto. Esto es para asegurar que otro hardware en el tablero que escuche la misma línea reciba un reinicio lo suficientemente largo. Excavando a través de U-boot, encontré que la duración del reinicio se estableció en 0x0D usando el campo ERSTL:

at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
  (AT91_RSTC_ERSTL & (0x0D << 8)) |
  AT91_RSTC_URSTEN);

La hoja de datos explica que la duración se establece en 2^(ERSTL + 1) períodos de reloj lento.

La duración del reinicio es de alrededor de 500 ms, el cristal del reloj lento es de 32768 Hz y Google me dice que log(0.500 * 32768) / log(2) = 14 y 0x0D + 1 = 14, por lo que todo esto tiene sentido.

Creo que el verdadero problema puede ser que U-boot se cuelgue; el hecho de que suceda justo después de este reinicio probablemente sea irrelevante. Lo que es confuso es por qué U-boot fallaría solo cuando JTAG no está conectado.

Segunda actualización

Todavía no sé qué está saliendo mal o por qué JTAG hace que se comporte de manera diferente, pero creo que he encontrado una solución (más o menos). Parece que el bloqueo de U-boot está causado de alguna manera por el flash NAND en la placa. Por casualidad, la próxima revisión de la placa, que acaba de llegar recientemente, utiliza una tarjeta microSD en lugar de una memoria flash NAND para el almacenamiento no volátil masivo (bueno, hay una memoria flash NAND dentro de la tarjeta microSD, pero entiende el punto).

Mi "solución" es simplemente comenzar a usar la próxima revisión de la placa. U-boot también falla en eso, pero por razones conocidas, está configurado para buscar un flash NAND, que no puede encontrar. Por lo tanto, muere una muerte de fuego.

Entonces, problema "resuelto". (Espere otra pregunta en breve como "¿Cómo hago para que AT91 Bootstrap cargue U-boot desde un flash en serie?" o "¿Cómo hago para que U-boot funcione con una tarjeta microSD?" o "¿Por qué estoy haciendo esto?" )

Supongo que la marca de verificación verde es para Joby por notar que la línea de reinicio puede ser impulsada por el micro, aunque a la larga resultó ser irrelevante. Gracias por la ayuda, a todos ustedes. Te lo agradezco.

Tercera actualización (alrededor de una semana después)

Recientemente he estado trabajando principalmente en otras cosas, pero eventualmente descubrí cuál era el problema. Mi último misterio lo resumí arriba como:

Lo que es confuso es por qué U-boot fallaría solo cuando JTAG no está conectado.

De hecho, resultó que estaba confundiendo el error de U-boot al enviar caracteres por el puerto serie de depuración con el bloqueo de U-boot. Todavía no entiendo los detalles, pero descubrí que no es JTAG lo que hace que U-boot funcione; es un terreno común entre mi circuito y el host USB de mi PC, que JTAG estaba proporcionando, porque se ejecuta a través de el puerto USB. De hecho, U-boot funcionó bien todo el tiempo, pero cada vez que se desconectaba JTAG, el cambiador de nivel de RS-232 a USB que había integrado dejaba de funcionar, el puerto serie fallaba y asumía que U-boot estaba muerto. En realidad, descubrí que podía, por ejemplo, escribir comandos ping y ver los paquetes ICMP producidos, aunque mis caracteres no se reprodujeran en la terminal.

No entiendo exactamente qué estaba pasando mal, pero realmente no me importa: puedo encontrar fácilmente otra forma de leer el puerto serie y, a corto plazo, puedo hacer la conexión a tierra del USB con un cable. .

Gracias por toda la ayuda.

"Interesante"... eso es todo lo que tengo que decir.
Probablemente sea una pregunta tonta, pero su circuito de reinicio (el botón) tiene una resistencia de extracción, ¿verdad? Quiero decir, cuando no se presiona el botón, el pin de reinicio no se deja flotar. Además, también puede probar un límite de rebote en el botón de reinicio para descartar un comportamiento extraño debido al rebote de la línea de reinicio.
(No es una pregunta tonta, fue una de las primeras cosas que verifiqué). Sí, hay un botón desplegable. No hay límite antirrebote, pero he mirado de cerca el borde ascendente y no rebota de manera detectable. El error ocurre casi 1 segundo después de soltar el botón, así que creo que puedo descartarlo.
Probablemente comenzaría a copiar el código de u-boot para averiguar dónde falla... Tal vez su adaptador JTAG se restablece y luego detiene la CPU por un tiempo, lo que le da tiempo a otra cosa en la placa para que se encienda correctamente.
JTAG lo está afectando, esto solo le dice con seguridad que debería poder encontrar algo relacionado en el código de uboot.

Respuestas (3)

Mirando la hoja de datos:

14.3.4.5 Restablecimiento de vigilancia El restablecimiento de vigilancia se ingresa cuando ocurre una falla de vigilancia. Este estado dura 3 ciclos de reloj lento.

Cuando está en Watchdog Reset, la afirmación de las señales de restablecimiento depende del bit WDRPROC en WDT_MR: Si WDRPROC es 0, se afirman el restablecimiento del procesador y el restablecimiento del periférico. También se afirma la línea NRST , dependiendo de la programación del campo ERSTL. Sin embargo, el nivel bajo resultante en NRST no genera un estado de restablecimiento de usuario.

¿Podría ser que el perro guardián esté disparando y conduciendo la línea de reinicio?

Lo siguiente que iba a leer era sobre el temporizador de vigilancia, pueden causar problemas extraños, pero no estaba seguro de si el JTAG deshabilitaría a Watchdog y haría que el problema se detuviera.

Esto puede ser una posibilidad remota. En un microcontrolador de gama mucho más baja, un PIC, he ayudado a personas con reinicios extraños muchas veces debido a que se habilitó un pin de programación de bajo voltaje.

cuando se conecta un programador, mantiene líneas similares a esta a un voltaje establecido, cuando se desconecta el programador, podrían flotar fácilmente. En un proyecto, cuando el dispositivo cruzaba metal, se reiniciaba. No comprobaron LVP cuando se lo pedí, trabajaron durante 2 semanas más y luego lo desactivaron y el problema se resolvió.

No creo que esto sea una posibilidad remota en absoluto. Puede que no sea LVP o pin similar, sino cualquier entrada flotante. Tuvimos un PowerPC que se apagó con la entrada de E/S general flotando solo porque el nivel de la entrada se verificaría al principio del código.

¿Las líneas JTAG de algún dispositivo están conectadas a cosas que no deberían estar?

¿Digamos direcciones de líneas de autobús?

(Tomó meses depurar esa vez).

Buena idea. Acabo de revisar el esquema y el diseño de PCB. No veo ningún cruce de línea de dirección accidental o conexiones incorrectas. Me di cuenta de que el conector JTAG está directamente debajo de la RAM, pero están separados por dos planos de alimentación y la placa arranca correctamente bajo el control de JTAG. Es cuando el JTAG está inactivo que ocurre el problema.
¿Está tirando del jtag tclk y trst a estados seguros?
Sí, todas las entradas JTAG se elevan a 3,3 V, por lo que su estado no debería cambiar a menos que se conecte JTAG y las controle.