A20 看门狗驱动
任務:板子上增加了獨立的復位芯片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以內。
?
???
總結
- 上一篇: 股市蒸发了好几个亿是什么意思?蒸发的钱去
- 下一篇: 京广高铁京武段350公里时速暂不实行?国