欧美性猛交xxxx免费看_牛牛在线视频国产免费_天堂草原电视剧在线观看免费_国产粉嫩高清在线观看_国产欧美日本亚洲精品一5区

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

OpenHarmony HDF平臺(tái)驅(qū)動(dòng)框架及驅(qū)動(dòng)適配介紹

OpenAtom OpenHarmony ? 來(lái)源:OpenAtom OpenHarmony ? 作者: 楊海舟 ? 2021-09-24 11:16 ? 次閱讀

開源項(xiàng)目 OpenHarmony是每個(gè)人的 OpenHarmony

OpenHarmony系統(tǒng)平臺(tái)驅(qū)動(dòng)概述

OpenHarmony系統(tǒng)平臺(tái)驅(qū)動(dòng)(PlatformDriver),即平臺(tái)設(shè)備驅(qū)動(dòng),它用于驅(qū)動(dòng)平臺(tái)設(shè)備(PlatformDevice),為系統(tǒng)及外設(shè)驅(qū)動(dòng)提供訪接口。這里的平臺(tái)設(shè)備,泛指I2C/UART等總線、以及GPIO/RTC等SOC片內(nèi)硬件資源。

OpenHarmony系統(tǒng)平臺(tái)驅(qū)動(dòng)框架是OpenHarmony系統(tǒng)驅(qū)動(dòng)框架的重要組成部分,它基于HDF驅(qū)動(dòng)框架、操作系統(tǒng)適配層(OSAL, operating system abstraction layer)以及驅(qū)動(dòng)配置管理機(jī)制,為各類平臺(tái)設(shè)備驅(qū)動(dòng)的實(shí)現(xiàn)提供標(biāo)準(zhǔn)模型。

OpenHarmony系統(tǒng)平臺(tái)驅(qū)動(dòng)框架為外設(shè)提供了標(biāo)準(zhǔn)的平臺(tái)設(shè)備訪問(wèn)接口,使其不必關(guān)注具體硬件及OS平臺(tái);同時(shí)為平臺(tái)設(shè)備驅(qū)動(dòng)提供統(tǒng)一的適配接口,使其只關(guān)注自身硬件的控制。

為實(shí)現(xiàn)這個(gè)目標(biāo),OpenHarmony系統(tǒng)平臺(tái)驅(qū)動(dòng)框架滿足如下特性:

統(tǒng)一的平臺(tái)設(shè)備訪問(wèn)接口:對(duì)平臺(tái)設(shè)備操作接口進(jìn)行統(tǒng)一封裝,屏蔽不同SOC平臺(tái)硬件差異以及不同OS形態(tài)差異。

統(tǒng)一的平臺(tái)驅(qū)動(dòng)適配接口:為平臺(tái)設(shè)備驅(qū)動(dòng)提供統(tǒng)一的適配接口,使其只關(guān)注自身硬件的控制,而不必關(guān)注設(shè)備管理及公共業(yè)務(wù)流程。

提供設(shè)備注冊(cè)、管理、訪問(wèn)控制等與SOC無(wú)關(guān)的公共能力。

OpenHarmony系統(tǒng)平臺(tái)驅(qū)動(dòng)框架目前支持的設(shè)備類型包括但不限于:I2C/SPI/UART/MIPI_DSI/SDIO/GPIO/PWM/WATCHDOG/RTC/DMA

OpenHarmony平臺(tái)驅(qū)動(dòng)框架介紹

OpenHarmony系統(tǒng)平臺(tái)驅(qū)動(dòng)框架組成

OpenHarmony系統(tǒng)平臺(tái)驅(qū)動(dòng)框架主要由平臺(tái)接口層、平臺(tái)核心層以及平臺(tái)適配層三個(gè)部分組成。

aa3b5eb2-10b0-11ec-8fb8-12bb97331649.png

1)平臺(tái)接口層以API的形式提供標(biāo)準(zhǔn)的平臺(tái)設(shè)備訪問(wèn)接口。

平臺(tái)接口層以設(shè)備句柄加配套API的形式對(duì)外提供統(tǒng)一的、標(biāo)準(zhǔn)的訪問(wèn)接口。

設(shè)備句柄是DevHandle類型的實(shí)例,通過(guò)不同設(shè)備模塊提供的Open/Close方法進(jìn)行獲取、釋放。成功獲取設(shè)備句柄后,即可使用相應(yīng)的API執(zhí)行設(shè)備操作。例如通過(guò)I2cTransfer完成一次I2C數(shù)據(jù)傳輸。

這是一種代理模式,即接口層API不直接引用實(shí)際設(shè)備對(duì)象,而是通過(guò)DevHandle作為代理,間接訪問(wèn)設(shè)備;而所有來(lái)自外設(shè)驅(qū)動(dòng)的訪問(wèn),都建議走接口層,以獲得最佳的穩(wěn)定性。

不同類型設(shè)備的API使用,請(qǐng)參考如下官方文檔的平臺(tái)驅(qū)動(dòng)章節(jié):

https://device.OpenHarmony系統(tǒng).com/cn/docs/develop/drive/oem_drive_hdfdev-0000001051715456

2)平臺(tái)核心層提供平臺(tái)設(shè)備模型及公共業(yè)務(wù)框架。

提供統(tǒng)一適配接口:定義了標(biāo)準(zhǔn)的設(shè)備對(duì)象模型,驅(qū)動(dòng)程序僅需關(guān)注標(biāo)準(zhǔn)對(duì)象模型的適配。

抽取公共業(yè)務(wù)框架:將不同設(shè)備模塊的公共流程、算法加以抽取,使得具體設(shè)備驅(qū)動(dòng)更加輕薄。

設(shè)備管理:設(shè)備注冊(cè)、注銷、設(shè)備查找、訪問(wèn)控制。

3)平臺(tái)適配層提供特定平臺(tái)設(shè)備的適配驅(qū)動(dòng),并遵守核心層約束。

驅(qū)動(dòng)具體平臺(tái)設(shè)備硬件,并創(chuàng)建對(duì)應(yīng)的設(shè)備模型對(duì)象,注冊(cè)到核心層納入統(tǒng)一管理。

平臺(tái)接口層分析

前面說(shuō)過(guò),在接口層,我們用DevHandle類型的設(shè)備句柄表示一個(gè)平臺(tái)設(shè)備對(duì)象,然后針對(duì)不同類型設(shè)備提供一套標(biāo)準(zhǔn)的API方法用于設(shè)備訪問(wèn)。那么設(shè)備句柄和真實(shí)的設(shè)備對(duì)象如何關(guān)聯(lián)呢?

查看DevHandle的定義,發(fā)現(xiàn)它就是一個(gè)void類型指針:

/**

* @brief Defines the common device handle of the platform driver.

*

* The handle is associated with a specific platform device and is used as the

* first input parameter for all APIs of the platform driver.

*

* @since 1.0

*/

typedef void* DevHandle;

實(shí)際上,在內(nèi)核態(tài),這個(gè)指針可以直接指向?qū)嶋H設(shè)備對(duì)象,但是對(duì)于某些類型的平臺(tái)設(shè)備,我們需要在用戶態(tài)提供同樣的DevHandle類型及配套API,而實(shí)際設(shè)備對(duì)象在內(nèi)核空間,我們無(wú)法直接獲取和使用內(nèi)核空間的地址。

我們的解決辦法是將平臺(tái)設(shè)備對(duì)象實(shí)現(xiàn)為一個(gè)HDF設(shè)備服務(wù),這樣借助HDF DeviceManager的設(shè)備服務(wù)機(jī)制,可以在用戶態(tài)、內(nèi)核態(tài)同時(shí)獲取到設(shè)備服務(wù),而用戶態(tài)同內(nèi)核態(tài)通信的問(wèn)題交由HDF DeviceManager處理。此時(shí),DevHandle只需要關(guān)聯(lián)到這個(gè)設(shè)備服務(wù)即可,而void*類型保證了足夠的靈活性。

根據(jù)DevHandle和設(shè)備對(duì)象關(guān)聯(lián)方式的不同,接口層的設(shè)計(jì)有三種模式,下面將一一講解。

1.獨(dú)立服務(wù)模式

aa5d017a-10b0-11ec-8fb8-12bb97331649.png

這種模式用于需要在用戶態(tài)和內(nèi)核態(tài)同時(shí)提供API的設(shè)備類型,DevHandle同設(shè)備對(duì)象的關(guān)聯(lián)方式為:

用戶態(tài):關(guān)聯(lián)到平臺(tái)設(shè)備對(duì)應(yīng)的設(shè)備服務(wù)

內(nèi)核態(tài)度:關(guān)聯(lián)到實(shí)際平臺(tái)設(shè)備對(duì)象或其設(shè)備服務(wù)(在內(nèi)核態(tài)兩者可互相轉(zhuǎn)換)

這樣,每一個(gè)設(shè)備對(duì)象,會(huì)獨(dú)立發(fā)布一個(gè)設(shè)備服務(wù),來(lái)處理外部訪問(wèn),服務(wù)收到API的訪問(wèn)請(qǐng)求之后,通過(guò)提取請(qǐng)求參數(shù),并調(diào)用實(shí)際設(shè)備對(duì)象的相應(yīng)內(nèi)部方法。

這種方式的優(yōu)點(diǎn)是管理比較簡(jiǎn)單,因?yàn)樗柚薍DF DeviceManager的服務(wù)管理能力;但是缺點(diǎn)是需要為每一個(gè)設(shè)備對(duì)象配置設(shè)備節(jié)點(diǎn),以便發(fā)布設(shè)備服務(wù)。

這種模式的典型實(shí)踐是UART模塊,這在后面介紹驅(qū)動(dòng)適配時(shí)會(huì)詳細(xì)介紹。

2.統(tǒng)一服務(wù)模式

aaa6b59a-10b0-11ec-8fb8-12bb97331649.png

有時(shí)候,同一類型的設(shè)備對(duì)象可能會(huì)很多,例如I2C模塊,可能同時(shí)有十幾個(gè)控制器。如果采用獨(dú)立服務(wù)的模式,每一個(gè)控制器,作為一個(gè)平臺(tái)設(shè)備,為其創(chuàng)建一個(gè)設(shè)備服務(wù),那么將會(huì)有十幾個(gè)服務(wù)被創(chuàng)建,不光要配置很多設(shè)備節(jié)點(diǎn),而且這些服務(wù)還會(huì)占用內(nèi)存資源。

這時(shí),我們可以為一類設(shè)備對(duì)象,創(chuàng)建一個(gè)平臺(tái)設(shè)備管理器(PlatformManager)對(duì)象,并同時(shí)對(duì)外發(fā)布一個(gè)管理器服務(wù),由這個(gè)管理器服務(wù)來(lái)統(tǒng)一處理外部訪問(wèn)。當(dāng)用戶需要打開某個(gè)設(shè)備時(shí),先通過(guò)HDF DeviceManager獲取到管理器服務(wù),然后管理器服務(wù)根據(jù)用戶指定參數(shù)查找到指定設(shè)備,并返回一個(gè)設(shè)備描述符,而這個(gè)描述符仍然可以由DevHandle類型表示。

這種模式的實(shí)踐代表是I2C模塊,PlatformManager實(shí)現(xiàn)為I2cManager,而PlatformDevice則是I2cCntlr,感興趣的讀者可以閱讀一下drivers/framework下的i2c_if.c/i2c_core.c一探究竟。

3.無(wú)服務(wù)模式

aab7f1b6-10b0-11ec-8fb8-12bb97331649.png

這種模式用于不需要在用戶態(tài)提供API的設(shè)備類型或者沒(méi)有用戶態(tài)、內(nèi)核區(qū)分的OS系統(tǒng),其關(guān)聯(lián)方式是DevHandle直接指向設(shè)備對(duì)象內(nèi)核態(tài)地址。而PlatformManager的實(shí)現(xiàn)比較自由,它不需要實(shí)現(xiàn)設(shè)備服務(wù),只需做好某種類型的設(shè)備管理即可,甚至在C語(yǔ)言中,由于無(wú)法進(jìn)行OOP編程,很多模塊直接將這個(gè)功能面向過(guò)程化了,使得沒(méi)有一個(gè)具體的結(jié)構(gòu)體與之對(duì)應(yīng)。但是,我們?nèi)匀粡?qiáng)調(diào)PlatformManager這個(gè)概念,也期望隨著后續(xù)平臺(tái)驅(qū)動(dòng)框架的演進(jìn),逐步完善、規(guī)范化,形成更加統(tǒng)一的編程風(fēng)格。

平臺(tái)核心層分析

平臺(tái)核心層的作用是承上啟下,其主要內(nèi)容包括:

提供適配接口:為具體的平臺(tái)設(shè)備驅(qū)動(dòng)提供統(tǒng)一的適配接口

平臺(tái)驅(qū)動(dòng)框架為不同設(shè)備類型,定義了標(biāo)準(zhǔn)的設(shè)備對(duì)象模型,具體設(shè)備驅(qū)動(dòng)只需要關(guān)注標(biāo)準(zhǔn)設(shè)備對(duì)象的適配即可

提供設(shè)備管理:提供設(shè)備的注冊(cè)、注銷、查找等功能、訪問(wèn)控制等能力

核心層會(huì)提供一系列內(nèi)部方法,用于設(shè)備的注冊(cè)、注銷,設(shè)備對(duì)象的查找、獲取、釋放,以及處理多線程訪問(wèn)。例如當(dāng)我們向核心層注冊(cè)一個(gè)I2C控制器對(duì)象時(shí),使用I2cCntlrAdd;當(dāng)希望獲取一個(gè)I2C控制器對(duì)象時(shí),通過(guò)I2cCntlrGet并指定控制器編號(hào);當(dāng)不再使用這個(gè)對(duì)象時(shí),還需要通過(guò)I2cCntlrPut釋放。這樣做的好處是將每一個(gè)具體的操作步驟高度抽象化,減小同平臺(tái)接口層及平臺(tái)適配層的耦合面,便于業(yè)務(wù)解耦、演進(jìn)。如果后續(xù),我們由于業(yè)務(wù)需求需要對(duì)I2cCntlr對(duì)象進(jìn)行引用計(jì)數(shù),那么只需要修改I2cCntlrGet/Put這對(duì)方法的實(shí)現(xiàn)即可,并不會(huì)影響平臺(tái)接口層和平臺(tái)適配層。

公共業(yè)務(wù)實(shí)現(xiàn):抽取公共的業(yè)務(wù)流程、算法

凡是跟特定硬件無(wú)關(guān)的業(yè)務(wù)邏輯,都會(huì)被抽取到核心層,例如RTC時(shí)鐘的時(shí)間格式轉(zhuǎn)換算法,GPIO模塊的線程中斷實(shí)現(xiàn)等等。


平臺(tái)適配層實(shí)現(xiàn)

適配層提供具體平臺(tái)硬件設(shè)備的驅(qū)動(dòng),按照核心層定義的模型創(chuàng)建設(shè)備對(duì)象,并完成對(duì)象的初始化(包括必要的成員變量初始化以及鉤子方法掛接,以及相關(guān)的硬件初始化操作),最后使用核心層提供的注冊(cè)方法將設(shè)備對(duì)象注冊(cè)到核心層納入統(tǒng)一管理。


OpenHarmony系統(tǒng)平臺(tái)驅(qū)動(dòng)適配介紹

下面以u(píng)art/i2c/gpio三個(gè)典型模塊為例介紹平臺(tái)驅(qū)動(dòng)適配的一般方法

UART模塊的適配

UART模塊適配的核心環(huán)節(jié),是UartHost對(duì)象的創(chuàng)建、初始化及注冊(cè)。

UART模塊采用的是獨(dú)立服務(wù)模式,要求每一個(gè)UartHost對(duì)象關(guān)聯(lián)一個(gè)HDF設(shè)備服務(wù),因此:

1).device_info.hcs中為每一個(gè)UART控制器配置一個(gè)HDF設(shè)備節(jié)點(diǎn)

device_uart :: device {

device0 :: deviceNode {

policy = 1;

priority = 40;

permission = 0644;

moduleName = "HDF_PLATFORM_UART";

serviceName = "HDF_PLATFORM_UART_0";

deviceMatchAttr = "hisilicon_hi35xx_uart_0";

}

device1 :: deviceNode {

policy = 2;

permission = 0644;

priority = 40;

moduleName = "HDF_PLATFORM_UART";

serviceName = "HDF_PLATFORM_UART_1";

deviceMatchAttr = "hisilicon_hi35xx_uart_1";

}

}

服務(wù)policy大于等于1(如需對(duì)用戶態(tài)可見(jiàn)為2,僅內(nèi)核態(tài)可見(jiàn)為1);

moduleName需要與驅(qū)動(dòng)Entry中moduleName 保持一致;

ServiceName必須要按照HDF_PLATFORM_UART_X的格式,X為UART控制器編號(hào)

deviceMatchAttr用于配置控制器私有數(shù)據(jù),要與uart_config.hcs中對(duì)應(yīng)控制器保持一致,如不需要?jiǎng)t忽略

2).uart_config.hcs中為每一個(gè)UART控制器配置私有數(shù)據(jù)

如果控制器需要配置一些私有數(shù)據(jù),例如寄存器基地址,初始化波特率等等,可以在uart_config.hcs中配置,該文件將在產(chǎn)品配置目錄的hdf.hcs中導(dǎo)入,具體路徑可由產(chǎn)品自由配置。

root {

platform {

template uart_controller {

match_attr = "";

num = 0;

baudrate = 115200;

fifoRxEn = 1;

fifoTxEn = 1;

flags = 4;

regPbase = 0x120a0000;

interrupt = 38;

iomemCount = 0x48;

}

controller_0x120a0000 :: uart_controller {

match_attr = "hisilicon_hi35xx_uart_0";

}

controller_0x120a1000 :: uart_controller {

num = 1;

baudrate = 9600;

regPbase = 0x120a1000;

interrupt = 39;

match_attr = "hisilicon_hi35xx_uart_1";

}

}

要注意的一點(diǎn)是每個(gè)控制器要獨(dú)立配置一個(gè)uart_controller節(jié)點(diǎn),并且其match_attr要與device_info.hcs中的deviceMatchAttr一致。

3).驅(qū)動(dòng)的Entry結(jié)構(gòu)需要有Bind方法,用于綁定服務(wù)

struct HdfDriverEntry g_hdfUartDevice = {

.moduleVersion = 1,

.moduleName = "HDF_PLATFORM_UART",

.Bind = HdfUartDeviceBind,

.Init = HdfUartDeviceInit,

.Release = HdfUartDeviceRelease,

};

HDF_INIT(g_hdfUartDevice);

注意:在Bind方法中,要使用UartHostCreate創(chuàng)建控制器對(duì)象并完成服務(wù)綁定。

static int32_t HdfUartDeviceBind(struct HdfDeviceObject *device)

{

HDF_LOGI("%s: entry", __func__);

if (device == NULL) {

return HDF_ERR_INVALID_OBJECT;

}

return (UartHostCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS;

}

4).UartHostCreate的實(shí)現(xiàn)屏蔽了一些細(xì)節(jié)

struct UartHost *UartHostCreate(struct HdfDeviceObject *device)

{

struct UartHost *host = NULL;

host = (struct UartHost *)OsalMemCalloc(sizeof(*host));

host->device = device;

device->service = &(host->service);

host->device->service->Dispatch = UartIoDispatch;

OsalAtomicSet(&host->atom, 0);

host->priv = NULL;

host->method = NULL;

return host;

}

該方法中將UartHost對(duì)象同HdfDeviceObject進(jìn)行了關(guān)聯(lián):關(guān)鍵環(huán)節(jié)是為HdfDeviceObject的service成員進(jìn)行賦值,使其指向UartHost的IDeviceIoService類型的成員對(duì)象;同時(shí)為service成員的Dispatch方法賦值。這樣:

為HdfDeviceObject對(duì)象綁定了IDeviceIoService類型的服務(wù)對(duì)象

UartHost和其IDeviceIoService類型的成員對(duì)象service可以相互轉(zhuǎn)換

通過(guò)UartHost對(duì)象即可獲取HdfDeviceObject對(duì)象

通過(guò)HdfDeviceObject對(duì)象即可間接獲取UartHost對(duì)象(先獲取service再轉(zhuǎn)為host)

5).在Init方法中完成UartHost對(duì)象的初始化

int32_t HdfUartDeviceInit(struct HdfDeviceObject *device)

{

int32_t ret;

struct UartHost *host = NULL;

host = UartHostFromDevice(device);

ret = Hi35xxAttach(host, device);

host->method = &g_uartHostMethod;

return ret;

}

這里通過(guò)UartHostFromDevice從HdfDeviceObject對(duì)象獲取之前關(guān)聯(lián)的UartHost對(duì)象,然后調(diào)用Hi35xxAttach方法完成host對(duì)象的初始化

最后為host對(duì)象掛接鉤子方法,這里不再一一分析這些鉤子方法,建議讀者直接去查看源碼。

struct UartHostMethod g_uartHostMethod = {

.Init = Hi35xxInit,

.Deinit = Hi35xxDeinit,

.Read = Hi35xxRead,

.Write = Hi35xxWrite,

.SetBaud = Hi35xxSetBaud,

.GetBaud = Hi35xxGetBaud,

.SetAttribute = Hi35xxSetAttribute,

.GetAttribute = Hi35xxGetAttribute,

.SetTransMode = Hi35xxSetTransMode,

.pollEvent = Hi35xxPollEvent,

};

總結(jié)

UART適配的關(guān)鍵是要在驅(qū)動(dòng)Entry的Bind方法中創(chuàng)建UartHost對(duì)象,而且是使用UartHostCreate創(chuàng)建。這個(gè)創(chuàng)建動(dòng)作同時(shí)也是注冊(cè)的動(dòng)作,因?yàn)樗鼘artHost以HDF設(shè)備服務(wù)的形式同HdfDeviceObject進(jìn)行綁定,這樣就完成了服務(wù)的發(fā)布,HDF Manager對(duì)設(shè)備服務(wù)的管理也就是對(duì)UartHost的管理,核心層可以通過(guò)HDF提供的服務(wù)獲取接口來(lái)訪問(wèn)UartHost。

UART適配采用獨(dú)立服務(wù)模式,每一個(gè)UartHost對(duì)象同時(shí)也是一個(gè)設(shè)備服務(wù),其優(yōu)點(diǎn)是可以直接利用HDF Manager進(jìn)行管理;缺點(diǎn)是需要在device_info.hcs為每一個(gè)UartHost對(duì)象定義設(shè)備節(jié)點(diǎn)。

說(shuō)明

UART模塊適配涉及到的代碼示例片段來(lái)自device/hisilicon/drivers/uart/

I2C模塊適配

I2C模塊適配的核心環(huán)節(jié)是I2cCntlr對(duì)象的創(chuàng)建、初始化及注冊(cè)。

I2C采用的是統(tǒng)一服務(wù)模式,需要一個(gè)設(shè)備服務(wù)來(lái)作為I2C模塊的管理器,統(tǒng)一處理外部訪問(wèn)。

1、device_info.hcs配置

device_i2c :: device {

device0 :: deviceNode {

policy = 2;

priority = 50;

permission = 0644;

moduleName = "HDF_PLATFORM_I2C_MANAGER";

serviceName = "HDF_PLATFORM_I2C_MANAGER";

deviceMatchAttr = "hdf_platform_i2c_manager";

}

device1 :: deviceNode {

policy = 0;

priority = 55;

permission = 0644;

moduleName = "hi35xx_i2c_driver";

serviceName = "HI35XX_I2C_DRIVER";

deviceMatchAttr = "hisilicon_hi35xx_i2c";

}

}

首先第一個(gè)設(shè)備節(jié)點(diǎn)必須是I2C管理器,其各項(xiàng)參數(shù)必須如上一樣設(shè)置。其中:

policy:這個(gè)同UART,具體配置為1或2取決于是否對(duì)用戶態(tài)可見(jiàn)

moduleName:固定為HDF_PLATFORM_I2C_MANAGER

serviceName:固定為HDF_PLATFORM_I2C_MANAGER

deviceMatchAttr:沒(méi)有使用,可忽略

而從第二個(gè)設(shè)備節(jié)點(diǎn)開始,配置具體I2C控制器信息。這里device1 并不表示某一路I2C控制器,而是一個(gè)資源性質(zhì)設(shè)備,用于描述一類I2C控制器的信息。

服務(wù)policy等于0,不需要發(fā)布服務(wù);

moduleName用于指定驅(qū)動(dòng)成語(yǔ),需要與期望的驅(qū)動(dòng)Entry中的moduleName一致;

ServiceName不需要使用,可忽略;

deviceMatchAttr用于配置控制器私有數(shù)據(jù),要與i2c_config.hcs中對(duì)應(yīng)控制器保持

同樣,具體的控制器信息在i2c_config.hcs中,由具體產(chǎn)品在hdf.hcs中導(dǎo)入。

2、i2c_config.hcs中可配置多個(gè)控制器信息

root {

platform {

i2c_config {

match_attr = "hisilicon_hi35xx_i2c";

template i2c_controller {

bus = 0;

reg_pbase = 0x120b0000;

reg_size = 0xd1;

irq = 0;

freq = 400000;

clk = 50000000;

}

controller_0x120b0000 :: i2c_controller {

bus = 0;

}

controller_0x120b1000 :: i2c_controller {

bus = 1;

reg_pbase = 0x120b1000;

}

}

}

}

可以看到,這里配置了多個(gè)控制器的信息,而這些信息將在驅(qū)動(dòng)程序員進(jìn)行逐一解析、處理,生成對(duì)應(yīng)的I2cCntlr對(duì)象。

3、I2C管理器服務(wù)的驅(qū)動(dòng)由核心層實(shí)現(xiàn)

struct HdfDriverEntry g_i2cManagerEntry = {

.moduleVersion = 1,

.Bind = I2cManagerBind,

.Init = I2cManagerInit,

.Release = I2cManagerRelease,

.moduleName = "HDF_PLATFORM_I2C_MANAGER",

};

HDF_INIT(g_i2cManagerEntry);

驅(qū)動(dòng)適配人員無(wú)需關(guān)注這個(gè)驅(qū)動(dòng)的實(shí)現(xiàn),有興趣的可以去閱讀源碼。

drivers/framework/support/platform/src/i2c_core.c

4、適配驅(qū)動(dòng)Entry只需要實(shí)現(xiàn)Init方法

struct HdfDriverEntry g_i2cDriverEntry = {

.moduleVersion = 1,

.Init = Hi35xxI2cInit,

.Release = Hi35xxI2cRelease,

.moduleName = "hi35xx_i2c_driver",

};

HDF_INIT(g_i2cDriverEntry);

static int32_t Hi35xxI2cInit(struct HdfDeviceObject *device)

{

int32_t ret;

const struct DeviceResourceNode *childNode = NULL;

ret = HDF_SUCCESS;

DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {

ret = Hi35xxI2cParseAndInit(device, childNode);

if (ret != HDF_SUCCESS) {

break;

}

}

return ret;

}

在Init方法中會(huì)將i2c_config.hcs中定義的每一個(gè)節(jié)點(diǎn)取出,分別進(jìn)行初始化

5、Hi35xxI2cParseAndInit里面很自由

static int32_t Hi35xxI2cParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)

{

int32_t ret;

struct Hi35xxI2cCntlr *hi35xx = NULL;

(void)device;

hi35xx = (struct Hi35xxI2cCntlr *)OsalMemCalloc(sizeof(*hi35xx));

ret = Hi35xxI2cReadDrs(hi35xx, node);

hi35xx->regBase = OsalIoRemap(hi35xx->regBasePhy, hi35xx->regSize);

Hi35xxI2cCntlrInit(hi35xx);

hi35xx->cntlr.priv = (void *)node;

hi35xx->cntlr.busId = hi35xx->bus;

hi35xx->cntlr.ops = &g_method;

hi35xx->cntlr.lockOps = &g_lockOps;

(void)OsalSpinInit(&hi35xx->spin);

ret = I2cCntlrAdd(&hi35xx->cntlr);

....

}

Hi35xxI2cParseAndInit會(huì)處理一個(gè)具體的I2C控制器的初始化工作,包括:

1)I2cCntlr對(duì)象的分配,Hi35xxI2cCntlr頭部?jī)?nèi)嵌了一個(gè)I2cCntlr,這是一種繼承。

struct Hi35xxI2cCntlr {

struct I2cCntlr cntlr;

OsalSpinlock spin;

volatile unsigned char *regBase;

uint16_t regSize;

int16_t bus;

uint32_t clk;

uint32_t freq;

uint32_t irq;

uint32_t regBasePhy;

};

2)在Hi35xxI2cReadDrs中完成節(jié)點(diǎn)屬性的讀取,并填充進(jìn)hi35xx對(duì)象

3)映射寄存器基地址OsalIoRemap(hi35xx->regBasePhy, hi35xx->regSize);

4)調(diào)用Hi35xxI2cCntlrInit完成控制器的初始化

5)I2cCntlr對(duì)象的填充及調(diào)用I2cCntlrAdd注冊(cè)

這里唯一形式化約束是必須創(chuàng)建一個(gè)合法的I2cCntlr并調(diào)用I2cCntlrAdd注冊(cè)到核心層。其他Hi35xx開頭的函數(shù)都是驅(qū)動(dòng)適配者自由封裝的,并無(wú)形式化要求。

總結(jié)

采用統(tǒng)一服務(wù)模式,其優(yōu)點(diǎn)是不用為每一個(gè)I2C控制器定義一個(gè)設(shè)備節(jié)點(diǎn),控制器對(duì)象的創(chuàng)建和注冊(cè)比較自由;而缺點(diǎn)是要?jiǎng)?chuàng)建一個(gè)I2C管理器服務(wù),以及一個(gè)虛擬的資源描述設(shè)備。


說(shuō)明

I2C模塊適配涉及到的代碼示例片段來(lái)自device/hisilicon/drivers/i2c/


GPIO模塊適配

GPIO模塊由于目前不向用戶態(tài)提供能力,所以不需要發(fā)布設(shè)備服務(wù)。其hcs配置同uart相似,這里不再贅述,唯一不同是device_info.hcs中設(shè)備節(jié)點(diǎn)的policy為0,表示不發(fā)布設(shè)備服務(wù)。

device_gpio :: device {

device0 :: deviceNode {

policy = 0;

priority = 10;

permission = 0644;

moduleName = "hisi_pl061_driver";

deviceMatchAttr = "hisilicon_hi35xx_pl061";

}

}

同樣的原因,GPIO的驅(qū)動(dòng)Entry不需要實(shí)現(xiàn)Bind方法,僅需要在Init方法中創(chuàng)建并初始化一個(gè)GpioCntlr,再調(diào)用GpioCntlrAdd完成注冊(cè)即可。

struct HdfDriverEntry g_gpioDriverEntry = {

.moduleVersion = 1,

.Bind = Pl061GpioBind,

.Init = Pl061GpioInit,

.Release = Pl061GpioRelease,

.moduleName = "hisi_pl061_driver",

};

HDF_INIT(g_gpioDriverEntry);

這里雖然給Bind方法賦值,但其實(shí)現(xiàn)為空。

static int32_t Pl061GpioInit(struct HdfDeviceObject *device)

{

int32_t ret;

struct Pl061GpioCntlr *pl061 = &g_pl061;

ret = Pl061GpioReadDrs(pl061, device->property);

pl061->regBase = OsalIoRemap(pl061->phyBase, pl061->groupNum * pl061->regStep);

ret = Pl061GpioInitCntlrMem(pl061);

pl061->cntlr.count = pl061->groupNum * pl061->bitNum;

pl061->cntlr.priv = (void *)device->property;

pl061->cntlr.ops = &g_method;

pl061->cntlr.device = device;

ret = GpioCntlrAdd(&pl061->cntlr);

}

Init方法里面注意是對(duì)GpioCntlr的初始化,以及通過(guò)GpioCntlrAdd完成注冊(cè)。這里Pl061GpioCntlr內(nèi)嵌了一個(gè)GpioCntlr,又是繼承。

GpioCntlr的鉤子方法實(shí)現(xiàn),請(qǐng)感興趣的讀者自己去閱讀源碼,這里僅對(duì)每個(gè)鉤子方法作用做簡(jiǎn)單注釋:

static struct GpioMethod g_method = {

.request = NULL, //暫時(shí)不用

.release = NULL, //暫時(shí)不用

.write = Pl061GpioWrite, //寫管腳

.read = Pl061GpioRead, //讀管腳

.setDir = Pl061GpioSetDir, //設(shè)置管腳方向

.getDir = Pl061GpioGetDir, //獲取管腳方向

.toIrq = NULL, //暫時(shí)不用

.setIrq = Pl061GpioSetIrq, //設(shè)置管腳中斷段,如不具備此能力可忽略

.unsetIrq = Pl061GpioUnsetIrq, //取消管腳中斷設(shè)置,如不具備此能力可忽略

.enableIrq = Pl061GpioEnableIrq, //使能管腳中斷,如不具備此能力可忽略

.disableIrq = Pl061GpioDisableIrq, //禁止管腳中斷,如不具備此能力可忽略

};

總結(jié)

GPIO適配在hcs配置及驅(qū)動(dòng)Entry編寫上比I2C/UART都簡(jiǎn)單,但是無(wú)法向用戶態(tài)提供能力支撐。

最后,對(duì)于其他模塊的適配,基本都是這三種方式之一,讀者可集合核心層代碼及現(xiàn)有驅(qū)動(dòng)案例對(duì)號(hào)入座,采取相應(yīng)的適配方式。

說(shuō)明:GPIO模塊適配涉及到的代碼示例片段來(lái)自device/hisilicon/drivers/gpio/

OpenHarmony系統(tǒng)平臺(tái)驅(qū)動(dòng)適配Linux內(nèi)核

不知道讀者有沒(méi)有思考過(guò),如果在Linux內(nèi)核下,我們?nèi)绾芜m配一個(gè)平臺(tái)設(shè)備呢?因?yàn)镠DF驅(qū)動(dòng)框架是跨平臺(tái)的,所以我們?nèi)匀豢梢园凑涨懊娼榻B的方式進(jìn)行驅(qū)動(dòng)適配。但是,Linux內(nèi)核有大量現(xiàn)存驅(qū)動(dòng),它們一起支撐著大量SOC芯片,如果要將這些驅(qū)動(dòng)按照HDF的方式重新適配,且不說(shuō)難度,就工作量來(lái)說(shuō)是巨大的。

那么有沒(méi)有辦法將這些現(xiàn)存驅(qū)動(dòng)利用起來(lái)呢?答案就是適配器模式,它可以將一個(gè)類的接口轉(zhuǎn)換成用戶希望的另外一個(gè)接口,通過(guò)增加一點(diǎn)點(diǎn)工作量,使得現(xiàn)有對(duì)象在新環(huán)境中應(yīng)用起來(lái)。在Linux內(nèi)核,HDF驅(qū)動(dòng)框架時(shí)新環(huán)境,而Linux原生的設(shè)備對(duì)象,例如i2c_adapter, spi_dev,gpio_chip等等,都是舊對(duì)象,我們需要通過(guò)適配器模式,將其適配成HDF平臺(tái)驅(qū)動(dòng)框架定義的I2cCntlr、SpiCntlr、GpioCntlr等新對(duì)象,從而快速將其應(yīng)用起來(lái)。

具體的適配方式是,針對(duì)Linux內(nèi)核每一種平臺(tái)設(shè)備,提供一個(gè)適配驅(qū)動(dòng),將Linux原生設(shè)備對(duì)象封裝成HDF平臺(tái)驅(qū)動(dòng)框架定義的設(shè)備對(duì)象,其他流程同正常硬件驅(qū)動(dòng)適配一樣,由于是直接基于現(xiàn)有對(duì)象封裝,硬件初始化工作,甚至hcs配置都可以省略。

以I2C為例,在Linux下,我們將I2cCntlr直接關(guān)聯(lián)到i2c_adapter,而其鉤子方法的實(shí)現(xiàn)也是通過(guò)調(diào)用i2c_adapter相應(yīng)的配套方法實(shí)現(xiàn)的,其對(duì)應(yīng)關(guān)系如下:

HDF平臺(tái)驅(qū)動(dòng) Linux內(nèi)核 說(shuō)明
I2cCntlr i2c_adapter 通過(guò)I2cCntlr的priv成員關(guān)聯(lián)
I2cTransfer i2c_transfer
I2cMsg i2c_msg 需要進(jìn)行參數(shù)轉(zhuǎn)換

有興趣的讀者,可以通過(guò)閱讀下面的源碼,來(lái)了解Linux內(nèi)核下對(duì)各類平臺(tái)設(shè)備的適配。

drivers/adapter_del/khdf/linux/platform

總結(jié)與展望

OpenHarmony系統(tǒng)平臺(tái)驅(qū)動(dòng)框架基于HDF驅(qū)動(dòng)框架,為外設(shè)驅(qū)動(dòng)提供標(biāo)準(zhǔn)的平臺(tái)設(shè)備訪問(wèn)接口,同時(shí)為平臺(tái)設(shè)備驅(qū)動(dòng)提供統(tǒng)一的適配接口,使得外設(shè)驅(qū)動(dòng)僅需“關(guān)心”自身業(yè)務(wù),而使設(shè)備驅(qū)動(dòng)僅“關(guān)心”自身硬件。

為此,平臺(tái)驅(qū)動(dòng)框架采用平臺(tái)接口層、平臺(tái)核心層、平臺(tái)適配層的三層結(jié)構(gòu),并抽象出平臺(tái)設(shè)備(PlatformDevice)、平臺(tái)設(shè)備管理器(PlatformManager)、等概念,形成平臺(tái)驅(qū)動(dòng)框架特有的編程風(fēng)格和設(shè)計(jì)思想。然而有些概念和思想,在框架實(shí)現(xiàn)中并不明顯,隨著架構(gòu)的演進(jìn),有些概念將會(huì)越來(lái)越明確,他們包括:

統(tǒng)一的平臺(tái)設(shè)備對(duì)象模型:目前各類型的設(shè)備對(duì)象模型,由各模塊自己定義,例如I2cCntlr、UartHost,他們并沒(méi)有公共的父類型,而這一公共類型,是必要的。所以,將來(lái)會(huì)抽象出PlatformDevice這一公共設(shè)備對(duì)象模型。

設(shè)備管理器:每一類設(shè)備有自己的管理器,它即充當(dāng)容器,也充當(dāng)管理者,在需要用戶態(tài)支持的情況下,還充當(dāng)設(shè)備服務(wù)。雖然目前沒(méi)有明確的數(shù)據(jù)結(jié)構(gòu)與之對(duì)應(yīng),但是隨著架構(gòu)演進(jìn),這個(gè)概念的體現(xiàn)一定會(huì)愈加明確。

引用計(jì)數(shù):設(shè)備對(duì)象需要進(jìn)行生命周期管理,設(shè)備的獲取和釋放需要計(jì)數(shù),雖然當(dāng)前沒(méi)有實(shí)現(xiàn)這個(gè)機(jī)制,但是我們要求每一類設(shè)備的獲取通過(guò)Get/Put方法實(shí)現(xiàn),以便后續(xù)擴(kuò)展引用計(jì)數(shù)機(jī)制

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7614

    瀏覽量

    137782
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3638

    瀏覽量

    94012
  • OOP
    OOP
    +關(guān)注

    關(guān)注

    0

    文章

    14

    瀏覽量

    8810
  • 驅(qū)動(dòng)框架
    +關(guān)注

    關(guān)注

    0

    文章

    14

    瀏覽量

    4074
  • OpenHarmony
    +關(guān)注

    關(guān)注

    25

    文章

    3749

    瀏覽量

    16624

原文標(biāo)題:OpenHarmony HDF 平臺(tái)驅(qū)動(dòng)框架介紹及驅(qū)動(dòng)適配指導(dǎo)

文章出處:【微信號(hào):gh_e4f28cfa3159,微信公眾號(hào):OpenAtom OpenHarmony】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    迅為RK3568開發(fā)板篇OpenHarmony實(shí)操HDF驅(qū)動(dòng)控制LED-編寫應(yīng)用APP

    HDF_FRAMEWORKS 和 HDF_ADAPTER,它們分別指向 HDF(HardwareDriver Foundation,硬件驅(qū)動(dòng)框架
    發(fā)表于 02-06 10:27

    迅為RK3568開發(fā)板篇OpenHarmony實(shí)操HDF驅(qū)動(dòng)控制LED-添加內(nèi)核編譯

    編譯內(nèi)核時(shí)將該 HDF 驅(qū)動(dòng)編譯到鏡像中,接下來(lái)編寫驅(qū)動(dòng)編譯腳本 Makefile,代碼如下所示: 加入編譯體系,填加模塊目錄到 drivers/hdf_core/adapter/kh
    發(fā)表于 01-22 10:35

    迅為RK3568開發(fā)板篇OpenHarmony實(shí)操HDF驅(qū)動(dòng)控制LED-接口函數(shù)

    在一小節(jié)的代碼中實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的 LED 驅(qū)動(dòng),下面是對(duì)代碼的詳細(xì)解釋: 包含的頭文件如下所示: 宏定義如下所示: 數(shù)據(jù)結(jié)構(gòu)如下所示: g_LedDriverEntry 結(jié)構(gòu)體是驅(qū)動(dòng)入口結(jié)構(gòu)體,如下
    發(fā)表于 01-20 10:36

    迅為RK3568開發(fā)板篇OpenHarmony實(shí)操HDF驅(qū)動(dòng)控制LED-編寫內(nèi)核 LED HDF 驅(qū)動(dòng)程序

    接下來(lái)編譯 LED 驅(qū)動(dòng),該驅(qū)動(dòng)用于在基于華為設(shè)備框架HDF)的系統(tǒng)中控制 LED 燈的開關(guān),完整代碼如下所示: 更多內(nèi)容可以關(guān)注:迅為RK3568開發(fā)板篇
    發(fā)表于 01-17 15:13

    迅為RK3568開發(fā)板篇OpenHarmony配置HDF驅(qū)動(dòng)控制LED-新增 topeet子系統(tǒng)

    程序目錄 ├── led_driver.c:內(nèi)核 LED HDF 驅(qū)動(dòng)程序 └── Makefile:內(nèi)核 LED HDF 驅(qū)動(dòng)編譯腳本 更多內(nèi)容可以關(guān)注:迅為RK3568開發(fā)板篇
    發(fā)表于 01-13 15:59

    迅為RK3568開發(fā)板篇OpenHarmony配置HDF驅(qū)動(dòng)控制LED-配置創(chuàng)建私有配置文件

    私有配置文件,用來(lái)填寫一些驅(qū)動(dòng)的默認(rèn)配置信息。HDF 框架在加載驅(qū)動(dòng)時(shí),會(huì)獲取相應(yīng)的配置信息并將其保存在 HdfDeviceObject 的 property 中。這些配置信息通過(guò) B
    發(fā)表于 01-10 11:13

    迅為RK3568開發(fā)板篇OpenHarmony配置HDF驅(qū)動(dòng)控制LED-修改HCS硬件配置

    驅(qū)動(dòng)的設(shè)備描述修改/vendor/hihope/rk3568/hdf_config/khdf/device_info/device_info.hcs 文件,添加如下代碼,如下所示: 接下來(lái)解釋一下
    發(fā)表于 01-08 15:25

    OpenHarmony程序分析框架論文入選ICSE 2025

      近日,ICSE 2025軟件工程實(shí)踐Track放榜,面向OpenAtom OpenHarmony(以下簡(jiǎn)稱“OpenHarmony”)的ArkTS程序分析基礎(chǔ)框架--方舟程序分析器(論文題目為
    的頭像 發(fā)表于 01-02 13:41 ?231次閱讀
    <b class='flag-5'>OpenHarmony</b>程序分析<b class='flag-5'>框架</b>論文入選ICSE 2025

    OpenHarmony人才生態(tài)大會(huì)南向生態(tài)社區(qū)發(fā)展論壇在武漢圓滿舉辦

    。 (Laval社區(qū)運(yùn)營(yíng)專家涂純) 深圳華秋電子有限公司電子發(fā)燒友平臺(tái)社區(qū)運(yùn)營(yíng)負(fù)責(zé)人劉勇介紹電子發(fā)燒友在OpenHarmony芯片創(chuàng)新應(yīng)用與生態(tài)布局,依托650多萬(wàn)用戶構(gòu)建開發(fā)者生態(tài)平臺(tái)
    發(fā)表于 11-29 09:54

    觸覺(jué)智能Purple Pi OH鴻蒙開發(fā)板成功適配OpenHarmony5.0 Release,開啟新征程

    觸覺(jué)智能Purple Pi OH鴻蒙開發(fā)板,成功適配OpenHarmony5.0 Release版本!為大家?guī)?lái)OpenHarmony5.0特性講解!關(guān)注觸覺(jué)智能,為大家?guī)?lái)更多OpenHar
    的頭像 發(fā)表于 10-25 10:51 ?499次閱讀
    觸覺(jué)智能Purple Pi OH鴻蒙開發(fā)板成功<b class='flag-5'>適配</b><b class='flag-5'>OpenHarmony</b>5.0 Release,開啟新征程

    紅外適配驅(qū)動(dòng)怎么安裝

    紅外適配驅(qū)動(dòng)安裝指南 1. 了解紅外適配器 紅外適配器是一種硬件設(shè)備,它允許計(jì)算機(jī)或其他設(shè)備通過(guò)紅外信號(hào)與遙控器、打印機(jī)、手機(jī)等進(jìn)行通信。在安裝驅(qū)
    的頭像 發(fā)表于 10-14 10:47 ?428次閱讀

    串口驅(qū)動(dòng)分析之serial driver

    前兩節(jié)我們介紹串口驅(qū)動(dòng)框架和tty core部分。這節(jié)我們介紹和硬件緊密相關(guān)的串口驅(qū)動(dòng)部分。
    的頭像 發(fā)表于 09-04 14:23 ?569次閱讀
    串口<b class='flag-5'>驅(qū)動(dòng)</b>分析之serial driver

    鴻蒙開發(fā):【OpenHarmony 4.0 Release指導(dǎo)】

    OpenHarmony 4.0版本如期而至,開發(fā)套件同步升級(jí)到API 10。相比3.2 Release版本,新增4000多個(gè)API,應(yīng)用開發(fā)能力更加豐富;HDF新增200多個(gè)HDI接口,硬件適配更加便捷;我們持續(xù)優(yōu)化圖形
    的頭像 發(fā)表于 05-14 09:59 ?1653次閱讀
    鴻蒙開發(fā):【<b class='flag-5'>OpenHarmony</b> 4.0 Release指導(dǎo)】

    鴻蒙開發(fā)實(shí)戰(zhàn):【Hdf Framework】

    該倉(cāng)主要存放OpenHarmony驅(qū)動(dòng)子系統(tǒng)核心源碼信息(包括驅(qū)動(dòng)框架、配置管理、配置解析、驅(qū)動(dòng)通用框架
    的頭像 發(fā)表于 03-21 20:29 ?600次閱讀
    鴻蒙開發(fā)實(shí)戰(zhàn):【<b class='flag-5'>Hdf</b> Framework】

    介紹一種OpenAtom OpenHarmony輕量系統(tǒng)適配方案

    本文在不改變?cè)邢到y(tǒng)基礎(chǔ)框架的基礎(chǔ)上, 介紹了一種OpenAtom OpenHarmony(以下簡(jiǎn)稱“OpenHarmony”)輕量系統(tǒng)適配
    的頭像 發(fā)表于 03-05 09:24 ?1286次閱讀
    <b class='flag-5'>介紹</b>一種OpenAtom <b class='flag-5'>OpenHarmony</b>輕量系統(tǒng)<b class='flag-5'>適配</b>方案