十四、【watchdog】看门狗

 

 

                   6818看门狗定时器框图

  由上图可知PCLK经过8bit分频器分频然后再经过最高1/128的分频就是看门狗定时器的时钟频率,8bit最大分频系数为255,t_watchdog=200M/(255+1)/128=6103HZ.所以最小频率为6103HZ.

如果我们想要实现10s不喂狗就产生复位信号的功能,那WTCNT(计数器)的值设定为10*6103=61030 ,十六进制为0xEE66.当在10s内不喂狗,当WTCNT减到0(即10s后)产生复位信号,系统复位。

1、代码编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
#include <cfg_type.h>
#include <linux/ioctl.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
 
#include <mach/platform.h>
#include <mach/devices.h>
#include <mach/soc.h>
#include <linux/clk.h>
//提供三个命令字,启动、停止、喂狗
#define  WDT_START _IO('W', 0)
#define  WDT_STOP   _IO('W', 1)
#define  WDT_FEED   _IO('W', 2)
 
//IO内存的静态映射
#define WTREG(x) ((x) + IO_ADDRESS(PHY_BASEADDR_WDT))
 
#define WTCON           WTREG(0x00)
#define WTDAT           WTREG(0x04)
#define WTCNT           WTREG(0x08)
#define WTCLRINT        WTREG(0x0C)
 
static long wdt_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
 
    switch(cmd)
    {
        case WDT_START:
            writel(( readl(WTCON)|(1<<5)|(1<<2)|(1<<0) ),WTCON);
        break;
        case WDT_STOP:
            writel(( readl(WTCON)&(~((1<<5)|(1<<2)|(1<<0))) ),WTCON);
        break;
        case WDT_FEED:
            writel(0xEE66,WTCNT);
        break;
        default:
            return -ENOIOCTLCMD;
    }
 
    return 0;
}
     
//定义文件操作集合结构体
static struct file_operations  wdt_misc_fops =
{
    //.open = wdt_open,//操作集合中没有提供.open和.release
    //.release = wdt_close,//使用系统默认的,其它操作函数没有默认
    .unlocked_ioctl = wdt_ioctl,
};
 
 
static struct miscdevice wdt_misc= //定义杂项字符设备
{
    .minor = MISC_DYNAMIC_MINOR,//让内核动态分配次设备号
    .name = "wdt_misc",//设备名,也是设备文件名
    .fops = &wdt_misc_fops,
};
 
 
//入口函数
static int  __init wdt_init (void)
{
    int ret;
    printk("<1>""wdt_init\n");
 
    //注册杂项设备
    ret = misc_register(&wdt_misc);
    if(ret < 0)
    {
        printk(KERN_ALERT"misc_register fail\n");
        goto misc_register_err;
    }
    printk("<1>""misc_register OK\n");
 
 
    //复位WDT
    nxp_soc_peri_reset_set(RESET_ID_WDT);
    nxp_soc_peri_reset_set(RESET_ID_WDT_POR);
     
    //通过虚拟地址设置寄存器
    writel( 0, WTCON);//
     
    writel( ( readl(WTCON)|(3<<3) ), WTCON);//再分频参数 11b = 128
    writel( ( (readl(WTCON) & (~(0xff<<8))) | (255<<8)  ), WTCON);//预分频参数255
    writel( 0xEE66, WTDAT);//10S对应的计数值
    writel( 0xEE66, WTCNT);//10S对应的计数值
    writel( 0, WTCLRINT);
    printk("<1>""wdt_init OK\n");
 
    return 0;
 
 
misc_register_err:
    return ret;
 
 
}
 
//出口函数
static void __exit wdt_exit(void)
{
 
    printk(KERN_ALERT"wdt_exit\n");
 
    //注销杂项设备
    misc_deregister(&wdt_misc);
}
 
 
module_init(wdt_init);
module_exit(wdt_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("XLG");
MODULE_DESCRIPTION("first chardev drv");  

 

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <sys/ioctl.h>
 
#define  WDT_START _IO('W', 0)
#define  WDT_STOP   _IO('W', 1)
#define  WDT_FEED   _IO('W', 2)
 
 
int main(void)
{
    int digtal = 0;
    int ret,i;
    int fd = open("/dev/wdt_misc",O_RDWR);
    if(fd < 0)
    {
        perror("open failed");
        return -1;
    }
 
    ret = ioctl(fd,WDT_START);
    if(ret < 0)
    {
        perror("ioctl failed");
        return ret;
    }
     
    i = 0;
     
    while(1)
    {
         
        sleep(8);
        printf("%d seconds\n",++i*8);
        ioctl(fd,WDT_FEED);   //喂狗
    }
   ioctl(fd,WDT_STOP);   
    close(fd);
     
    return 0;
 
}

  

  

 

posted @   轻轻的吻  阅读(475)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2019-12-26 DVB-T和DVB-T2区别
2017-12-26 socket网络编程
2017-12-26 Python正则表达式
2017-12-26 python类的使用
点击右上角即可分享
微信分享提示