Skip to content

Instantly share code, notes, and snippets.

@prodeveloper0
Created December 5, 2017 05:39
Show Gist options
  • Save prodeveloper0/412b68ad794e7a0c1b60e4016d4ec66a to your computer and use it in GitHub Desktop.
Save prodeveloper0/412b68ad794e7a0c1b60e4016d4ec66a to your computer and use it in GitHub Desktop.
USB Watchdog for Linux
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <errno.h>
#define USBWD_SYN ((unsigned char)0x80)
#define USBWD_ACK ((unsigned char)0x81)
#define USBWD_PWRST ((unsigned char)0xFF)
#define USBWD_MIN_TIMEOUT ((unsigned char)0x01)
#define USBWD_MAX_TIMEOUT ((unsigned char)0x7F)
#define USBWD_OK ((unsigned char)0x82)
#define USBWD_FAIL ((unsigned char)0x83)
void close_usbwd(int fd)
{
close(fd);
}
int open_usbwd(const char* path)
{
struct termios newtio;
int fd = open(path, O_RDWR | O_NOCTTY);
if (fd == -1)
return -1;
memset(&newtio, 0x00, sizeof(newtio));
newtio.c_cflag |= B9600;
newtio.c_cflag |= CS8;
newtio.c_cflag |= CLOCAL;
newtio.c_cflag |= CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 1;
newtio.c_cc[VEOF] = 4;
if (tcflush(fd, TCIFLUSH))
{
close_usbwd(fd);
return -1;
}
if (tcsetattr(fd, TCSANOW, &newtio))
{
close_usbwd(fd);
return -1;
}
return fd;
}
unsigned char sigout(int fd, unsigned char b)
{
if (write(fd, &b, 1) == -1)
return USBWD_FAIL;
return USBWD_OK;
}
unsigned char sigin(int fd)
{
unsigned char b = 0x00;
if (read(fd, &b, 1) == -1)
return USBWD_FAIL;
return b;
}
int main(int argc, char** argv)
{
if (argc != 2)
{
printf("usage: usbwd ttyfile\n");
return 0;
}
int fd = open_usbwd(argv[1]);
if (fd == -1)
{
printf("Cannot open USBWatchdog device\n");
return -1;
}
// Send SYN signal, USBWatchdog is started
if (sigout(fd, USBWD_SYN) != USBWD_OK)
goto cleanup;
// USBWatchdog send ACK signal to system
if (sigin(fd) != USBWD_ACK)
goto cleanup;
// Send PWRST(0xFF) signal, reset system immediately
// if (sigout(fd, USBWD_PWRST) == USBWD_OK)
//
// Timeout range: [USBWD_MIN_TIMEOUT, USBWD_MAX_TIMEOUT]
// Timeout can be calcluated from "Timeout = 10 x T"
while (sigout(fd, USBWD_MIN_TIMEOUT) == USBWD_OK)
sleep(1);
cleanup:
close_usbwd(fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment