一、鸿蒙驱动开发概述

大家好,我是老李。做嵌入式驱动开发十几年了,从Linux内核到RTOS,再到现在的OpenHarmony,一路踩坑一路成长。今天咱们聊聊OpenHarmony驱动开发的开篇内容——什么是驱动、HDF框架是什么、以及环境怎么搭。

说实话,我第一次接触OpenHarmony驱动时,心里也犯嘀咕:这不就是又一套驱动框架吗?但真正用起来才发现,它跟Linux驱动、RT-Thread驱动还真不太一样。咱们慢慢聊。

1.1 什么是OpenHarmony驱动?

驱动,说白了就是操作系统跟硬件之间的翻译官。你写个应用程序,想点亮一个LED灯,总不能直接操作GPIO寄存器吧?驱动就是干这个活的——把上层应用的请求,翻译成硬件能听懂的指令。

在OpenHarmony里,驱动的作用跟其他操作系统类似,但有个显著特点:它要支持多种内核。什么意思?OpenHarmony既能跑在Linux内核上,也能跑在LiteOS上,甚至未来可能支持更多内核。这就要求驱动框架必须足够抽象,不能跟某个内核绑死。

核心要点:OpenHarmony驱动 = 硬件操作逻辑 + 内核适配层 + 用户态接口

我在项目中遇到过这样一个场景:同一个传感器,在Linux内核下用I2C驱动,在LiteOS下也得用I2C驱动。如果两套驱动分开写,维护成本翻倍不说,还容易出bug。HDF框架就是为了解决这个问题而生的。

1.2 驱动框架HDF简介

HDF,全称是Hardware Driver Foundation,翻译过来就是硬件驱动基础框架。嗯,名字挺朴实,但功能不简单。

HDF的核心思想是:驱动与内核解耦。它把驱动拆成三层:

  • 驱动实现层:写具体的硬件操作代码,比如读写寄存器、配置DMA等
  • 驱动管理层:负责驱动的加载、卸载、绑定、消息传递等
  • 驱动服务层:向上层提供统一的服务接口,用户态也能调用

你想想看,这三层一分开,好处就来了:

  • 换内核?只需要改驱动管理层那一小部分
  • 换硬件?只需要改驱动实现层
  • 上层应用?完全不用动

我刚开始用HDF时,觉得它有点重。但后来在一个项目里,产品需要同时支持Linux和LiteOS两个版本,HDF帮我省了至少40%的代码量。嗯,真香。

下面这张图是我自己整理的HDF框架结构,你看一眼就明白了:

HDF驱动框架结构图 应用层(App / Service) 通过HDF服务接口调用驱动功能 驱动服务层(Driver Service) 提供统一API,支持用户态/内核态调用 驱动管理层(Driver Management) 加载/卸载/绑定/消息路由 驱动实现层(Driver Implementation) 硬件寄存器操作、中断处理、DMA配置 硬件设备(GPIO / I2C / SPI / UART ...)

1.3 驱动开发环境搭建

环境搭建这块,我踩过的坑最多。记得第一次搭OpenHarmony开发环境,折腾了整整两天——不是工具链版本不对,就是依赖库缺这缺那。后来我把步骤整理成清单,照着来基本一次过。

1.3.1 DevEco Studio安装

DevEco Studio是华为基于IntelliJ IDEA定制的IDE,专门用来开发OpenHarmony应用和驱动。我个人习惯用它的原因是:调试方便,代码补全做得好,而且集成了设备模拟器。

安装步骤其实很简单:

  1. 去官网下载DevEco Studio安装包(注意选对操作系统版本)
  2. 双击安装,一路下一步就行
  3. 安装完成后,打开SDK Manager,下载OpenHarmony SDK
  4. 配置NDK和工具链(这个后面细说)

小技巧:安装路径不要带中文和空格,否则编译时可能报一些莫名其妙的错。我吃过这个亏,后来学乖了。

1.3.2 源码编译环境

OpenHarmony的源码编译,说白了就是一套基于gn + ninja的构建系统。如果你用过Chromium或WebRTC的编译,应该不会陌生。

编译环境需要准备这些东西:

组件 版本要求 说明
Python 3.7+ 构建脚本依赖
gn 最新版 元构建系统,生成ninja文件
ninja 1.10+ 真正的构建执行器
交叉编译工具链 根据目标芯片选 比如ARM GCC、RISC-V GCC等
hb工具 最新版 OpenHarmony的构建命令行工具

编译命令也很直接:

# 进入源码根目录
cd ohos

# 设置编译环境
hb set

# 选择产品(比如 rk3568、hispark_taurus 等)
# 然后执行编译
hb build -f

第一次编译会比较慢,因为要下载依赖、编译工具链等。我建议你泡杯咖啡,或者去干点别的。嗯,大概半小时到一小时吧,看机器性能。

注意:编译过程中如果报错,先检查网络连接。很多失败是因为依赖包下载超时。我曾经因为公司网络代理没配好,卡了整整一个下午。建议提前配好pip和git的代理。

1.3.3 驱动开发的基本流程

环境搭好了,怎么写驱动?我一般按这个流程走:

  1. 写HDF驱动配置文件(.hcs文件):描述硬件资源、驱动加载策略
  2. 实现驱动入口函数:Bind、Init、Release三个回调
  3. 实现硬件操作逻辑:读写寄存器、配置中断等
  4. 注册驱动服务:让上层应用能找到你的驱动
  5. 编译测试:烧录到开发板上验证

这个流程看起来简单,但每一步都有坑。比如.hcs文件的语法,跟设备树有点像但又不完全一样;再比如Bind函数里怎么跟硬件资源绑定,稍不注意就段错误。

别担心,后面几章我会带着大家一步步写一个完整的GPIO驱动、I2C驱动,把每个坑都踩一遍。你跟着做一遍,基本就入门了。

好了,这一章就聊到这儿。环境搭好是第一步,也是最磨人的一步。但相信我,熬过去之后,后面的路就好走了。


公众号:蓝海资料掘金营,微信deep3321