Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1254136
  • 博文数量: 479
  • 博客积分: 12240
  • 博客等级: 上将
  • 技术积分: 4999
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-24 17:12
文章分类

全部博文(479)

文章存档

2014年(1)

2013年(1)

2012年(1)

2011年(95)

2010年(177)

2009年(167)

2008年(16)

2007年(21)

分类: 嵌入式

2009-10-14 20:58:59

U-Boot HW Watchdog


概述

include/watchdog.h文件中有宏定义
#ifdef CONFIG_HW_WATCHDOG
        #if defined(__ASSEMBLY__)
                #define WATCHDOG_RESET bl hw_watchdog_reset
        #else
                extern void hw_watchdog_reset(void);

                #define WATCHDOG_RESET hw_watchdog_reset
        #endif /* __ASSEMBLY__ */
#else


所以,需要打开CONFIG_HW_WATCHDOG开关以及实现hw_watchdog_reset喂狗函数。



首先在include/configs/abing2440.h文件中打开CONFIG_HW_WATCHDOG
#define CONFIG_HW_WATCHDOG 1

然后在board/zhiyuan/abing2440/abing2440.c文件中实现喂狗函数hw_watchdog_reset
喂狗使用GPG7,
    需要设置为输出模式:GPGCON[15:14] = 01
    使能内部上拉:         GPGUP[7]   = 0

        gpio->GPGCON = 0xFF957F3A;
        gpio->GPGUP = 0x0000FF7F;


#ifdef CONFIG_HW_WATCHDOG
void hw_watchdog_reset(void)
{
        S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
        int i;

        gpio->GPGDAT |= 1<<7;

        for (i=100; i>0; i--);

        gpio->GPGDAT = gpio->GPGDAT & (~(1<<7));
}
#endif





另外,为了在其它地方调用WATCHDOG_RESET函数,可以将watchdog.h添加包含到common.h文件中:

//#if defined (CONFIG_HW_WATCGDOG)   //为何不能要这句????

#include

//#endif



然后进行调试,在合适的地方加入喂狗语句:
WATCHDOG_RESET();

U-Boot默认已经加入和很多喂狗函数,但是一些地方是没有喂狗的,比如NAND的驱动就没有加入喂狗的操作。

喂狗历程

(1)加上看门狗后,可以运行到NAND检测的地方:
U-Boot 1.3.4
DRAM:  64 MB
Flash:  2 MB
NAND:                     <--------------------------

跟踪到了drivers/mtd/nand/nand.c文件的nand_init函数:
void nand_init(void)
{
        int i;
        unsigned int size = 0;

        WATCHDOG_RESET();//ABING

        for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
                nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]);
                size += nand_info[i].size;
                if (nand_curr_device == -1)
                        nand_curr_device = i;
        }
        printf("%u MiB\n", size / (1024 * 1024));
......

}
 
应该进入到nand_init_chip函数(drivers/mtd/nand/nand.c)中喂狗:
static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
                           ulong base_addr)
{
        WATCHDOG_RESET();//ABING
        mtd->priv = nand;

        nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr;
        if (board_nand_init(nand) == 0) {
                if (nand_scan(mtd, 1) == 0) {
                        if (!mtd->name)
                                mtd->name = (char *)default_nand_name;
                } else
                        mtd->name = NULL;
        } else {
                mtd->name = NULL;
                mtd->size = 0;
        }

}

依然在NAND处复位,看来得进入board_nand_init中喂狗。

board_nand_init函数在cpu/arm920t/s3c24x0/nand.c文件中实现,没有长时间的操作,看来得进入nand_scan了。


在rivers/mtd/nand/nand_base.c文件的nand_scan函数末尾喂狗:
nand_scan(........) {
........
        WATCHDOG_RESET();//ABING
        /* Build bad block table */
        return this->scan_bbt (mtd);
}

依然停在NAND这个地方,看来只有scan_bbt了。
scan_bbt很费时间,扫描坏块,个人觉得在bootloader阶段没有必要扫描,将最后一句直接改为return 0;减少喂狗操作,更加节省启动时间。


写NOR FLASH超时复位:
Writing data at 0x1ce800 -- 100% complete.
 1896348 bytes written: OK
Saving Environment to Flash...
Un-Protected 1 sectors
Erasing Flash...Erasing sector  4 ... ok.
Erased 1 sectors
Writing to Flash...           <---------------------------

文件common/env_flash.c中。

进入到U-Boot命令提示符,如果不输入字符也会超时复位。


至此,U-Boot的喂狗暂时到这里,转而进行内核喂狗。

阅读(2170) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~