会怎么处理呢?软件“看门狗”技术若失控的程序进入“死循环”?
一,不是所有的单片机都有内置看门狗,就好比不是所有家庭都养狗一样。比如AT89C51没带看门狗,AT89S51有带看门狗,STC单片机一般都带看门狗。
二,看门狗是用来防止程序“跑飞”的,不是来防止你程序死循环的。因为死循环有可能是人为故意造成的;而程序跑飞,是因为电磁干扰等非人为的不预测的因素造成的(就好比是天灾),程序一旦跑飞,我们就控制不了单片机了,而死循环还在我们的控制范围内。
三,while(1),这样的死循环,看门狗是不会报错的,只要你的程序能正常按时“喂狗”,看门狗就不是出错,反之则报错。 -完-
延伸阅读
西门子PLC中,看门狗作用是什么?原理是什么?简洁一点,不要到网站上复制一大堆文字过来,谢谢?
看门狗是防止程序死机而设置的定时复位,在正常运行的程序中加入一个指令定时将复位电路清零,当程序死机或地址溢出时,会造成该清零指令不执行,复位电路动作,重启程序,恢复运行!与加密狗(软狗或硬狗)是不同的!
随开机运行的程序中,总有一个:BIG DOG 303;是什么?
就是监视狗程序,俗称看门狗。是种防火墙。
c++如何开发看门狗软件?
1、注册服务
2、检测指定进程是否运行,如果没有运行,则运行进程
// WatchDogSvr.cpp : 定义控制台应用程序的入口点。
//
#include “stdafx.h”
#include “Windows.h”
#include “tlhelp32.h”
SERVICE_STATUS m_ServiceStatus;
SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
BOOL bRunning=true;
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
void WINAPI ServiceCtrlHandler(DWORD Opcode);
BOOL InstallService();
BOOL DeleteService();
const int nBufSize=512;
void WriteLog(const char* strLog)
{
FILE * fp;
fp=fopen(“C:\WatchDog.log”,”a”);
if( fp==NULL ) return;
//fputs(strLog,fp);
fprintf(fp,”%sn”,strLog);
fclose(fp);
}
int GetProcessCount(const TCHAR* szExeName)
{
TCHAR sztarget[MAX_PATH];
lstrcpy(sztarget, szExeName);
CharLowerBuff(sztarget, MAX_PATH);
int count = 0;
PROCESSENTRY32 my;
HANDLE l = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (((int)l) != -1)
{
my.dwSize = sizeof(my);
if (Process32First(l, &my))
{
do
{
CharLowerBuff(my.szExeFile, MAX_PATH);
if (lstrcmp(sztarget, my.szExeFile) == 0)
{
count++;
}
}while (Process32Next(l, &my));
}
CloseHandle(l);
}
return count;
}
void RunServiceProcess(const TCHAR *strServiceName)
{
//清空结构
STARTUPINFO sInfo;
PROCESS_INFORMATION pInfo;
ZeroMemory(&sInfo,sizeof(sInfo));
sInfo.cb=sizeof(sInfo);
sInfo.dwFlags=STARTF_USESHOWWINDOW;
sInfo.wShowWindow=SW_SHOWNORMAL;
ZeroMemory(&pInfo,sizeof(pInfo));
//输出出错信息
char chBuf[nBufSize];
ZeroMemory(chBuf,nBufSize);
//创建一个进程
if(!::CreateProcess(strServiceName,NULL,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&sInfo,
&pInfo))
{
sprintf(chBuf,”CreateProcess failed(%d).n”,GetLastError());
WriteLog(chBuf);
return;
}
// Wait until child process exits.
WaitForSingleObject(pInfo.hProcess,INFINITE);
//关闭进程和线程的句柄
CloseHandle(pInfo.hProcess);
CloseHandle(pInfo.hThread);
}
void DoTask()
{
if( GetProcessCount(_T(“SjkDataCollect.exe”))==0)
{
RunServiceProcess(_T(“C:\xxx.exe”));
WriteLog(“can not find process [SjkDataCollect.exe] and run process!”);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
if(argc>1)
{
if( wcscmp(argv[1],L”-i”)==0)
{
if(InstallService())
printf(“n Service Installed Sucessfullyn”);
else
printf(“n Service has been installedn”);
}
else if(wcscmp(argv[1],L”-d”)==0)
{
if(DeleteService())
printf(“n Service UnInstalled Sucessfullyn”);
else
printf(“nInstalled Easin Central Service Not Foundn”);
}
else
{
printf(“nUnknown Switch UsagenFor Install use Servicetest -inFor UnInstall use Servicetest -dn”);
}
}
else
{
SERVICE_TABLE_ENTRY DispatchTable[]={{L”WatchDogSvr”,ServiceMain},{NULL,NULL}};
StartServiceCtrlDispatcher(DispatchTable);
}
return 0;
}
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
// DWORD status;
// DWORD specificError;
m_ServiceStatus.dwServiceType = SERVICE_WIN32;
m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
m_ServiceStatus.dwWin32ExitCode = 0;
m_ServiceStatus.dwServiceSpecificExitCode = 0;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
m_ServiceStatusHandle = RegisterServiceCtrlHandler(L”WatchDogSvr”,ServiceCtrlHandler);
if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
return;
}
m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus))
{
}
bRunning=true;
while(bRunning)
{
Sleep(3000);
//Place Your Code for processing here….
DoTask();
}
return;
}
void WINAPI ServiceCtrlHandler(DWORD Opcode)
{
switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:
m_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
m_ServiceStatus.dwWin32ExitCode = 0;
m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus);
bRunning=false;
break;
case SERVICE_CONTROL_INTERROGATE:
break;
}
return;
}
BOOL InstallService()
{
WCHAR strDir[1024];
SC_HANDLE schSCManager,schService;
GetCurrentDirectory(1024,strDir);
lstrcat(strDi1、注册服务
2、检测指定进程是否运行,如果没有运行,则运行进程
// WatchDogSvr.cpp : 定义控制台应用程序的入口点。
//
#include “stdafx.h”
#include “Windows.h”
#include “tlhelp32.h”
SERVICE_STATUS m_ServiceStatus;
SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
BOOL bRunning=true;
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
void WINAPI ServiceCtrlHandler(DWORD Opcode);
BOOL InstallService();
BOOL DeleteService();
const int nBufSize=512;
void WriteLog(const char* strLog)
{
FILE * fp;
fp=fopen(“C:\WatchDog.log”,”a”);
if( fp==NULL ) return;
//fputs(strLog,fp);
fprintf(fp,”%sn”,strLog);
fclose(fp);
}
int GetProcessCount(const TCHAR* szExeName)
{
TCHAR sztarget[MAX_PATH];
lstrcpy(sztarget, szExeName);
CharLowerBuff(sztarget, MAX_PATH);
int count = 0;
PROCESSENTRY32 my;
HANDLE l = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (((int)l) != -1)
{
my.dwSize = sizeof(my);
if (Process32First(l, &my))
{
do
{
CharLowerBuff(my.szExeFile, MAX_PATH);
if (lstrcmp(sztarget, my.szExeFile) == 0)
{
count++;
}
}while (Process32Next(l, &my));
}
CloseHandle(l);
}
return count;
}
void RunServiceProcess(const TCHAR *strServiceName)
{
//清空结构
STARTUPINFO sInfo;
PROCESS_INFORMATION pInfo;
ZeroMemory(&sInfo,sizeof(sInfo));
sInfo.cb=sizeof(sInfo);
sInfo.dwFlags=STARTF_USESHOWWINDOW;
sInfo.wShowWindow=SW_SHOWNORMAL;
ZeroMemory(&pInfo,sizeof(pInfo));
//输出出错信息
char chBuf[nBufSize];
ZeroMemory(chBuf,nBufSize);
//创建一个进程
if(!::CreateProcess(strServiceName,NULL,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&sInfo,
&pInfo))
{
sprintf(chBuf,”CreateProcess failed(%d).n”,GetLastError());
WriteLog(chBuf);
return;
}
// Wait until child process exits.
WaitForSingleObject(pInfo.hProcess,INFINITE);
//关闭进程和线程的句柄
CloseHandle(pInfo.hProcess);
CloseHandle(pInfo.hThread);
}
void DoTask()
{
if( GetProcessCount(_T(“SjkDataCollect.exe”))==0)
{
RunServiceProcess(_T(“C:\xxx.exe”));
WriteLog(“can not find process [SjkDataCollect.exe] and run process!”);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
if(argc>1)
{
if( wcscmp(argv[1],L”-i”)==0)
{
if(InstallService())
printf(“n Service Installed Sucessfullyn”);
else
printf(“n Service has been installedn”);
}
else if(wcscmp(argv[1],L”-d”)==0)
{
if(DeleteService())
printf(“n Service UnInstalled Sucessfullyn”);
else
printf(“nInstalled Easin Central Service Not Foundn”);
}
else
{
printf(“nUnknown Switch UsagenFor Install use Servicetest -inFor UnInstall use Servicetest -dn”);
}
}
else
{
SERVICE_TABLE_ENTRY DispatchTable[]={{L”WatchDogSvr”,ServiceMain},{NULL,NULL}};
StartServiceCtrlDispatcher(DispatchTable);
}
return 0;
}
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
// DWORD status;
// DWORD specificError;
m_ServiceStatus.dwServiceType = SERVICE_WIN32;
m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
m_ServiceStatus.dwWin32ExitCode = 0;
m_ServiceStatus.dwServiceSpecificExitCode = 0;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
m_ServiceStatusHandle = RegisterServiceCtrlHandler(L”WatchDogSvr”,ServiceCtrlHandler);
if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
return;
}
m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus))
{
}
bRunning=true;
while(bRunning)
{
Sleep(3000);
//Place Your Code for processing here….
DoTask();
}
return;
}
void WINAPI ServiceCtrlHandler(DWORD Opcode)
{
switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:
m_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
m_ServiceStatus.dwWin32ExitCode = 0;
m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus);
bRunning=false;
break;
case SERVICE_CONTROL_INTERROGATE:
break;
}
return;
}
BOOL InstallService()
{
WCHAR strDir[1024];
SC_HANDLE schSCManager,schService;
GetCurrentDirectory(1024,strDir);
lstrcat(strDir,L”\WatchDogSvr.exe”);
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
return false;r,L”\WatchDogSvr.exe”);
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
return false;
怎么计算看门狗的喂狗时间?C语言的程序?
对于裸奔的程序,最理想的看门狗是程序只在主循环中加一个喂狗,计算主循环执行一个循环的最长时间的1.5倍作为看门狗定时器的时间,这样只要程序超出了预计的时间未回到主循环,就会自动复位。
这样的程序尽量不要让中断服务函数占用太多的处理器资源,将耗费处理器资源的工作放在程序的主循环中,可以更有效的利用看门狗。