附录一、驱动程序:at91sam9g20核心板的看门狗驱动看门狗的驱动一般来说比较简单,只要做寄存器的设置实现开启、关闭、喂狗功能。
本项目中我们使用的是at91sam920处理器,带有看门狗定时器。
这个看门狗的驱动却比较复杂,应用层想用它的话,将涉及到boot引导设置,uboot配置及驱动,改写驱动程序。
下面将逐步说明。
1、boot引导(bootstrap-v1.15)由于该看门狗的MR寄存器只能写一次(Only a processor reset resets it.),而默认情况下看门狗在boot引导程序中被关闭了,所以在boot引导程序中我们要开启看门狗。
在board/at91sam9g20ek/at91sam9g20ek.c文件的硬件初始化函数hw_init中注释掉下面的配置即可开启看门狗:/* writel(AT91C_WDTC_WDDIS, AT91C_BASE_WDTC + WDTC_WDMR); */为了功能设置:我们配置如下:writel(AT91C_WDTC_WDV | AT91C_WDTC_WDD | AT91C_WDTC_WDRSTEN | AT91C_WDTC_WDFIEN, AT91C_BASE_WDTC + WDTC_WDMR);2、uboot配置及驱动(uboot-v1.3.4):默认情况下,看门狗在uboot中没有配置,需要手动添加配置,在文件include/configs/at91sam9g20ek.h中添加如下配置#define CONFIG_HW_WA TCHDOG 1#define CONFIG_AT91SAM9_WA TCHDOG 1此时编译uboot,会提示你找不到hw_watchdog_reset复位函数,这是因为虽然我们配置看门狗,但看门狗的uboot驱动并不存在,下面就来添加uboot下的看门狗驱动。
1)添加include/asm-arm/arch-at91sam9/at91_wdt.h,内容如下/** [origin: Linux kernel arch/arm/mach-at91/include/mach/at91_wdt.h]** Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD <plagnioj at >* Copyright (C) 2007 Andrew Victor* Copyright (C) 2007 Atmel Corporation.** Watchdog Timer (WDT) - System peripherals regsters.* Based on AT91SAM9261 datasheet revision D.** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.*/#ifndef AT91_WDT_H#define AT91_WDT_H#define AT91_WDT_CR (AT91_WDT + 0x00) /* Watchdog Control Register */ #define AT91_WDT_WDRSTT (1<<0) /* Restart */#define AT91_WDT_KEY (0xa5 << 24) /* KEY Password */#define AT91_WDT_MR (AT91_WDT + 0x04) /* Watchdog Mode Register */ #define AT91_WDT_WDV (0xfff << 0) /* Counter Value */#define AT91_WDT_WDFIEN (1 << 12) /* Fault Interrupt Enable */#define AT91_WDT_WDRSTEN (1 << 13) /* Reset Processor */#define AT91_WDT_WDRPROC (1 << 14) /* Timer Restart */#define AT91_WDT_WDDIS (1<< 15) /* Watchdog Disable */#define AT91_WDT_WDD (0xfff << 16) /* Delta Value */#define AT91_WDT_WDDBGHLT (1 << 28) /* Debug Halt */#define AT91_WDT_WDIDLEHLT (1 << 29) /* Idle Halt */#define AT91_WDT_SR (AT91_WDT + 0x08) /* Watchdog Status Register */#define AT91_WDT_WDUNF (1 << 0) /* Watchdog Underflow */#define AT91_WDT_WDERR (1 << 1) /* Watchdog Error */#endif2)添加drivers/watchdog/at91sam9_wdt.c,内容如下/** [origin: Linux kernel drivers/watchdog/at91sam9_wdt.c]** Watchdog driver for Atmel AT91SAM9x processors.** Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD <plagnioj at > * Copyright (C) 2008 Renaud CERRATO r.cerrato at til-technologies.fr** This program is free software; you can redistribute it and/or* modify it under the terms of the GNU General Public License* as published by the Free Software Foundation; either version* 2 of the License, or (at your option) any later version.*//** The Watchdog Timer Mode Register can be only written to once. If the * timeout need to be set from U-Boot, be sure that the bootstrap doesn't * write to this register. Inform Linux to it too*/#include <common.h>#include <watchdog.h>#include <asm/arch/hardware.h>#include <asm/arch/io.h>#include <asm/arch/at91_wdt.h>//#include <asm-arm/arch-at91sam9/at91_wdt.h>#define ms_to_ticks(t) (((t << 8) / 1000) - 1)#define ticks_to_ms(t) (((t + 1) * 1000) >> 8)/* Hardware timeout in seconds */#define WDT_HW_TIMEOUT 2/** Set the watchdog time interval in 1/256Hz (write-once)* Counter is 12 bit.*/static int at91_wdt_settimeout(unsigned int timeout){unsigned int reg;unsigned int mr;/* Check if disabled */mr = at91_sys_read(AT91_WDT_MR);if (mr & AT91_WDT_WDDIS){printf("sorry, watchdog is disabled/n");return -1;}/** All counting occurs at SLOW_CLOCK / 128 = 256 Hz** Since WDV is a 12-bit counter, the maximum period is* 4096 / 256 = 16 seconds.*/reg = AT91_WDT_WDRSTEN /* causes watchdog reset *//* | AT91_WDT_WDRPROC causes processor reset only */| AT91_WDT_WDDBGHLT /* disabled in debug mode */| AT91_WDT_WDD /* restart at any time */| (timeout & AT91_WDT_WDV); /* timer value */at91_sys_write(AT91_WDT_MR, reg);return 0;}void hw_watchdog_reset(void){at91_sys_write(AT91_WDT_CR,A T91_WDT_KEY | AT91_WDT_WDRSTT); }void hw_watchdog_init(void){/* 16 seconds timer, resets enabled */at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000));}3)添加drivers/watchdog/Makefile## (C) Copyright 2008# Wolfgang Denk, DENX Software Engineering, wd at denx.de.## See file CREDITS for list of people who contributed to this# project.## This program is free software; you can redistribute it and/or# modify it under the terms of the GNU General Public License as# published by the Free Software Foundation; either version 2 of# the License, or (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY W ARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston,# MA 02111-1307 USA#include $(TOPDIR)/config.mkLIB := $(obj)libwatchdog.aCOBJS-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.oCOBJS := $(COBJS-y)SRCS := $(COBJS:.o=.c)OBJS := $(addprefix $(obj),$(COBJS))all: $(LIB)$(LIB): $(obj).depend $(OBJS)$(AR) $(ARFLAGS) $@ $(OBJS)######################################################################### # defines $(obj).depend targetinclude $(SRCTREE)/rules.mksinclude $(obj).depend######################################################################### 4)修改uboot的Makefile,主要是把watchdog编辑到工程里修改1:LIBS += drivers/video/libvideo.a+LIBS += drivers/watchdog/libwatchdog.a(添加)LIBS += common/libcommon.a修改2:TAG_SUBDIRS += drivers/usbTAG_SUBDIRS += drivers/video+TAG_SUBDIRS += drivers/watchdog (添加)5)另外,为了在其它地方调用WA TCHDOG_RESET函数,可以将watchdog.h添加包含到include/common.h文件中:#if defined (CONFIG_HW_WATCHDOG)#include <watchdog.h>#endif6)修改串口驱动drivers/serial/atmel_usart.c,主要是在串口读的时候复位看门狗,防止系统重启int serial_getc(void){- while (!(usart3_readl(CSR) & USART3_BIT(RXRDY))) ; (删除)+ while (!(usart3_readl(CSR) & USART3_BIT(RXRDY))) (添加)+ WATCHDOG_RESET(); (添加)return usart3_readl(RHR);}3、改写驱动程序(linux2.6.30内核)1、配置内核在默认情况,系统并不加载看门狗驱动,需要配置内核:make menuconfigDevice drivers-->Watchdog Timer Support-->AT91SAM9X / A T91CAP9 watchdog 然后编译,重新烧写uImage文件到板子上。