概述
** 看门狗驱动实现**## 标题
1.看门狗的主要功能
看门狗本质是一个定时器,用于恢复处理器。本次所用看门狗包含一个数据寄存器(Data register)和一个计数寄存器 (16-bit counter register),当计数寄存器的值和数据寄存器的值相等时,系统会复位。为了防止复位,要定时“喂狗”,避免计数器和数据寄存器的值相等。
1.1利用看门狗使系统复位的原理:使能看门狗,没有喂狗操作,一段时间后系统会复位;
2. 喂狗操作
当计数器(COUNT)的值从0开始递增时,喂狗就是给COUNT值清零,避免和数据寄存器的值相等。
这里有专门的清零寄存器,即给第十位赋值为1.
喂狗的方式:一是当看门狗是中断模式时,可以在中断服务函数中喂狗;二是定时喂狗,(开启看门狗,使用延时功能,然后喂狗);
给寄存器的某一位单独赋值时,三步走:先读出寄存器的值——修改某一位的值——将值写入寄存器。
uiVal = WDT_REG_RD(WDT_CONTROL); /* 清除计数器的值 */
uiVal |= WDT_CLRZ;
WDT_REG_WR(WDT_CONTROL, uiVal);
3.停止看门狗 jzx2kWdtStop (VOID)
先失能看门狗,再停止时钟
4.启动看门狗 jzx2kWdtStart (UINT uiMSecs)
定时器时钟频率为RTC_CLK,分频为64,除以1000后时钟频率为毫秒。
uiMSecs为喂狗时间,单位为毫秒。 uiTime为计数器的值
uiTime = RTC_CLK / 64 * uiMSecs / 1000;
if (uiTime > 65535) {
uiTime = 65535;
}
进行下面一系列的操作,:
/* WATCH_DOG失能 /
/ 停止时钟 */
/* 设置比较值 ,为 uiTime /
/ 设置分频,选择时钟源,清除计数器 */
/* 打开时钟 /
/ WATCH_DOG使能 */
5.打开看门狗
/*********************************************************************************************************
** 函数名称: jzx2kWdtOpen
** 功能描述: 打开看门狗
** 输 入: pwdt 设备
** pcName 设备名
** iFlags 标志
** iMode 模式
** 输 出: 成功: 文件结点
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static LONG jzx2kWdtOpen (PJZX2K_WDT_DEV pwdt,
PCHAR pcName,
INT iFlags,
INT iMode)
{
。。。。。。。。。。
。。。。。。。。。。
if (LW_DEV_INC_USE_COUNT(&pwdt->WDT_devHdr) != 1) { /* 判断设备最多打开一次 */
_ErrorHandle(EBUSY);
LW_DEV_DEC_USE_COUNT(&pwdt->WDT_devHdr); /* 设备数减一 */
return (PX_ERROR);
}
pfdNode = API_IosFdNodeAdd(&pwdt->WDT_lineHeader, (dev_t)pwdt, 0,
iFlags, iMode, 0, 0, 0, LW_NULL, &bIsNew);
if (pfdNode == LW_NULL) {
printk(KERN_ERR "jzx2kWdtOpen(): failed to add fd node!n");
return (PX_ERROR);
}
return ((LONG)pfdNode);
}
- 关闭看门狗
因为使用的NEW_1 型设备驱动类型,设备和文件节点的指针变量的赋值有以下写法:
PJZX2K_WDT_DEV pwdt = (PJZX2K_WDT_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
PLW_FD_NODE pfdNode = (PLW_FD_NODE)pFdEntry->FDENTRY_pfdnode;
停止看门狗
文件节点减一
设备减一
7.控制函数
static INT jzx2kWdtIoctl (PLW_FD_ENTRY pfdEntry,
INT iCmd,
LONG lArg) {
case WDT_CMD_START:
jzx2kWdtStart(pwdt->WDT_uiCycle); /* 启动 WATCH_DOG */
break;
case WDT_CMD_STOP: /* 停止 WATCH_DOG */
jzx2kWdtStop();
break;
case WDT_SET_FEED_CYCLE: /* 设置看门狗定时器超时周期 */
pwdt->WDT_uiCycle = lArg;
break;
case WDT_GET_FEED_CYCLE: /* 获取看门狗定时器超时周期 */
*(LONG *)lArg = pwdt->WDT_uiCycle;
break;
case WDT_GET_TCNT: /* 获取看门狗的计数器值 */
*(LONG *)lArg = WDT_REG_RD(WDT_COUNT);
break;
case WDT_FEED_DOG: /* 设置喂狗时间,小于看门狗周期*/
jzx2kWdtFeed();
break;
}
8. 安装看门狗驱动
NEW_1型字符设备驱动的安装
struct file_operations fileop; /* 文件操作系统
if (_G_iWdtDrvNum) {
return (ERROR_NONE);
}
lib_memset(&fileop, 0, sizeof(struct file_operations));
fileop.owner = THIS_MODULE;
fileop.fo_create = jzx2kWdtOpen;
fileop.fo_open = jzx2kWdtOpen;
fileop.fo_close = jzx2kWdtClose;
fileop.fo_ioctl = jzx2kWdtIoctl;
fileop.fo_lstat = jzx2kWdtLstat;
_G_iWdtDrvNum = iosDrvInstallEx2(&fileop, LW_DRV_TYPE_NEW_1); /* 获取驱动号 */
最后
以上就是机智宝马为你收集整理的看门狗的原理和驱动实现的全部内容,希望文章能够帮你解决看门狗的原理和驱动实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复