Linux驱动开发 基础

驱动开发与裸机开发区别

  • 集成环境:linux驱动开发没有像裸机开发时使用的MDK等集成IDE的开发软件

  • 模块复用化:驱动开发模块化与复用化更强(分离与分层),裸机开发的不同芯片的同一功能函数实现各不相同,而驱动开发为所有芯片提供统一的驱动框架。

  • 学习裸机与Linux关于驱动的开发都初始化相应的外设寄存器。只是在 Linux 驱动开发中需要按照其规定的框架来编写驱动。

驱动开发步骤

1、驱动模块的加载和卸载

Linux 驱动有两种运行方式:

  1. 将驱动编译进 Linux 内核中,这样当 Linux 内核启动的时候就会自动运行驱动程序。(通常不使用)

  2. 将驱动编译成模块(Linux 下模块扩展名为.ko),在Linux 内核启动以后使用“modprobe”或者“insmod”命令加载驱动模块。

采用第二种方式更方便开发,如果以后修改驱动,不需要编译整个 Linux 代码,只需要编译一下驱动代码即可。而且在调试的时候不需要重启整个系统,只需要加载或者卸载驱动模块。

在编写驱动的时候需要注册加载函数module_init与卸载函数module_exit。当使用“modprobe”命令加载驱动的时候,会调用module_init内的参数的xxx_init 函数。当使用“rmmod”命令卸载具体驱动的时,会调用module_exit内的参数 的xxx_exit 函数。

/* 驱动入口函数 */ 
static int __init xxx_init(void) 
{ 
    /* 入口函数具体内容 */  
    return 0; 
} 
/* 驱动出口函数 */ 
static void __exit xxx_exit(void) 
{ 
    /* 出口函数具体内容 */ 
} 

/* 将上面两个函数指定为驱动的入口和出口函数 */
module_init(xxx_init); //向Linux内核注册一个模块加载函数xxx_init 
module_exit(xxx_exit); //向Linux内核一个注册模块卸载函数xxx_exit

加载和卸载命令的使用

  • 驱动编译完成以后生成的模块的扩展名为.ko,有两种命令可以加载驱动模块:insmod 和 modprobe:

      注意:加载前要先执行depmod

    • insmod 命令用于加载指定的.ko 模块但不能解决模块的依赖关系,比如 drv.ko 依赖 first.ko 这个模块,就必须先使用insmod 命令加载 first.ko 这个模块,然后再加载 drv.ko 这个模块。

    • modprobe 会分析模块的依赖关系,然后会将所有的依赖模块都加载到内核中,因此modprobe 命令相比 insmod 要智能一些,modprobe 命令主要智能在提供了模块的依赖性分析、错误检查、错误报告等功能。modprobe 命令默认会去/lib/modules/<kernel-version>目录中查找模块,比如使用的 Linux kernel 的版本号为 5.4.31,因此 modprobe 命令默认会到/lib/modules/5.4.31 这个目录中查找相应的驱动模块,一般自己制作的根文件系统中是不会有这个目录的,所以需要自己手动创建。

  • 驱动模块的卸载使用命令“rmmod”即可,比如要卸载 drv.ko:

  • rmmod drv.ko;      //推荐使用
    modprobe -r drv    //卸载掉驱动模块所依赖的其他模块,前提是依赖模块没有被其他模块所使用否则卸载失败

2、设备注册与注销(详情见驱动分类章节)

2.5、设备号讲解

为了方便管理,Linux 中每个设备都有一个设备号,设备号由主设备号和次设备号两部分组成,主设备号表示某一个具体的驱动,次设备号表示使用这个驱动的各个设备。Linux 提供了一个名为 dev_t 的数据类型表示设备号,dev_t 定义在文件 include/linux/types.h 里面,定义如下:

typedef __u32 __kernel_dev_t;     //__u32是被定义过的unsigned int 32类型
...... 
typedef __kernel_dev_t dev_t; 

这 32 位的数据构成了主设备号和次设备号两部分,其中高 12 位为主设备号,低 20 位为次设备号。因此 Linux 系统中主设备号范围为 0~4095

设备号的分配

1、静态分配设备号

注册设备需要给设备指定一个设备号,可以指定的一个静态的设备号,一些设备号已经被 Linux 内核开发者给分配了的常用设备号可以查看文档 Documentation/devices.txt 。已经分配掉的主设备号能否使用得看硬件平台运行过程中有没有使用,使用“cat /proc/devices”命令即可查看当前系统中所有已经使用了的设备号。

2、动态分配设备号

静态分配需要挑选一个没有使用设备号这容易带来冲突问题,因此Linux 社区推荐使用动态分配设备号。在注册设备之前先申请一个设备号,系统会自动给你一个没有被使用的设备号;卸载驱动时需要释放掉这个设备号:

//申请设备号函数
int alloc_chrdev_region(dev_t *dev,          //保存申请到的设备号
                        unsigned baseminor,  //次设备号起始地址,函数可以申请一段连续的多个设备号,这些设备号的主设备号一样,但次设备号不同,次设备号以 baseminor 为起始地址地址开始递增。一般 baseminor 为 0。
                        unsigned count,      //要申请的设备号数量
                        const char *name)    //设备名字。 
 

//设备号释放函数: 
void unregister_chrdev_region(dev_t from,    //要释放的设备号
                              unsigned count)//表示从 from 开始,要释放的设备号数量

3、添加 LICENSE 和作者信息

最后需要在驱动中加入 LICENSE 信息和作者信息,其中 LICENSE 是必须添加的,否则的话编译的时候会报错,作者信息可以添加也可以不添加。LICENSE 和作者信息的添加使用


                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值