embedded - razas - Estrategia para alimentar a un perro guardián en un entorno multitarea.
perros guardianes que no sean peligrosos (4)
Este es de hecho un gran dolor con los temporizadores de vigilancia.
Mis tableros tienen un LED en una línea GPIO, así que lo destello en un bucle while / sleep, (750ms encendido, 250ms apagado), en un hilo de prioridad de siguiente a menor, (el más bajo es el hilo inactivo que solo va a baja potencia modo en un bucle). He puesto un feed wdog en el hilo de flash LED.
Esto ayuda con los bloqueos completos y los subprocesos de mayor prioridad que el bucle de la CPU, pero no ayuda si el sistema se bloquea. Afortunadamente, mis diseños de paso de mensajes no están en punto muerto, (bueno, no muy a menudo, de todos modos :).
Tras trasladar algunos códigos incrustados a FreeRTOS, me queda un interesante dilema sobre el perro guardián. El temporizador de vigilancia es una necesidad para nuestra aplicación. El uso de FreeRTOS también ha sido de gran ayuda para nosotros. Cuando la aplicación era más sencilla, alimentaba al perro guardián en los puntos oportunos de su flujo lógico para que pudiéramos asegurarnos de que la tarea estaba progresando de manera oportuna.
Con múltiples tareas, sin embargo, eso no es fácil. Una tarea podría estar vinculada por alguna razón, no progresar, pero otra está funcionando bien y avanzando lo suficiente como para mantener feliz al perro guardián.
Un pensamiento fue lanzar una tarea separada únicamente para alimentar al perro guardián, y luego usar algunos contadores que las otras tareas incrementan regularmente, cuando la tarea del perro guardián marque, se aseguraría de que todos los contadores parecieran que se estaba progresando en todos los demás Tareas, y si es así, avanza y alimenta al perro guardián.
Tengo curiosidad por lo que otros han hecho en situaciones como esta?
He diseñado la solución utilizando los temporizadores FreeRTOS:
- SystemSupervisor SW Timer que alimenta el HW WD . El fallo de FreeRTOS provoca el reinicio.
- Cada tarea crea "su propio" temporizador SW con función SystemReset.
- Cada tarea responsable de "manualmente" recargar su temporizador antes de que caduque.
- La función SystemReset guarda los datos antes de cometer un Suiside
Aquí hay un listado de pseudocódigo:
//---------------------------------
//
// System WD
//
void WD_init(void)
{
HW_WD_Init();
// Read Saved Failure data, Send to Monitor
// Create Monitor timer
xTimerCreate( "System WD", // Name
HW_WD_INTERVAL/2, // Reload value
TRUE, // Auto Reload
0, // Timed ID (Data per timer)
SYS_WD_Feed);
}
void SYS_WD_Feed(void)
{
HW_WD_Feed();
}
//-------------------------
// Tasks WD
//
WD_Handler WD_Create()
{
return xTimerCreate( "", // Name
100, // Dummy Reload value
FALSE, // Auto Reload
pxCurrentTCB, // Timed ID (Data per timer)
Task_WD_Reset);
}
Task_WD_Reset(pxTimer)
{
TaskHandler_t th = pvTimerGetTimerID(pxTimer)
// Save Task Name and Status
// Reset
}
Task_WD_Feed(WD_Handler, ms)
{
xTimerChangePeriod(WD_Handler, ms / portTICK_PERIOD_MS, 100);
}
No olvide manejar una posible situación en la que las tareas se eliminan o permanecen inactivas durante períodos de tiempo más largos. Si esas tareas se registraron previamente con una tarea de vigilancia, también deben tener un mecanismo de "extracción".
En otras palabras, la lista de tareas de las que es responsable una tarea de vigilancia debe ser dinámica, y debe organizarse de modo que algún código salvaje no pueda eliminar fácilmente la tarea de la lista.
Lo sé, más fácil decirlo luego hecho ...
Una tarea de vigilancia que supervisa el estado de todas las demás tareas es una buena solución. Pero en lugar de un contador, considere usar un indicador de estado para cada tarea. El indicador de estado debe tener tres valores posibles: UNKNOWN, ALIVE y ASLEEP. Cuando se ejecuta una tarea periódica, establece el indicador en VIVO. Las tareas que se bloquean en un evento asíncrono deben establecer su marca en ASLEEP antes de bloquear y VIVIR cuando se ejecuta. Cuando la tarea del monitor de vigilancia se ejecute, debe patear al vigilante si cada tarea está VIVA o ASLEEP. Luego, la tarea del monitor de vigilancia debe establecer todos los indicadores ALIVE en DESCONOCIDO. (Los indicadores ASLEEP deben permanecer como ASLEEP). Las tareas con el indicador UNKNOWN deben ejecutarse y establecer sus indicadores en ALIVE o ASLEEP de nuevo antes de que la tarea del monitor vuelva a patear el watchdog.
Consulte la sección "Multitarea" de este artículo para obtener más detalles: http://www.embedded.com/design/debug-and-optimization/4402288/Watchdog-Timers