news 2026/4/28 17:07:25

鸿蒙 HDF 驱动开发初探:如何为 Hi3861 开发板编写一个自定义的 LED 驱动?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙 HDF 驱动开发初探:如何为 Hi3861 开发板编写一个自定义的 LED 驱动?

标签:#HarmonyOS #HDF #驱动开发 #Hi3861 #嵌入式 #南向开发


🧬 前言:为什么一定要用 HDF?

你可能会问:“直接操作寄存器或者调 GPIO 库不香吗?为什么要套这么厚一层 HDF 壳子?”

HDF 的核心价值:

  1. 解耦:驱动代码不依赖具体的 OS 内核。
  2. 统一管理:系统统一加载、管理驱动的生命周期(加载、初始化、卸载)。
  3. 安全性:在标准系统(Standard)中,HDF 驱动运行在用户态,挂了也不会导致内核崩溃。

HDF 驱动架构图 (Mermaid):

内核空间 / HDF 框架

1. HdfIoServiceBind
2. Dispatch
3. Bind/Init
4. GpioWrite

用户态应用 (APP)

HDF 框架管理器

驱动入口 (DriverEntry)

驱动实现逻辑

硬件 (GPIO LED)


📝 一、 配置文件:描述你的硬件 (HCS)

鸿蒙引入了HCS (HDF Configuration Source),类似于 Linux 的设备树 (Device Tree)。我们需要告诉系统:有一个名为sample_led的设备。

找到源码中的device_info.hcs(通常在vendor/hisilicon/hispark_pegasus/hdf_config/ihct/下),添加节点:

root { device_info { match_attr = "hdf_manager"; template host { hostName = "host0"; priority = 100; // 定义一个名为 sample_host 的宿主 device_sample :: device { device0 :: deviceNode { policy = 2; // 2: 对外发布服务,应用层可见 priority = 100; preload = 0; // 0: 按需加载 1: 随系统启动 permission = 0664; moduleName = "HDF_SAMPLE_LED"; // ⚠️ 关键:要与C代码匹配 serviceName = "hdf_led_service"; // 应用层绑定的名字 deviceMatchAttr = "sample_led_config"; } } } } }

💻 二、 驱动实现:核心 C 代码

drivers/hdf_core/adapter/khdf/liteos_m/(或其他驱动目录) 下新建hdf_led_driver.c

驱动开发的核心就是填充HdfDriverEntry结构体。

1. 定义控制指令
#include"hdf_device_desc.h"#include"hdf_log.h"#include"gpio_if.h"// LED 连接的 GPIO 管脚 (Hi3861通常是 GPIO 9)#defineLED_GPIO_PIN9// 命令码enum{LED_WRITE_ON=1,LED_WRITE_OFF,};
2. 业务逻辑 (Dispatch)

这是应用层调用驱动的入口。

// 接收用户态发来的指令staticint32_tLedDriverDispatch(structHdfDeviceIoClient*client,intcmdId,structHdfSBuf*data,structHdfSBuf*reply){if(cmdId==LED_WRITE_ON){// 点亮 LED (低电平还是高电平取决于电路,假设低电平亮)GpioWrite(LED_GPIO_PIN,0);HDF_LOGI("LED Driver: ON");}elseif(cmdId==LED_WRITE_OFF){// 熄灭 LEDGpioWrite(LED_GPIO_PIN,1);HDF_LOGI("LED Driver: OFF");}else{returnHDF_FAILURE;}returnHDF_SUCCESS;}
3. 生命周期绑定 (Bind & Init)
// 1. 驱动对外提供的服务对象staticint32_tHdfLedDriverBind(structHdfDeviceObject*deviceObject){staticstructIDeviceIoServiceservice={.Dispatch=LedDriverDispatch,// 绑定分发函数};deviceObject->service=&service;returnHDF_SUCCESS;}// 2. 驱动初始化 (设置 GPIO 方向)staticint32_tHdfLedDriverInit(structHdfDeviceObject*deviceObject){GpioSetDir(LED_GPIO_PIN,GPIO_DIR_OUT);HDF_LOGI("Hdf Led Driver Init Success!");returnHDF_SUCCESS;}// 3. 驱动卸载staticvoidHdfLedDriverRelease(structHdfDeviceObject*deviceObject){HDF_LOGI("Hdf Led Driver Released");}
4. 注册驱动

这一步将 C 代码与 HCS 配置文件关联起来。

// 定义驱动入口structHdfDriverEntryg_ledDriverEntry={.moduleVersion=1,.moduleName="HDF_SAMPLE_LED",// ⚠️ 必须与 HCS 中的 moduleName 一致.Bind=HdfLedDriverBind,.Init=HdfLedDriverInit,.Release=HdfLedDriverRelease,};// 宏注册HDF_INIT(g_ledDriverEntry);

🔨 三、 编译构建:GN 脚本

鸿蒙使用 GN + Ninja 进行构建。你需要修改BUILD.gn文件,将你的.c文件加入编译列表。

hdf_driver("hdf_sample_led") { sources = [ "hdf_led_driver.c", ] include_dirs = [ "//drivers/hdf_core/framework/include", "//drivers/hdf_core/framework/include/core", "//drivers/hdf_core/adapter/khdf/liteos_m", ] }

🕹️ 四、 应用层调用:点灯时刻

最后,我们写一个简单的 APP 来验证驱动。

#include"hdf_io_service_if.h"voidTestLedDriver(){// 1. 获取驱动服务 (对应 HCS 中的 serviceName)structHdfIoService*serv=HdfIoServiceBind("hdf_led_service");if(serv==NULL){printf("Fail to bind service!\n");return;}// 2. 发送指令staticstructHdfSBuf*data=NULL;staticstructHdfSBuf*reply=NULL;// 亮灯printf("Send command: ON\n");serv->dispatcher->Dispatch(&serv->object,1,data,reply);osDelay(100);// 延时// 灭灯printf("Send command: OFF\n");serv->dispatcher->Dispatch(&serv->object,2,data,reply);// 3. 回收资源HdfIoServiceRecycle(serv);}

🎯 总结

通过这个案例,我们走通了鸿蒙驱动开发的完整链路:

  1. HCS 配置:像填写简历一样描述硬件。
  2. HdfDriverEntry:像填写表格一样实现驱动生命周期。
  3. HdfIoServiceBind:像调用 API 一样在应用层控制硬件。

这比直接写裸机代码要复杂,但它带来的标准化可移植性,是迈向高级嵌入式开发的必经之路。

Next Step:
尝试给驱动增加一个“读取状态”的功能。在LedDriverDispatch中增加一个 cmdId,利用GpioRead读取当前 LED 的电平,并通过reply参数返回给应用层。这能让你理解 HDF 是如何做双向数据传输的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/26 19:06:30

COOH-CH2-S-CH2-COOH,羧基-双硫醚-羧基,偶联药物与生物分子

COOH-CH2-S-CH2-COOH,羧基-双硫醚-羧基,偶联药物与生物分子一、COOH–CH₂–S–CH₂–COOH 的基本描述COOH–CH₂–S–CH₂–COOH 是一种以 硫醚桥链(–S–) 连接两端羧基的双功能化小分子,化学结构可以表示为&#xf…

作者头像 李华
网站建设 2026/4/27 6:43:07

SGMICRO圣邦微 SGM811B-TXKA4G/TR SOT143 监控和复位芯片

功能特性 MAX811/MAX812和ADM811/ADM812的卓越升级版 高精度固定检测选项:3V和3.3V 低供电电流:<1uA(典型值) 200毫秒(典型值)上电复位脉冲宽度 复位输出选项: 低电平有效复位输出:SGM811B 高电平复位输出:SGM812B 手动复位输入 复位有效电压低至VccIV -40C至125C工作温度范…

作者头像 李华
网站建设 2026/4/25 17:54:59

基于深度学习的船舶识别与会遇态势判断方法研究【附代码】

✅ 博主简介&#xff1a;擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。✅成品或者定制&#xff0c;扫描文章底部微信二维码。(1) 基于多尺度特征提取的船舶图像识别网络设计船舶会遇态势识别是海上交通安全的重要…

作者头像 李华
网站建设 2026/4/25 17:56:38

书匠策AI:文献综述写作的“时空折叠器”,开启学术探索新次元

当你在浩如烟海的学术文献中苦苦寻觅&#xff0c;试图拼凑出研究领域的历史脉络与未来方向时&#xff0c;是否幻想过拥有一台“时空折叠器”&#xff0c;能瞬间将散落的学术碎片整合成一幅完整的地图&#xff1f;书匠策AI&#xff08;官网&#xff1a;http://www.shujiangce.co…

作者头像 李华
网站建设 2026/4/27 6:38:06

深度学习在钢板表面缺陷与字符识别中的应用【附代码】

✅ 博主简介&#xff1a;擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。✅成品或者定制&#xff0c;扫描文章底部微信二维码。(1) 基于多尺度感受野与图像重构的钢板表面缺陷分类方法钢板表面缺陷图像具有类内差异…

作者头像 李华
网站建设 2026/4/25 19:25:46

打工人上班摸魚小說-第六章 病遁、加薪与U盘深处的秘密

第六章 病遁、加薪与U盘深处的秘密 “精力充沛&#xff08;被动&#xff09;”的效果是潜移默化的。 周末两天&#xff0c;林舟睡得格外踏实&#xff0c;醒来时那种仿佛被卡车碾过的沉重感消失了。喉咙的不适也彻底消退&#xff0c;周一清晨站在镜子前&#xff0c;他甚至觉得…

作者头像 李华