A20 看门狗驱动

来源:互联网 发布:fix you知乎 编辑:程序博客网 时间:2024/06/05 11:52

任务:板子上增加了独立的复位芯片SP706S,为了在设备死机的时候重启系统。

资源:芯片使能管脚 PH13     喂狗管脚 PI16

1. 为了省事,直接在drivers/sunxi_gpio/gpio_sw.c这个文件里加了,这里有现成的操作GPIO管脚的函数例子,而且还有

    获取GPIO号的函数例子。


2. 这个驱动实际就是A20的GPIO驱动,也是一个平台总线驱动,他为每一个sys_config.fex里配置的GPIO调用probe函数创建驱动。


3. 我们先在probe函数的最后面增加这一句,以获得GPIO的号码

    printk(KERN_ERR "------gpio %s = %d\n", pdata->name, item.gpio.gpio);


4. 然后接着增加看门狗使能和喂狗定时器

   if(!strcmp("gpio_pin_10", pdata->name))

   {

          __gpio_set_value(item.gpio.gpio,1);

          printk(KERN_ERR "-------enable watchdog-------");

          init_timer(&mytimer);

          mytimer.expires = jiffies;

          mytimer.data = 0;

          mytimer.function = watchdog_timer;

          add_timer(&mytimer);

    }

    gpio_pin_10是我使用的看门狗使能的gpio名字,另外,probe函数会被执行多次,有几个gpio会执行几次,所以

    关于定时器的这几个函数一定要放到这个括号里,否则会多次初始化定时器,会出现意想不到的效果。

    其中一块板子,我在定时函数里做的打印,现象就是打印频率比我设置的时间要快的多。最后发现是因为多个定时器一起在跑。

   另一块板子,直接就内存泄露了。报这个错,Unable to handle kernel NULL pointer dereference。

   耽误了我整整3个小时时间就查这个问题。

  

5.  增加喂狗定时器函数

    #include <linux/sched.h>

    #include <linux/timer.h>

    struct timer_list mytimer;

    static dog = 0;

    void watchdog_timer(unsigned long arg)

   {

         printk(KERN_ERR "feed watchdog %d\n", dog);

         dog = ! dog;

         __gpio_set_value(217,dog);    //217为gpio编号

        mytimer.expires = jiffies+ 50;    // 500ms

        mytimer.data = 0;

        mytimer.function = watchdog_timer;

        add_timer(&mytimer);

  }


6. 下面是定时器喂狗函数的打印,可以看出,linux内核定时器的精度是相当高的。我设置的是500ms的定时器,

    通过下图的计算可以看出,误差基本在10us以内。

 

   

0 0
原创粉丝点击