Chinaunix首页 | 论坛 | 博客
  • 博客访问: 264868
  • 博文数量: 52
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 277
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-09 10:57
文章分类

全部博文(52)

文章存档

2016年(52)

我的朋友

分类: LINUX

2016-09-26 21:33:46

        接着上篇文章,这篇文章说一下kpad设备支持的文件操作,以及几个重要的数据结构。在这篇文章中你可以再次体会到驱动编程时固定模式占40%的意义了。

        下图是文件的打开和关闭操作,不论是打开、关闭还是读写以及定位操作,函数的参数都是固定的,不能更改的,只有函数的名字能改!
这个需要切记。
                            

          第102行函数的参数struct inode *inode 传入的是文件的一些物理信息,具体的可以参考我以前的博文,参数struct  file *file 传入的则是打开文件的一些信息,如打开方式,读写位置等。

          第104行,container_of 这是一个宏,这个宏在驱动编程中很重要,也很方便,它有三个参数,它的第二个参数和第三个参数分别是一个结构体类型的名称及它的某个成员的名称。第一个参数则要求是一个指针,指向这个类型的变量中的相应成员,返回的结构则是指向这个变量的指针。说白了,它的作用就是根据结构体变量中个一个域成员变量的指针来获取指向整个结构体变量的指针。比如此处,第二个参数结构体名称(类型)为struct kpad_dev ,第三个参数cdev为这个类型中的一个成员,而第一个参数则指向struct kpad_dev类型的变量xx中的cdev成员(可以看一下struct cdev 和结构体struct inode  struct ionde 中有一个dev_t *i_cdev指针,它是指向一个cdev的)。如何实在是理解不了就强行记住就行啦!这样就得到了指向kpad设备的一个指针。

          第107行也是一个重点:结构体struct file 中的成员 private_data的用法比较特殊,内核本身不会读写这个数据,而是预留给驱动使用的。一般来说驱动要为每个设备建立一些变量,用于保存一些必要的数据,称为设备的私有数据。这些数据可以包装成一个结构体(例如源码中的kpad_dev就是这个设备的全部信息,然后把结构体的指针赋值给private_data成员,这样就把设备数据和打开的文件联系到一起了

          在设备的其它操作里又使用别的语句获取指向kpad设备的指针如: struct kpad_dev *dev = (struct kpad_dev *)file->private_data;实际上在上述的驱动源码中,代表kpad设备的变量被定义为全局变量,因此它的指针可以直接通过&kpad来获得,在各种文件操作中之所以没这样做,是为了让这些操作函数相对独立,尽可能地少于其它源码发生关联,以提高代码的可维护性。例如要对上述的驱动程序进行修改,以同时支持多个kpad设备,则这些操作函数都可以原封不动的用于各个设备。每个设备都有自己的private_data,并且通过107行都与自己的文件打开信息相关联。
    
           截止到现在,对于三个数据结构struct file_operations (设备支持的文件操作)、struct inode(设备的物理信息) 、struct file(设备文件的一些打开的一些信息) 应该有一个很好的理解啦(包括后两个为什么作为参数)!       
         
         上图剩下的也没什么需要注意的了。下面来看下面的几个函数:

                            
                            
                            
                
        截止到目前为止驱动程序就写完了,然后再一个Makefile 就可以对驱动程序进行安装并应用了。安装之后用命令dmesg 查看内核缓冲区,看到输出信息的最后有如下图的信息:

                        

        这个并不影响模块的加载。这时你会发现一个问题,为什么pr_debug()函数中的语句没有输出?原因是函数pr_debug和函数pr_devel是一样的,它只有在定义了宏DEBUG时才起作用,否则就相当于一条空语句。这样当程序在调试时可以加上DEBUG宏定义使函数pr_debug有输出,发布时去掉就行了,函数pr_devel 也是一样的。解决方法还有一个就是把pr_debug()换成printk()这样就行了,如下图:

                        

        接着要创建设备文件了:mknod -m 666 kpad c 247 0  。

        然后就可以用命令echo 和命令cat向设备文件中输入和查看内容了。这个就不上图了。

        这个简单的驱动程序到目前为止就彻底的写完了。欢迎各位大神多指正指正!嘿嘿!


阅读(1258) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~