ioctl作为linux userspace 与kernel space交互的一种方式,其基于一dev id序列号去使用。一般做法步骤:
Kernel 部分的实现方式:
1, 建立device 设备。
2, 为该device设备绑定file_operation操作[struct file_operations ]为比较关键的操作。
基本结构体函数:
- 注册设备驱动。
- #define CDD_MAJOR (256)
- #define CDD_MINOR (0)
- #defein CDD_COUNT (6)
-
<ol start="1" class="dp-objc" style="padding: 0px; border: none; list-style-position: initial; list-style-image: initial; color: rgb(92, 92, 92); font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 26px; margin: 0px 0px 1px 45px !important;"><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; background-color: rgb(248, 248, 248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"><span class="keyword" style="margin: 0px; padding: 0px; border: none; color: rgb(0, 102, 153); background-color: inherit; font-weight: bold;">struct</span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> file_operations cdd_fops = { </span></span></li><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> <span class="xcodeconstants" style="margin: 0px; padding: 0px; border: none; background-color: inherit;">.owner</span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> = THIS_MODULE, </span></span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; background-color: rgb(248, 248, 248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> <span class="xcodeconstants" style="margin: 0px; padding: 0px; border: none; background-color: inherit;"><u>.open</u></span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"><u> = cdd_open,</u> </span></span></li><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> <span class="xcodeconstants" style="margin: 0px; padding: 0px; border: none; background-color: inherit;">.read</span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> = cdd_read, </span></span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; background-color: rgb(248, 248, 248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> <span class="xcodeconstants" style="margin: 0px; padding: 0px; border: none; background-color: inherit;">.write</span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> = cdd_write, </span></span></li><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> <span class="xcodeconstants" style="margin: 0px; padding: 0px; border: none; background-color: inherit;"><u>.ioctl</u></span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"><u> = cdd_ioctl, </u> </span></span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; background-color: rgb(248, 248, 248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> <span class="xcodeconstants" style="margin: 0px; padding: 0px; border: none; background-color: inherit;">.release</span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> = cdd_release, </span></span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; background-color: rgb(248, 248, 248); line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> <u>.mmap = cdd_mmap</u></span></span></li><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> }; </span></li></ol>
-
<span style="background-color: inherit; color: black; line-height: 18px; font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px;"></span><pre class="SCREEN" name="code" style="background-color: rgb(255, 255, 255); white-space: pre-wrap; word-wrap: break-word; color: rgb(51, 51, 51); font-size: 14px; line-height: 26px;"><span class="comment" style="background-color: inherit; line-height: 18px; font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; margin: 0px; padding: 0px; border: none; color: rgb(0, 130, 0);">//生成设备号</span><span style="background-color: inherit; color: black; line-height: 18px; font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; margin: 0px; padding: 0px; border: none;"> </span>
-
<span style="background-color: inherit; color: black; font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; line-height: 18px;">dev = MKDEV(CDD_MAJOR, CDD_MINOR);</span>
- //注册设备号;1、要注册的起始设备号2、连续注册的设备号个数3、名字
- ret = register_chrdev_region(dev, CDD_COUNT, "cdd_demo");
- /*初始化cdev,绑定fs operation*/
- cdev_init(&cdd_cdev, &cdd_fops);
- /*添加cdev到内核*/
- cdev_add(&cdd_cdev, dev, CDD_COUNT);
-
user space的使用方式:
通过上面就创建了一个设备驱动,且对该设备驱动绑定了相应文件操作方式。 那user space怎么去使用该设备驱动。
- #define DEV "/dev/cdd_demo"
- fb = open(DEV,O_RDWR) ; ->其实际运行到kernel调用的就是注册设备cdd_fops.open函数。
- ioctl(fb,xxxx) ; ->其实际运行到kernel调用的就是注册设备cdd_fops.ioctl函数。
- mmap(xxx,fb,xx);->其实际运行到kernel 调用的注册设备cdd_fops.mmap函数。
经过上面的描述,关于通过dev去控制相应kernel操作,注意如下几点:
1,确定user space需要做哪些必要操作,且需要对这些必要的操作做一些定制化需求。那么就需要实现file_operations对应的接口函数,否则
其会使用默认的定义形式。
2,driver 部分创建device,并且去初始化该部分。
3,确定了1,2部分就可以正常使用ioctl这些函数操作:
1)通过device file去控制ioctl部分。
2)mmap的使用中,建立
map关系,这样子对user来说,直接写到user buffer,其就将数据自动sync到kernel buffer。同样对kernel
buffer的数据操作也会自动sync到user space的buffer,这样子减少了user space与kernel space的不断copy动作,对频繁数据访问的
driver来讲是高效的。且一般使用中为了让driver去更好的操作指定内存,一般回去客制化,mmap,指定一块特定的buffer空间让其使用。
Reference:
具体使用方法链接:
http://www.linuxidc.com/Linux/2013-04/83307.htm(对GPIO的控制方法)
参数定义链接:http://blog.csdn.net/styyzxjq2009/article/details/8023501