泰山派3M-RK3576-Linux内核驱动教程-Linux驱动基础-字符驱动设备-什么是字符设备

01.什么是字符设备

一、设备与设备文件

在 Linux 中,内核通过驱动程序管理各种硬件设备或虚拟设备,例如:

  • 串口控制器
  • GPIO 控制器
  • 随机数发生器
  • 存储控制器
  • 显示控制器等

用户空间程序不会直接操作硬件寄存器,而是通过内核提供的统一接口访问设备。

前面的章节我们讲过,就是 设备文件(device file),通常位于 /dev 目录下。

在开发板上执行:

ls -l /dev

可以看到类似:

crw-rw-rw-  1 root  root      1,   3 12月  9 19:02 null
crw-rw----  1 root  tty       4,   0 12月  9 19:02 tty0
brw-rw----  1 root  disk    179,   0 12月  9 19:02 mmcblk0

这些条目并不是普通的磁盘文件,而是“设备的访问入口”。 用户空间通过对这些设备文件进行 open / read / write / ioctl 等操作,从而间接访问实际设备。

二、字符设备与块设备的基本分类

从“访问方式”的角度,Linux 将设备大致分为两大类:

  1. 字符设备(Character Device)
  2. 块设备(Block Device)

/dev 中,可以通过 ls -l 输出的第 1 列第 1 个字符区分:

  • c 开头的:字符设备(character)
  • b 开头的:块设备(block)

示例:

crw-rw-rw-  1 root  root      1,   3 ...  null     # 字符设备
brw-rw----  1 root  disk    179,   0 ...  mmcblk0  # 块设备

1. 字符设备

字符设备(Character Device)字节流的方式对外提供访问接口。其特点包括:

  • 按字节(或字节序列)顺序读写数据,类似于流式 I/O。
  • 通常不要求对齐到固定大小的数据块。
  • 适用于各种控制类设备或流式数据设备。

典型例子:

  • 串口终端:/dev/ttyS0/dev/ttyS1
  • 控制台:/dev/console
  • 随机数设备:/dev/random/dev/urandom
  • 虚拟设备:/dev/null/dev/zero
  • GPIO / I2C / SPI 等控制接口在很多系统上也通过字符设备形式呈现
  • 用户自定义的字符设备:如 /dev/mychar

用户空间访问字符设备示例:

int fd = open("/dev/ttyS0", O_RDWR);
write(fd, buf, len);
read(fd, buf, len);
close(fd);

在内核中,这类设备通常由字符设备驱动实现,通过一组回调函数(file_operations)响应上述系统调用。

2. 块设备

块设备(Block Device)固定大小的数据块为单位进行访问,例如 512 字节、4 KB 等。其特点包括:

  • 支持高效的随机访问和缓存机制。
  • 主要用于各种持久化存储介质。

典型例子:

  • eMMC / SD 卡:/dev/mmcblk0/dev/mmcblk0p1
  • U 盘、SATA/USB 磁盘:/dev/sda/dev/sdb
  • 压缩内存块设备:/dev/zram0

块设备通常并不会直接被应用程序以“原始块”形式频繁访问,而是:

  1. 在其上创建文件系统(如 ext4、vfat 等);
  2. 把该块设备挂载到某个目录;
  3. 通过普通文件读写接口访问文件系统中的文件。

块设备驱动与文件系统配合使用,相对复杂,暂不不重点展开。

三、为什么重点学习字符设备驱动

在 Linux 驱动开发中,存在多种类型的驱动:

  • 字符设备驱动
  • 块设备驱动
  • 网络设备驱动
  • 输入子系统驱动(键盘、触摸屏等)
  • 声音子系统驱动(ALSA)
  • 图形 / 显示驱动等

对于初学者而言,从字符设备驱动入门具有以下优势:

  1. 接口形式直观 字符设备使用的操作接口与普通文件类似,包括:
    - open
    - read
    - write
    - ioctl
    - close 等 这些接口在用户空间编程中也经常使用,便于理解。
  2. 调试方式简洁 字符设备一旦在 /dev 下建立了节点,可以直接通过:
    - echo / cat
    - hexdump
    - 简单的 C 测试程序 对设备进行读写操作,验证驱动逻辑。
  3. 适用范围广 很多简单或中等复杂度的外设,都可以通过字符设备模型进行封装,例如:
    - GPIO 控制
    - 简单的传感器
    - LED 灯控制
    - 虚拟测试设备等

因此,这一章节将围绕字符设备的基本概念和实现方式展开,包括:

  • 设备号的申请与管理
  • 字符设备框架(cdev / miscdevice 等)
  • 设备节点的创建(/dev/mychar
  • 用户应用与驱动之间的数据交互方式等。

四、接口:file_operations

用户空间在访问设备文件时,使用标准的系统调用:

  • open() / close()
  • read() / write()
  • ioctl()

内核在接收到这些调用后,需要将其转交给具体设备驱动去处理。 这一过程在字符设备中,主要通过 struct file_operations 完成。

一个典型的字符设备驱动中,会定义类似如下的结构体:

static const struct file_operations my_fops = {
    .owner          = THIS_MODULE,
    .open           = my_open,
    .release        = my_release,
    .read           = my_read,
    .write          = my_write,
    .unlocked_ioctl = my_ioctl,
};

含义可以简单理解为:

  • 当用户空间对 /dev/mychar 调用 open() 时,内核会调用驱动中的 my_open()
  • 当调用 read() 时,会进入 my_read()
  • 当调用 write() 时,会进入 my_write()
  • 当调用 ioctl() 时,会进入 my_ioctl()

因此,从内核实现角度看:

字符设备驱动 = 一组 **file_operations** 回调函数 + 设备号注册 + 与 **/dev** 设备节点的绑定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值