linux的watchdog代码分析,linux watchdog 分析

WatchDog接口适配

1、sp805相关驱动接口

(1)sp805 支持的接口===具体芯片支持的接口

static const structwatchdog_ops wdt_ops = {

.owner =THIS_MODULE,

.start =wdt_enable,

.stop =wdt_disable,

.ping = wdt_ping,

.set_timeout =wdt_setload,

.get_timeleft =wdt_timeleft,

};

wdt->wdd.ops = &wdt_ops;

(2) watch_core支持的接口======通用框架接口

static const structfile_operations watchdog_fops = {

.owner =THIS_MODULE,

.write =watchdog_write,

.unlocked_ioctl =watchdog_ioctl,

.open =watchdog_open,

.release =watchdog_release,};

struct cdev {

struct kobject kobj;

ruct module *owner;

const structfile_operations *ops;

struct list_head list;

dev_t dev;

unsigned int count;};

cdev_init(&watchdog->cdev,&watchdog_fops);

这里对字符设备的注册,为后续open文件系统接口,提供获取具体设备的信息,后续inode通过设备文件节点号关联到cdev,从而访问驱动。

static intwatchdog_open(struct inode *inode, struct file *file)

{

int err = -EBUSY;

struct watchdog_device*wdd;

/* Get the correspondingwatchdog device */

if (imajor(inode) ==MISC_MAJOR)

wdd = old_wdd;

else

wdd =container_of(inode->i_cdev, struct watchdog_device, cdev);

…........................................

}

其中ioctl通过获取具体wdd设备,从而可以获取具体设备的功能接口,支持上层ioctl功能

static longwatchdog_ioctl(struct file *file, unsigned int cmd,

unsigned long arg)

{

struct watchdog_device*wdd = file->private_data;

void __user *argp =(void __user *)arg;

int __user *p = argp;

unsigned int val;

int err;

…..............................

}

ioctl支持的功能

case WDIOC_GETSUPPORT:

case WDIOC_GETSTATUS:

case WDIOC_GETBOOTSTATUS:

case WDIOC_SETOPTIONS:

case WDIOC_KEEPALIVE:

case WDIOC_SETTIMEOUT:

case WDIOC_GETTIMEOUT:

case WDIOC_GETTIMELEFT:

2、sp805标准实现

注意sp805标准实现:目前实现没有WDIOF_GETTIMEOUT WDIOC_GETTIMELEFT:

其中WDIOC_GETTIMELEFT操作的寄存器观察都是0

static const structwatchdog_info wdt_info = {

.options =WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,

.identity = MODULE_NAME,

};

3、测试代码:

int main(intargc, char *argv[])

{

int flags = 0;

unsigned inttime = 0;

structwatchdog_info wdgInfo;

int err = 0;

fd =open("/dev/watchdog0", O_RDWR);

if (fd == -1){

fprintf(stderr,"Watchdog device not enabled.\n");

fflush(stderr);

exit(-1);

}

if (argc >1) {

if(!strncasecmp(argv[1], "-d", 2)) {

flags =WDIOS_DISABLECARD;

ioctl(fd,WDIOC_SETOPTIONS, &flags);

fprintf(stderr,"Watchdog card disabled.\n");

fflush(stderr);

goto end;

} else if(!strncasecmp(argv[1], "-e", 2)) {

flags =WDIOS_ENABLECARD;

ioctl(fd,WDIOC_SETOPTIONS, &flags);

fprintf(stderr,"Watchdog card enabled.\n");

fflush(stderr);

goto end;

}else if (!strncasecmp(argv[1], "-settimeout", 11)) { //代码问题

time =atoi(argv[2]) ;

err =ioctl(fd, WDIOC_SETTIMEOUT, &time);

if(err <0)

{

fprintf(stderr,"settimefailed,errno is %d\n",err);

}

fprintf(stderr,"Watchdog set time %d.\n",time);

fflush(stderr);

goto end;

}else if (!strncasecmp(argv[1], "-gettimeout", 11)) { //代码问题

err =ioctl(fd, WDIOC_GETTIMEOUT, &time);

if(err <0)

{

fprintf(stderr,"gettimeout failed,errno is %d\n",err);

}

fflush(stderr);

goto end;

} elseif (!strncasecmp(argv[1], "-gettimeleft",12)) {

time = 0;

err =ioctl(fd, WDIOC_GETTIMELEFT, &time);

if( err <0)

{

fprintf(stderr,"gettimeleft failed,errno is %d\n",err);

}

fprintf(stderr,"Watchdog get time %d.\n",time);

fflush(stderr);

goto end;

} else if(!strncasecmp(argv[1], "-getsupport", 11)) {

ioctl(fd,WDIOC_GETSUPPORT, &wdgInfo);

fprintf(stderr,"Watchdog card info.\n");

fprintf(stderr,"Watchdog card is %#x, %s.\n",wdgInfo.options,wdgInfo.identity);

fflush(stderr);

goto end;

} elseif(!strncasecmp(argv[1], "-ping", 5)) {

fprintf(stderr,"ping.\n");

fprintf(stderr,"run by itself to tick the card.\n");

fflush(stderr);

goto end;

}else{

fprintf(stderr,"errorintput.\n");

fflush(stderr);

}

}

end:

close(fd);

return 0;

}

4、sp805适配问题

GetTimeout功能适配需要修改sp805和watchdog_dev.c中的代码。

IOCTl 函数:

case WDIOC_SETTIMEOUT:

if(get_user(val, p))

return-EFAULT;

err =watchdog_set_timeout(wdd, val);//这里最终只修改了wdt中的timeout,不是wdd中的timeout

pr_err("WDIOC_SETTIMEOUT errno %d,wdd->timeout %d\n",err,wdd->timeout);

if (err< 0)

returnerr;

/* Ifthe watchdog is active then we send a keepalive ping

* tomake sure that the watchdog keep's running (and if

*possible that it takes the new timeout) */

watchdog_ping(wdd);

/* Fall*/

caseWDIOC_GETTIMEOUT:

pr_err("WDIOC_GETTIMEOUT in\n");

/*timeout == 0 means that we don't know the timeout */

if (wdd->timeout == 0) //所以这里会出现问题,应该算是代码bug

return-EOPNOTSUPP;

intret=put_user(wdd->timeout, p);

pr_err("WDIOC_GETTIMEOUT %d,return ret%d\n",wdd->timeout,ret);

Sp805中剩余时间硬件寄存器为0导致GET_TIMELEFT功能不正常,可能是硬件不支持,也可能是没有配置正确,需要硬件人员提供信息,但是sp805中本省对外提供的capility也没有GET_TIMELEFT功能,暂时mark一下。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值