一、什么是看门狗定时器
看门狗是一个定时器(倒计时),有计时的功能。当看门狗的计数值减为0,会产生一个复位信号给处理器,这样处理器就会重启,软件就会重新运行。

二、看门狗定时器的作用
当系统在运行的过程中,由于受到干扰(雷击、电机运行、手机、汽车…)或者系统的错误,而产生了死机(程序跑飞)不能正常工作,看门狗可以让系统自动重启,重新开始运行代码,让系统恢复到正常工作的状态。

看门狗不是用来解决产品设计的bug。

三、S5PV210的看门狗
1、计时值是16bits的。
2、看门狗定时器有两个功能:
1)作为看门狗,可以产生复位信号(讲解)
2)作为一个普通的定时器,可以产生周期性的中断

四、S5PV210看门狗的原理(复位功能)

见看门狗框图

五、看门狗的寄存器
只需要理解WTCON和WTCNT两个寄存器。

六、解决三个问题
1)C语言的位操作运算
在处理器中,一般一个寄存器都是32bits的,每个位都有特殊的含义,通常配置寄存器的时候,不是配置寄存器的整个值,而是配置寄存器的某个位。
C位操作运算符:&、|、~、^、<<、>>

求:
1<<2 + 3 = 1<<(2+3)=32

例1:求一个字节数据中,有多少个位为1?
int byte_cnt(unsigned char data)
{
int count = 0;
for(int i=0;i<8;i++)
{
if(data & (1<<i))
count++;
}

return count;

}

例2:unsigned int data,将data的第10位置1,其他位保持不变。
data = data | (1<<10);
data |= (1<<10);

例3:unsigned int data,将data的第10位清0,其他位保持不变。
data = data & ~(1<<10);
data &= ~(1<<10);

例4:unsigned int data,将data的第10位取反,其他位保持不变。
data ^= (1<<10);

2)如何通过地址访问地址下的数据
在处理器中,每个寄存器都有唯一的地址,我们配置寄存器的时候,通常都是通过寄存器的地址来配置的。所以需要理解通过寄存器的地址如何访问地址下的内容。

例1:将0xaa66写入地址0x67a9
0x67a9 = 0xaa66;不对

unsigned short *p=NULL;//定义一个指向unsigned short数据的指针。思考:sizeof§\sizeof(*p)
p = (unsigned short *)0x67a9;
*p = 0xaa66;
或者:
*(unsigned short *)0x67a9 = 0xaa66

题目是有问题的。

例2:将0x12345678写入0x40000000地址。
答:
*(unsigned int *)0x40000000 = 0x12345678;

例3:读出0x40000000地址下int的数据给a;
答:
unsigned int a;
a = *(unsigned int *)0x40000000;

3)在驱动中,如何访问处理器的寄存器?

物理地址:硬件实际的地址,在原理图或者处理器的使用手册中,得到的都是物理地址,在裸机环境下,可以直接访问物理地址。

虚拟地址:操作系统使用的地址是虚拟地址,虚拟地址是对应到物理地址的。操作做系统不能直接使用物理地址,要使用物理地址对应的虚拟地址。

驱动程序是工作在Linux内核中的,是的地址是虚拟地址。

结论:我们需要知道WTCON和WTCNT这两个寄存器物理地址对应的虚拟地址,然后通过虚拟地址再访问寄存器。

七、如何得到物理地址对应的虚拟地址

//驱动的头文件
#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <asm/io.h>#define WDT_START  1 //看门狗打开
#define WDT_STOP   2 //看门狗关闭
#define WDT_ALIVE  3 //看门狗喂狗static void __iomem * WTBASE_VA;
static void __iomem * WTCON_VA; //WTCON的虚拟地址
static void __iomem * WTCNT_VA; //WTCNT的虚拟地址//定义一个文件操作集--给应用程序提供接口//给应用程序open()的接口
static int mini210_wdt_open(struct inode *inode, struct file *filp)
{printk("mini210 wdt driver openning\n");return 0;
}
//给应用程序read()的接口
static ssize_t mini210_wdt_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{char wdt_flag;int ret,i;if(len != 1) return -EINVAL;//Invalid argumentret = copy_from_user(&wdt_flag, buf, len);if(ret != 0){return -EFAULT;}switch(wdt_flag){case WDT_START:*(unsigned int *)WTCON_VA |= (1<<5); //enable wdtbreak;case WDT_STOP:*(unsigned int *)WTCON_VA &= ~(1<<5); //disable wdtbreak;   case WDT_ALIVE:*(unsigned int *)WTCNT_VA = 26050;//计数值重新赋值break;   default:return -EINVAL;}return len;
}//给应用程序close()的接口
static int mini210_wdt_release(struct inode *inode, struct file *filp)
{printk("mini210 wdt driver closing\n");return 0;
}
static struct file_operations mini210_wdt_fops = {.owner = THIS_MODULE,.open =   mini210_wdt_open,.write = mini210_wdt_write,.release = mini210_wdt_release,
};//定义一个混杂设备驱动模型
static struct miscdevice mini210_misc = {.minor = MISC_DYNAMIC_MINOR,//内核自动分配次设备号.name = "wdt_drv",//混杂设备的名字,也是设备文件的名字.fops = &mini210_wdt_fops, //文件操作集
};//看门狗驱动的安装函数
static int __init mini210_wdt_init(void)
{//看门狗驱动的安装过程int ret,i;//得到虚拟地址对应的物理地址WTBASE_VA =  ioremap(0xE2700000, 16);if(WTBASE_VA == NULL){printk("ioremap failed\n");return -EFAULT;}WTCON_VA = WTBASE_VA + 0x00;WTCNT_VA = WTBASE_VA + 0x08;printk("VA: %p,%p\n", WTCON_VA,WTCNT_VA);//将混杂设备驱动模型注册到内核ret = misc_register(&mini210_misc);if(ret < 0){printk("wdt misc register error\n");goto misc_reg_err;}printk("mini210 wdt driver init....\n");//初始化看门狗(不能让看门狗工作)//prescaler value=199,disable wdt,division factor=128,enable reset*(unsigned int *)WTCON_VA = (199<<8)+(3<<3)+(1<<0);//看门狗的计数频率:2605Hz//设置看看门狗的计数值,确定看门狗的复位时间是10秒*(unsigned int *)WTCNT_VA = 26050;// 26050/2605=10秒return 0;misc_reg_err: iounmap(WTBASE_VA);return ret;
}//蜂鸣器驱动的卸载函数
static void __exit mini210_wdt_exit(void)
{int i;//蜂鸣器驱动的卸载过程iounmap(WTBASE_VA);misc_deregister(&mini210_misc);printk("mini210 wdt driver exit....\n");
}//模块的入口和出口
module_init(mini210_wdt_init);//#insmod wdt_drv.ko-->驱动的入口
module_exit(mini210_wdt_exit);//#rmmod wdt_drv-->驱动的出口//模块的描述(驱动的描述)
MODULE_AUTHOR("bobeyfeng@163.com");
MODULE_DESCRIPTION("S5PV210 wdt Device Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("V1.0");
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>#define WDT_START  1 //看门狗打开
#define WDT_STOP   2 //看门狗关闭
#define WDT_ALIVE  3 //看门狗喂狗/**开启看门狗,10秒内喂狗,测试看门狗不复位功能,过一段时间,关闭看门狗,系统不会复位**/
int main(void)
{int fd_wdt,count=0;unsigned char wdt_cmd;fd_wdt = open("/dev/wdt_drv", O_RDWR);if(fd_wdt == -1){perror("open wdt error");return -1; }wdt_cmd = WDT_START;write(fd_wdt, &wdt_cmd , 1);//打开看门狗pirntf("wdt is starting, please keep alive in 10 second\n");while(1){sleep(8);wdt_cmd = WDT_ALIVE;write(fd_wdt, &wdt_cmd , 1);//看门狗喂狗printf("wdt keepalive \n");count++;if(count == 5)break;}wdt_cmd = WDT_STOP;write(fd_wdt, &wdt_cmd , 1);//关闭看门狗while(1){pirntf("wdt was stopped, no reset\n");sleep(1);        }   close(fd_wdt);return 0;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>#define WDT_START  1 //看门狗打开
#define WDT_STOP   2 //看门狗关闭
#define WDT_ALIVE  3 //看门狗喂狗/**开启看门狗,10秒内没有喂狗,测试自动复位功能**/
int main(void)
{int fd_wdt;unsigned char wdt_cmd;fd_wdt = open("/dev/wdt_drv", O_RDWR);if(fd_wdt == -1){perror("open wdt error");return -1; }wdt_cmd = WDT_START;write(fd_wdt, &wdt_cmd , 1);//打开看门狗pirntf("wdt is starting, please keep alive in 10 second\n");while(1){for(i=9;i>0;i--){printf("%d second\n",i);sleep(1);}printf("wdt resetting \n");}close(fd_wdt);return 0;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>#define WDT_START  1 //看门狗打开
#define WDT_STOP   2 //看门狗关闭
#define WDT_ALIVE  3 //看门狗喂狗/**开启看门狗,10秒内喂狗,测试看门狗不复位功能**/
int main(void)
{int fd_wdt;unsigned char wdt_cmd;fd_wdt = open("/dev/wdt_drv", O_RDWR);if(fd_wdt == -1){perror("open wdt error");return -1; }wdt_cmd = WDT_START;write(fd_wdt, &wdt_cmd , 1);//打开看门狗pirntf("wdt is starting, please keep alive in 10 second\n");while(1){sleep(8);wdt_cmd = WDT_ALIVE;write(fd_wdt, &wdt_cmd , 1);//看门狗喂狗printf("wdt keepalive \n");}close(fd_wdt);return 0;
}

Linux高级应用(十四)看门狗的驱动设计相关推荐

  1. 【分析笔记】Linux gpio_wdt.c 看门狗设备驱动源码分析

    基本原理 该看门狗的设备驱动实现原理很简单,比较主要的有两点: 一.定时器喂狗 通过定时器根据配置文件配置的喂狗方式(如脉冲切换.电平切换),对指定的 gpio 进行脉冲切换或电平切换实现喂狗. 脉冲 ...

  2. i.MX 6ULL 驱动开发 十四:LED(paltform驱动框架)

    一.驱动设计思想(机制.策略.分离.分层) 驱动设计思想(机制.策略.分离.分层)_正在起飞的蜗牛的博客-CSDN博客_机制与策略分离 二.驱动开发框架 三.platform 基本概念 Linux 驱 ...

  3. 《Dreamweaver CS6 完全自学教程》笔记 第十四章:使用 CSS 设计网页

    文章目录 第十四章:使用 CSS 设计网页 14.1 CSS 样式表简介 14.2 CSS 的基本语法 14.3 伪类.伪元素以及样式表的层叠顺序 14.3.1 伪类和伪元素 14.3.2 样式表的层 ...

  4. 微服务详解(四):领域驱动设计

    微服务详解(一):概述 微服务详解(二):解决方案 微服务详解(三):设置开发环境 微服务详解(四):领域驱动设计 微服务详解(五):实现微服务 微服务详解(六):部署与测试 微服务详解(七):微服务 ...

  5. linux看门狗设备,基于Linux构建无人值守系统(看门狗)

    基于Linux构建无人值守系统(看门狗) 在各种嵌入式设备soc中基本都提供了看门狗,在很长一段时间里我对看门狗的理解就是"关掉它,不然它会找麻烦".但是当某种需求存在的时候,它又 ...

  6. 在linux返回目录并查看,Linux命令(十四) 查看工作目录文件 ls

    目录 命令简介 ls 命令是 Linux 下最常用的命令. ls 就是 list 的缩写.默认情况下 ls 命令用来打印出当前目录的清单, 如果 ls 指定其他目录,那么就会显示指定目录里的文件及其文 ...

  7. 秉火429笔记之十二 看门狗

    目录 1. 概述 2. 独立看门狗(IWDG) 3. 窗口看门狗(WWDG) 1. 概述 STM32有两个看门狗,一个是独立看门狗,另外一个是窗口看门狗,独立看门狗号称宠物狗,窗口看门狗号称警犬. 一 ...

  8. RK3399驱动开发 | 02 - 使用Linux自带的硬件看门狗驱动(SGM706B)

    一.SGM706 SGM706是一种集成微处理器的监控装置. 与使用单个集成电路或分立元件的设计相比,这种集成设计具有提高系统稳定性和准确性的优点. SGM706可以在上电.下电甚至降压断电的情况下进 ...

  9. 我的内核学习笔记9:Intel内部看门狗iTCO_wdt驱动

    本文对Intel e3800内部看门狗驱动源码进行分析. 一.概述 Intel e3800内部看门狗在手册的PCU - Power Management Controller (PMC)章节中介绍-- ...

最新文章

  1. ABAP development tools实现原理介绍
  2. 10 i lt shell的if_shell脚本----if(数字条件,字符串条件,字符串为空)
  3. 【矩阵乘法】Matrix Power Series(poj 3233)
  4. jvm 垃圾收集算法_JVM垃圾收集和优化
  5. 表格在首行,添加空行
  6. 软件工程复习提纲——第四章
  7. xcode工程间的引用,iOS静态库
  8. pycharm出现乱码
  9. Django:学习笔记(9)——用户身份认证
  10. 白话文:几个例子马上看懂typescript基础类型
  11. android 3dtouch插件,iOS-3DTouch的简单实现
  12. 小米一加等手机如何正确的刷入PixelExperience_Plus系统-完整谷歌服务
  13. jq 隔行变色(横、纵)
  14. Luma推出分布式路由器,哪里有WIFI死角放哪里
  15. 关于Connection aborted等问题的解决
  16. 性能指标:队列深度、IOPS与时延
  17. ZJNU 2448 Spiderman
  18. Python实战案例:旅游方面博文的数据分析
  19. 【TensorFlow】神经网络中间层截取、可视化中间层结果
  20. C++学习记录8:定义一个分数类Score和学生类Student

热门文章

  1. 制作属于自己的过狗菜刀:为菜刀添加接口
  2. san 备份,BCV
  3. 关于 J2Objc 编译静态库的一些问题记录
  4. 超棒的 Windows 8 Metro UI 风格框架
  5. kindeditor html5 播放,更改kindeditor编辑器,改用支持h5的video标签替换原有embed标签...
  6. [Windows][Photoshop] 透视变开形工具灰色不可选择的原因
  7. SEC文件:摩托罗拉移动为什么值得Google花124亿美元收购
  8. 2021年中国通信基建现状及重点企业:我国5G基站累计建成开通142.5万个,5G投资额达1849亿元[图]
  9. CSS/HTML 一个漂亮的用户举报页面(网址举报)样式
  10. 【读书笔记】你不知道的JavaScript(中)