十四、【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; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于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类的使用