Do not panic!
分类: LINUX
2016-03-25 19:51:25
原文地址:看门狗驱动的实现-基于hi3510 作者:caicai0119
1系统简介
基于hi3510的嵌入式DVR
看门狗芯片:pt
2 uboot
uboot阶段hi3510运行在实模式,所以喂狗的代码较为简单。
定义喂狗函数:
/**in file watchdog.c**/
int watchdog_state=0;
void reset_pt7m_watchdog()
{
*(unsigned char*)(0x101E6400)|=0x40;
if(watchdog_state==0)
{
*(unsigned char*)(0x101E6100)=0x40;
watchdog_state=1;
}
else
{
*(unsigned char*)(0x101E6100)=0x00;
watchdog_state=0;
}
//puts("feed dog\n");
}
较复杂的是何时喂狗。
使用的uboot版本为:u-boot-1.1.4
在该版本中定义了宏:WATCHDOG_RESET
将该宏定义为:
#define WATCHDOG_RESET reset_pt7m_watchdog
在uboot的启动过程中,所有 define WATCHDOG_RESET()被替换为:reset_pt7m_watchdog()。
成功启动uboot。
3 kernel
加载内核映像后,uboot将cpu的控制权交给kernle。在decompress_kernel/** msic.c**/函数,解压内核,花时间较长,在此处必须喂狗。因为仍然处于实模式,所以可以使用上述代码喂狗(重新定义新的函数)。
Kernel在start_kernle会创建init线程,在init线程里创建一个内核线程,用来定期喂狗,直到用户加载看门狗驱动。线程为:ptm7m_init./**driver/char/watchdog/pt7m_wtd.c**/,同时在该文件中到处一个符号:EXPORT_SYMBOL(pt7m_wtd_state) ,在加载pt7m的驱动程序模块时结束该线程,由驱动程序收回喂狗的权利。
*最好不要在start_kernel函数创建喂狗线程。因为这样会导致init线程的pid为2,会给以后带来麻烦。
内核成功启动。
4看门驱动比较简单。
后记:最后测试阶段,发现有的板子不行,而最开始的那个开发板已不可还原。只能重新跟踪内核。最后发现,加载jffs2根文件系统时发生复位,可能是因为在sys_mount函数里/**namespace.c/调用了lock_kernel,从而使pt7m_init线程失去了调度机会。在函数jffs2_scan_medium/*scan.c*/的一个for循环消耗时间较多,导致看门狗复位。在for循环里进行喂狗。kernel成功启动。
体会:跟踪内核是一件痛苦并快乐的事。