看门狗驱动详解.docx
- 文档编号:22781552
- 上传时间:2023-04-27
- 格式:DOCX
- 页数:15
- 大小:18.16KB
看门狗驱动详解.docx
《看门狗驱动详解.docx》由会员分享,可在线阅读,更多相关《看门狗驱动详解.docx(15页珍藏版)》请在冰豆网上搜索。
看门狗驱动详解
【WinCE驱动】基于S3C2440A芯片的看门狗驱动
【引子】
小弟日前正在开发一个仪器项目,核心芯片采用三星公司的S3C2440A,操作系统移植的是微软公司的WinCE5.0。
在实际调试中发现,系统由于受到强干扰而经常死机,虽然后来在硬件上增加了屏蔽等措施,效果已经很好,但这个问题仍引起了我的重视,因此我打算采用看门狗来增强系统最终的可靠性。
然而,现有的开发包(BSP)并没有看门狗驱动,只能自己动手写了。
经过两个白昼的努力,终于搞定,现将这个看门狗驱动整理出来,以免以后忘记了,毕竟“好记性不如烂笔头”。
【步骤】
WinCE下的驱动,一般分为本机驱动(NativeDriver)和流驱动(StreamDriver)两种。
对于我们的应用,大多数都可以归结到流驱动,而我的看门狗驱动正是按照流驱动格式来编写的。
基本思路就是利用S3C2440A的定时器1来产生中断,然后在中断程序中完成“喂狗”这一动作,从而实现看门狗功能。
首先,在Drivers目录下建立一个子目录watchdog,然后建立4个文件:
makefile、source、wdg.DEF、wdg.c。
【makefile】文件内容如下(就一句):
!
INCLUDE$(_MAKEENVROOT)\makefile.def
【source】文件内容如下:
RELEASETYPE=PLATFORM
TARGETNAME=wdg
TARGETTYPE=DYNLINK
TARGETLIBS=$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib
DLLENTRY=DllEntry
DEFFILE=wdg.def
SOURCES=\
wdg.c\
【wdg.DEF】文件内容如下:
LIBRARYwdg
EXPORTS
wdg_Init
wdg_Deinit
wdg_Open
wdg_Close
wdg_Read
wdg_Write
wdg_Seek
wdg_IOControl
wdg_PowerUp
wdg_PowerDown
【wdg.c】文件内容如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include"BSP.h"
#definePUBLIC
HANDLEg_hInstance;
HANDLEIntThread;
HANDLEIntEvent;
UINT32g_TimerIrq=IRQ_TIMER1;
UINT32g_SysIrq=SYSINTR_UNDEFINED;
DWORDdwTime;
DWORDwtdata;
DWORDnum;
volatileS3C2440A_WATCHDOG_REG*v_pWDGregs;//创建watchdog寄存器指针对象
volatileS3C2440A_PWM_REG*v_pPWMregs;
volatileS3C2440A_INTR_REG*v_pINTregs;
BOOLwdg_InitAddr(void);
voidVitural_Alloc(void);
voidTimer_Init(void);
DWORDTimer_IST(void);
voidVitural_Alloc(void)
{
/*INTRRegisterAllocation*/
v_pINTregs=(volatileS3C2440A_INTR_REG*)VirtualAlloc(0,sizeof(S3C2440A_INTR_REG),MEM_RESERVE,PAGE_NOACCESS);
if(v_pINTregs==NULL)
{
ERRORMSG(1,(TEXT("ForINTRregs:
VirtualAllocfailed!
\r\n")));
}
else
{
if(!
VirtualCopy((PVOID)v_pINTregs,(PVOID)(S3C2440A_BASE_REG_PA_INTR>>8),sizeof(S3C2440A_INTR_REG),PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE))
{
ERRORMSG(1,(TEXT("ForINTRregs:
VirtualCopyfailed!
\r\n")));
}
}
/*PWMRegisterAllocation*/
v_pPWMregs=(volatileS3C2440A_PWM_REG*)VirtualAlloc(0,sizeof(S3C2440A_PWM_REG),MEM_RESERVE,PAGE_NOACCESS);
if(v_pPWMregs==NULL)
{
ERRORMSG(1,(TEXT("ForPWMregs:
VirtualAllocfailed!
\r\n")));
}
else
{
if(!
VirtualCopy((PVOID)v_pPWMregs,(PVOID)(S3C2440A_BASE_REG_PA_PWM>>8),sizeof(S3C2440A_PWM_REG),PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE))
{
ERRORMSG(1,(TEXT("ForPWMregs:
VirtualCopyfailed!
\r\n")));
}
}
}
voidTimer_Init(void)
{
v_pPWMregs->TCFG0&=~0xFF;
v_pPWMregs->TCFG0|=199;//Timer1预分频值199
v_pPWMregs->TCFG1&=~(0x0F<<4);
v_pPWMregs->TCFG1|=(0<<20)|(3<<4);//Timer1分频值16
v_pPWMregs->TCON&=~(0xF<<8);
v_pPWMregs->TCNTB1=dwTime;
v_pPWMregs->TCON|=(2<<8);
v_pPWMregs->TCON|=(9<<8);//自动装载模式,启动Timer
v_pPWMregs->TCON&=~(1<<9);//这句很重要,这句不写定时器将不会启动
v_pINTregs->INTMSK&=~(1< } DWORDTimer_IST(void) { DWORDdwStatus; IntEvent=CreateEvent(NULL,FALSE,FALSE,NULL); if(! IntEvent) { RETAILMSG(1,(TEXT("ERROR: Timer: Failedtocreateevent.\r\n"))); returnFALSE; } if(! InterruptInitialize(g_SysIrq,IntEvent,NULL,0)) { RETAILMSG(1,(TEXT("FailtoinitializeTimerinterruptevent\r\n"))); returnFALSE; } while (1) { dwStatus=WaitForSingleObject(IntEvent,INFINITE); if(dwStatus==WAIT_OBJECT_0) { v_pWDGregs->WTCNT=wtdata;//0x6000;//更新看门狗计数器 num++;//测试 InterruptDone(g_SysIrq); //RETAILMSG(1,(TEXT("CompleteTimerInterrupt.num=%d.\r\n"),num)); } else { CloseHandle(IntEvent);//这句很重要 } } } BOOL wdg_InitAddr(void) { BOOLRetValue=TRUE; v_pWDGregs=(volatileS3C2440A_WATCHDOG_REG*)VirtualAlloc(0,sizeof(S3C2440A_WATCHDOG_REG),MEM_RESERVE,PAGE_NOACCESS); if(v_pWDGregs==NULL) { ERRORMSG(1,(TEXT("Forwdg_regs: VirtualAllocfailed! \r\n"))); RetValue=FALSE; } else { if(! VirtualCopy((PVOID)v_pWDGregs,(PVOID)(S3C2440A_BASE_REG_PA_WATCHDOG>>8),sizeof(S3C2440A_WATCHDOG_REG),PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) { ERRORMSG(1,(TEXT("Forwdg_regs: VirtualCopyfailed! \r\n"))); RetValue=FALSE; } } if(! RetValue) { RETAILMSG(1,(TEXT(": : : wdg_InitializeAddresses-Fail! ! \r\n"))); if(v_pWDGregs) { VirtualFree((PVOID)v_pWDGregs,0,MEM_RELEASE); } v_pWDGregs=NULL; } else { //RETAILMSG(1,(TEXT("wdg_InitializeAddresses-Success\r\n"))); } return(RetValue); } BOOLWINAPI DllEntry(HANDLEhInstDLL, DWORDdwReason, LPVOIDlpvReserved) { switch(dwReason) { caseDLL_PROCESS_ATTACH: //g_hInstance=hInstDLL; RETAILMSG(1,(TEXT("wdg: DLL_PROCESS_ATTACH.\r\n"))); DisableThreadLibraryCalls((HMODULE)hInstDLL); break; //returnTRUE; caseDLL_THREAD_ATTACH: RETAILMSG(1,(TEXT("wdg: DLL_THREAD_ATTACH\r\n"))); break; caseDLL_THREAD_DETACH: RETAILMSG(1,(TEXT("wdg: DLL_THREAD_DETACH\r\n"))); break; caseDLL_PROCESS_DETACH: RETAILMSG(1,(TEXT("wdg: DLL_PROCESS_DETACH\r\n"))); break; #ifdefUNDER_CE caseDLL_PROCESS_EXITING: RETAILMSG(1,(TEXT("wdg: DLL_PROCESS_EXITING\r\n"))); break; caseDLL_SYSTEM_STARTED: RETAILMSG(1,(TEXT("wdg: DLL_SYSTEM_STARTED\r\n"))); break; #endif } returnTRUE; } DWORDwdg_Init(DWORDdwContext) { dwTime=0x5000; num=0; wtdata=0x6000; RETAILMSG(1,(TEXT("wdg: wdg_INIT.\r\n"))); wdg_InitAddr(); Vitural_Alloc(); if(! KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,&g_TimerIrq,sizeof(UINT32),&g_SysIrq,sizeof(UINT32),NULL)) { RETAILMSG(1,(TEXT("ERROR: Timer: Failedtorequestsysintrvalue.\r\n"))); returnFALSE; } Timer_Init(); returnTRUE; } //Returnshandlevaluefortheopeninstance. DWORDwdg_Open( DWORDdwData, DWORDdwAccess, DWORDdwShareMode ) { DWORDthreadID; v_pWDGregs->WTCON&=~((1<<5)|(1<<2));//DisableWatchdog v_pWDGregs->WTCNT=wtdata;//0x6000;//20480 v_pWDGregs->WTDAT=wtdata;//0x6000;//20480 v_pWDGregs->WTCON|=(199<<8)|(1<<5)|(0x00>>3); /*200presacle,EnableWatchdog,16divisionfactor*/ v_pWDGregs->WTCON|=(1<<0);//startwatchdogtimer IntThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Timer_IST,0,0,&threadID); //创建定时器中断线程 if(NULL==IntThread) { RETAILMSG(1,(TEXT("ERROR: failedtoCreateTimerThread! \r\n"))); returnFALSE; } //以下两句为调试打印语句 RETAILMSG(1,(TEXT("num=%d,TCNTO1=0x%x.\r\n"),num,v_pPWMregs->TCNTO1)); RETAILMSG(1,(TEXT("wdg: wdg_Open.dwTime=0x%x,wtdata=0x%x,TCNTB1=0x%x,WTCNT=0x%x.\r\n"),dwTime,wtdata,v_pPWMregs->TCNTB1,v_pWDGregs->WTCNT)); return1; } DWORD wdg_Close(DWORDHandle) { v_pPWMregs->TCON|=(0<<8);//停止定时器1 v_pINTregs->INTMSK|=(1< v_pWDGregs->WTCON&=~((1<<5)|(1<<2));//禁止看门狗 CloseHandle(IntThread); if(IntEvent) CloseHandle(IntEvent); //RETAILMSG(1,(TEXT("num=%d,TCNTO1=0x%x.\r\n"),num,v_pPWMregs->TCNTO1)); //RETAILMSG(1,(TEXT("wdg: wdg_Close.dwTime=0x%x,wtdata=0x%x,TCNTB1=0x%x,WTCNT=0x%x.\r\n"),dwTime,wtdata,v_pPWMregs->TCNTB1,v_pWDGregs->WTCNT)); returnTRUE; } //Devicedeinit-devicesareexpectedtoclosedown. //Thedevicemanagerdoesnotcheckthereturncode. DWORDwdg_Deinit(DWORDdwContext) { //释放中断资源 InterruptDisable(g_SysIrq); KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&g_SysIrq,sizeof(UINT32),NULL,0,NULL); if(v_pPWMregs) { VirtualFree((PVOID)v_pPWMregs,0,MEM_RELEASE); } v_pPWMregs=NULL; if(v_pINTregs) { VirtualFree((PVOID)v_pINTregs,0,MEM_RELEASE); } v_pINTregs=NULL; if(v_pWDGregs) { VirtualFree((PVOID)v_pWDGregs,0,MEM_RELEASE); } v_pWDGregs=NULL; RETAILMSG(1,(TEXT("wdg: wdg_Deinit.\r\n"))); returnTRUE; } DWORDwdg_IOControl( DWORDHandle, DWORDdwIoControlCode, PBYTEpInBuf, DWORDnInBufSize, PBYTEpOutBuf, DWORDnOutBufSize, PDWORDpBytesReturned ) { switch(dwIoControlCode) { case0: dwTime=0x6000;wtdata=0x6000;break;//dwTime=wtdata case1: dwTime=0x5000;wtdata=0x6000;break;//dwTime case2: dwTime=0x6000;wtdata=0x5000;break;//dwTime>wtdata //case3: dwTime=data[0];wtdata=data[1];break;, } v_pPWMregs->TCNTB1=dwTime; v_pWDGregs->WTCNT=wtdata; v_pPWMregs->TCON|=(2<<8); v_pPWMregs->TCON&=~(1<<9);//这句很重要 RETAILMSG(1,(TEXT("wdg: wdg_IOControl.dwTime=0x%x,wtdata=0x%x,TCNTB1=0x%x,WTCNT=0x%x.\r\n"),dwTime,wtdata,v_pPWMregs->TCNTB1,v_pWDGregs->WTCNT)); returnTRUE; } DWORDwdg_Read(DWORDHandle,LPVOIDpBuffer,DWORDdwNumBytes) { RETAILMSG(1,(TEXT("wdg: wdg_Read.\r\n"))); *((DWORD*)pBuffer)=dwTime; ((DWORD*)pBuffer)++; *((DWORD*)pBuffer)=wtdata; ((DWORD*)pBuffer)++; *((DWORD*)pBuffer)=num; returnTRUE; } DWORDwdg_Write(DWORDHandle,LPCVOIDpBuffer,DWORDdwNumBytes) { RETAILMSG(1,(TEXT("wdg: wdg_Write.\r\n"))); dwTime=*((DWORD*)pBuffer); ((DWORD*)pBuffer)++; wtdata=*((DWORD*)pBuffer); ((DWORD*)pBuffer)++; num=*((DWORD*)pBuffer); v_pPWMregs->TCNTB1=dwTime; v_pWDGregs->WTCNT=wtdata; v_pPWMregs->TCON|=(2<<8); v_pPWMregs->TCON&=~(1<<9);//这句很重要 RETAILMSG(1,(TEXT("wdg: wdg_IOControl.dwTime=0x%x,wtdata=0x%x.\r\n"),dwTime,wtdata)); returnTRUE; } DWORDwdg_Seek(DWORDHandle,longlDistance,DWORDdwMoveMethod) { return0; } voidwdg_PowerUp(void) { return; } voidwdg_PowerDown(void) { return; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 看门狗 驱动 详解