(十一)1 简单的看门狗驱动

来个简单的看门狗驱动——静态平台类的杂设备看门狗驱动,有定时和重启两个基本功能。一、S3C2440中的看门狗——具体请看s3c2440文档看门狗应该可以算是S3C2440中最简单的一个设备的,仅仅只有三个寄存器需要配置。S3C2440中的看门狗有两种功能(只能二选一):1、复位功能,在指定时间内,如果没有执行喂狗操作。指定时间到达后会执行系统重启操作
摘要由CSDN通过智能技术生成

来个简单的看门狗驱动——静态平台类的杂设备看门狗驱动,有定时和重启两个基本功能


一、S3C2440中的看门狗——具体请看s3c2440文档


看门狗应该可以算是S3C2440中最简单的一个设备的,仅仅只有三个寄存器需要配置。S3C2440中的看门狗有两种功能(只能二选一):

1、复位功能,在指定时间内,如果没有执行喂狗操作。指定时间到达后会执行系统重启操作。

2、定时功能,每隔指定的时间,看门狗就会往处理器发送中断,执行中断处理函数。


接下来就要看看控制看门狗的三个寄存器:

1、控制寄存器——WTCON

首先要看看分频系数Prescaler value[15:8]和时钟分频Clock select[4:3]。看门狗的时钟频率就是通过这两个值分频得出的:

t_watchdog = 1/[ PCLK / (Prescaler value + 1) / Division_factor ]

每个(1/t_watchdog)秒,看门狗计数器减一。

Watchdog timer[5]是看门狗的是能控制位,初始化时必须将此为置一,不然看门狗无法操作。

Interrupt generation[2]是控制中断的产生,如果你使用看门狗来执行定时功能,置一代表使能看门狗产生中断,反之不产生中断。

Reset enable/disable[0]用控制看门狗是否复位,如果置一,代表当时间到达后系统重启。


2、数据寄存器WTDAT和计数寄存器WTCNT


这两个都是用于存放16位数据的寄存器。

1、如果是复位模式,从WTCON[5]置一开始,每隔(1/t_watchdog)秒,WTCNT中的值减一,直到WTCNT0,系统就会复位。在WTCNT还没有为0前,可以重新往WTCNT中赋值,这样WTCNT就会从新的数值开始减一,这就是所谓的喂狗操作,重复地在WTCNT0前喂狗,就可以让系统不复位。

2、如果是定时模式, 从WTCON[5]置一开始,每隔(1/t_watchdog)秒,WTCNT中的值减一,直到WTCNT0,看门狗往处理器发送中断信号,并自动将WTDAT赋值给WTCNT,让WTCNT重新开始减一。这样的重复操作就实现了看门狗的定时。

注意:不管是哪一种模式,一开始时看门狗都不会将WTDAT的值赋给WTCNT,都是直接以WTCNT的值开始计数。所以,在是能看门狗之前,必须先设备WTCNT的值,指定时间长短。


接下来的程序我需要的时间间隔是1秒,所以,Prescaler value[15:8]我赋值为99Clock select[4:3]我赋值为128S3C2440中的PCLK定义为50000000,通过公式可以计算出:

t_watchdog = 1/[ PCLK / (Prescaler value + 1) / Division_factor ] = 3906.25

所以,看门狗的计数间隔是(1/3906.25)秒,1秒需要计数大约3906


看门狗介绍完毕,接着就开始写驱动了,在写驱动前贴张之前我介绍过的图,我写驱动的步骤:

接在来我就会按这个顺序来写个简单的看门狗驱动,实现看门狗的两种功能,定时和复位。


二、第一个看门狗程序


写驱动前先要写一些基本的操作代码,检验一下该设备是否能正常工作。


第一个看门狗程序做了三步,简单实现了看门狗的复位操作:

1、定义了一个维护看门狗数据的结构体:

9 struct _wdt_t {

10      unsigned long phys, virt; //存放物理地址和对应的虚拟地址

11     unsigned long wtcon, wtdat, wtcnt; //存放寄存器

12     unsigned long reg;

13

14     void (*init_reset)(struct _wdt_t *); //操作看门狗的函数指针

15 };

2、实现了看门狗的复位操作:

19 static void s3c_wdt_init_reset(struct _wdt_t *wdt)

20 {

21     iowrite32((int)(WDT_1S * 10), wdt->wtdat); //其实这个不设置也可以

22     iowrite32((int)(WDT_1S * 10), wdt->wtcnt); //设置10秒后系统复位

23     iowrite32(0x6339, wdt->wtcon); //设置wtcon寄存器为0x6339,使能了看门狗和复位功能

24 }

3、封装了设备的初始化和注销函数:

26 int init_wdt_device(struct _wdt_t *wdt)

27 {

28     int ret = 0;

29     //ioremap

30     wdt->phys = 0x53000000;

31     wdt->virt = (unsigned long)ioremap(wdt->phys, 0x0c);

32      wdt->wtcon = wdt->virt + 0x0;

33      wdt->wtdat = wdt->virt + 0x4;

34      wdt->wtcnt = wdt->virt + 0x8;

35

36     //function

37      wdt->init_reset = s3c_wdt_init_reset;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的uboot看门驱动的示例代码: 1. 首先,在uboot目录下的include/configs/目录下添加一个新的配置文件(例如:myboard.h),并在其中添加以下宏定义: #define CONFIG_HW_WATCHDOG #define CONFIG_HW_WATCHDOG_TIMEOUT_MS 10000 //看门超时时间为10秒 2. 在uboot目录下的drivers/watchdog/目录下添加一个新的文件(例如:myboard_wdt.c),并添加以下代码: #include <common.h> #include <watchdog.h> #define WDT_BASE_ADDR 0x10000000 //看门控制器的基地址 #define WDT_CR 0x00 //看门控制寄存器 static void myboard_reset_watchdog(void) { writel(0x1, WDT_BASE_ADDR + WDT_CR); //重置看门计数器 } static int myboard_init_wdt(void) { writel(CONFIG_HW_WATCHDOG_TIMEOUT_MS * 2, WDT_BASE_ADDR + WDT_CR); //设置看门超时时间 writel(0x3, WDT_BASE_ADDR + WDT_CR); //使能看门 return 0; } static const struct watchdog_ops myboard_wdt_ops = { .start = myboard_init_wdt, .reset = myboard_reset_watchdog, }; U_BOOT_DEVICE(myboard_wdt) = { .name = "myboard_wdt", .ops = &myboard_wdt_ops, }; 3. 在uboot目录下的common/board_f.c文件中添加以下代码: #ifdef CONFIG_HW_WATCHDOG extern void watchdog_init(void); void watchdog_init(void) { watchdog_register_device(&myboard_wdt); } #endif 4. 编译uboot,并将生成的u-boot.bin烧写到开发板中。现在,uboot就支持看门了,当uboot在指定的时间内没有收到喂信号时,开发板将会自动重启。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值