L61 附录导读:SOWL HDF 服务一览

L61

学习目标

HDF 是 OpenHarmony 的硬件驱动框架。本课教学版应用侧签名对齐官方(HdfIoService + HdfSBuf Dispatch),非 hdf_core 二进制兼容;应用只认服务名和命令,不写死寄存器。

  • 能说明 HDF 在 I/O 分层中的位置:应用 → 服务绑定 → 驱动 Dispatch/Write → 仿真宿主或真机 HAL。
  • 能区分 moduleName(驱动模块)与 serviceName(应用打开的名字)。
  • 能默写应用侧入口:HdfSowlBoardInit、HdfIoServiceBind、Dispatch(HdfSBuf)、HdfDeviceWrite、HdfIoServiceRecycle。
  • 能按服务名对照本板 19 项外设及后续附录实验课号。
  • 仿真与真机共用 Bind/READ 等应用接口;▼ 面板只负责给仿真喂传感器数值。

原理 · 深入理解

HDF 是什么

HDF(Hardware Driver Foundation)是 OpenHarmony 的硬件驱动框架:把「找设备、发命令、传数据」从芯片寄存器细节里抽出来,让应用按服务名访问外设。官方用 HCS 描述板级配置,驱动实现 HdfDriverEntry 的 Bind、Init、Release。

本课是教学子集,不是官方 hdf_core 的二进制兼容实现。配置改成静态设备表 g_sowl_devices;应用侧签名对齐官方:HdfIoServiceBind / Recycle,Dispatch(cmdId, HdfSBuf *data, HdfSBuf *reply)。概念与第六章对齐,便于在 MixGo SOWL 上把 LiteOS-M 和板载外设接起来。

Bind

把 IDeviceIoService 挂到设备对象上,上层才能按名找到它。

Init

初始化硬件或仿真通道;Bind 失败就不应 Init。

Release

对称拆掉服务、释放资源,防止重复加载泄漏。

当前实现:从应用到板

附录实验的共同入口是 HdfSowlBoardInit():先注册 uart/gpio 以及全部 SOWL 外设驱动,再按优先级加载设备表。应用随后只做两件事:按名绑定,再发命令或写字节。

  1. HdfSowlBoardInit:注册驱动 + HdfDeviceManagerInit(g_sowl_devices)。
  2. HdfIoServiceBind("rgb"):按 serviceName 取得 HdfIoService*(官方同形)。
  3. Dispatch:serv->dispatcher->Dispatch(&serv->object, cmdId, data, reply),载荷为 HdfSBuf;便捷可用 HdfIoCall。
  4. HdfDeviceWrite / HdfDeviceRead:字节流;本板主要用于 uart0 打日志。
  5. HdfIoServiceRecycle:用毕释放服务句柄(教学静态池)。

签名对齐官方:Bind 得 HdfIoService*,命令经 HdfSBuf。教学便捷 HdfIoCall 内部 Obtain/Write/Dispatch/Read/Recycle。像素参数仍可用 SowlRgbPixelArg 打成 uint32 再写入 data。

struct HdfIoService *rgb = HdfIoServiceBind("rgb");
HdfIoCall(rgb, HDF_RGB_CMD_SET_PIXEL, SowlRgbPixelArg(0, 255, 0, 0), 1, NULL);
HdfIoCall(rgb, HDF_RGB_CMD_SHOW, 0, 0, NULL);

仿真与真机用同一套应用代码:Bind + Dispatch/Write。差别只在驱动底下——仿真时工作台把按键、触摸、▼ 传感器写入 0x6000FE00 起的 MMIO,驱动 READ 读到的就是这些数;真机则读真实芯片。点灯/画屏经 FX 邮箱或串口 @MIXOS_JSON 映到壳上,便于对照。应用课不要自己拼 JSON。

服务一览(19 项)

moduleName 决定加载哪份驱动,serviceName 是应用 Bind 的名字。priority 越小越先加载:uart0 为 10,便于所有实验打日志。杜邦 LED/蜂鸣/按键没有单独服务名,走 gpio 的 P1/P7/P4;电位器另有 adc。

服务名模块类别附录课
uart0hdf_uart总线 · 写日志本课 / 第六章
gpiohdf_gpio总线 · 杜邦脚L77
rgbhdf_sowl_rgb执行 · RGB×4L62
tfthdf_sowl_tft执行 · 128×128L63
ledhdf_sowl_led执行 · L1/L2L64
keyshdf_sowl_keys输入 · A1–A4/B1/B2L65
touchhdf_sowl_touch输入 · T0/T1/滑条L66
buzzerhdf_sowl_buzzer执行 · 板载喇叭L67
adchdf_sowl_adc输入 · 电位器 0..100L78
alshdf_sowl_als传感 · 光强/接近L68
thshdf_sowl_ths传感 · 温度/湿度×10L69
acchdf_sowl_acc传感 · 加速度 XYZL70
bpshdf_sowl_bps传感 · 气压 PaL71
mgshdf_sowl_mgs传感 · 地磁 XYZL72
rfidhdf_sowl_rfid传感 · UID/数据L73
asrhdf_sowl_asr传感 · 语音命令号L74
audiohdf_sowl_audio传感 · 麦克风L75
rtchdf_sowl_rtc传感 · 时分秒L76
wifihdf_sowl_wifi网络 · STA 教学本课 / 自学

接口函数与命令号

执行类外设用专用 CMD 宏;传感类用 HDF_SENSOR_CMD_READ / READ2 / READ3,读数写入 reply(HdfSbufReadInt32),返回值只表示成功/失败。网络类 wifi 可用 WifiConstruct / IWiFi,或直接 Bind("wifi") + Dispatch。表中的 INJECT 不是给学生实验写的:工作台 ▼ 面板改滑条时,由壳把数值写入仿真 MMIO;真机则从 I2C/HAL 读真实芯片。应用永远只 Bind + Dispatch/READ,不必分支「是不是仿真」。gpio 的 data:低 8 位为脚号,次 8 位为电平或模式。

服务命令cmd参数与返回
rgbSET_PIXEL1arg:idx<<24 | r<<16 | g<<8 | b
rgbFILL / SHOW / CLEAR2 / 3 / 4FILL 的 arg 为 r<<16|g<<8|b;SHOW 提交到板
tftFILL / PIXEL / SET_XY / BRIGHT / CLEAR1…5颜色为 RGB565;SET_XY 为 x<<8|y
ledSET / ONOFF / GET1 / 2 / 3arg:index<<8 | duty 或 on;index=1|2
keysREAD / IS_DOWN / INJECT1 / 2 / 3返回位图;B1=bit0 … A4=bit5
touchREAD / SLIDE / VALUE / INJECT1…4bit0=T0 bit1=T1;滑条 0..100
buzzerTONE / BEEP1 / 2TONE 的 arg 为频率 Hz,0 静音
adcREAD1返回 0..100,默认对接杜邦电位器
gpioSET_MODE / WRITE / READ1 / 2 / 3写 P1/P7 会同步杜邦 LED/蜂鸣可视化
alsREAD / READ21 / 2光强;接近
thsREAD / READ21 / 2温度×10;湿度×10
acc / mgsREAD / READ2 / READ31 / 2 / 3X / Y / Z
bps / audioREAD1气压 Pa;麦克风 0..65535
rfidREAD / READ2 / INJECT1 / 2 / 4UID;块数据;按下刷卡后非 0
asrREAD / INJECT1 / 4命令号,0 表示空闲
rtcREAD / READ2 / READ31 / 2 / 3时 / 分 / 秒
wifiENABLE/CONNECT/STATUS/RSSI/SCAN…1..7STA:写 SSID;读状态/RSSI/扫描数
uart0Write / Read按字节打日志;Dispatch 本板不用

本课实验怎么读串口

overview 实验不点灯、不读传感器:它只 Bind 上表每一个名字。成功打印「名字 ok」,缺驱动打印「MISSING」。全部通过后打印 overview ok。若某行 MISSING,先查 HdfSowlBoardInit 是否编译进 LOS_HAVE_HDF,再核对设备表里的 serviceName 拼写。

从 L62 起,每一课只深入一个服务:在本页表里找到命令,再到对应 main.c 里看 Dispatch 怎么用。仿真与真机共用同一份 main;若行为不同,查驱动里是读 MMIO 还是读 HAL,而不是改应用分支。

术语表

HDF(硬件驱动框架)
OpenHarmony Hardware Driver Foundation。本课为教学子集:按名发布服务,不是官方 hdf_core 的二进制兼容实现。
HdfIoServiceBind(绑定服务)
按 serviceName 取得 HdfIoService*,之后才能 Write/Read/Dispatch;用毕 HdfIoServiceRecycle。
HdfSBuf(序列化缓冲区)
官方 Dispatch 用 data/reply 传参;本课为教学实现(静态池),非 hdf_core ABI。
Dispatch(命令分发)
serv->dispatcher->Dispatch(object, cmdId, data, reply);读数在 reply,返回值是成功/失败。
WifiConstruct(WiFi 对象)
教学薄封装,对齐官方名字;内部仍 Bind("wifi") + SBuf。
MMIO(仿真寄存器)
基址 0x6000FE00,工作台把按键、滑条、NFC 等写入对应偏移,驱动读这些单元。

自学 · 建议步骤

先读「原理」,再动手;不要跳过检查点。

  1. 复习 L33/L36:Bind、Init、Release 与 I/O 分层。
  2. 打开 hdf_device.h,对照 HdfDriverEntry 与 IDeviceIoService。
  3. 浏览 hdf_sowl_board.c 的 g_sowl_devices,记下 19 个 serviceName。
  4. 对照 hdf_sowl_periph.h,把执行类(rgb/tft/led/buzzer)、传感类(als…rtc)和网络类(wifi)分成三列。
  5. 上工作台跑 overview,把串口名单勾到设备表上。

做 · 实验

  • 打开工作台 lab=appendix-hdf-overview,编译后看串口是否逐行打印 uart0 ok … wifi ok。
  • 对照 hdf_sowl_board.c 的设备表,核对串口名单与表中 serviceName 一致。
  • 任选 rgb / keys / als / wifi,在 hdf_sowl_periph.h 中标出对应 CMD 宏。

打开工作台

代码导读

先读 user/appendix-hdf-overview/main.c:HdfSowlBoardInit 后 Bind/Recycle,以及 WifiConstruct 演示。再读 kernel/include/hdf/hdf_device.h 与 hdf_sbuf.h,对照官方 Dispatch(data,reply)。驱动表见 hdf_sowl_board.c。

总结与提升

  • 能用自己的话解释为何应用不要直接写 GPIO 号去点灯。
  • 串口出现 MixOSLesson | appendix-overview 与 overview ok。
  • 能指出至少三个服务的 Bind 名和一条 Dispatch 命令。

延伸思考

  • 若新增一块 I2C 温湿度芯片,应改设备表、驱动入口还是每个实验的 main?
  • 仿真 MMIO 与真机 I2C 在 Dispatch 里如何分叉,而不让应用感知?
  • 多任务同时 Dispatch 同一 uart0,锁应放在驱动还是应用?

← 本阶段封面 · 课程列表