字符设备控制技术
前面的学习,我们学习了驱动程序,实现程序的读写功能。现在设备还有一项更重要的功能--控制。
控制设备的函数:ioctl。
Cmd:参数是我们发送的命令,例如重启。
第三个参数:是依赖第二个,例如我们要修改波特率的值,我们就会在第三个参数传上波特率的值。当第二个不需要参数,就是空值。
前面知道,当我们系统调用read函数的时候,系统会自动调用***.read函数。上面是我们ioctl系统调用的时候,系统调用的函数版本。参数一一对应传递。
总结:我们从上面的学习read和write的内容知道,我们在程序里调用read函数,在系统会调用***_read函数,然后找在内核的相应的实现函数。Write也是一样的:write->***_write,他在内核的实现。所以现在控制程序:ioctl,对应系统的unlock_ioctl,接下来也是看系统是如何实现的。
定义命令:
系统用宏来定义命令:
我们知道类型是8位的,然后一个字母刚好是8位,一个字符例如m。
0是命令的序号,最后int是命令的类型。
通过上面知道,我们知道了如何实现。下面看程序的实现,功能:第一实现设备的重启的命令,第二是设参数。
首先是定义命令宏:memdev.h:
接着就是在mem_fops结构里添加我们的控制函数:
接下来就是我实现控制函数:
在内核的unlocked_ioctl的函数原型:
从上面我们得到:
Long mem_iotcl(struct file *filp, unsigned int cmd, unsigned long arg).我们知道里面有一个switch的选择结构。
记得是在struct结构的前面实现
运行的结果:
接下来是写个应用程序来测试一下,mem_ctl.c:
编译结果:
写好了驱动程序memdev.ko和应用程序mem_ctl,拷贝到我们的开发板:
首先是安装memdev.ko驱动并查看主设备号:
接下来创建字符设备文件:memdev0:
接下来运行我们的应用程序:
./mem_ctl执行了这个命令之后会输出:
Arg is 115200
Restart devices