嵌入式系統開發 -基于分布式系統OpenHarmony 課件 04-HDF驅動程序框架;05-OpenHarmony的系統構成_第1頁
嵌入式系統開發 -基于分布式系統OpenHarmony 課件 04-HDF驅動程序框架;05-OpenHarmony的系統構成_第2頁
嵌入式系統開發 -基于分布式系統OpenHarmony 課件 04-HDF驅動程序框架;05-OpenHarmony的系統構成_第3頁
嵌入式系統開發 -基于分布式系統OpenHarmony 課件 04-HDF驅動程序框架;05-OpenHarmony的系統構成_第4頁
嵌入式系統開發 -基于分布式系統OpenHarmony 課件 04-HDF驅動程序框架;05-OpenHarmony的系統構成_第5頁
已閱讀5頁,還剩112頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

基于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"http://驅動對外提供的服務能力,將相關的服務接口綁定到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("http://build/lite/config/component/lite_component.gni")import("http://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實現步驟:.

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論