提交 56997993 authored 作者: blu's avatar blu

new feature: hardware watchdog support [optional]

上级 75b89ac2
......@@ -15,6 +15,8 @@ update: 2019/09/10
#include <unistd.h>
#include <sys/wait.h>
#include <fstream>
#include <fcntl.h>
#include <termios.h>
#include "inc/tinythread.hpp"
#include "inc/httplib.h"
......@@ -1067,14 +1069,132 @@ public:
~EvDaemon() {};
};
#define EV_WATCHDOG_STOP uint8_t(0xFD)
class EvWatchDog {
private:
int fd_dog = 0;
string tty;
bool disabled = false;
int watchdog_init(string ttyPath)
{
const char *tty = ttyPath.c_str();
struct termios tio;
int tty_fd;
memset(&tio,0,sizeof(tio));
tio.c_iflag=0;
tio.c_oflag=0;
tio.c_cflag=CS8|CREAD|CLOCAL; // 8n1, see termios.h for more information
tio.c_lflag=0;
tio.c_cc[VMIN]=1;
tio.c_cc[VTIME]=5;
tty_fd=open(tty, O_RDWR | O_NONBLOCK);
if(tty_fd == -1) {
spdlog::error("evdaemon failed to open tty {}", tty);
return -1;
}
cfsetospeed(&tio,B115200); // 115200 baud
//cfsetispeed(&tio,B115200);
if(-1 == tcsetattr(tty_fd,TCSANOW,&tio)){
spdlog::error("evdaemon failed to set tty {}", tty);
return -1;
}
return tty_fd;
}
int watchdog_feed(int fd, uint8_t intervalMs){
if(fd <=0) {
spdlog::error("evdaemon invalid watchdog fd");
return -1;
}
uint8_t check = ~intervalMs;
uint8_t data[] = {0xFE, 0xFE, intervalMs, check, 0xEF};
spdlog::info("evdaemon feed watch dog: {}, {}", intervalMs, check);
if( -1 == write(fd,data,5)){
spdlog::error("evdaemon failed to write watchdog fd");
return -1;
}else{
return 0;
}
}
int _EV_WATCHDOG_STOP(int fd){
return watchdog_feed(fd, EV_WATCHDOG_STOP);
}
int watchdog_close(int fd) {
spdlog::info("evdaemon disabling watch dog..");
if(fd > 0) {
_EV_WATCHDOG_STOP(fd);
close(fd);
}
return 0;
}
public:
EvWatchDog() = delete;
EvWatchDog(string tty):tty(tty){
if((fd_dog = watchdog_init(tty)) < 0) {
spdlog::error("evdaemon can't open watchdog tty, ignore watchdog");
fd_dog = 0;
}
}
thread run(){
thread th = thread([this](){
uint8_t intval = 10;
if(this->fd_dog > 0) {
while(!this->disabled) {
watchdog_feed(this->fd_dog, intval);
this_thread::sleep_for(chrono::milliseconds(intval/2*100));
}
watchdog_close(this->fd_dog);
this->fd_dog = 0;
}else{
this->fd_dog = 0;
}
});
return th;
}
void stop(){
if(fd_dog > 0 && !disabled) {
disabled = true;
while(fd_dog != 0) {
spdlog::info("evdaemon waiting watchdog to stop");
this_thread::sleep_for(chrono::milliseconds(500));
}
}
}
};
EvWatchDog gWatchDog = EvWatchDog("/dev/ttyS1");
void cleanup(int signal)
{
// STOP watch dog
spdlog::warn("evdaemon received control signal {}, waiting to stop watch dog", signal);
gWatchDog.stop();
spdlog::info("evdaemon watchdog stopped, exiting");
while (waitpid((pid_t) (-1), 0, WNOHANG) > 0) {}
exit(signal);
}
int main()
{
signal(SIGCHLD, cleanup);
signal(SIGINT, cleanup);
signal(SIGTERM, cleanup);
signal(SIGKILL, cleanup);
thread t = gWatchDog.run();
if(t.joinable()){
t.detach();
}
//sigignore(SIGCHLD);
EvDaemon srv;
srv.run();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论