Linux高级应用(十四)看门狗的驱动设计
一、什么是看门狗定时器
看门狗是一个定时器(倒计时),有计时的功能。当看门狗的计数值减为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高级应用(十四)看门狗的驱动设计相关推荐
- 【分析笔记】Linux gpio_wdt.c 看门狗设备驱动源码分析
基本原理 该看门狗的设备驱动实现原理很简单,比较主要的有两点: 一.定时器喂狗 通过定时器根据配置文件配置的喂狗方式(如脉冲切换.电平切换),对指定的 gpio 进行脉冲切换或电平切换实现喂狗. 脉冲 ...
- i.MX 6ULL 驱动开发 十四:LED(paltform驱动框架)
一.驱动设计思想(机制.策略.分离.分层) 驱动设计思想(机制.策略.分离.分层)_正在起飞的蜗牛的博客-CSDN博客_机制与策略分离 二.驱动开发框架 三.platform 基本概念 Linux 驱 ...
- 《Dreamweaver CS6 完全自学教程》笔记 第十四章:使用 CSS 设计网页
文章目录 第十四章:使用 CSS 设计网页 14.1 CSS 样式表简介 14.2 CSS 的基本语法 14.3 伪类.伪元素以及样式表的层叠顺序 14.3.1 伪类和伪元素 14.3.2 样式表的层 ...
- 微服务详解(四):领域驱动设计
微服务详解(一):概述 微服务详解(二):解决方案 微服务详解(三):设置开发环境 微服务详解(四):领域驱动设计 微服务详解(五):实现微服务 微服务详解(六):部署与测试 微服务详解(七):微服务 ...
- linux看门狗设备,基于Linux构建无人值守系统(看门狗)
基于Linux构建无人值守系统(看门狗) 在各种嵌入式设备soc中基本都提供了看门狗,在很长一段时间里我对看门狗的理解就是"关掉它,不然它会找麻烦".但是当某种需求存在的时候,它又 ...
- 在linux返回目录并查看,Linux命令(十四) 查看工作目录文件 ls
目录 命令简介 ls 命令是 Linux 下最常用的命令. ls 就是 list 的缩写.默认情况下 ls 命令用来打印出当前目录的清单, 如果 ls 指定其他目录,那么就会显示指定目录里的文件及其文 ...
- 秉火429笔记之十二 看门狗
目录 1. 概述 2. 独立看门狗(IWDG) 3. 窗口看门狗(WWDG) 1. 概述 STM32有两个看门狗,一个是独立看门狗,另外一个是窗口看门狗,独立看门狗号称宠物狗,窗口看门狗号称警犬. 一 ...
- RK3399驱动开发 | 02 - 使用Linux自带的硬件看门狗驱动(SGM706B)
一.SGM706 SGM706是一种集成微处理器的监控装置. 与使用单个集成电路或分立元件的设计相比,这种集成设计具有提高系统稳定性和准确性的优点. SGM706可以在上电.下电甚至降压断电的情况下进 ...
- 我的内核学习笔记9:Intel内部看门狗iTCO_wdt驱动
本文对Intel e3800内部看门狗驱动源码进行分析. 一.概述 Intel e3800内部看门狗在手册的PCU - Power Management Controller (PMC)章节中介绍-- ...
最新文章
- ABAP development tools实现原理介绍
- 10 i lt shell的if_shell脚本----if(数字条件,字符串条件,字符串为空)
- 【矩阵乘法】Matrix Power Series(poj 3233)
- jvm 垃圾收集算法_JVM垃圾收集和优化
- 表格在首行,添加空行
- 软件工程复习提纲——第四章
- xcode工程间的引用,iOS静态库
- pycharm出现乱码
- Django:学习笔记(9)——用户身份认证
- 白话文:几个例子马上看懂typescript基础类型
- android 3dtouch插件,iOS-3DTouch的简单实现
- 小米一加等手机如何正确的刷入PixelExperience_Plus系统-完整谷歌服务
- jq 隔行变色(横、纵)
- Luma推出分布式路由器,哪里有WIFI死角放哪里
- 关于Connection aborted等问题的解决
- 性能指标:队列深度、IOPS与时延
- ZJNU 2448 Spiderman
- Python实战案例:旅游方面博文的数据分析
- 【TensorFlow】神经网络中间层截取、可视化中间层结果
- C++学习记录8:定义一个分数类Score和学生类Student
热门文章
- 制作属于自己的过狗菜刀:为菜刀添加接口
- san 备份,BCV
- 关于 J2Objc 编译静态库的一些问题记录
- 超棒的 Windows 8 Metro UI 风格框架
- kindeditor html5 播放,更改kindeditor编辑器,改用支持h5的video标签替换原有embed标签...
- [Windows][Photoshop] 透视变开形工具灰色不可选择的原因
- SEC文件:摩托罗拉移动为什么值得Google花124亿美元收购
- 2021年中国通信基建现状及重点企业:我国5G基站累计建成开通142.5万个,5G投资额达1849亿元[图]
- CSS/HTML 一个漂亮的用户举报页面(网址举报)样式
- 【读书笔记】你不知道的JavaScript(中)