Tengo curiosidad? Un temporizador de vigilancia podría hacer esto, pero me gustaría hacerlo manualmente.
Tengo curiosidad? Un temporizador de vigilancia podría hacer esto, pero me gustaría hacerlo manualmente.
Tras echar un vistazo rápido a la hoja de datos, creo que el perro guardián es la única forma de restablecer bajo el control del software.
El reinicio tiene dos fuentes en el LPC2101 / 02/03: el pin RST y reinicio de perro guardián. El pin RST es un Schmitt gatillo de entrada de entrada con un filtro de falla adicional. Afirmación de reinicio del chip por cualquier fuente comienza el temporizador de activación (ver temporizador de activación descripción abajo), causando la reinicio interno del chip para permanecer afirmado hasta que el reinicio externo sea desestimado, el oscilador es funcionando, un número fijo de relojes tienen pasado, y el flash en chip el controlador ha completado su inicialización.
Para reiniciar el software, inicie el watchdog con un pequeño valor de tiempo de espera, luego entre en un bucle infinito.
reemrevnivek tiene la idea correcta, pero hay una mejor manera.
WDTC = 1024; // short timeout; we don't care (won't be using it)
WDMOD = WDEN | WDRESET; // watchdog resets CPU
WDFEED = 0xAA; // start ...
WDFEED = 0x55; // ... watchdog.
WDFEED = 0xAA; // start ...
WDFEED = 0x00; // ... invalid WDFEED sequence causes instant reset.
Eso te dará un reinicio inmediato sin necesidad de esperar.
Tenga en cuenta que simplemente saltar a la ubicación 0 no es lo mismo que un reinicio real. Saltar a 0 no restablece ningún periférico ni restablece el estado del núcleo ARM. Puede sonar como si no estuviera trabajando aquí, pero puedes encontrarte con algunos problemas muy inusuales y difíciles de depurar si estás esperando un reinicio y no obtienes uno.
No ejecute las interrupciones iniciando los temporizadores con un valor pequeño: escriba directamente en el indicador de interrupción. La publicación de Leon quiere que ejecute la interrupción como se define en manual del usuario , página 219:
WDTC = 1024; // short timeout - WASTEFUL!
WDMOD = WDEN | WDRESET; // watchdog resets CPU
WDFEED = 0xAA; // start ...
WDFEED = 0x55; // ... watchdog.
En su lugar, haga el trabajo del temporizador para ello: escriba directamente en el bit WDINT (lo que activa la interrupción del watchdog) del registro WDMOD, en lugar de esperar al temporizador:
WDMOD = WDEN; // Enable interrupt
WDMOD |= WDINT; // Trigger interrupt
La hoja de datos dice que es de solo lectura, lo que es una sorpresa para mí, pero los procesadores de TI y Atmel que he usado generalmente tienen activadores de interrupción de escritura. Pruébelo y vea qué sucede.
La alternativa más portátil es una interrupción de software. No he trabajado con los procesadores NXP, pero la familia ARM7TDMI (de la que es miembro el LPC2100) se puede restablecer mediante la derivación a 0x00000000. Curiosamente, NXP se refiere a esta dirección como la interrupción del perro guardián. Debería poder derivar a cero con código como:
void (*reset)(void); // Declare function to call
reset = 0x00000000; // Address in memory of reset ISR
// (See Table 2-4 of ARM7TDMI TRM or
// Table 2 of NXP UM10161)
reset(); // Call your new function
Alternativamente, use:
asm volatile ("mov pc, #0\n");
para lograr lo mismo.
Es posible que queden algunas tareas de limpieza, pero este código básicamente hará lo mismo que el temporizador de vigilancia, que es comenzar tu programa nuevamente desde el principio. Este código también funcionará en un gran número de microcontroladores.