字符设备驱动

字符设备驱动开发

字符设备驱动

图 1 字符设备驱动框架

 

字符设备是Linux驱动中最基本的设备驱动。其一个字节一个字节,按照字节流进行读写操作。常见的点灯,按键,IIC,SPI等都是字符驱动设备。

在Linux内部,一切都是设备都被抽象为文件。驱动加载成功,在/dev目录下生成对应的文件。应用程序操作/dev/xxx的方式来实现对于设备硬件操作。

例:对于LED这种硬件操作。在驱动内核中,与LED对应的驱动设备文件/dev/led。使用open,close来打开与关闭驱动设备文件。

使用write函数来向驱动设备文件写入参数,进而达到LED的控制参数的调整,来控制LED等硬件。

备注:open,write,close,read函数是由于C库提供。一条指令的执行,在空间上分为用户空间与内核空间(这种空间方式,主要是为了保护系统,内核空间主要与设备具体操作有关)。

在用户空间使用open,write,read,close函数,通过系统调用,进入内核空间,进而操作具体硬件。

 

 

驱动框架

驱动运行方式:1.驱动编译进Linux,随着Linux内核启动而运行。2.将驱动编译成驱动模块(后缀.KO的模块文件),使用ismod或modprobe指令来加载驱动模块,rmmod指令来卸载模块。

驱动加载与卸载注册函数

Module_init(xxx_init),注册模块加载函数,使用insmod,modprobe指令,会调用module_init(xxx_init),进行注册。

Module_exit(xxx_exit),注册模块卸载函数,使用rmmod指令,会调用module_exit(xxx_exit),进行卸载。

 

图 3 驱动入口与出口函数框架

 

字符设备注册与注销

驱动模块加载成功,接下来进行注册字符设备。卸载驱动模块,需要注销字符设备。字符设备的注册与注销函数原型:

图 4 字符设备的注册与注销函数

major:主设备号,linux中每个设备都分配一个设备号。设备主要分为主设备号与次设备号。

name:设备名字,是一串字符串。

fops:结构体file_operations类型指针,设备的操作函数集合。

使用register_chrdev函数来完成字符设备的注册。会在对应的 /proc/devices下生成对应的设备。核对信息:设备号,设备名字

设备操作函数

file_operations结构体包含对设备的具体操作函数。主要实现的内容:open,write,read,close。

图 5 设备操作函数集合

对应的操作函数原型:

图 6 对应的设备操作函数原型

 

添加LICENSE和作者信息

图 7 作者与LICENSE信息

设备号

每个设备在linux下都有对应的设备号,设备号分为主设备号与次设备号两部分组成。一般主设备号表示一个具体的驱动,次设备号表示使用驱动的各个设备。

图 8 设备号设置

宏 MINORBITS 表示次设备号位数,一共是 20 位。宏 MINORMASK 表示次设备号掩码。

宏 MAJOR 用于从 dev_t 中获取主设备号,将 dev_t 右移 20 位即可。

宏 MINOR 用于从 dev_t 中获取次设备号,取 dev_t 的低 20 位的值即可。

宏 MKDEV 用于将给定的主设备号和次设备号的值组合成 dev_t 类型的设备号。

设备号分配

静态分配设备号:

静态设备号分配,主要针对主设备号分配。注册字符设备时候给设备指定一个设备号。这个设备号是静态指定的一个指定号(有些设备号被Linux内核分配掉)。

具体在/proc/devices 目录下,查看系统中已经使用的设备号。

动态分配:

静态分配需要先查看设备号的分配情况。比较容易引起设备号冲突。推荐使用动态分配,主动申请一个设备号,避免冲突。

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

*dev:保存申请到的设备号。baseminor:次设备号起始地址。一般从0开始。count:申请设备号数量。name:设备名字。

注销字符设备需要释放设备号:

void unregister_chrdev_region(dev_t from, unsigned count)

from:待释放的设备号

count:待释放的设备号数量。

注意事项:

Insmod指令加载驱动成功之后,使用lsmod指令之后,可以查看到驱动模块:查看驱动模块(基于驱动名字查看)。

在/proc/devices目录下,可以查看到具体的设备:基于设备号与设备名字。

设备节点文件创建:

mknod /dev/chrdevbase c 200 0

c:表示一个字符设备

200:主设备号

0:设备的次设备号

后续可以继续操作设备节点文件。

 

 

posted @ 2022-07-26 14:58  JwChu  阅读(572)  评论(0编辑  收藏  举报