看门狗的原理和驱动实现

** 看门狗驱动实现**## 标题

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);

}

  1. 关闭看门狗

因为使用的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);       /*  获取驱动号                  */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值