6.1 I/O系统的功能、模型和接口

L33

学习目标

设备驱动负责把寄存器细节藏起来;OpenHarmony HDF 用 HdfDriverEntry 的 Bind、Init、Release 描述驱动一生,教学版与之对齐。

  • Bind:把 IO 服务挂到设备对象上,让上层能按名找到它。
  • Init:真正初始化硬件;Bind 失败就不应 Init。
  • Release:对称拆掉服务并释放资源,防止重复加载泄漏。
  • moduleName 与设备表匹配,决定加载哪一份驱动;serviceName 是应用打开的名字。
  • LOS_HAVE_HDF 打开后,设备管理器按表加载 uart 驱动。
  • 应用持有的是服务,不是 GPIO 号;换引脚应改驱动/表,而不是改所有 printf。
  • 多任务同时写 uart0 需要互斥,否则日志交错——这是同步章在设备上的再现。
  • 输入设备和输出设备一样,先查服务再发命令,不要在应用里写死 GPIO 号。

原理 · 深入理解

I/O 软件分层 用户进程 / 库 独立于设备的 I/O 设备驱动程序 · HDF 中断处理 硬件 控制器 · DMA · 设备

6.1 I/O系统的功能、模型和接口

本节概览:先建立「I/O系统的功能、模型和接口」的框架,再依次展开下列小节。

  1. I/O系统的基本功能
  2. I/O系统的层次结构和模型
  3. I/O系统接口

6.1.1 I/O系统的基本功能

从设备的共享属性上,可将系统中的设备分为独占设备和共享设备两类。I/O系统应具备以下基本功能。

隐藏物理设备的细节

I/O设备类型繁多,彼此在多方面存在差异,需要不同的命令和参数。I/O系统通过对设备加以适当抽象,隐藏物理实现细节,仅向上层进程提供少量抽象的读/写命令,如read、write等。

与设备的无关性

与设备的无关性是在隐藏物理设备细节的基础上实现的。用户既可使用抽象I/O命令,也可使用抽象逻辑设备名;对OS而言,允许在不重新编译整个系统的情况下增添新的设备驱动程序,方便新I/O设备安装。

提高处理机和I/O设备的利用率

许多I/O设备相互独立、可并行操作,处理机与设备之间也能并行操作。I/O系统应让处理机快速响应I/O请求,使设备尽快运行;同时尽量减少设备运行时处理机的干预时间,以提高利用率。

对I/O设备进行控制

对I/O设备的控制是驱动程序的功能。目前有四种控制方式:轮询可编程I/O方式、中断可编程I/O方式、直接存储器访问方式、I/O通道方式。具体采用何种方式,与设备传输速率、传输数据单位等因素有关。

确保对设备的正确共享

独占设备:进程应互斥访问,系统一旦分配给某进程便由其独占直至释放,典型如打印机、磁带机;分配时还需考虑安全性。

错误处理

共享设备:一段时间内允许多个进程同时访问,典型如磁盘,多个进程交叉读写不影响正确性。

6.1.2 I/O系统的层次结构和模型

通常把I/O软件组织成四个层次。

图6-1 I/O系统的层次结构 用户层 I/O 与设备无关软件 设备驱动程序 中断处理 硬件
图6-1 I/O系统的层次结构

I/O系统包含上、下接口和I/O系统接口软件/硬件(RW/HW)接口,分层依次为:中断处理程序、设备驱动程序、设备独立性软件。

图6-2 I/O系统中各种模块之间的层次视图 系统调用 独立于设备的 I/O 驱动 控制器
图6-2 I/O系统中各种模块之间的层次视图

6.1.3 I/O系统接口

块设备接口是块设备管理程序与高层之间的接口,反映大部分磁盘和光盘存储器的本质特征,用于控制该类设备的输入输出。

块设备指数据存取和传输以数据块为单位的设备。该接口隐藏了磁盘地址的二维结构,并将上层发来的打开、读、写、关闭等抽象命令映射为低层操作。

现代OS都提供面向网络的功能。需要通过某种方式把计算机连接到网络上,并提供相应的网络软件和网络通信接口,使计算机能与网络上其他计算机通信或上网浏览。

流设备接口是流设备管理程序与高层之间的接口,又称字符设备接口,反映大部分字符设备的本质特征,用于控制字符设备的输入输出。

字符设备指数据存储和传输以字符为单位的设备,提供get和put操作以及in-control指令。

做 · 实验

  • 根据「学习目标」列出 3 个关键词,对照原理段落解释给自己听。
  • 编译 HDF UART 实验,确认输出能表明走了服务而不是纯裸机路径。
  • 对照裸机串口实验的日志,列出多出来的标识或调用层次。
  • 烧录 08-hdf-uart,串口有课程标识行。

打开工作台

I/O系统的功能、模型和接口

interrupt-path

用控件单步操作;日志区记下每一步发生了什么。

代码导读

本课在工作台编译烧录。先读 user 实验入口,再对照 kernel / HDF 中被调用的函数,不要一上来改链接脚本。

总结与提升

  • 能默写 Bind/Init/Release 职责。
  • 能用自己的话复述学习目标,并指出概念与板上实验的对应。
  • 串口输出稳定,并能说明访问路径经过 HDF。
  • 能区分 moduleName 与 serviceName。
  • 按下/松开有 HDF 日志。
  • 能叙述中断处理大致步骤。
  • 能指出 SOWL 至少一个外设的控制路径。
  • 能默写 I/O 软件分层。

延伸思考

  • Bind 失败为什么不应 Init?
  • 如果把本节机制拿到 Linux 或完整 OpenHarmony 上,会多出哪些硬件假设?
  • 多任务写同一 uart0 要不要加锁?锁放在驱动还是应用?
  • 消抖放 Dispatch 里还是任务里?

← 本阶段封面 · 课程列表