赞
踩
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一下。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。