【内核驱动注册流程】

1.申请设备号

​ 驱动结构体填充完毕后,需要注册到内核之中,其中有三种方法来注册设备驱动:

(1) 动态注册申请设备号 + cdev 注册设备驱动

​ 在不知道设备号的情况下,通过动态注册驱动申请到的设备号并存到dev_t 类型中,通过cdev_init将驱动结构体ops赋值给cdev->ops,然后通过cdev_add将cdev结构体与设备号关联。

动态注册并申请设备号API:

  alloc_chrdev_region(dev_t*dev, unsigned baseminor, unsigned count, constchar *name)

  dev:        alloc_chrdev_region函数向内核申请下来的设备号结构体

  baseminor :  次设备号的起始

  count:      申请次设备号的个数

  name :      执行cat /proc/devices显示的名称

cdev的使用:

a. 执行cdev_init函数,将cdev和file_operations关联起来

b. 使用cdev_add函数,将cdev和设备号关联起来

卸载API:

unregister_chrdev_region(dev *dev, int num);

eg:

驱动动态设备号注册实例: flashlight_devno为被赋值的结构体变量

img

1.1 动态注册

cdev_init原型

img

1.2 cdev_init原型

cdev_add原型

img

1.3 cdev_add原型

cdev卸载API: void cdev_del(structcdev *p)

(2) 静态申请设备号 + cdev 注册设备驱动

在已知驱动主设备号的情况下,可以通过静态注册驱动。其步骤与动态注册有些区别。需要先定义一个dev_t结构体,然后通过MKDEV将主设备号与此设备号合成赋值给dev_t。

静态注册驱动API:

 int register_chrdev_region(dev_t*dev, unsigned int count, char *name);

  dev: 由已知的主设备号合成的设备号结构体MKDEV(major,mnior)的返回值

  count: 申请此设备号个数

  name: 设备名 出现在/proc/devices

卸载静态注册API:

  unregister_chrdev_region(dev *dev, int num);

eg.静态注册获取设备号,其中major为已经被赋值的变量

img

1.4 静态注册驱动

(3) 自动识别静态、动态分配

程序也可以自动选择静态或动态分配API:

 int register_chrdev(unsigned int num, const char *name,struct file_operations *ops)

  num:0时动态注册,非零时以num为主设备号静态注册。

  Name:设备名

  ops: 驱动结构体

卸载API:int unregister_chrdev(unsigned int major, const char *name)

与上两个注册方法不同的是,int register_chrdev会自动将ops与设备号关联,不用手动cdev_init、cdev_add。且当创建class节点需要设备号结构体时,需要MKDEV(major,minor)返回值。但是此API较为耗资源。

eg.自动识别静态、动态分配

img

1.5 自动识别注册

根据主次设备号获取设备号结构体API:

dev_num=MKDEV(major,minor); major是一个表示设备号的主设备号,minor次设备号

根据设备号结构体获取主次设备号API:

major = MAJOR(dev_num); 获取主设备号

minor = MINOR(dev_num); 获取从设备号

设备注册成功后,在/pro/device可查看

2.创建节点

设备注册进去后,需要创建节点才可以使驱动被调用。

在/sys/class创建节点类API:

struct class *class_create(structmodule *owner, const char *name)

owner:模块所有者

name: 指定类名 //在/sys/下可见

在/sys/class/name已知类节点下创建设备节点API:

struct device device_create(struct classcls, struct device *parent, dev_t devt, void *drvdata,const char *fmt, …);

eg.创建节点

img

2.1 创建节点

注意:/sys/class/xx/device与/dev/device区别(xx表示设备类名,device表示设备名)

在驱动注册成功后,需要软件创建设备节点。在设备节点创建成功后,内核就会在/dev/下生成设备名。其中/dev/下存的是真实的设备,/sys/class/xx/存的是设备节点名,反映驱动设备的层次。调用驱动时需要将/dev下的设备作为路径,也可以通过设备节点名再下一级的节点传参。即”/sys/class/xx/device”不能作为调用路径,”/dev/device”可以作为调用路径。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux内核UART设备驱动注册流程如下: 1. 分配tty_driver结构体 在驱动初始化时,首先需要分配一个tty_driver结构体,该结构体描述了tty设备的驱动属性信息,包括驱动名称、打开、关闭、读写等操作的回调函数指针等。 2. 注册tty_driver 调用tty_register_driver函数,将tty_driver结构体注册内核中,该函数会将tty_driver结构体添加到tty_drivers链表中,同时会创建一个tty_class结构体和一个tty_class_dev结构体,并将其关联起来。 3. 创建tty设备节点 调用tty_register_device函数,该函数会根据tty_driver结构体中的信息创建tty设备节点,并将其添加到tty_drivers链表中。 4. 设置tty设备驱动回调函数 在tty_driver结构体中设置相应的驱动回调函数,例如open、close、read、write等操作的回调函数指针。 5. 注册tty设备驱动与硬件设备的关联 在驱动初始化时,需要将tty设备驱动与硬件设备进行关联,通常是通过platform_device_register函数将platform_device结构体注册内核中,并调用platform_driver_register函数将platform_driver结构体注册内核中。 6. 实现tty设备驱动回调函数 在驱动初始化时,需要实现相应的tty设备驱动回调函数,例如open、close、read、write等操作的回调函数。当用户调用相应的操作时,内核会自动调用相应的回调函数执行相应的操作。 7. 注销tty设备驱动驱动卸载时,需要调用tty_unregister_driver函数注销tty_driver结构体,并释放相关资源。同时也需要注销与硬件设备的关联关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值