当前位置: 首页 > news >正文

鸿蒙 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 是如何做双向数据传输的。

http://www.jsqmd.com/news/248459/

相关文章:

  • 通孔PCB vsSMT贴片:教你选对组装方案
  • 计算机论文写作一站式指南:6款AI工具1天生成8000字附真实参考文献
  • 通孔PCB的5大核心优势
  • 【时频分析】面向相交群延迟多分量信号的时频重分配同步挤压频域线性调频小波变换【附MATLAB代码】
  • 课程论文不用 “水”!虎贲等考 AI 一键解锁高质量写作捷径
  • 计算机领域学术发表地图:CCF与CAAI等分级体系全解析
  • 五行代码,逼疯整个硅谷!澳洲放羊大叔,捅开AI编程奇点
  • COOH-SS-PEG-COOH,羧基-二硫键-聚乙二醇-羧基,适用于药物递送系统
  • 人工造问卷 VS 虎贲等考 AI:30 分钟搞定学术调研 “黄金问卷”
  • 必藏!大模型“记忆力“突破:从2K到百万Token的技术演进与原理详解
  • 数据不会说话?虎贲等考 AI 数据分析:让论文实证硬核到惊艳导师
  • 无缝集成指南,SpringBoot三步接入华为云短信服务
  • 黑灯工厂的本质就是无人经济
  • 一张图看懂上下文工程:AI提示技术的核心概念解析
  • 【收藏必备】大模型开发核心技能:格式化输出与解析器全攻略
  • COOH-S-CH2-S-COOH,双羧基和响应性桥链
  • Python+Vue的记账系统的设计与实现 Pycharm django flask
  • GraphRAG 落地:用 Neo4j 构建知识图谱,让 AI 读懂《红楼梦》的人物关系
  • Python+Vue的学生选课管理系统 Pycharm django flask
  • 【收藏学习】大模型RAG技术全攻略:从基础原理到高级优化方案
  • Webpack 慢到离谱?迁移到 Rspack (Rust) 实战:构建速度从 5 分钟缩短到 10 秒
  • Python+Vue的养老院信息管理系统设计与实现 Pycharm django flask
  • 书匠策AI:你的文献综述“第二大脑”,如何重塑学术写作的游戏规则?
  • Service Mesh 落地:Istio 流量治理实战,如何实现“金丝雀发布”与全链路熔断?
  • Python+Vue的线上社区信息发布管理平台设计 Pycharm django flask
  • 书匠策AI:文献综述写作的“时空穿越指南”
  • 从 Chat 到 Agent:Solon AI 带你进入“行动派”大模型时代
  • 学术写作新革命:书匠策AI如何让文献综述“自动成章”
  • 解锁文献综述新境界:书匠策AI的“学术星图导航仪”
  • 微信投票源码系统的十大核心优势,支持图片、音频、视频等多形式投票