snifer

[原创]Blackfin ADSP BF561 Watch Dog定时器精析

0
阅读(3886)

BF561这个强大地ADSP处理芯片中,有一个非常重要的看门狗定时器,针对我在Linux对这个部件的使用情况,给大家做个分析。使用这个部件主要用Visual DSP++这个工具.

实现:设计一个WatchDog驱动与应用程序,每10秒去喂狗一次,watchdog timeout时间小于1分钟。

1 WatchDog驱动程序需要的库文件

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

2 WatchDog初始参数的设置

//WTCON

#define BLACKFIN_WTCON_PRESCALER(x) (x <<8) // x= 0 - 255

#define BLACKFIN_WTCON_ENABLE 0x0020

#define BLACKFIN_WTCON_CLOCK(x) (x<<3) // x = 0, 1, 2, 3

#define BLACKFIN_WTCON_INTEN 0x0004

#define BLACKFIN_WTCON_RESET 0x0001

//WTDAT

#define BLACKFIN_WTDAT_COUNT 0xFFFF

//WTCNT

#define BLACKFIN_WTCNT_COUNT 0xFFFF

static int timer_alive;

static u8 soft_margin = 44; // in seconds timeout value (0, 44) seconds

3 WatchDog设置函数

void Blackfin_wdt_config(void)

{

//_reg_CRM_PCCR1 |= 0x01000000; //enable clk gate to watchdog

WTCON &= ~BLACKFIN_WTCON_ENABLE;

WTDAT = BLACKFIN_WTDAT_COUNT;

WTCNT = BLACKFIN_WTCNT_COUNT;

WTCON = BLACKFIN_WTCON_PRESCALER(255) | // set prescaler value

BLACKFIN_WTCON_ENABLE | // watchdog timer enable

BLACKFIN_WTCON_CLOCK(3) | // set clock divider value

BLACKFIN_WTCON_INTEN | // watchdog timer interrupt enable

BLACKFIN_WTCON_RESET; // watchdog timer reset enable

}

4 Watchdog的read函数

static ssize_t Blackfin_wdt_write(struct file *file, const char *buf, size_t len, loff_t *ppos)

{

//Refresh the timer.

if (len) {

Blackfin_wdt_config();

return 1;

}

return 0;

}

5 Watchdog的ioctl函数

static int Blackfin_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)

{

int new_margin;

switch(cmd) {

case WDIOC_KEEPALIVE:

Blackfin_wdt_config();

return 0;

case WDIOC_SETTIMEOUT:

if (get_user(new_margin, (int *)arg))

return -EFAULT;

if (new_margin < 0)

return -EINVAL;

if (new_margin > 44)

new_margin = 44;

//soft_margin = new_margin;

return 0;

case WDIOC_GETTIMEOUT:

return put_user(soft_margin, (int *)arg);

default:

return -ENOTTY;

}

}

6 Watchdog的open函数

static int Blackfin_wdt_open(struct inode *inode, struct file *file)

{

int ret;

if (timer_alive)

return -EBUSY;

ret = request_irq(IRQ_WDT, Blackfin_wdt_interrupt, SA_INTERRUPT, "Blackfin-watchdog", NULL);

if (ret) {

printk(KERN_ERR "watchdog: can't request irq: %d \n", INT_WDOG);

return ret;

}

Blackfin_wdt_config();

MOD_INC_USE_COUNT;

timer_alive = 1;

return 0;

}

6 Watchdog的release函数

static int Blackfin_wdt_release(struct inode *inode, struct file *file)

{

lock_kernel();

free_irq(INT_WDOG, NULL);

timer_alive = 0;

unlock_kernel();

MOD_DEC_USE_COUNT;

return 0;

}

7 Watchdog的fops结构体

static struct file_operations Blackfin_wdt_fops = {

owner: THIS_MODULE,

write: Blackfin_wdt_write,

ioctl: Blackfin_wdt_ioctl,

open: Blackfin_wdt_open,

release: Blackfin_wdt_release,

};

掌握了这些我们在使用看门狗的时候才会得心应手,堪称ADI利器。

Baidu
map