嵌入式IO驱动

上传人:lis****211 文档编号:127146594 上传时间:2022-07-29 格式:DOCX 页数:12 大小:12.76KB
收藏 版权申诉 举报 下载
嵌入式IO驱动_第1页
第1页 / 共12页
嵌入式IO驱动_第2页
第2页 / 共12页
嵌入式IO驱动_第3页
第3页 / 共12页
资源描述:

《嵌入式IO驱动》由会员分享,可在线阅读,更多相关《嵌入式IO驱动(12页珍藏版)》请在装配图网上搜索。

1、1770MM 的 ioctl 简介我这里说的ioctl函数是在驱动程序里的,因为我不知道还有没有别的场合用到了 ioctl,所以就规定了我们讨论的范围。为什么要写篇文章呢,是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑。一、什么是ioctl。ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是 对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数如下:int ioctl(int fd, ind cmd,);其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设备的控制命

2、令,至于后面的省略号,那是一些补充 参数,一般最多一个,有或没有是和cmd的意义相关的。ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函 数控制设备的I/O通道。二、ioctl的必要性如果不用ioctl的话,也可以实现对设备I/O通道的控制,但那就是蛮拧了。例如,我们可 以在驱动程序中实现write的时候检查一下是否有特殊约定的数据流通过,如果有的话,那么后 面就跟着控制命令(一般在socket编程中常常这样做)。但是如果这样做的话,会 导致代 码所以,我们就使用ioctl来分工不明,程序结构混乱,程序员自己也会头

3、昏眼花的。实现控制的功能。要记住,用户程序所作的只是通过命令码告诉驱动程序它想做什么,至于怎 么解释这些命令和怎么实现这些命令,这都是驱动程序要做的事情。三、ioctl如何实现 这是一个很麻烦的问题,我是能省则省。要说清楚它,没有四五千字是不行的,所以我这里 是不可能把它说得非常清楚了,不过如果有读者对用户程序怎么和驱动程序联系起来感兴趣的 话,可以看我前一阵子写的write的奥秘。读者只要把write换成ioctl,就知道用户程序的 ioctl是怎么和驱动程序中的ioctl实现联系在一起的了。我这里说一个大概思路,因为我觉得Linux设备驱动程序这本书已经说的非常清楚了, 但是得化一些时间来

4、看。在驱动程序中实现的ioctl函数体内,实际上是有一个switchcase 结构,每一个case对应一个命令码,做出一些相应的操作。怎么实现这些操作,这是每一个程 序员自己的事情,因为设备都是特定的,这里也没法说。关键在于怎么样组织命令码,因为在ioctl中命令码是唯一联系用户程序命令和驱动程序支持的途径。命令码的组织是有一些讲究的, 因为我们一定要做到命令和设备是一一对应的,这样才不会将正确的命令发给错误的设备, 或者是把错误的命令发给正确的设备,或者是把错误的命令发给错误的设备。这些错误都会 导致不可预料的事情发生,而当程序员发现了这些奇怪的事情的时候,再来调试程序查找错 误,那将是非常

5、困难的事情。所以在Linux核心中是这样定义一个命令码的:|设备类型|序列号|方向|数据尺寸| 8 bit | 8 bit |2 bit |814 bit|I11-|这样一来,一个命令就变成了一个整数形式的命令码。但是命令码非常的不直观,所以LinuxKernel中提供了一些宏,这些宏可根据便于理解的字符串生成命令码,或者是从命令码得 到一些用户可以理解的字符串以标明这个命令对应的设备类型、设备序列号、数据传送方向 和数据传输尺寸。这些宏我就不在这里解释了,具体的形式请读者察看Linux核心源代码中 的和,文件里给除了这些宏完整的定义。这里我只多说一个地方,那就是幻数。幻数是一 个字母,数据长

6、度也是8,所以就用一个特定的字母来标明设备类型,这和用一个数字是 一样的,只是更加利于记忆和理解。就是这样,再没有更复杂的了。更多的说了也没有,读 者还是看一看源代码吧,推荐各位阅读Linux设备驱动程序所带源代码中的short 一例, 因为它比较短小,功能比较简单,可以看明白ioctl的功能和细节。四、cmd参数如何得出这里确实要说一说,cmd参数在用户程序端由一些宏根据设备类型、序列号、传送方向、 数据尺寸等生成,这个整数通过系统调用传递到内核中的驱动程序,再由驱动程序使用解码 宏从这个整数中得到设备的类型、序列号、传送方向、数据尺寸等信息,然后通过 switchcase结构进行相应的操作

7、。要透彻理解,只能是通过阅读源代码,我这篇文章实际 上只是一个引子。Cmd参数的组织还是比较复杂的,我认为要搞熟它还是得花不少时间的, 但是这是值得的,驱动程序中最难的是对中断的理解。五、小结ioctl其实没有什么很难的东西需要理解,关键是理解cmd命令码是怎么在用户程序里生成 并在驱动程序里解析的,程序员最主要的工作量在switchcase结构中,因为对设备的I/O控制 都是通过这一部分的代码实现的。参考资料:1. Linux设备驱动程序,鲁宾尼著,中国电力出版社。2. write的奥秘要按照Linux内核的约定方法为驱动程序选择ioctl编号,应该首先 看看 include/asm/ioc

8、tl.h和 Documentation/ioctl-number.txt这两个文件。_IO(type, nr)用于构造无参数的命令编号;_IOR(type, nr, datatype)用于构造从驱动程序中读取数据的命令编号;_IOW(type, nr, datatype)用于写入数据的命令;_IOWR(type, nr, datatype)用于双向传输。返回值ioctl的实现通常就是一个基于命令号的switch语句。但是当命令 号不能匹配任何合法的操作时,默认的选择是什么呢?对于这个问题 颇有争议。有些内核函数会返回-ENVAL(Invalid argument,非法参数 ),这是合理的,因为

9、命令参数的确不是合法的参数。然而,POSIX 标准规定,如果使用了不合适的ioctl命令参数,应该返回-ENOTTY C库将这个错误码解释为“Inappropriate ioctl for device,不合适的设 备ioctl”,这看起来更贴切些。尽管如此,对非法的ioctl命令放回-EINVAL仍然时很普遍的做法。cd ioctl_testioctl_test.c#include #include #include #include #include #include #include #include ioctl_test.htypedef struct (struct class *c

10、lass;int major;char *dev_name; MODULE_DATA;static MODULE_DATA *g_module;static int test_dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)(int ret, val;switch (cmd) (case DEVICE_READ:(return put_user(10, (long *) arg);case DEVICE_WRITE:(ret = get_user(val, (long *

11、) arg);if (ret)return ret;printk(val = %dn, val);break;default:return -ENOTTYreturn 0; static int test_dev_open(struct inode *inode, struct file *file) (printk(test_dev openn);return 0;static struct file_operations test_dev_fops = (ioctl: test_dev_ioctl,open: test_dev_open,;static int _init test_dev

12、_init(void)(int res;struct class_device *temp_class;struct class *dev_class;int major;char dev_name = test_dev;g_module = kmalloc(sizeof (MODULE_DAA), GFP_KERNEL);if (g_module = NULL) (PERROR(kmalloc errorn);return -ENOMEM;memset(g_module, 0, sizeof (MODULE_DJTA);res = register_chrdev(0, dev_name, &

13、test_dev_fops);if (res major = major;g_module-class = dev_class;g_module-dev_name = dev_name;return 0;static void _exit test_dev_exit(void)(struct class *dev_class;int major;char *dev_name;dev_class = g_module-class;major = g_module-major;dev_name = g_module-dev_name;class_device_destroy(dev_class,

14、MKDEV(major, 0);class_destroy(dev_class);unregister_chrdev(major, dev_name);kfree(g_module);PINFO(test_dev driver removedn);return;module_init(test_dev_init);module_exit(test_dev_exit);MODULE_LICENSE(GPL);ioctl_test.h#ifndef MXC_CMMB_INNO_H#define MXC_CMMB_INNO_H#undef PERROR#define PERROR(fmt, args

15、.) printk(KERN_ERR cmmb drivererror: line %d- %s(): fmt,_LINE, FUNCTION_, # args)#undef PINFO#define PINFO(fmt, args.) printk(KERN_INFO fmt, # args)#undef PDEBUG/* undef it, just in case */#ifdef CMMB_INNO_DEBUG#define PDEBUG(fmt, args.) printk(KERN_DEBUG cmmb driverline %d - %s(): fmt,_LINE, FUNCTI

16、ON_, # args)#else#define PDEBUG(fmt, args.) /* not debugging: nothing */#endif#define DEVICE_READ _IOR(t, 1, int)#define DEVICE_WRITE _IOW(t, 2, int)#endifMakefileKDIR=/usr/src/linux-headers-2.6.24-19-genericobj-m += ioctl_test.oall:make -C $(KDIR) M=pwd modules clean:make -C $(KDIR) M=pwd clean cd

17、.test_ioctl.c#include #include #include #include ioctl_test/ioctl_test.h#define INNO_DEV_NAME /dev/test_devint main()(int fd, ret, get_int, put_int = 527;fd = open(INNO_DEV_NAME, O_RDWR);ret = ioctl(fd, DEVICE_READ, &get_int);if (ret 0) (perror(DEVICE_READ);return -1; else (printf(get_int = %dn, get_int);ret = ioctl(fd, DEVICE_WRITE, &put_int);if (ret 0) (perror(DEVICE_WRITE);return -1; close(INNO_DEV_NAME);

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!