Linux设备驱动开发入门--设备驱动程序框架

一、Linux设备分类

  Linux将设备主要分为三类:字符设备、块设备、网络设备。

  1. 字符设备:必须以串行顺序依次访问的设备,不能让随机访问设备内存中某一组数据;

  2. 块设备:可以按照任意顺序进行访问,以块为单位,例如硬盘、eMMc等;

  3. 网络设备:面向数据包的接收和发送而设计,不倾向于对应文件系统的节点。

二、Linux设备驱动程序与外界的接口

  1. 驱动程序于操作系统内核的接口

  2. 驱动程序与系统引导的接口

  3. 驱动程序与设备的接口

三、根据功能划分

  1. 驱动程序的注册和注销。

  设备驱动程序可以再系统启动的时候初始化,也可以在需要的时候动态加载。

  字符设备的初始化由chr_dev_init()完成。

  块设备初始化由blk_dev_init()完成。

  每个字符设备或是块设备的初始化都是通过devfs_register_chrdev() 或是devfs_register_blkdev() 向内核注册,在关闭字符设备或是块设备时,需要通过devfs_unregister_chrdev() 或是 devfs_register_blkdev() 从内核中注销设备。

 

  2. 设备的打开与释放

  设备打开:

  打开设备是由open()来完成的,例如打印机lp_open()

  设备打开要经过一下几个步骤:

  (1)增加设备使用计数

  (2)检查设备相关错误,如设备尚未准备好类似的硬件问题

  (3)检查是首次打开,则初始化设备

  (4)识别设备号,如有必要则更新f_op指针

  (5)如果需要,分配且设置要放在filp->private_data里的数据结构

  设备释放:

  关闭释放设备由release()来完成,例如释放打印机是用lp_release(),而释放终端设备是用tty_release ().

  释放设备步骤如下:

  (1)释放在filp->private_data中的open分配的内存。

  (2)如果是最后一次释放,则关闭设备。

  (3)递减设备使用计数。

  3. 设备的读写操作

  字符设备使用各自的read()和write()来进行数据读写。

  块设备使用 generic_file_read() 和genertc_file_write()来进行数据读写。

  这两个通用函数向请求表添加读写请求,内核可以通过ll_rw_block()优化请求顺序。由于是对内存缓冲区而不是设

备进行操作的,因而可以加快读写请求。如果内存缓冲区内没有要读入的数据或是要将写请求写入设备,那么就要真正

的执行数据传输。这是通过数据结构request_queue和request_fn()来完成 (include/linux/blkdev.h)。

  4. 设备的控制操作

 除了读写操作,有时还要控制设备。这可以通过设备驱动程序中的ioctl()来完成。例如IDE硬盘的控制可以通过hd_ioctl(),对光驱的控制可以通过cdrom_ioctl()。

  与读写操作不同,ioctl()的用法与具体设备密切相关。以软驱的floppy_ioctl()为例(drivers/block/floppy。c):

  static int fd_ioctl(struct inode *inode,

  struct file *filp,

  unsigned int cmd,

  unsigned long param);

  其中,cmd的取值及含义都是与软驱有关的,比如,FDEJECT表示弹出软盘。

  除了ioctl(),设备驱动程序还可能有其他控制函数,比如llseek()等。

  5. 设备的中断和轮询处理

  对于不支持中断的设备,读写时需要轮询设备状态,以及是否需要继续进行数据传输。例如,打印机。如果设备支持中断,则可按照中断方式进行。

 

 

 

本文摘自:https://tech.hqew.com/news_589150

上一篇:Linux CentOS 7网络配置基础


下一篇:Linux 各种取ip的方法总结