¿Puedo enviar un latido al reloj de hardware desde mi propio programa?

14

A continuación de la pregunta y la excelente respuesta proporcionada por Steve Robillard aquí:

¿Cómo restablezco un Raspberry Pi?

¿Cómo puedo enviar una señal de latido desde mi propio programa al watchdog de hardware del BCM2708 en lugar de hacerlo desde el daemon de watchdog de Linux? En otras palabras, quiero restablecer el RPi si MI programa no se está ejecutando (que se ejecuta al inicio), no solo cuando todo el sistema está congelado.

Gracias.

Chico
fuente

Respuestas:

7

Puedes y es bastante fácil. RPi tiene un módulo Linux que implementa la API estándar de Linux Watchdog. Puede encontrar documentación de esto aquí .

Ahora, si lees esto, sabrás que hay un archivo de dispositivo especial llamado /dev/watchdogy para usarlo watchdogtienes que abrir este archivo y escribir algunos datos (un byte, es mejor escribir algo que no sea 'V' que yo ' m explicando más tarde) de vez en cuando. Si no escribe nada en este archivo durante el tiempo suficiente, watchdogactivará un reinicio. Puede encontrar un programa de ejemplo (muy simple) aquí .

Tenga en cuenta que en una situación normal, si cierra /dev/watchdog, watchdogpuede deshabilitarse. Hay un modo especial llamado 'Función de cierre mágico' que parece ser implementado por un controlador RPi pero AFAIK no está habilitado en la configuración predeterminada del kernel (opción CONFIG_WATCHDOG_NOWAYOUT). En este caso, el reinicio se activará incluso si cierra a /dev/watchdogmenos que escriba 'V' justo antes de salir de la aplicación.

Debe probarse a sí mismo si está deshabilitado (no tengo un RPi aquí ahora para probar), pero si no lo está, no es bueno para usted. Si su aplicación falla, el archivo del dispositivo de vigilancia se cerrará y el reinicio no se activará y es por eso que lo desea. En esta situación, puede cambiar la configuración del kernel y reconstruirla o escribir una aplicación personalizada que supervisará si su aplicación principal está funcionando (utilizando algún método IPC, por ejemplo).

También existe la API ioctl que le permite hacer algo más con watchdog. Puede, por ejemplo, establecer un tiempo de espera diferente: IOCTL con WDIOC_SETTIMEOUT (parece ser compatible con el controlador RPI) u obtener un tiempo de espera: IOCTL con WDIOC_GETTIMEOUT (que también parece ser compatible). Es posible que desee usarlo para modificar el tiempo de espera predeterminado (10 segundos). Sin embargo, hay un límite estricto de 16 segundos. Aquí hay un ejemplo:

int timeout = 15;
int fd = open("/dev/watchdog", O_WRONLY);
ioctl(fd, WDIOC_SETTIMEOUT, &timeout);

También puede usar IOCTL con WDIOC_KEEPALIVE en lugar de escribir un carácter si lo desea. Ambos métodos son válidos.

Krzysztof Adamski
fuente
Ah, y lo olvidé: puedes usar watchdogd para esto. Admite llamar a un programa externo que verificará e informará el estado del sistema. Lea "Comprobar binario" en esta página de manual
Krzysztof Adamski, el
Gracias. Lo tengo funcionando! Después de agregar bcm2708_wdog a / etc / modules creé una aplicación de prueba simple de VB.NET para verificar mi comprensión: Dim fs As New System.IO.FileStream (fn, IO.FileMode.Open) para iniciar el temporizador y fs.WriteByte ( H) luego fs.Flush () para enviarle latidos. ¡Funciona genial!
Chico
¿Cuál es la representación numérica de WDIOC_KEEPALIVE? No puedo encontrarlo en ningún lado.
Flash Thunder
@FlashThunder: Se define aquí: lxr.free-electrons.com/source/include/uapi/linux/watchdog.h#L29 pero tendrías que resolver un par de niveles de macros para encontrar el valor exacto. La mejor manera es escribir un simple programa en C para imprimir el valor. Solo incluya el <linux / watchdog.h>. En mi sistema es0x80045705
Krzysztof Adamski