kernel 中ioctl应用

来源:互联网 发布:windows编程入门视频 编辑:程序博客网 时间:2024/05/29 08:54

ioctl是操作非文件类型的设备的一个常用方法,同时也是调试过程一个很有用的方式。

这里还是承接wdt的那篇来继续

static long at91_wdt_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
int new_value;


switch (cmd) {
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &at91_wdt_info,
sizeof(at91_wdt_info)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
return put_user(0, p);
case WDIOC_SETOPTIONS:
if (get_user(new_value, p))
return -EFAULT;
if (new_value & WDIOS_DISABLECARD)
at91_wdt_stop();
if (new_value & WDIOS_ENABLECARD)
at91_wdt_start();
return 0;
case WDIOC_KEEPALIVE:
at91_wdt_reload();/* pat the watchdog */
return 0;
case WDIOC_SETTIMEOUT:
if (get_user(new_value, p))
return -EFAULT;
if (at91_wdt_settimeout(new_value))
return -EINVAL;
/* Enable new time value */
at91_wdt_start();
/* Return current value */
return put_user(wdt_time, p);
case WDIOC_GETTIMEOUT:
return put_user(wdt_time, p);
default:
return -ENOTTY;
}
}

这里先定义两个一个最底层的被调用接口,在这里面初始化了几个命令,这些命令就可以直接调用你自己的底层函数了

之后面临的就是怎么让这个ioctl被上层可一调用  

这里有一个系统设置的结构体

static const struct file_operations at91wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.unlocked_ioctl= at91_wdt_ioctl,
.open = at91_wdt_open,
.release = at91_wdt_close,
.write = at91_wdt_write,
};

把ioctl赋给unlocked  

再把这个结构体赋给miscdevice结构体   这里就可以看出来他是一个杂项设备  不是block  或者字符设备了

static struct miscdevice at91wdt_miscdev = {
.minor = WATCHDOG_MINOR,
.name = "watchdog",
.fops = &at91wdt_fops,
};

这里再把它注册给系统就好了

static int __devinit at91wdt_probe(struct platform_device *pdev)
{
int res;


if (at91wdt_miscdev.parent)
return -EBUSY;
at91wdt_miscdev.parent = &pdev->dev;


res = misc_register(&at91wdt_miscdev);
if (res)
return res;


printk(KERN_INFO "AT91 Watchdog Timer enabled (%d seconds%s)\n",
wdt_time, nowayout ? ", nowayout" : "");
return 0;
}

上面就是这个设备备注测时的调用   可以看到开始就把这个ioctl的父结构体赋给系统了 

后面系统的上层就可以看到这个函数了    就可以一层层的穿到驱动来了

0 0