微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM-Linux驱动--Watch Dog Timer(看门狗)驱动分析

ARM-Linux驱动--Watch Dog Timer(看门狗)驱动分析

时间:11-20 来源:互联网 点击:
硬件平台:FL2440

内核版本:2.6.28

主机平台:Ubuntu 11,04

内核版本:2.6.39

1、看门狗驱动的原理

下图是看门狗驱动的原理图

可以看出,PCLK是系统时钟,经过8位的预分频,然后再被分频(16、32、64、128)然后产生计数脉冲,进行计数,当计数器WTCNT加到0或减到0,然后产生中断,或引起系统复位。所以要隔一段时间,重置WTCNT的值,防止WTCNT减到0,称之“喂狗”。

2、驱动分析

下面是自己的驱动分析,如有理解错误,请指正

注,为了尽量是驱动容易理解,这个驱动暂时将有关电源管理的功能删除了,等理解透彻再完善

  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #include
  10. #includeinterrupt.h>
  11. #include
  12. #include
  13. #include
  14. #include
  15. #include
  16. #undefS3C_VA_WATCHDOG
  17. #defineS3C_VA_WATCHDOG(0)
  18. #include
  19. #definePFX"s3c2410-wdt:"
  20. #defineCONFIG_S3C2410_WATCHDOG_ATBOOT(0)
  21. #defineCONFIG_S3C2410_WATCHDOG_DEFAULT_TIME(15)
  22. staticintnowayout=WATCHDOG_NOWAYOUT;
  23. staticinttmr_margin=CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME;
  24. staticinttmr_atboot=CONFIG_S3C2410_WATCHDOG_ATBOOT;
  25. staticintsoft_noboot=1;//设置默认为执行中断
  26. staticintdebug;
  27. staticintcount;//用于计数,控制LED灯的亮灭
  28. module_param(tmr_margin,int,0);
  29. module_param(tmr_atboot,int,0);
  30. module_param(nowayout,int,0);
  31. module_param(soft_noboot,int,0);
  32. module_param(debug,int,0);
  33. MODULE_PARM_DESC(tmr_margin,"Watchdogtmr_margininseconds.default="
  34. __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME)")");
  35. MODULE_PARM_DESC(tmr_atboot,
  36. "Watchdogisstartedatboottimeifsetto1,default="
  37. __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT));
  38. MODULE_PARM_DESC(nowayout,"Watchdogcannotbestoppedoncestarted(default="
  39. __MODULE_STRING(WATCHDOG_NOWAYOUT)")");
  40. MODULE_PARM_DESC(soft_noboot,"Watchdogaction,setto1toignorereboots,0to\
  41. reboot(defaultdependsonONLY_TESTING)");
  42. MODULE_PARM_DESC(debug,"Watchdogdebug,setto>1fordebug,(default0)");
  43. typedefenumclose_state
  44. {
  45. CLOSE_STATE_NOT,
  46. CLOSE_STATE_ALLOW=0x4021
  47. }close_state_t;
  48. staticunsignedlongopen_lock;
  49. staticstructdevice*wdt_dev;/*platformdeviceattachedto*/
  50. staticstructresource*wdt_mem;//用来保存IO端口占用的内存资源
  51. staticstructresource*wdt_irq;//保存wdt中断号
  52. staticstructclk*wdt_clock;//保存从平台获取的watchdog时钟
  53. staticvoid__iomem*wdt_base;//经过ioremap后的内存基地址
  54. staticunsignedintwdt_count;//保存向WTCNT写的计数值
  55. staticclose_state_tallow_close;
  56. staticDEFINE_SPINLOCK(wdt_lock);//定义一个自旋锁,用于资源的互斥访问
  57. /*watchdogcontrolroutines*/
  58. #defineDBG(msg...)do{\
  59. if(debug)\
  60. printk(KERN_INFOmsg);\
  61. }while(0)
  62. /*functions*/
  63. //喂狗函数,实际上是将wdt_count写入WTCNT寄存器
  64. staticvoids3c2410wdt_keepalive(void)
  65. {
  66. spin_lock(&wdt_lock);//给资源上锁
  67. writel(wdt_count,wdt_base+S3C2410_WTCNT);//写WTCNT寄存器
  68. spin_unlock(&wdt_lock);//解锁资源,下同
  69. }
  70. staticvoid__s3c2410wdt_stop(void)
  71. {
  72. unsignedlongwtcon;
  73. wtcon=readl(wdt_base+S3C2410_WTCON);
  74. wtcon&=~(S3C2410_WTCON_ENABLE|S3C2410_WTCON_RSTEN);
  75. writel(wtcon,wdt_base+S3C2410_WTCON);//设备看门狗使能无效、复位功能无效
  76. }
  77. //停止watchdog计时
  78. staticvoids3c2410wdt_stop(void)
  79. {
  80. spin_lock(&wdt_lock);
  81. __s3c2410wdt_stop();
  82. spin_unlock(&wdt_lock);
  83. }
  84. //启动watchdog计时
  85. staticvoids3c2410wdt_start(void)
  86. {
  87. unsignedlongwtcon;
  88. spin_lock(&wdt_lock);
  89. __s3c2410wdt_stop();
  90. wtcon=readl(wdt_base+S3C2410_WTCON);
  91. wtcon|=S3C2410_WTCON_ENABLE|S3C2410_WTCON_div128;//看门狗定时器使能、时钟除数因子128
  92. if(soft_noboot)//使用参数soft_noboot来选择看门狗到时是重启还是执行中断函数
  93. {
  94. wtcon|=S3C2410_WTCON_INTEN;//中断使能
  95. wtcon&=~S3C2410_WTCON_RSTEN;//复位功能无效
  96. }
  97. else
  98. {
  99. wtcon&=~S3C2410_WTCON_INTEN;//中断不使能
  100. wtcon|=S3C2410_WTCON_RSTEN;//复位功能有效
  101. }
  102. writel(wdt_count,wdt_base+S3C2410_WTDAT);//将wdt_count写入WTDAT
  103. writel(wdt_count,wdt_base+S3C2410_WTCNT);//将wdt_count写入WTCNT
  104. writel(wtcon,wdt_base+S3C2410_WTCON);//设置WTCON
  105. spin_unlock(&wdt_lock);
  106. }
  107. //设置WatchDog周期timeout
  108. staticints3c2410wdt_set_hea

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top