树莓派4B编写HDF驱动示例 原创 精华
丨张明亮丨
发布于 2021-12-31 12:45
浏览
4收藏
【本文正在参与优质创作者激励】
前言
前段时间已经在树莓派4B成功加入了HDF驱动框架,帖子链接。得用HDF编写个自己的驱动来测试下移植的效果。不说了代码最实在,看代码吧。
1.内核态驱动代码
一个简单的测试驱动,可以认为是串口驱动。因为在linux内核下,所以驱动放置在linux\platform\uart目录下。
drivers\adapter\khdf\linux\platform\uart\my_hdf_uart.c
#include "hdf_device_desc.h" // HDF框架对驱动开发相关能力接口的头文件
#include "hdf_log.h" // HDF 框架提供的日志接口头文件
#define HDF_LOG_TAG "my_hdf_uart" // 打印日志所包含的标签,如果不定义则用默认定义的HDF_TAG标签
// 【3.1驱动消息机制管理】Dispatch是用来处理用户态发下来的消息
int32_t MyUartDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
{
HDF_LOGE("%s::enter", __func__);
HDF_LOGE("get cmdId::%d",cmdId);
return HDF_SUCCESS;
}
// 【1.驱动开发】驱动对外提供的服务能力,将相关的服务接口绑定到HDF框架
int32_t MyHdfUartDriverBind(struct HdfDeviceObject *deviceObject)
{
HDF_LOGE("%s::enter", __func__);
// 【2.驱动服务管理】deviceObject为HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口
if (deviceObject == NULL) {
HDF_LOGE("My Uart device object is null!");
return HDF_FAILURE;
}
static struct IDeviceIoService testService = {
.Dispatch = MyUartDriverDispatch, // 【3.2驱动消息机制管理】在服务实现过程中,实现服务基类成员IDeviceIoService中的Dispatch方法
.Open = NULL, // 【2.驱动服务管理】驱动提供的其他服务。
.Release = NULL,
// .ServiceA = SampleDriverServiceA,
};
deviceObject->service = &testService;
return HDF_SUCCESS;
}
// 【1.驱动开发】驱动自身业务初始的接口
int32_t MyHdfUartDriverInit(struct HdfDeviceObject *deviceObject)
{
HDF_LOGE("%s::enter", __func__);
HDF_LOGD("Uart driver bind success");
return 0;
}
static int32_t MyUartParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)
{
HDF_LOGE("%s::enter", __func__);
return 0;
}
// 【1.驱动开发】驱动资源释放的接口
void MyHdfUartDriverRelease(struct HdfDeviceObject *deviceObject)
{
HDF_LOGE("%s::enter", __func__);
return;
}
// 【1.驱动开发】定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量
struct HdfDriverEntry g_myhdfUartDriverEntry = {
.moduleVersion = 1,
.moduleName = "my_hdf_uart",
.Bind = MyHdfUartDriverBind,
.Init = MyHdfUartDriverInit,
.Release = MyHdfUartDriverRelease,
};
// 【1.驱动开发】调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
HDF_INIT(g_myhdfUartDriverEntry);
drivers\adapter\khdf\linux\platform\uart\Makefile:将驱动加入内核编译
- uart_adapter.o
+ uart_adapter.o \
+ my_hdf_uart.o
2.添加驱动配置文件
vendor\raspberrypi\RPI4B\hdf_config\khdf\device_info\device_info.hcs
# device_uart :: device 下添加
device2 :: deviceNode {
policy = 2;
permission = 0644;
priority = 40;
moduleName = "my_hdf_uart";
serviceName = "my_hdf_uart_service";
}
3.用户态HDF驱动交互验证
applications\standard\app\myuarttest.c:用户态主程序,主要代码已经添加注释了。
#include <utils/hdf_log.h>
#include <core/hdf_io_service_if.h>
#include "hdf_sbuf.h"
#define HDF_LOG_TAG "my_hdf_uart"
#define SAMPLE_SERVICE_NAME "my_hdf_uart_service"
#define SAMPLE_WRITE_READ 1001 // 【驱动消息机制管理】读写操作码,驱动定义消息处理函数中的cmd类型
int main()
{
HDF_LOGE("%s::enter", __func__);
int ret = 0;
// 用户态获取驱动的服务,获取该服务之后通过服务中的Dispatch方法向驱动发送消息。
struct HdfIoService *serv = HdfIoServiceBind(SAMPLE_SERVICE_NAME); // 【3驱动消息机制管理】用户态(通过服务名)获取服务接口
if (serv == NULL) {
HDF_LOGE("fail to get service %s", SAMPLE_SERVICE_NAME);
return HDF_FAILURE;
}
char *sendData = "";
struct HdfSBuf *data = HdfSBufObtainDefaultSize(); // 存放要发送的数据
if (!HdfSbufWriteString(data, sendData)) { // 发送的内容赋值
HDF_LOGE("fail to write sbuf");
ret = HDF_FAILURE;
}
struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); // 存放返回的数据
ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); // 发送消息到驱动
if (ret != HDF_SUCCESS) {
HDF_LOGE("fail to send service call");
}
HdfIoServiceRecycle(serv);
return HDF_SUCCESS;
}
applications\standard\app\BUILD.gn:编写构建脚本
import("//build/ohos.gni")
import("//drivers/adapter/uhdf2/uhdf.gni")
ohos_executable("myuarttest") {
sources = [
"myuarttest.c"
]
include_dirs = [
"//drivers/framework/include", # <utils/hdf_log.h> <core/hdf_io_service_if.h>
"//drivers/adapter/uhdf2/osal/include", # hdf_log_adapter.h
"//base/hiviewdfx/hilog/interfaces/native/innerkits/include", # <hilog/log.h>
"//drivers/framework/ability/sbuf/include", # hdf_sbuf.h
"//drivers/framework/include/utils", # hdf_base.h
]
deps = [
"//drivers/adapter/uhdf2/osal:libhdf_utils", # hdf_log_adapter.h
"//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog" # <hilog/log.h>
]
subsystem_name = "applications"
part_name = "prebuilt_hap"
}
applications\standard\hap\ohos.build:最后将app加入编译框架
+ "//applications/standard/app:myuarttest",
4.测试
最后执行用户态的myuarttest程序,就可以测试驱动是否添加成功了。
用户态只需要发送cmdId
比如1001,然后内核驱动程序根据cmdID执行相应的操作即可。
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
赞
6
收藏 4
回复
相关推荐
亮哥太实在了