kernel 中ioctl應用

迷霧綠洲發表於2014-10-23

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的父結構體賦給系統了 

後面系統的上層就可以看到這個函式了    就可以一層層的穿到驅動來了

相關文章