嵌入式Linux驱动及内核模块问题总结

一、驱动程序测试

    1、在Kconfig文件中添加相应的config xxx编译选项,在Makefile中添加obj-$(CONFIG_xxx) += xx.o

          <注意上面的两个xxx是对应的,而xx需要与源文件xx.c相对应>

    2、配置好后需要先编译一遍内核和dtb文件,在make modules才能正确加载模块。<至于是跟内核有关还是跟dtb文件有关就不知道了>


二、内核驱动设备号、设备类、设备节点等的操作

    1、第一组组合

        ①、int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)

                自动分配设备号,成功返回0,失败返回小于0值。

        ②、

                a、void cdev_init(struct cdev *cdev, const struct file_operations *fops)

                       建立cdev与file_operations 之间的连接

                 b、int cdev_add(struct cdev *, dev_t, unsigned)

                       向系统添加cdev完成设备注册

         ③、

                 a、class_create( , )

                        在/sys/class下创建设备类

                  b、device_create( , , , , )

                        创建设备节点

                  <还有一组>

          ④、卸载设备采取上述相反的操作即可

                  device_destroy() =》class_destroy() =》cdev_del() =》unregister_chrdev_region()。

                  删除涉设备节点    =》  删除设备类      =》注销字符设备=》注销设备号

         

         

         

         


三、申请I/O内存函数

              request_mem_region(start, n, name)

              release_mem_region(start, n)

四、ioctl函数

              2.6.x版本后取消了ioctl(),转而用unlocked_ioctl()和compat_ioctl(),后两者区别有机会日后补充。

         1、long unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)

               ①、cmd参数介绍

                       每一个cmd命令由一个整形数据构成(32bits),将一个命令分成四部分:设备类型(幻数)8bits,方向2bits,序号8bits,数据大小14bits。

                       可以使用Linux提供的宏来实现cmd命令定义:

                             _IO(type,nr)                       表示定义一个没有方向的命令,
                             _IOR(type,nr,size)            表示定义一个类型为type,序号为nr,数据大小为size的读命令
                             _IOW(type,nr,size)            表示定义一个类型为type,序号为nr,数据大小为size的写命令
                             _IOWR(type,nr,size)         表示定义一个类型为type,序号为nr,数据大小为size的写读命令

                        例:

                             #define MAGIC_NUM 'k'                      //幻数,主要用于表示类型
                             #define MEMDEV_PRINTF   _IO(MAGIC_NUM,1)
                             #define MEMDEV_READ      _IOR(MAGIC_NUM,2,int)
                             #define MEMDEV_WRITE     _IOW(MAGIC_NUM,3,int)

                             #define MEM_MAX_CMD 3                  //最大的序列号

                             为什么不直接#define MEMDEV_PRINTF   1这样,因为这样遇到了错误,至于为什么还没搞清楚。。。。

                       解析命令的宏:

                            /*确定命令的方向*/
                            _IOC_DIR(nr)                    
                            /*确定命令的类型*/
                            _IOC_TYPE(nr)                     
                            /*确定命令的序号*/
                            _IOC_NR(nr)                           
                            /*确定命令的大小*/
                            _IOC_SIZE(nr) 

                 具体参考http://blog.chinaunix.net/uid-20937170-id-3033633.html吧,感谢!

五、模块编译过程(*.mod.o文件)

         编译过程经历了这样的步骤:先进入Linux内核所在的目录,并编译出hello.o文件,运行MODPOST会生成临时的hello.mod.c文件,而后根据此文件编译出hello.mod.o,之后连接hello.o和hello.mod.o文件得到模块目标文件hello.ko,最后离开Linux内核所在的目录。


你可能感兴趣的:(嵌入式Linux)