国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

一文解析鴻蒙系統中的HDF架構

鴻蒙系統HarmonyOS ? 來源:CSDN博主 ? 作者:悠然紅茶 ? 2021-03-25 16:06 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1 鋪墊一下

鴻蒙系統終于公開源代碼了,正可謂“千呼萬喚始出來”。筆者也手癢下載了一套代碼,并研讀了一二。這里就先編寫一篇關于HDF的文檔。

其實,不同讀碼人都會有各自讀代碼的習慣和切入點,我之所以從HDF入手,完全是出于偶然。因為在一開始讀官方文檔時,看到說一部機器可以操作另一部機器的設備,為此,設備需要有一個重要的PublishService()函數。這種跨設備操作的能力也是鴻蒙的一大特色,應該比較有趣,于是就以這個PublishService()為切入點,開始研讀代碼,慢慢就涉及了HDF的更多知識,現在是時候整理出來了。

所謂HDF,應該是Harmony Driver Fundation的縮寫,說到底是鴻蒙形成的一套管理設備驅動的框架模型,也被稱為“驅動子系統”。在官網的文檔里介紹說這個驅動子系統具有以下重要能力:

彈性化的框架能力

規范化的驅動接口

組件化的驅動模型

歸一化的配置界面

讀完這四句話,不免讓人覺得好像明白了什么,又好像什么都沒明白。好吧,我還是按自己的習慣直接讀代碼吧。

為了便于理解代碼,我習慣于把軟件圖形化。為此,我介紹一點我的圖形表達方法。在我讀Java代碼時,如果要表達A類對象的某個成員引用了另一個B類對象,我常常會這樣繪制:

但是HDF的代碼是用C寫的,所以對應的圖形表達法也要有所變化。我們要區分一下:

1)A結構以某成員組合了另一個B結構;

2)A結構某成員是個指向B的指針;

這兩種情況可以分別表示為:

另外,有時候HDF會使用C語言的一些技巧進行鏈表表達或基類轉換,那么上面的圖形畫出來就會很累贅,針對這種情況,我有時候會這樣表達(以DevmgrService結構為例):

可以看出,DevmgrService繼承于IDevmgrService,而IDevmgrService又在起始處組合了一個HdfDeviceObject(有時候也可以說是繼承于HdfDeviceObject)。也就是說:

1)DevmgrService的起始地址;

2)DevmgrService內部IDevmgrService部分的起始地址;

3)IDevmgrService內部HdfDeviceObject部分的起始地址;

這3個起始地址其實是同一處。用這種表達法,我們就不必畫出3個分離的框圖了。

好了,鋪墊部分就先寫這么多,下面我們來看HDF的實際內容。

2 DevmgrService和Dev Host

我們以hi3516 dv300為例,其系統一啟動,會運行到SystemInit(),其中會調用DeviceManagerStart()啟動與HDF相關的部分:

【vendor/hisi/hi35xx/hi3516dv300/module_init/src/System_init.c】

void SystemInit(void)

{

. . . . . .

#ifdef LOSCFG_DRIVERS_HDF

if (DeviceManagerStart()) {

PRINT_WARN("No drivers need load by hdf manager!");

}

#endif

. . . . . .

}

2.1 啟動DeviceManager

【drivers/hdf/lite/manager/src/Devmgr_service_start.c】

int DeviceManagerStart()

{

struct IDevmgrService *instance = DevmgrServiceGetInstance();

if (instance == NULL || instance->StartService == NULL) {

HDF_LOGE("Device manager start failed, service instance is null!");

return HDF_FAILURE;

}

struct HdfIoService *ioService = HdfIoServiceBind(DEV_MGR_NODE, DEV_MGR_NODE_PERM);

if (ioService != NULL) {

static struct HdfIoDispatcher dispatcher = {

.Dispatch = DeviceManagerDispatch,

};

ioService->dispatcher = &dispatcher;

ioService->target = (struct HdfObject *)&instance->object;

}

return instance->StartService(instance);

}

簡單地說,要啟動DeviceManager服務,就得先獲取一個DevmgrService實例,然后調用它的StartService(),又因為DevmgrService繼承于IDevmgrService,所以可以強制轉換成IDevmgrService*。

2.1.1 獲取DevmgrService單例

獲取實例時,其實用到了HDF機制提供的一個對象管理器,相關代碼如下:

【drivers/hdf/frameworks/core/manager/src/Devmgr_service.c】

struct IDevmgrService *DevmgrServiceGetInstance()

{

static struct IDevmgrService *instance = NULL; // 注意是static的,表示是個靜態單例

if (instance == NULL) {

instance = (struct IDevmgrService *)

HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVMGR_SERVICE);

}

return instance;

}

以后我們會看到,這個HdfObjectManagerGetObject()會在多個地方調用,以便獲取不同的HDF對象。說起來也簡單,HDF機制里有一張表,記錄著該如何創建、釋放一些重要的HDF對象,該表格為g_liteObjectCreators:

【drivers/hdf/lite/manager/src/Devlite_object_config.c】

static const struct HdfObjectCreator g_liteObjectCreators[]

基于讀到的代碼,我們可以畫出這個表格:

概念還是比較簡單的,如果系統中的DevmgrService單例對象已經存在,就使用之。否則就利用HDF對象管理器創建一個DevmgrService對象。對于HDF對象管理器而言,不同類型的HDF對象,需要用到不同的創建函數,所以要查一下上表。比如DevmgrService對應的創建函數就是DevmgrServiceCreate(),該函數代碼如下:

【drivers/hdf/frameworks/core/manager/src/Devmgr_service.c】

struct HdfObject *DevmgrServiceCreate()

{

static bool isDevMgrServiceInit = false;

static struct DevmgrService devmgrServiceInstance;

if (!isDevMgrServiceInit) {

if (!DevmgrServiceConstruct(&devmgrServiceInstance)) {

return NULL;

}

isDevMgrServiceInit = true;

}

return (struct HdfObject *)&devmgrServiceInstance; // ???HdfObject,有小問題!

}

在“創建”時,如果發現是首次創建,則調用一個類似構造函數的DevmgrServiceConstruct()函數,來初始化對象里的函數表。這種做法是用C語言實現面向對象概念的常用做法。不過,此處的代碼有一個小bug,即最后那個強制轉換,從目前看到的代碼來說,DevmgrService間接繼承于HdfDeviceObject,而HdfDeviceObject并不繼承于HdfObject,所以是不應該這樣強制轉換的,除非HdfDeviceObject的第一個成員從“IDeviceIoService*”改為“IDeviceIoService”,我估計最早的代碼就是IDeviceIoService,后來因為某些原因,變成了指針形式,至于以后具體該怎么修正,這個就讓鴻蒙的工程師去費腦筋吧。DevmgrService的構造函數如下:

【drivers/hdf/frameworks/core/manager/src/Devmgr_service.c】

static bool DevmgrServiceConstruct(struct DevmgrService *inst)

{

if (OsalMutexInit(&inst->devMgrMutex) != HDF_SUCCESS) {

HDF_LOGE("%s mutex init failed", __func__);

return false;

}

struct IDevmgrService *devMgrSvcIf = (struct IDevmgrService *)inst;

if (devMgrSvcIf != NULL) {

devMgrSvcIf->AttachDevice = DevmgrServiceAttachDevice;

devMgrSvcIf->AttachDeviceHost = DevmgrServiceAttachDeviceHost;

devMgrSvcIf->StartService = DevmgrServiceStartService;

devMgrSvcIf->AcquireWakeLock = DevmgrServiceAcquireWakeLock;

devMgrSvcIf->ReleaseWakeLock = DevmgrServiceReleaseWakeLock;

HdfSListInit(&inst->hosts);

}

return true;

}

2.1.2 HdfIoServiceBind()

啟動DeviceManager時,第二個重要的動作是調用HdfIoServiceBind():

struct HdfIoService *ioService = HdfIoServiceBind(DEV_MGR_NODE, DEV_MGR_NODE_PERM);

這一步在做什么呢?我們可以這樣理解,DevmgrService作為一個核心的系統服務,我們希望能像訪問虛文件系統的文件那樣打開它,并進一步向它傳遞諸如AttachDevice、StartServie......這樣的語義。這些語義最終會執行到上面列舉的DevmgrServiceAttachDevice、DevmgrServiceStartService等函數。

我們不必列舉太多代碼,下面是我繪制的一張關于DeviceManagerStart()的調用關系示意圖,可供參考:

圖中已經明確注明,DevmgrService在虛文件系統里對應的路徑應該是“/dev/dev_mgr”,而上面調用HdfIoServiceBind()后,實際上建立了一個文件系統的inode節點,示意圖如下:

HdfVNodeAdapter的target在最后賦值為(struct HdfObject*)&instance->object,說到底其實就是指向了DevmgrService。

2.1.3 執行DevmgrService的StartService

接下來是啟動DeviceManager的第三步,調用instance->StartService(),這一步其實是在調用DevmgreviceStartService()函數。

【drivers/hdf/frameworks/core/manager/src/Devmgr_service.c】

int DevmgrServiceStartService(struct IDevmgrService *inst)

{

struct DevmgrService *dmService = (struct DevmgrService *)inst;

if (dmService == NULL) {

HDF_LOGE("Start device manager service failed, dmService is null");

return HDF_FAILURE;

}

return DevmgrServiceStartDeviceHosts(dmService);

}

主要就是在調用一個DevmgrServiceStartDeviceHosts()函數。這個函數應該算是個重量級函數,它會負責建立起DevmgrService內部主要的數據結構。我們先繪制一下該函數第一層次的調用關系,如下圖:

在進一步深入代碼細節之前,我們最好先大概說明一下。在鴻蒙HDF架構里,有一個“設備Host”的概念,根據官方的文檔,我們大概可以知道,一個Host用于整合若干業務相近的設備,這個原則被稱為相似相容原則。為了實現這個原則,HDF構造了一系列數據結構,我們列舉一下:

1)HdfHostInfo

2)DevHostServiceClnt

3)DevHostService

4)HdfDevice

5)HdfDeviceNode

. . . . . .

我們當然沒必要在一篇文檔里列出所有的數據結構,只需先明白:

1)設備管理服務(DevmgrService)內部可以管理若干Host;

2)每個Host內部可以整合若干業務相近的設備;

3)每個Host可以拆分成兩個部分:DevHostServiceClnt 和 DevHostService;

4)每個DevHostService可以添加多個設備;

從上面的調用關系圖中,我們可以看到DevmgrServiceStartDeviceHosts()函數的主要行為是:

1)先獲取一個驅動安裝器(單例)對象;

2)解析系統配置信息,將其轉換成一個以HdfHostInfo為表項的列表,這個就對應著系統里所有的host;

3)遍歷這張HdfHostInfo列表,為每個HdfHostInfo節點創建一個對應的DevHostServiceClnt對象;

4)新創建的DevHostServiceClnt節點會被插入DevmgrService的hosts列表中;

5)針對每個HdfHostInfo節點,利用剛剛獲取的驅動安裝器具體啟動該host。

2.1.3.1獲取驅動安裝器

現在我們詳細看上圖中調用的關鍵函數。

installer = DriverInstallerGetInstance();

先拿到一個驅動安裝器。

struct IDriverInstaller *DriverInstallerGetInstance()

{

static struct IDriverInstaller *installer = NULL;

if (installer == NULL) {

installer = (struct IDriverInstaller *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DRIVER_INSTALLER);

}

return installer;

}

又看到HdfObjectManagerGetObject(),于是我們查前文那張表,可以找到驅動安裝器對應的創建函數是DriverInstallerCreate():

【drivers/hdf/frameworks/core/manager/src/Hdf_driver_installer.c】

struct HdfObject *DriverInstallerCreate(void)

{

static bool isDriverInstInit = false;

static struct DriverInstaller driverInstaller;

if (!isDriverInstInit) {

DriverInstallerConstruct(&driverInstaller);

isDriverInstInit = true;

}

return (struct HdfObject *)&driverInstaller;

}

用的是一個單例的DriverInstaller對象。

2.1.3.2 獲取HdfHostInfo列表

啟動所有hosts的第二步,是獲取一個HdfHostInfo列表:

HdfAttributeManagerGetHostList(&hostList)

我們摘選該函數的主要句子,如下:

【drivers/hdf/lite/manager/src/Hdf_attribute_manager.c】

bool HdfAttributeManagerGetHostList(struct HdfSList *hostList)

{

. . . . . .

hdfManagerNode = GetHdfManagerNode(HcsGetRootNode());

. . . . . .

hostNode = hdfManagerNode->child;

while (hostNode != NULL) {

struct HdfHostInfo *hostInfo = HdfHostInfoNewInstance();

. . . . . .

if (!GetHostInfo(hostNode, hostInfo)) {

HdfHostInfoFreeInstance(hostInfo);

hostInfo = NULL;

hostNode = hostNode->sibling;

continue;

}

hostInfo->hostId = hostId;

if (!HdfSListAddOrder(hostList, &hostInfo->node, HdfHostListCompare)) {

HdfHostInfoFreeInstance(hostInfo);

hostInfo = NULL;

hostNode = hostNode->sibling;

continue;

}

hostId++;

hostNode = hostNode->sibling;

}

return true;

}

我們稍微擴展一點知識來說明一下。在鴻蒙系統中,有一些系統級的配置文件,叫做HCS文件。系統可以利用類似hc-gen這樣的工具,根據配置文件生成二進制碼。當HDF啟動時,它會將二進制信息傳給DriverConfig模塊。該模塊會將二進制碼轉換成配置樹,并向開發者提供API去查詢這棵樹。

配置樹的根節點是g_hcsTreeRoot,節點類型為DeviceResourceNode。這棵配置樹里有一個特殊的節點,具有“hdf_manager”屬性,上面代碼中調用GetHdfManagerNode()一句,就是在獲取這個特殊節點。接著,上面的代碼里會嘗試遍歷該節點的所有child,并將每個child的信息整理進一個HdfHostInfo對象里。注意此時就會給HdfHostInfo分派一個hostId了,這個hostId后續還會用到。所有讀出的HdfHostInfo節點會按照其內記錄的優先級進行排序,并連成一個列表,優先級越高越靠近表頭。

2.1.3.3 遍歷HdfHostInfo列表

得到HdfHostInfo列表后,緊接著就會嘗試遍歷這張表。因為每個HdfHostInfo節點代表的就是一個host,所以每讀取一個HdfHostInfo,就會對應地生成一個DevHostServiceClnt對象。這些生成的DevHostServiceClnt都會插入到DevmgrService的hosts列表中。

每讀取一個HdfHostInfo信息后,就會利用驅動安裝器,啟動對應的host。

2.1.3.4啟動host

啟動host的動作是installer->StartDeviceHost()一步,它的調用關系如下:

大家還記得前文我說過,每個Host可以拆分成兩個部分:DevHostServiceClnt 和 DevHostService。這個就體現在上面的調用關系里。

StartDeviceHost一開始就會創建一個DevHostService對象,

【drivers/hdf/frameworks/core/manager/src/Hdf_driver_installer.c】

static int DriverInstallerStartDeviceHost(uint32_t devHostId, const char *devHostName)

{

struct IDevHostService *hostServiceIf = DevHostServiceNewInstance(devHostId, devHostName);

if ((hostServiceIf == NULL) || (hostServiceIf->StartService == NULL)) {

HDF_LOGE("hostServiceIf or hostServiceIf->StartService is null");

return HDF_FAILURE;

}

int ret = hostServiceIf->StartService(hostServiceIf);

if (ret != HDF_SUCCESS) {

HDF_LOGE("Start host service failed, ret is: %d", ret);

DevHostServiceFreeInstance(hostServiceIf);

}

return ret;

}

隨后調用的StartService,實際上對應DevHostServiceStartService()函數:

【drivers/hdf/frameworks/core/host/src/Devhost_service.c】

static int DevHostServiceStartService(struct IDevHostService *service)

{

struct DevHostService *hostService = (struct DevHostService*)service;

if (hostService == NULL) {

HDF_LOGE("Start device service failed, hostService is null");

return HDF_FAILURE;

}

return DevmgrServiceClntAttachDeviceHost(hostService->hostId, service);

}

此處調用的DevmgrServiceClntAttachDeviceHost()函數,內部涉及的內容挺多,我打算在下一篇文檔里再細說。現在我們已經對“啟動DeviceManager”的流程有了一點初步的認識,為了便于理解里面host的部分,我們畫一張示意圖總結一下,繪圖如下:

編輯:hfy

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 鴻蒙系統
    +關注

    關注

    183

    文章

    2642

    瀏覽量

    69828
  • HarmonyOS
    +關注

    關注

    80

    文章

    2153

    瀏覽量

    36037
  • HDF框架
    +關注

    關注

    0

    文章

    10

    瀏覽量

    3002
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    感知、決策規劃與執行控制:智能系統的三層核心架構解析

    解析這三層架構的功能、互動關系及其在構建魯棒智能體的關鍵作用。 01 智能閉環起點:感知層的多維信息融合 感知層是智能系統與物理世界交互的起點,其核心任務是多源信息獲取與環境理解。它
    的頭像 發表于 01-24 15:00 ?358次閱讀
    感知、決策規劃與執行控制:智能<b class='flag-5'>系統</b>的三層核心<b class='flag-5'>架構</b><b class='flag-5'>解析</b>

    無人機高效能動力推進系統:功能特點與平臺架構解析

    無人機高效能動力推進系統:功能特點與平臺架構解析
    的頭像 發表于 01-14 15:27 ?213次閱讀
    無人機高效能動力推進<b class='flag-5'>系統</b>:功能特點與平臺<b class='flag-5'>架構</b><b class='flag-5'>解析</b>

    大模型支撐后勤保障方案生成系統:功能特點與平臺架構解析

    支撐,實現資源高效配置與響應速度提升。以下從支撐作用、系統架構、核心功能及應用場景展開精簡解析: ? ?系統軟件供應可以來這里,這個首肌開始是幺伍扒,中間是幺幺叁叁,最后
    的頭像 發表于 12-17 15:49 ?306次閱讀

    軟國際攜手愛聚科技完成義烏鴻蒙生態合作簽約

    10月15日,軟國際科技服務有限公司(以下簡稱“軟國際”)聯合上海愛聚網絡科技有限公司(以下簡稱“愛聚科技”),與義烏市文化旅游發展有限公司正式簽署義烏全域鴻蒙生態智慧旅合作協議
    的頭像 發表于 10-16 11:11 ?938次閱讀

    五大電磁頻譜管理系統:原理、架構與應用全景解析

    五大電磁頻譜管理系統:原理、架構與應用全景解析
    的頭像 發表于 09-26 10:21 ?513次閱讀
    五大電磁頻譜管理<b class='flag-5'>系統</b>:原理、<b class='flag-5'>架構</b>與應用全景<b class='flag-5'>解析</b>

    軟國際攜手愛聚科技,與山東旅完成省級鴻蒙生態合作簽約

    ? 8月6日,軟國際科技服務有限公司(以下簡稱“軟國際”)聯合上海愛聚網絡科技有限公司(以下簡稱“愛聚科技”),與山東省文旅集團旗下山東旅云智能科技有限公司正式簽署省級鴻蒙生態智
    的頭像 發表于 08-08 21:05 ?1884次閱讀

    軟國際助力打造甘肅省首個鴻蒙生態智慧旅平臺

    近日,軟國際科技服務有限公司(以下簡稱“軟國際”)聯合上海愛聚網絡科技有限公司(以下簡稱“愛聚科技”),與甘肅省武威市文體廣電和旅游局正式簽署華為鴻蒙生態智慧旅合作框架協議,共同
    的頭像 發表于 07-25 14:28 ?933次閱讀

    軟國際助力打造黑龍江省首個鴻蒙生態智慧旅平臺

    近日,軟國際科技服務有限公司(以下簡稱“軟國際”)聯合上海愛聚網絡科技有限公司(以下簡稱“愛聚科技”),與齊齊哈爾市文化廣電和旅游局完成「樂游鶴城」鴻蒙生態智慧旅合作框架協議簽署
    的頭像 發表于 07-14 14:51 ?1391次閱讀

    鴻蒙Stage模型與FA模型詳解

    【HarmonyOS 5】鴻蒙Stage模型與FA模型詳解 ##鴻蒙開發能力 ##HarmonyOS SDK應用服務##鴻蒙金融類應用 (金融理財#
    的頭像 發表于 07-07 11:50 ?909次閱讀

    鴻蒙5開發寶藏案例分享---性能優化案例解析

    鴻蒙性能優化寶藏指南:實戰工具與代碼案例解析 大家好呀!今天在翻鴻蒙開發者文檔時,意外挖到個 性能優化寶藏庫 ——原來官方早就提供了超多實用工具和案例,但很多小伙伴可能沒發現!這篇就
    發表于 06-12 16:36

    鴻蒙5開發寶藏案例分享---應用架構實戰技巧

    大家好! 今天咱們聊聊鴻蒙開發那些“官方文檔提了但實際開發難找”的架構設計技巧。結合官方文檔,我會用 真實代碼案例+通俗講解 ,幫你把分層架構和線程通信落地到項目里,告別“理論會了,
    發表于 06-12 16:14

    GPU架構深度解析

    GPU架構深度解析從圖形處理到通用計算的進化之路圖形處理單元(GPU),作為現代計算機不可或缺的部分,已經從最初的圖形渲染專用處理器,發展成為強大的并行計算引擎,廣泛應用于人工智能
    的頭像 發表于 05-30 10:36 ?1850次閱讀
    GPU<b class='flag-5'>架構</b>深度<b class='flag-5'>解析</b>

    成都匯陽投資關于華為鴻蒙PC 操作系統發布,相關公司迎來發展

    電腦技術與生態溝通會上正式亮相,展示了其 UI設計 、辦公特點 、系統生態 、設備互聯 、安全架構和 AI 能力等 。該系統鴻蒙底座 、鴻蒙
    的頭像 發表于 05-12 09:39 ?1213次閱讀

    【北京迅為】iTOP-RK3568開發板鴻蒙OpenHarmony系統南向驅動開發實操-HDF驅動配置UART

    【北京迅為】iTOP-RK3568開發板鴻蒙OpenHarmony系統南向驅動開發實操-HDF驅動配置UART
    的頭像 發表于 03-25 11:02 ?1725次閱讀
    【北京迅為】iTOP-RK3568開發板<b class='flag-5'>鴻蒙</b>OpenHarmony<b class='flag-5'>系統</b>南向驅動開發實操-<b class='flag-5'>HDF</b>驅動配置UART

    北京迅為RK3568開發板OpenHarmony系統南向驅動開發內核HDF驅動框架架構

    北京迅為RK3568開發板OpenHarmony系統南向驅動開發內核HDF驅動框架架構
    的頭像 發表于 03-11 14:13 ?1847次閱讀
    北京迅為RK3568開發板OpenHarmony<b class='flag-5'>系統</b>南向驅動開發內核<b class='flag-5'>HDF</b>驅動框架<b class='flag-5'>架構</b>