#include 赞 踩 本文首发于: LHM’s notes欢迎关注我的新博客 vendor/huawei/hdf下新建文件夹,内部新增驱动文件 目录:vendor/hisi/hi35xx/hi3518ev300/config/device_info/device_info/device_info.hcs 添加方式有两种,第一种是新建一个sample_host节点 第二种是在host节点下面,新增一个device节点 目录:vendor/hisi/hi35xx/hi3518ev300/config/ 新建test 目录,新增sample_config.hcs 私有配置写好后,需要加载到板级配置入口文件vendor/hisi/hi35xx/hi3518ev300/config/hdf.hcs 驱动代码的编译必须使用HDF框架提供的Makefile模板进行编译 1/首先是Kconfig, 路径与驱动文件同级 2/然后在test目录下新增Makefile文件 3/将新增Kconfig文件添加到test文件夹同级目录下的Kconfig文件中 目录:vendor/huawei/hdf/Kconfig 修改: 4/修改vendor/huawei/hdf/hdf_vendor.mk文件 首先在官网指导最后面,有这样一句话 修改成空格后,接着编译,报错找不到头文件。 找了下头文件的位置: 将头文件目录添加到BUILD.gn中,再次编译,报错hdf_sbuf.h中include的一个头文件找不到,说明头文件目录还没有添加全,继续全局搜索,添加头文件目录 最后添加目录如下: 此时编译,不会出现头文件找不到的目录,出现另一个错误 重新梳理了下流程,这个感觉是没有正确依赖so; 官网最后的声明也确实强调要新增两个库的依赖,那会不会是这两行deps 放的位置不对呢? 在看了其他文件夹中BUILD.gn的写法后,修改尝试下(将deps上移) Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。
鸿蒙驱动实战_鸿蒙系统接入驱动
用户态代码
#include <stdio.h>
#include "los_sample.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "hdf_sbuf.h"
#include "hdf_io_service_if.h"
enum rw {
regrd,
regwd,
};
int main(int argc, char **argv)
{
printf("\n************************************************\n");
printf("\n\t\t lhm's test --> fist drv!\n");
printf("\n***********************************************\n\n");
struct HdfIoService *serv = HdfIoServiceBind("sample_service", 0);
if (serv == NULL) {
printf("fail to get service %s\n", "sample_service");
return HDF_FAILURE;
} else {
printf("get service %s\n", "sample_service");
}
// 分配两个消息交互需要的hdfbuf
struct HdfSBuf *data = HdfSBufObtainDefaultSize();
if (data == NULL) {
printf("fail to obtain sbuf data\n");
return -1;
}
struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
if (data == NULL) {
printf("fail to obtain sbuf reply\n");
return -1;
}
//向data中写入寄存器数据 32位
if (HdfSbufWriteUint32(data, (int)0x45) == false) {
printf("fail to write sbuf\n");
return -1;
}
// 调用dispatch
int ret = serv->dispatcher->Dispatch(&serv->object, regwd, data, reply);
if (ret != HDF_SUCCESS) {
printf("app fail to write\n");
return -1;
}
ret = serv->dispatcher->Dispatch(&serv->object, regrd, data, reply);
if (ret != HDF_SUCCESS) {
printf("app fail to read\n");
return -1;
}
int regdata = 0;
if (HdfSbufReadUint32(reply, (unsigned int*)®data) == false) {
printf("app fail to read ss\n");
return -1;
}
printf("reg data: 0x%x\n", regdata);
return 0;
}
驱动文件
#include "hdf_device_desc.h" // HDF框架对驱动开放相关能力接口的头文件
#include "hdf_log.h" // HDF 框架提供的日志接口头文件
#define HDF_LOG_TAG sample_driver // 打印日志所包含的标签,如果不定义则用默认定义的HDF_TAG标签
int reg = 0;
enum rw {
regrd,
regwd,
};
int func_regrd(void) {
return reg;
}
void func_regwd(int regdata) {
reg = regdata;
}
// 驱动服务结构的定义
struct ISampleDriverService {
struct IDeviceIoService ioService; //服务结构的首个成员必须是IDeviceIoService类型的成员
// 下面可以自定义驱动的服务接口
int (*ServiceRd)(void);
void (*ServiceWd)(int);
};
int32_t SampleDriverDispatch(struct HdfDeviceIoClient *client, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) {
int tmp = 0;
const struct ISampleDriverService *sampleService =
(const struct ISampleDriverService*)DevSvcManagerClntGetService("sample_service");
if (cmdCode == regrd) {
tmp = sampleService->ServiceRd();
if (HdfSbufWriteUint32(reply, tmp) == false) {
HDF_LOGE("fail to write sbuf");
} else {
HDF_LOGI(" write sbuf success");
}
} else if (cmdCode == regwd) {
if (HdfSbufReadUint32(data, (unsigned int*)&tmp) == false) {
HDF_LOGE("DRV fail to READ sbuf");
} else {
sampleService->ServiceWd(tmp);
HDF_LOGI(" READ sbuf success");
}
}
return 0;
}
//驱动对外提供的服务能力,将相关的服务接口绑定到HDF框架
int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
{
// deviceObject为hdf框架每一个驱动创建设备对象 用来保存设备相关的私有数据和服务接口
if (deviceObject == NULL) {
HDF_LOGE("deviceObject is null");
return -1;
}
static struct ISampleDriverService mySampleDriver = {
.ioService.Dispatch = SampleDriverDispatch,
.ServiceRd = func_regrd,
.ServiceWd = func_regwd,
};
deviceObject->service = &mySampleDriver.ioService;
HDF_LOGD("Sample driver bind success");
return 0;
}
// 驱动自身业务初始的接口
int32_t HdfSampleDriverInit(struct HdfDeviceObject *deviceObject)
{
HDF_LOGD("Sample driver Init success");
return 0;
}
// 驱动资源释放的接口
void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject)
{
HDF_LOGD("Sample driver release success");
return;
}
// 定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量
struct HdfDriverEntry g_sampleDriverEntry = {
.moduleVersion = 1,
.moduleName = "sample_driver",
.Bind = HdfSampleDriverBind,
.Init = HdfSampleDriverInit,
.Release = HdfSampleDriverRelease,
};
// 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
HDF_INIT(g_sampleDriverEntry);
配置文件
sample_host :: host{
hostName = "host0"; // host名称,host节点是用来存放某一类驱动的容器
priority = 100; //值越大 优先级越低
}
device_sample :: device {
device0 :: deviceNode {
policy = 2; // 2->内核态 和用户态都发布服务
priority = 100;
permission = 0644;
moduleName = "sample_driver";
serviceName = "sample_service";
deviceMatchAttr = "sample_driver";
}
}
私有配置文件信息
root{
sample_version = 1;
author = "lhm";
module = "sample_driver";
serviceName = "sample_service";
match_attr = "sample_config"; //该字段的值必须和device_info.hcs中deviceMatchAttr值一致
}
驱动编译配置项
config DRIVERS_HDF_PLATFORM_UART_SAMPLE
bool "Enable HDF platform lhm sample driver"
default n
depends on DRIVERS_HDF_PLATFORM
help
Answer Y to enable HDF platform uart sample driver.
include $(LITEOSTOPDIR)/config.mk
include $(LITEOSTOPDIR)/../../drivers/hdf/lite/lite.mk
MODULE_NAME := sample_driver
LOCAL_CFLAGS += $(HDF_INCLUDE)
LOCAL_SRCS += sample_driver.c
LOCAL_HCS_SRCS+=test/sample_config.hcs
LOCAL_CFLAGS += -fstack-protector-strong
include $(HDF_DRIVER)
source "../../vendor/hisi/hi35xx/platform/Kconfig"
source "../../vendor/huawei/hdf/wifi/driver/Kconfig"
source "../../vendor/huawei/hdf/input/driver/Kconfig"
source "../../vendor/huawei/hdf/display/driver/Kconfig"
source "../../vendor/huawei/hdf/test/Kconfig"
LITEOS_BASELIB += -lsample_driver
LIB_SUBDIRS += $(VENDOR_HDF_DRIVERS_ROOT)/test
遇到的问题
harmony_docs
然后按这个说明将这个deps替代原来那个;这个位置其实依赖的是共享so; 原来代码是不需要任何依赖,但是里面写了个:hello_word 估计是个模板。
需要注意的是,间距调整不能用table键,不然会报如下错误:ERROR at //applications/sample/camera/app/BUILD.gn:41:1: Invalid token.
"//drivers/hdf/lite/manager:hdf_core",
^
You got a tab character in here. Tabs are evil. Convert to spaces.
helloworld.c:22:10: fatal error: 'hdf_sbuf.h' file not found
[root@iZ8vb7hcv48qpdyb1zrnfjZ sourceCode]# find -name hdf_sbuf.h ./drivers/hdf/frameworks/ability/sbuf/include/hdf_sbuf.h
include_dirs = [
"include",
"//drivers/hdf/frameworks/ability/sbuf/include",
"//drivers/hdf/frameworks/utils/include",
"//drivers/hdf/frameworks/include/core",
"//drivers/hdf/frameworks/include/utils",
]
ld.lld: error: undefined symbol: HdfIoServiceBind
>>> referenced by ld-temp.o
>>> lto.tmp:(main)
放到feature后,这个问题就迈过去了;