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

本文总结了嵌入式Linux驱动及内核模块的相关操作,包括驱动程序测试、内核驱动设备号的分配、I/O内存申请、ioctl函数的使用以及模块编译过程。详细阐述了如何在Kconfig和Makefile中配置驱动,以及如何通过alloc_chrdev_region、cdev_init和device_create等函数进行设备注册。同时提到了ioctl命令的定义及其宏的使用。

一、驱动程序测试

    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()。

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

          <class_creat()         ----      class_destory()>

          <device_create()    ----      device_destory()>

          <class_register()     ----      class_unregister()>

          <device_register()  ----      device_unregister()>


三、申请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内核所在的目录。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值