嵌入式系统开发 -基于分布式系统OpenHarmony 课件 04-HDF驱动程序框架;05-OpenHarmony的系统构成;06用户程序框架_第1页
嵌入式系统开发 -基于分布式系统OpenHarmony 课件 04-HDF驱动程序框架;05-OpenHarmony的系统构成;06用户程序框架_第2页
嵌入式系统开发 -基于分布式系统OpenHarmony 课件 04-HDF驱动程序框架;05-OpenHarmony的系统构成;06用户程序框架_第3页
嵌入式系统开发 -基于分布式系统OpenHarmony 课件 04-HDF驱动程序框架;05-OpenHarmony的系统构成;06用户程序框架_第4页
嵌入式系统开发 -基于分布式系统OpenHarmony 课件 04-HDF驱动程序框架;05-OpenHarmony的系统构成;06用户程序框架_第5页
已阅读5页,还剩217页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于OpenHarmony的嵌入式开发

第四章HDF驱动程序框架安全边距4.1HDF编程特点[4.1]硬件适配问题背景:OpenHarmony需要面对大量硬件设备的适配问题。这些硬件的离散度很高,其性能差异与配置差异也很大,所以系统中必须要有更灵活、功能更强大、能耗更低的驱动框架,消除硬件差异。

HDF(HardwareDriverFoundation)驱动框架,为驱动开发者提供了驱动框架能力,包括了驱动加载、驱动服务管理和驱动消息机制。

HDF提供操作系统抽象层(OSAL,OperatingSystemAbstractionLayer)和平台抽象层(PAL,PlatformAbstractionLayer)来保证驱动程序的跨系统跨平台部署特性。

HDF提供驱动模型的抽象、公共工具、外围器件框架等能力。开发者应该基于HDF提供的这些能力开发驱动,从而保证驱动程序可以在各种形态的OpenHarmony上进行部署。基于OpenHarmony的嵌入式开发2安全边距4.1HDF编程特点[4.1.1]HDF驱动框架概述基于OpenHarmony的嵌入式开发3安全边距4.1HDF编程特点[4.1.1]HDF驱动框架概述基于OpenHarmony的嵌入式开发4驱动基础框架功能。HDF驱动基础框架提供统一的硬件资源管理,驱动加载管理以及设备节点管理等功能。驱动框架采用的是主从模式设计,由DeviceManager和DeviceHost组成。DeviceManager提供了统一的驱动管理,DeviceManager启动时根据DeviceInformation提供驱动设备信息加载相应的驱动DeviceHost,并控制Host完成驱动的加载。DeviceHost提供驱动运行的环境,同时预置HostFramework与DeviceManager进行协同,完成驱动加载和调用。根据业务的需求DeviceHost可以有多个实例。安全边距4.1HDF编程特点[4.1.1]HDF驱动框架概述基于OpenHarmony的嵌入式开发5驱动程序。驱动程序实现驱动具体的功能,每个驱动由一个或者多个驱动程序组成,每个驱动程序都对应着一个DriverEntry。DriverEntry主要完成驱动的初始化和驱动接口绑定功能。驱动配置文件。驱动配置文件.hcs主要由设备信息(DeviceInformation)和设备资源(DeviceResource)组成。DeviceInformation完成设备信息的配置。如配置接口发布策略,驱动加载的方式等。DeviceResource完成设备资源的配置。如GPIO管脚、寄存器等资源信息的配置。安全边距4.1HDF编程特点[4.1.1]HDF驱动框架概述基于OpenHarmony的嵌入式开发6驱动接口HDI(HardwareDriverinterface)。HDI提供标准化的接口定义和实现,驱动框架提供IOService和IODispatcher机制,使得不同部署形态下驱动接口趋于形式一致。其中,HDI是对硬件功能的较高层次抽象接口,各类外设完成HDI接口定义后便只会在HDI的兼容性规则下进行变更,从而保证接口的稳定性。具体的驱动实现不需要再重复定义HDI接口,只需要按需实现即可接入系统功能安全边距4.1HDF编程特点[4.1.2]HDF框架特点基于OpenHarmony的嵌入式开发7多种驱动加载方式HDF驱动加载包括按需加载和按序加载。按需加载是指HDF框架支持驱动在系统启动过程中默认加载,或者在系统启动之后动态加载。按序加载是指HDF框架支持驱动在系统启动的过程中按照驱动的优先级进行加载。驱动服务管理HDF框架可以集中管理驱动服务,开发者可直接通过HDF框架对外提供的能力接口获取驱动相关的服务。驱动消息机制HDF框架提供统一的驱动消息机制,支持用户态应用向内核态驱动发送消息,也支持内核态驱动向用户态应用发送消息。HDF框架将一类设备驱动放在同一个host里面,开发者也可以将驱动功能分层独立开发和部署,支持一个驱动多个node。Host:同一类设备放置在相同Host中,Host不可重复配置,Device也禁止在不同Host中安全边距4.1HDF编程特点[4.1.2]HDF的重要数据结构编码特点:使用C语言实现了面向对象的编程(1)HdfObject(2)HdfDeviceObject

基于OpenHarmony的嵌入式开发8structHdfObject{int32_tobjectId;/**<BaseobjectID*/};structHdfDeviceObject{/**Pointertotheserviceinterfaceobject,whichisregisteredwiththeHDFbythedriver*/structIDeviceIoService*service;/**Pointertothepropertyofthedevice,whichisreadbytheHDFfromtheconfigurationfileandtransmittedtothedriver.*/#ifdefLOSCFG_DRIVERS_HDF_CONFIG_MACROconstchar*deviceMatchAttr;#elseconststructDeviceResourceNode*property;#endifDeviceClassdeviceClass;/**Pointertotheprivatedataofthedevice*/void*priv;};DescribesbaseclassobjectsdefinedbytheHDF.ThisstructureisadeviceobjectdefinedbytheHDFandisusedtostoreprivatedataandinterfaceinformation

ofadevice.安全边距4.1HDF编程特点[4.1.2]HDF的重要数据结构编码特点:使用C语言实现了面向对象的编程(3)HdfDeviceIoClient(4)IDeviceIoService注册服务IDeviceIoService对外提供了三个接口,分别是:①Open,在用户态程序调用驱动服务时被调用,用于启动服务;②Dispatch,在用户态程序调用驱动服务分发消息时被调用,用于分发消息;③Release,在用户态程序不再需要该驱动服务时被调用,用于释放服务。基于OpenHarmony的嵌入式开发9structHdfDeviceIoClient{/**Deviceobjectcorrespondingtotheclientobject*/structHdfDeviceObject*device;/**Privatedataoftheclientobject.Thedrivercanuse<b>priv</b>tobindtheinternaldatawiththeclient.*/void*priv;};ThisstructuredescribestheinvokerinformationoftheI/Oservcie.安全边距4.1HDF编程特点[4.1.2]HDF的重要数据结构编码特点:使用C语言实现了面向对象的编程(4)IDeviceIoService注册服务

①Open启动服务;②Dispatch分发消息;③Release释放服务。基于OpenHarmony的嵌入式开发10structIDeviceIoService{/**DriverserviceobjectID*/structHdfObjectobject;/***@briefCalledwhenthedriverserviceisenabledbyauser-levelapplication.*/

int32_t(*Open)(structHdfDeviceIoClient*client);/***@briefCalledwhenthedriverserviceisinvokedbyauser-levelapplication.

*/

int32_t(*Dispatch)(structHdfDeviceIoClient*client,intcmdId,structHdfSBuf*data,structHdfSBuf*reply);/***@briefCalledwhenthedriverserviceisreleasedbyauser-levelapplication.

*/

void(*Release)(structHdfDeviceIoClient*client);};安全边距4.1HDF编程特点[4.1.2]HDF的重要数据结构编码特点:使用C语言实现了面向对象的编程

(5)HdfDriverEntry:所有启动程序入口的虚基类:驱动必须实现基于OpenHarmony的嵌入式开发11structHdfDriverEntry{

int32_tmoduleVersion;

constchar*moduleName;/***@briefBindstheexternalserviceinterfaceofadrivertotheHDF.Thisfunctionisimplementedbythedriver*developerandcalledbytheHDF.

*/

int32_t(*Bind)(structHdfDeviceObject*deviceObject);

/***@briefInitializesthedriver.ThisfunctionisimplementedbythedriverdeveloperandcalledbytheHDF.*/int32_t(*Init)(structHdfDeviceObject*deviceObject);

/***@briefReleasesdriverresources.Thisfunctionisimplementedbythedriverdeveloper.Whenanexception*occursduringdriverloadingorthedriverisuninstalled,theHDFcallsthisfunctiontoreleasethe*driverresources.

*/

void(*Release)(structHdfDeviceObject*deviceObject);};将驱动函数的外部接口绑定到HDF上,驱动需要实现自身的IDeviceIoService接口初始化驱动程序,主要是对驱动程序的特有数据进行初始化销毁驱动程序,包括驱动程序在初始化过程中申请的内存和硬件资源等安全边距4.2驱动程序配置文件[4.1.2]HDF的重要数据结构编码特点:使用C语言实现了面向对象的编程(6)HdfObjectCreator

:实现了对象的构建机制基于OpenHarmony的嵌入式开发12structHdfObjectCreator{structHdfObject*(*Create)(void);void(*Release)(structHdfObject*);};staticconststructHdfObjectCreatorg_liteObjectCreators[]={[HDF_OBJECT_ID_DEVMGR_SERVICE]={.Create=DevmgrServiceCreate,.Release=DevmgrServiceRelease,},

……conststructHdfObjectCreator*HdfObjectManagerGetCreators(intobjectId){intnumConfigs=sizeof(g_liteObjectCreators)/sizeof(g_liteObjectCreators[0]);if((objectId>=0)&&(objectId<numConfigs)){return&g_liteObjectCreators[objectId];}returnNULL;}注意实现机制安全边距4.2驱动程序配置文件[4.2.1]驱动开发的基本步骤

HDF框架进行驱动的开发主要分为驱动实现和驱动配置两部分1驱动实现-入口基于OpenHarmony的嵌入式开发13驱动必须要实现什么?功能?启动程序入口int32_t(*Bind)(structHdfDeviceObject*deviceObject);int32_t(*Init)(structHdfDeviceObject*deviceObject);void(*Release)(structHdfDeviceObject*deviceObject);#include“hdf_device_desc.h”

//HDF框架对驱动开放相关能力接口的头文件#include“hdf_log.h”

//HDF框架提供的日志接口头文件//打印日志所包含的标签,如果不定义则用默认定义的HDF_TAG标签#defineHDF_LOG_TAG"sample_driver"//驱动对外提供的服务能力,将相关的服务接口绑定到HDF框架int32_tHdfSampleDriverBind(structHdfDeviceObject*deviceObject){HDF_LOGD(“Sampledriverbindsuccess”);

return0;

}//驱动自身业务初始的接口int32_tHdfSampleDriverInit(structHdfDeviceObject*deviceObject){HDF_LOGD(“SampledriverInitsuccess”);return0;

}//驱动资源释放的接口voidHdfSampleDriverRelease(structHdfDeviceObject*deviceObject){HDF_LOGD(“Sampledriverreleasesuccess”);return;

}//定义驱动入口的对象//必须为HdfDriverEntry类型的全局变量structHdfDriverEntryg_sampleDriverEntry={.moduleVersion=1,.moduleName="sample_driver",.Bind=HdfSampleDriverBind,.Init=HdfSampleDriverInit,.Release=HdfSampleDriverRelease,};……HDF_INIT(g_sampleDriverEntry);①②安全边距4.2驱动程序配置文件[4.2.1]驱动开发的基本步骤

HDF框架进行驱动的开发主要分为驱动实现和驱动配置两部分2驱动实现-

LiteOS编译:makefile和BUILD.gn基于OpenHarmony的嵌入式开发14include$(LITEOSTOPDIR)/../../drivers/adapter/khdf/liteos/lite.mk#导入HDF的预定义MODULE_NAME:=

#生成的结果文件LOCAL_INCLUDE:=#本驱动的头文件目录LOCAL_SRCS:=

#本驱动的源代码文件LOCAL_CFLAGS:=#自定义的编译选项include$(HDF_DRIVER)#导入模板makefile完成编译LITEOS_BASELIB+=-lxxx#链接生成的静态库LIB_SUBDIRS+=

#驱动代码Makefile的目录import("//build/lite/config/component/lite_component.gni")import("//drivers/adapter/khdf/liteos/hdf.gni")module_switch=defined(LOSCFG_DRIVERS_HDF_xxx)module_name="xxx"hdf_driver(module_name){sources=["xxx/xxx/xxx.c",#模块要编译的源码文件

]public_configs=[":public"]#使用依赖的头文件配置}config("public"){#定义依赖的头文件配置

include_dirs=["xxx/xxx/xxx",#依赖的头文件目录

]}①②group("liteos"){public_deps=[":$module_name"]deps=[“xxx/xxx”,#新增模块BUILD.gn所在的目录

#目录结构是相对于/drivers/adapter/khdf/liteos的]}③④安全边距4.2驱动程序配置文件[4.2.2]基于HCS的配置管理

HDF框架进行驱动的开发主要分为驱动实现和驱动配置两部分HCS以Key-Value形式保存数据,实现配置代码与驱动代码解耦

HC-GEN实现HDF配置文件到软件可读取的文件格式的转换基于OpenHarmony的嵌入式开发15root{device_info{match_attr="hdf_manager";templatehost{hostName="";priority=100;templatedevice{templatedeviceNode{

……

}}}

……sample_host::host{hostName="host0";priority=100;device_sample::device{device0::deviceNode{policy=1;priority=100;preload=0;permission=0664;moduleName="sample_driver";serviceName="sample_service";deviceMatchAttr="sample_config";}}}}}templatehost{}是host模板,也是默认值hostName,表示host的名称,host节点用来存放某一类驱动的容器;priority表示该host的启动优先级(0~200),值越大优先级越低,建议默认设置为100,优先级相同则不保证host的加载顺序;device_sample::device{}中保存的是sample设备节点;device0::deviceNode{}中保存的是sample驱动的DeviceNode节点;安全边距4.2驱动程序配置文件[4.2.3]配置文件的基本语法:关键字和语法

HCS配置文件的基本语法主要包括关键字、基本结构、数据结构和预处理等几个部分,分为属性和节点,都以Key-Value形式保存数据。attribute_name=value;基于OpenHarmony的嵌入式开发16关键字关键字说明root配置根节点,用于声明配置表的根节点。每个配置表必须以root节点开始include引用其他HCS配置文件。文件名必须使用双引号(""),不在同一目录使用相对路径引用。被include文件也必须是合法的HCS文件使用多个include时,如果存在相同的节点,后者覆盖前者,其余的节点依次展开delete删除节点或属性,只能用于操作include导入的配置树template定义模板节点match_attr用于标记节点的匹配查找属性,解析配置时可以使用该属性的值查找到对应节点字母、数字、下划线的组合且以字母或下划线开头,字母区分大小写数字常量、数组、bool型、双引号包裹的字符串或对节点的引用安全边距4.2驱动程序配置文件[4.2.3]配置文件的基本语法:关键字和语法

HCS配置文件的基本语法主要包括关键字、基本结构、数据结构和预处理等几个部分,分为属性和节点,都以Key-Value形式保存数据。

value的则可以是数字常量,支持二进制、八进制、十进制(无前缀,且支持有符号和无符号,例如104、+102和-666均是合法的)、十六进制数、数组(整形或字符串型数组,例如attr_foo=[0x01,0x02,0x03,0x04];再如attr_bar=["hello","world"];)、bool型(true表示真,false表示假),也可以是双引号包裹的字符串或节点引用。

节点则是一组属性的集合,其中,节点名是字母、数字、下划线的组合且必须以字母或下划线开头,字母区分大小写。root节点中必须包含module属性,其值应该为一个字符串,用于表征该配置所属模块。节点中可以增加match_attr属性,其值为一个全局唯一的字符串。在解析配置时可以调用查找接口以该属性的值查找到包含该属性的节点。基于OpenHarmony的嵌入式开发17安全边距4.2驱动程序配置文件[4.2.3]配置文件的基本语法:引用、复制、修改和删除(1)引用修改可以实现修改另外任意一个节点的内容node:&source_node

基于OpenHarmony的嵌入式开发18root{module="sample";foo{foo_:&root.bar{attr="foo";}foo1:&foo2{attr=0x2;}foo2{attr=0x1;}}bar{attr="bar";}}foo.foo_以及foo.foo1节点表示对目标节点内容的修改,其自身并不会存在最终生成的配置树中。foo.foo_节点通过引用将bar.attr属性的值修改为了"foo"foo.foo1节点通过引用将foo.foo2.attr属性的值修改为了0x2root{module="sample";foo{foo2{attr=0x2;}}bar{attr="foo";}}对本配置无效改其他的配置安全边距4.2驱动程序配置文件[4.2.3]配置文件的基本语法:引用、复制、修改和删除(2)复制则是实现在节点定义时从另一个节点先复制内容node:source_node

基于OpenHarmony的嵌入式开发19root{

module="sample";foo{attr_0=0x0;}bar:foo{attr_1=0x1;}}root{module="sample";foo{attr_0=0x0;}bar{attr_1=0x1;attr_0=0x0;}}编译后bar节点即包含attr_0属性也包含attr_1属性,在bar中对attr_0的修改不会影响到foo在foo和bar在同级node中可不指定foo的路径,否则需要使用绝对路径引用安全边距4.2驱动程序配置文件[4.2.3]配置文件的基本语法:引用、复制、修改和删除(3)删除指对include导入的base配置树中不需要的节点或属性删除delete基于OpenHarmony的嵌入式开发20//sample2.hcs文件内容root{attr_1=0x1;attr_2=0x2;foo_2{t=0x1;}}root{attr_1=0x1;}//sample1.hcs文件内容#include"sample2.hcs"root{attr_2=delete;foo_2:delete{}}sample1.hcs文件通过include导入了sample2.hcs文件中的配置内容使用delete删除了sample2.hcs文件中的attribute2属性和foo_2节点安全边距4.2驱动程序配置文件[4.2.3]配置文件的基本语法:引用、复制、修改和删除(4)属性引用指在解析配置时快速定位到关联的节点,可以把节点作为属性的右值,通过读取属性查找到对应节点的方法attribute=&node;基于OpenHarmony的嵌入式开发21node1{attributes;}node2{attr_1=&root.node1;}node2{node1{attributes;}attr_1=&node1;}安全边距4.2驱动程序配置文件[4.2.3]配置文件的基本语法:引用、复制、修改和删除(5)模板用于生成严格一致的node结构,以便对同类型node进行遍历和管理。使用template关键字定义模板node,子node通过双冒号“::”声明继承关系。子节点可以改写但不能新增和删除template中的属性,子节点中没有定义的属性将使用template中的定义作为默认值。基于OpenHarmony的嵌入式开发22root{module="sample";templatefoo{attr_1=0x1;attr_2=0x2;}bar::foo{}bar_1::foo{attr_1=0x2;}}root{module="sample";bar{attr_1=0x1;attr_2=0x2;}bar_1{attr_1=0x2;attr_2=0x2;}}bar和bar_1节点继承了foo节点生成配置树节点结构与foo保持了完全一致bar_1的属性值不同安全边距4.2驱动程序配置文件基于OpenHarmony的嵌入式开发23[4.2.4]配置生成工具配置生成工具hc-gen:语法检查并将HCS源文件转化成HCB文件

生成.c/.h配置文件的方法生成HCB配置文件的方法生成宏定义配置文件的方法反编译HCB文件为HCS的方法hc-gen

-o[OutputCFileName]

-t[SourceHcsFileName]hc-gen

-o[OutputHcbFileName]

-b[SourceHcsFileName]hc-gen-o[OutputMacroFileName]-m[SourceHcsFileName]hc-gen-o[OutputHcsFileName]-d[SourceHcbFileName]安全边距4.3加载驱动程序基于OpenHarmony的嵌入式开发24[4.3.1]用户态驱动程序服务启动配置

将驱服务配置到drivers/adapter/uhdf2/host/hdf_devhostmusl.cfg中{"jobs":[{"name":"post-fs-data","cmds":["starthdf_devhost"]}],"services":[{"name":"blue_host",

……},

{"name":"sample_host","dynamic":true,"path":["/vendor/bin/hdf_devhost"],"uid":"sample_host","gid":["sample_host"],"caps":["DAC_OVERRIDE","DAC_READ_SEARCH"]

},……name是驱动服务进程名字,必须要与device_info.hcs文件中配置的hostName对应;dynamic用来表示是否是动态加载,目前驱动服务只支持动态加载,即由hdf_devmgr在初始化时调用init模块接口启动;path指hdf_devhost所在的目录;uid和gid分别是进程的用户id和进程的组id;caps表示进程的Linuxcapabilities配置。HDF的驱动加载方式可以分为按需加载和按序加载两种方式(动态加载属于哪一种?)安全边距4.3加载驱动程序基于OpenHarmony的嵌入式开发25[4.3.1]用户态驱动程序服务启动配置

按需加载具体使用方法sample_host::host{hostName="host0";priority=100;device_sample::device{device0::deviceNode{policy=1;priority=100;preload=0;permission=0664;moduleName="sample_driver";serviceName="sample_service";deviceMatchAttr="sample_config";}}}}}device_info.hcs

typedefenum{DEVICE_PRELOAD_ENABLE=0,DEVICE_PRELOAD_ENABLE_STEP2,DEVICE_PRELOAD_DISABLE,DEVICE_PRELOAD_INVALID}DevicePreload;0(DEVICE_PRELOAD_ENABLE),则系统启动过程中默认加载1(DEVICE_PRELOAD_ENABLE_STEP2),当系统支持快启的时候,则在系统完成之后再加载这一类驱动,否则和DEVICE_PRELOAD_ENABLE含义相同2(DEVICE_PRELOAD_DISABLE),则系统启动过程中默认不加载,支持后续动态加载,当用户态获取驱动服务时,如果驱动服务不存在时,HDF框架会尝试动态加载该驱动priority的问题:不同的host内的驱动,host的priority值越小,驱动加载优先级越高同一个host内驱动的priority值越小,加载优先级越高。安全边距4.3加载驱动程序基于OpenHarmony的嵌入式开发26[4.3.2]驱动加载过程

按需加载具体使用方法安全边距4.3加载驱动程序基于OpenHarmony的嵌入式开发27[4.3.2]驱动加载过程

按需加载具体使用方法SystemInit()->HDFInit()->DeviceManagerStart()完成HDF启动DeviceManagerStart()

->DevmgrServiceGetInstance(),获取DevmgrService实例,调用该实例的StartService()启动服务(有DevmgrService实例对象则用之,无则创建后再用之)

DeviceManagerStart()还将调用HdfIoServicePublish(),进而调用HdfIoServiceAdapterPublish()。该过程主要完成将设备服务发布为一个设备服务节点,例如/dev/hdf/dev_mgr

最后,调用DevmgrService的启动接口StartService,启动设备管理的服务主题,为每个host设备创建DevHostServiceClnt,并启动对应host所在的host域的DevHostService。安全边距4.3加载驱动程序基于OpenHarmony的嵌入式开发28[4.3.3]驱动服务管理:驱动服务的发布和获取驱动对外发布的策略typedefenum{SERVICE_POLICY_NONE=0,

//驱动不提供服务

SERVICE_POLICY_PUBLIC=1,

//驱动对内核态发布服务

SERVICE_POLICY_CAPACITY=2,

//驱动对内核态和用户态都发布服务

SERVICE_POLICY_FRIENDLY=3,

//驱动服务不对外发布,但可以被订阅

SERVICE_POLICY_PRIVATE=4,

//驱动私有,不对外发布,也不能被订阅

SERVICE_POLICY_INVALID

//错误的服务策略}ServicePolicy;int32_t(*Bind)(structHdfDeviceObject*deviceObject);该接口需要驱动开发者实现Bind函数,用于将自己的服务接口绑定到HDF框架中重要接口conststructHdfObject*DevSvcManagerClntGetService(constchar*svcName);该接口用于获取驱动的服务intHdfDeviceSubscribeService(structHdfDeviceObject*deviceObject,constchar*serviceName,structSubscriberCallbackcallback);该接口用于订阅驱动的服务。安全边距4.3加载驱动程序基于OpenHarmony的嵌入式开发29[4.3.3]驱动服务管理:驱动服务的发布和获取驱动对外发布的策略typedefenum{SERVICE_POLICY_NONE=0,

//驱动不提供服务

SERVICE_POLICY_PUBLIC=1,

//驱动对内核态发布服务

SERVICE_POLICY_CAPACITY=2,

//驱动对内核态和用户态都发布服务

SERVICE_POLICY_FRIENDLY=3,

//驱动服务不对外发布,但可以被订阅

SERVICE_POLICY_PRIVATE=4,

//驱动私有,不对外发布,也不能被订阅

SERVICE_POLICY_INVALID

//错误的服务策略}ServicePolicy;int32_t(*Bind)(structHdfDeviceObject*deviceObject);该接口需要驱动开发者实现Bind函数,用于将自己的服务接口绑定到HDF框架中重要接口conststructHdfObject*DevSvcManagerClntGetService(constchar*svcName);该接口用于获取驱动的服务intHdfDeviceSubscribeService(structHdfDeviceObject*deviceObject,constchar*serviceName,structSubscriberCallbackcallback);该接口用于订阅驱动的服务。安全边距4.3加载驱动程序基于OpenHarmony的嵌入式开发30[4.3.3]驱动服务管理:驱动服务的发布和获取

1驱动服务发布示例//驱动服务结构的定义structISampleDriverService{//服务结构的首个成员必须是IDeviceIoService类型的成员

structIDeviceIoServiceioService;int32_t(*ServiceA)(void);

//驱动的第一个服务接口

int32_t(*ServiceB)(uint32_tinputCode);//驱动的第二个服务接口,可更多};//驱动服务接口的实现int32_tSampleDriverServiceA(void){//++驱动开发者实现业务逻辑

return0;}int32_tSampleDriverServiceB(uint32_tinputCode){//++驱动开发者实现业务逻辑

return0;}安全边距4.3加载驱动程序基于OpenHarmony的嵌入式开发31[4.3.3]驱动服务管理:驱动服务的发布和获取

2绑定驱动服务:将驱动服务绑定到HDF框架中(Bind函数的实现)

int32_tSampleDriverBind(structHdfDeviceObject*deviceObject){//deviceObject是每一个驱动创建的设备对象,保存设备私有数据和服务接口

if(deviceObject==NULL){HDF_LOGE("Sampledeviceobjectisnull!");return-1;}staticstructISampleDriverServicesampleDriverA={.ServiceA=SampleDriverServiceA,.ServiceB=SampleDriverServiceB,};deviceObject->service=&sampleDriverA.ioService;return0;}安全边距4.3加载驱动程序基于OpenHarmony的嵌入式开发32[4.3.3]驱动服务管理:驱动服务的发布和获取

3驱动服务获取:(1)通过HDF框架提供接口直接获取

3驱动服务获取:(2)通过HDF提供的订阅机制获取

当内核态对驱动(同一个host)加载的时机不感知时,可以通过HDF框架提供的订阅机制来订阅该驱动

当该驱动加载完成时,HDF框架会将被订阅的驱动服务发布给订阅者conststructISampleDriverService*sampleService=

(conststructISampleDriverService*)DevSvcManagerClntGetService("sample_driver");if(sampleService==NULL){return-1;}sampleService->ServiceA();sampleService->ServiceB(5);HDF框架提供的接口:该接口用于获取驱动的服务安全边距4.3加载驱动程序基于OpenHarmony的嵌入式开发33[4.3.3]驱动服务管理:驱动服务的发布和获取

3驱动服务获取:(2)通过HDF提供的订阅机制获取//object为订阅者的私有数据,service为被订阅的服务对象int32_tTestDriverSubCallBack(structHdfDeviceObject*deviceObject,conststructHdfObject*service)

{conststructISampleDriverService*sampleService=(conststructISampleDriverService*)service;if(sampleService==NULL){return-1;}sampleService->ServiceA();sampleService->ServiceB(5);}//订阅过程的实现int32_tTestDriverInit(structHdfDeviceObject*deviceObject)

{if(deviceObject==NULL){HDF_LOGE("Testdriverinitfailed,deviceObjectisnull!");return-1;}structSubscriberCallbackcallBack;callBack.deviceObject=deviceObject;callBack.OnServiceConnected=TestDriverSubCallBack;int32_tret=HdfDeviceSubscribeService(deviceObject,"sample_driver",callBack);if(ret!=0){

HDF_LOGE("Testdriversubscribesampledriverfailed!");}returnret;}安全边距4.4驱动消息机制管理[4.4.1]驱动消息接口

消息机制的功能主要有两种方式:①用户态应用发送消息到驱动;②用户态应用接收驱动主动上报的事件。主要接口包括:(1)structHdfIoService*HdfIoServiceBind(constchar*serviceName);该接口用于用户态获取驱动的服务,获取该服务之后通过服务中的Dispatch方法向驱动发送消息;(2)voidHdfIoServiceRecycle(structHdfIoService*service);该接口用于释放驱动服务。(3)intHdfDeviceRegisterEventListener(structHdfIoService*target,structHdfDevEventlistener*listener);该接口是用户态程序注册接收驱动上报事件的操作方法。(4)intHdfDeviceSendEvent(structHdfDeviceObject*deviceObject,uint32_tid,structHdfSBuf*data);该函数用于将驱动事件主动上报。基于OpenHarmony的嵌入式开发34安全边距4.4驱动消息机制管理[4.4.2]驱动消息开发示例(1)将驱动配置信息中服务策略policy字段设置为2,即4.3.3节中policy的定义(SERVICE_POLICY_CAPACITY,驱动对内核态和用户态都发布服务)(2)配置驱动信息中的服务设备节点权限(permission字段),即HDF框架给驱动创建设备节点的权限,默认是0666。

驱动开发者根据驱动的实际使用场景配置驱动设备节点的权限。基于OpenHarmony的嵌入式开发35device_sample::Device{policy=2;...}安全边距4.4驱动消息机制管理[4.4.2]驱动消息开发示例(3)在服务实现过程中,实现服务基类成员IDeviceIoService中的Dispatch方法,此外Bind方法的实现也一并在此实现。基于OpenHarmony的嵌入式开发36//Dispatch是用来处理用户态发下来的消息int32_tSampleDriverDispatch(structHdfDeviceObject*device,intcmdCode,structHdfSBuf*data,structHdfSBuf*reply){HDF_LOGE("sampledriverliteAdispatch");return0;}int32_tSampleDriverBind(structHdfDeviceObject*device){HDF_LOGE("testforliteossampledriverAOpen!");if(device==NULL){HDF_LOGE("testforliteossampledriverAOpenfailed!");return-1;}staticstructISampleDriverServicesampleDriverA={.ioService.Dispatch=SampleDriverDispatch,.ServiceA=SampleDriverServiceA,.ServiceB=SampleDriverServiceB,};device->service=(structIDeviceIoService*)(&sampleDriverA);return0;}安全边距4.4驱动消息机制管理[4.4.2]驱动消息开发示例(4)定义消息处理函数中的cmd类型。(5)用户态获取服务接口并发送消息到驱动。基于OpenHarmony的嵌入式开发37#defineSAMPLE_WRITE_READ1//读写操作码1

intSendMsg(constchar*testMsg){if(testMsg==NULL){HDF_LOGE("testmsgisnull");return-1;}structHdfIoService*serv=HdfIoServiceBind("sample_driver");if(serv==NULL){

HDF_LOGE(“failtogetservice”);

return-1;}structHdfSBuf*data=HdfSBufObtainDefaultSize();if(data==NULL){HDF_LOGE("failtoobtainsbufdata");return-1;}structHdfSBuf*reply=HdfSBufObtainDefaultSize();if(reply==NULL){

HDF_LOGE(“failtoobtainsbufreply”);

ret=HDF_DEV_ERR_NO_MEMORY;gotoout;}

if(!HdfSbufWriteString(data,testMsg)){

HDF_LOGE(“failtowritesbuf”);

ret=HDF_FAILURE;

gotoout;}intret=serv->dispatcher->Dispatch(&serv->object,SAMPLE_WRITE_READ,data,reply);if(ret!=HDF_SUCCESS){HDF_LOGE(“failtosendservicecall”);

gotoout;}out:HdfSBufRecycle(data);HdfSBufRecycle(reply);HdfIoServiceRecycle(serv);returnret;}安全边距4.4驱动消息机制管理[4.4.2]驱动消息开发示例(6)用户态接收该驱动上报的消息前,应先实现驱动上报消息的处理函数。基于OpenHarmony的嵌入式开发38staticintOnDevEventReceived(void*priv,uint32_tid,structHdfSBuf*data){OsalTimespectime;OsalGetTime(&time);HDF_LOGE("%sreceivedeventat%llu.%llu",(char*)priv,time.sec,time.usec);constchar*string=HdfSbufReadString(data);if(string==NULL){HDF_LOGE("failtoreadstringineventdata");return-1;}HDF_LOGE("%s:deveventreceived:%d%s",(char*)priv,id,string);return0;}安全边距4.4驱动消息机制管理[4.4.2]驱动消息开发示例(7)实现用户态注册接收驱动上报消息的操作方法。(8)实现驱动上报事件。基于OpenHarmony的嵌入式开发39intRegisterListen(){structHdfIoService*serv=HdfIoServiceBind("sample_driver");if(serv==NULL){HDF_LOGE(“failtogetservice”);

return-1;}staticstructHdfDevEventlistenerlistener={.callBack=OnDevEventReceived,.priv="Service0"};if(HdfDeviceRegisterEventListener(serv,&listener)!=0){HDF_LOGE(“failtoregistereventlistener”);

return-1;}

HdfDeviceUnregisterEventListener(serv,&listener);HdfIoServiceRecycle(serv);return0;}int32_tSampleDriverDispatch(structHdfDeviceObject*device,intcmdCode,

structHdfSBuf*data,structHdfSBuf*reply){...//processapicallherereturnHdfDeviceSendEvent(deviceObject,cmdCode,data);}安全边距4.5用户态使用驱动程序HDI

[4.5.0]用户态使用驱动程序HDI

HDF驱动框架的一个重要功能是为系统提供稳定的统一的硬件接口,保证系统服务可以运行在不同硬件上而不需要额外的适配工作。基于OpenHarmony的嵌入式开发40驱动接口HDI(HardwareDriverinterface)。HDI提供标准化的接口定义和实现,驱动框架提供IOService和IODispatcher机制,使得不同部署形态下驱动接口趋于形式一致。HDI是HDF对上层服务提供的统一接口,是操作对应设备的驱动能力的接口及实现。HDI是对硬件功能的较高层次抽象接口。各类外设完成HDI接口定义后,可以随时对驱动的具体实现过程和方法进行变更,驱动实现的变更也无需重复定义HDI接口,只需要完成实现即可接入系统功能,保证了接口的稳定性。安全边距4.5用户态使用驱动程序HDI

[4.5.0]用户态使用驱动程序HDI

HDF驱动框架的一个重要功能是为系统提供稳定的统一的硬件接口,保证系统服务可以运行在不同硬件上而不需要额外的适配工作。

相比于直接操作硬件或者是使用HAL库操作硬件,HDI有着明显的优势:(1)HDI实现了设备的抽象管理,可以将一类设备抽象为统一设备,例如键盘、鼠标、轨迹球和数控板等都可以抽象为input设备;(2)HDI与HDF相似,采用了C语言编写的C++语法形式,有利于服务层调用和集成;(3)HDI屏蔽了硬件端口、中断等细节,从服务层和用户层解决了与硬件设备繁琐的交互问题;(4)仅要求HDI开源,而不要求驱动实现过程开源,设备商可以有效保护驱动的实现过程和实现方法。基于OpenHarmony的嵌入式开发41安全边距4.5用户态使用驱动程序HDI

[4.5.1]驱动消息开发示例

LiteOS-M/LiteOS-A性能不同->HDF复杂程度不同->HDI形态不同HDI有两种形态:直通模式和IPC模式基于OpenHarmony的嵌入式开发42轻量级OpenHarmony系统上(LiteOS-M内核),为了减小系统性能负载。HDI以用户态共享库的形式存在,由系统服务直接加载HDI实现到进程中被函数调用。通过HDI实现封装具体用户态与内核态的交互过程,当需要访问驱动程序时使用IOService请求将消息通过SystemCall方式调用到内核驱动实现,即直通模式。LiteOS-A内核的OpenHarmony系统上,HDI则是以独立进程方式部署的,系统服务仅仅加载HDIClient到进程中,也会在独立进程中实现相关功能,HDIClient也是通过IPC与HDIServer交互的,实现了架构解耦。安全边距4.5用户态使用驱动程序HDI

[4.5.1]驱动消息开发示例直通模式:函数的实现方式,其调用和实现都不需要其他组件的支持

IPC模式:基于C/S结构的HDI接口实现方法-IDL语言

IDL(InterfaceDescriptionLanguage)通过一种中立的方法定义客户端与服务端两端均认可的编程接口,实现了在二者间的IPC,实现了一个进程访问另一个进程的数据的功能,或调用另一个进程的方法。基于OpenHarmony的嵌入式开发43IDL先将需要传递的对象分解为操作系统能够理解的基本类型,然后根据接口声明编译,生成IPC/RPC代理(Proxy)和桩(Stub)的C/C++代码,从而为调用者提供一致的接口和调用方式。安全边距4.5用户态使用驱动程序HDI

[4.5.1]驱动消息开发示例基于IDL的HDI实现步骤:.idl

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论