自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Hi3516驅(qū)動(dòng)開(kāi)發(fā)全面詳解

開(kāi)發(fā) 前端
內(nèi)核驅(qū)動(dòng)是軟件與硬件交互的橋梁,通過(guò)文件系統(tǒng)接口訪問(wèn)OpenHarmony內(nèi)核的硬件資源,是用戶與內(nèi)核之間、進(jìn)程與進(jìn)程之間通信的一種方式。

[[410422]]

想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

驅(qū)動(dòng)框架介紹

驅(qū)動(dòng)子系統(tǒng)

內(nèi)核驅(qū)動(dòng)是軟件與硬件交互的橋梁,通過(guò)文件系統(tǒng)接口訪問(wèn)OpenHarmony內(nèi)核的硬件資源,是用戶與內(nèi)核之間、進(jìn)程與進(jìn)程之間通信的一種方式。每類驅(qū)動(dòng)代表一種能力,用戶可以根據(jù)需求選擇對(duì)應(yīng)驅(qū)動(dòng),完成數(shù)據(jù)的傳輸。OpenHarmony驅(qū)動(dòng)子系統(tǒng)采用C面向?qū)ο缶幊棠P蜆?gòu)建,通過(guò)平臺(tái)解耦、內(nèi)核解耦,兼容不同內(nèi)核,提供了歸一化的驅(qū)動(dòng)平臺(tái)底座,旨在為開(kāi)發(fā)者提供更精準(zhǔn)、更高效的開(kāi)發(fā)環(huán)境,力求做到一次開(kāi)發(fā),多系統(tǒng)部署。

1、架構(gòu)

OpenHarmony驅(qū)動(dòng)框架采用主從架構(gòu)設(shè)計(jì)模式,圍繞著框架、模型、能力庫(kù)和工具四個(gè)維度能力展開(kāi)構(gòu)建。

Hi3516驅(qū)動(dòng)開(kāi)發(fā)-鴻蒙HarmonyOS技術(shù)社區(qū)

2、目錄

  1. drivers 
  2. ├── adapter               #適配平臺(tái)差異性的代碼 
  3. ├── framework             #驅(qū)動(dòng)框架核心代碼 
  4. └── peripheral            #外設(shè)驅(qū)動(dòng)代碼 
  5. └── liteos                #hievent和tzdrivert驅(qū)動(dòng)代碼。hievent:事件日志管理驅(qū)動(dòng);tzdrivert:用于ree/tee切換、通訊,提供應(yīng)用層訪問(wèn)的設(shè)備節(jié)點(diǎn) 

3、驅(qū)動(dòng)框架交互流程

Hi3516驅(qū)動(dòng)開(kāi)發(fā)-鴻蒙HarmonyOS技術(shù)社區(qū)

驅(qū)動(dòng)框架完成大部分驅(qū)動(dòng)加載的動(dòng)作,用戶只需注冊(cè)自己所需的接口和配置,然后驅(qū)動(dòng)框架就會(huì)解析配置的內(nèi)容,完成驅(qū)動(dòng)加載和初始化動(dòng)作。

4、安裝

OpenHarmony驅(qū)動(dòng)主要部署在內(nèi)核態(tài),當(dāng)前主要采用靜態(tài)鏈接方式,隨內(nèi)核子系統(tǒng)編譯和系統(tǒng)鏡像打包。

Hi3516驅(qū)動(dòng)開(kāi)發(fā)-鴻蒙HarmonyOS技術(shù)社區(qū)

5、HDF驅(qū)動(dòng)加載的過(guò)程

Hi3516驅(qū)動(dòng)開(kāi)發(fā)-鴻蒙HarmonyOS技術(shù)社區(qū)

HDF Framework

1、簡(jiǎn)介

HDF Framework提供包括驅(qū)動(dòng)框架、配置管理、配置解析、驅(qū)動(dòng)通用框架模型、硬件通用平臺(tái)能力接口等,驅(qū)動(dòng)框架的架構(gòu)圖:

Hi3516驅(qū)動(dòng)開(kāi)發(fā)-鴻蒙HarmonyOS技術(shù)社區(qū)

 2、目錄

  1. /drivers/framework 
  2. ├── ability        #提供驅(qū)動(dòng)開(kāi)發(fā)的能力支持,如消息模型庫(kù)等 
  3. │   ├── config     #配置解析代碼 
  4. │   └── sbuf       #數(shù)據(jù)序列化代碼 
  5. ├── core           #實(shí)現(xiàn)驅(qū)動(dòng)框架的核心代碼 
  6. │   ├── adapter    #實(shí)現(xiàn)對(duì)內(nèi)核操作接口適配,提供抽象化的接口供開(kāi)發(fā)者使用 
  7. │   ├── common     #驅(qū)動(dòng)框架公共基礎(chǔ)代碼 
  8. │   ├── host       #驅(qū)動(dòng)宿主環(huán)境模塊 
  9. │   ├── manager    #驅(qū)動(dòng)框架管理模塊 
  10. │   └── shared     #host和manager共享模塊代碼 
  11. ├── include        #驅(qū)動(dòng)框架對(duì)外提供能力的頭文件 
  12. │   ├── config     #提供配置解析能力的頭文件 
  13. │   ├── core       #驅(qū)動(dòng)框架對(duì)外提供的頭文件 
  14. │   ├── net        #網(wǎng)絡(luò)數(shù)據(jù)操作相關(guān)的頭文件 
  15. │   ├── osal       #系統(tǒng)適配相關(guān)接口的頭文件 
  16. │   ├── platform   #平臺(tái)設(shè)備相關(guān)接口的頭文件 
  17. │   ├── utils      #驅(qū)動(dòng)框架公共能力的頭文件 
  18. │   └── wifi       #WLAN對(duì)外提供能力的頭文件 
  19. ├── model          #提供驅(qū)動(dòng)通用框架模型 
  20. │   ├── display    #顯示框架模型 
  21. │   ├── input      #輸入框架模型 
  22. │   ├── network    #WLAN框架模型 
  23. │   └── sensor     #Sensor驅(qū)動(dòng)模型 
  24. ├── support        #提系統(tǒng)的基礎(chǔ)能力  
  25. │   └── platform   #平臺(tái)設(shè)備驅(qū)動(dòng)框架及訪問(wèn)接口,范圍包括GPIO、I2C、SPI等 
  26. ├── tools          #hdf框架工具相關(guān)的源碼 
  27. │   └── hc-gen     #配置管理工具源碼 
  28. └── utils          #提供基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)和算法等 

HDF適配

HDF適配主要實(shí)現(xiàn)OpenHarmony驅(qū)動(dòng)子系統(tǒng)內(nèi)核或用戶態(tài)驅(qū)動(dòng)框架的代碼和編譯腳本,提供驅(qū)動(dòng)框架的能力。

2、目錄

  1. /drivers/adapter 
  2. ├── khdf/linux          #提供驅(qū)動(dòng)框架對(duì)Linux內(nèi)核依賴適配 
  3. ├── khdf/liteos         #提供驅(qū)動(dòng)框架對(duì)LiteOS-A內(nèi)核依賴適配 
  4. ├── khdf/liteos_m       #提供驅(qū)動(dòng)框架對(duì)LiteOS-M內(nèi)核依賴適配 
  5. ├── uhdf                #提供用戶態(tài)驅(qū)動(dòng)接口對(duì)系統(tǒng)依賴適配 
  6. └── uhdf2               #提供用戶態(tài)驅(qū)動(dòng)框架對(duì)系統(tǒng)依賴適配 

linux khdf

1、簡(jiǎn)介

drivers/adapter/khdf/linux下提供OpenHarmony驅(qū)動(dòng)子系統(tǒng)適配linux內(nèi)核的代碼和編譯腳本,在linux內(nèi)核中部署OpenHarmony驅(qū)動(dòng)框架。

2、目錄

  1. /drivers/adapter/khdf/linux 
  2. ├── config               #linux內(nèi)核下編譯配置解析代碼的編譯腳本 
  3. ├── hcs                  #linux內(nèi)核下HDF的配置管理目錄 
  4. ├── manager              #linux內(nèi)核下啟動(dòng)適配啟動(dòng)HDF框架代碼 
  5. ├── model                #驅(qū)動(dòng)模型適配linux代碼 
  6. │   ├── display          #顯示驅(qū)動(dòng)模型 
  7. │   ├── input            #輸入驅(qū)動(dòng)模型 
  8. │   ├── network          #wifi驅(qū)動(dòng)模型 
  9. │   └── sensor           #傳感器驅(qū)動(dòng)模型 
  10. ├── network              #適配linux內(nèi)核網(wǎng)絡(luò)代碼 
  11. ├── osal                 #適配linux內(nèi)核的posix接口 
  12. ├── platform             #平臺(tái)設(shè)備接口適配linux內(nèi)核代碼 
  13. │   ├── emmc             #emmc操作接口 
  14. │   ├── gpio             #gpio接口 
  15. │   ├── i2c              #i2c接口 
  16. │   ├── mipi_dsi         #mipi dsi接口 
  17. │   ├── pwm              #pwm接口 
  18. │   ├── rtc              #rtc接口 
  19. │   ├── sdio             #sdio接口 
  20. │   ├── spi              #spi接口 
  21. │   ├── uart             #uart接口 
  22. │   └── watchdog         #watchdog接口 

peripheral

1、簡(jiǎn)介

peripheral主要包含各外設(shè)器件驅(qū)動(dòng)相關(guān)的HDI(Hardware Driver Interface)接口、HAL實(shí)現(xiàn)、驅(qū)動(dòng)模型及測(cè)試用例等,根據(jù)模塊劃分不同目錄,具體模塊的相關(guān)信息可參閱各模塊子目錄下的readme。

2、目錄

代碼目錄為 /drivers/peripheral,其中包含的各子目錄簡(jiǎn)介如下。

  • audio:Audio HDI接口的定義,用于管理聲卡驅(qū)動(dòng)的加載和卸載、創(chuàng)建音頻播放對(duì)象3及錄音對(duì)象、選擇音頻場(chǎng)景、設(shè)置音頻屬性及音量、控制音頻播放及錄音的啟停等。
  • codec:Codec HDI接口的定義,這些接口對(duì)上層服務(wù)提供媒體編解碼的驅(qū)動(dòng)能力。
  • display:Display HDI 接口定義及其默認(rèn)實(shí)現(xiàn),對(duì)上層圖形服務(wù)提供顯示驅(qū)動(dòng)能力,包括顯示圖層的管理、顯示內(nèi)存的管理及硬件圖形加速。
  • format:Format HDI接口定義,此類接口對(duì)上層服務(wù)提供媒體文件復(fù)用和解復(fù)用的驅(qū)動(dòng)能力。
  • input:Input HDI接口定義及其實(shí)現(xiàn),對(duì)上層輸入系統(tǒng)服務(wù)提供操作input設(shè)備的驅(qū)動(dòng)能力,包括input設(shè)備管理、業(yè)務(wù)流控制、數(shù)據(jù)上報(bào)等。
  • sensor:Sensor HDI接口定義與實(shí)現(xiàn),接口主要包括所有Sensor信息查詢、Sensor啟停、Sensor訂閱/去訂閱、Sensor參數(shù)配置等穩(wěn)定的接口,簡(jiǎn)化服務(wù)開(kāi)發(fā)。
  • wlan:WLAN HDI接口定義與實(shí)現(xiàn),包括創(chuàng)建和銷毀HAL層和WLAN驅(qū)動(dòng)的通道、獲取本設(shè)備支持的WLAN特性等。

HDF

1、HDF驅(qū)動(dòng)開(kāi)發(fā)簡(jiǎn)介

HDF框架以組件化的驅(qū)動(dòng)模型作為核心設(shè)計(jì)思路,為開(kāi)發(fā)者提供更精細(xì)化的驅(qū)動(dòng)管理,讓驅(qū)動(dòng)開(kāi)發(fā)和部署更加規(guī)范。HDF框架將一類設(shè)備驅(qū)動(dòng)放在同一個(gè)host里面,開(kāi)發(fā)者也可以將驅(qū)動(dòng)功能分層獨(dú)立開(kāi)發(fā)和部署,支持一個(gè)驅(qū)動(dòng)多個(gè)node,HDF框架管理驅(qū)動(dòng)模型如下圖所示:

Hi3516驅(qū)動(dòng)開(kāi)發(fā)-鴻蒙HarmonyOS技術(shù)社區(qū)

基于HDF(Hardware Driver Foundation驅(qū)動(dòng)框架)開(kāi)發(fā)驅(qū)動(dòng),用戶只需注冊(cè)自己所需的接口和配置,然后驅(qū)動(dòng)框架就會(huì)解析配置的內(nèi)容,完成驅(qū)動(dòng)加載和初始化動(dòng)作。

開(kāi)發(fā)者基于HDF驅(qū)動(dòng)框架開(kāi)發(fā)的驅(qū)動(dòng)主要包含三大部分:

  • 驅(qū)動(dòng)程序部分----完成驅(qū)動(dòng)的功能邏輯。
  • 驅(qū)動(dòng)配置信息----指示驅(qū)動(dòng)的加載信息內(nèi)容。
  • 驅(qū)動(dòng)資源配置----配置驅(qū)動(dòng)的硬件配置信息。

驅(qū)動(dòng)程序主要是完成驅(qū)動(dòng)功能的邏輯代碼:

對(duì)于開(kāi)發(fā)者首先看到的是驅(qū)動(dòng)入口部分,驅(qū)動(dòng)入口部分通過(guò)DriverEntry進(jìn)行描述。

其中主要包含Bind, Init 和Release三個(gè)接口。

  1. struct HdfDriverEntry g_deviceSample = { 
  2.     .moduleVersion = 1, 
  3.     .moduleName = "sample_driver",  
  4.     .Bind = SampleDriverBind, 
  5.     .Init = SampleDriverInit, 
  6.     .Release = SampleDriverRelease, 
  7. }; 

Bind接口描述:該接口的作用主要是完成驅(qū)動(dòng)設(shè)備和設(shè)備服務(wù)接口的bind動(dòng)作。

  1. int32_t SampleDriverBind(struct HdfDeviceObject *deviceObject) 
  2.     // TODO: Bind device service to device object. 
  3.     // And you can also initialize device resources here. 
  4.     return HDF_SUCCESS; 

Init接口描述:當(dāng)框架完成設(shè)備綁定動(dòng)作后,就開(kāi)始調(diào)用驅(qū)動(dòng)初始化接口,當(dāng)初始化成功后,驅(qū)動(dòng)框架根據(jù)配置文件決定是否對(duì)外創(chuàng)建設(shè)備服務(wù)接口,還是只是對(duì)當(dāng)前服務(wù)接口可見(jiàn)。如果Init初始化失敗的話,驅(qū)動(dòng)框架就會(huì)主動(dòng)釋放創(chuàng)建的設(shè)備接口等信息。

  1. int32_t SampleDriverInit(struct HdfDeviceObject *deviceObject) 
  2.     // TODO: Init hardware or other resources here. 
  3.     return HDF_SUCCESS; 

Release接口描述:當(dāng)用戶需要卸載驅(qū)動(dòng)時(shí),驅(qū)動(dòng)框架先通過(guò)該接口通知驅(qū)動(dòng)程序釋放資源。然后在執(zhí)行其他內(nèi)部資源釋放。

  1. void SampleDriverRelease(struct HdfDeviceObject *deviceObject) 
  2.     // Release all resources. 
  3.     return

2、驅(qū)動(dòng)加載

HDF驅(qū)動(dòng)加載包括按需加載和按序加載。

  • 按需加載

HDF框架支持驅(qū)動(dòng)在系統(tǒng)啟動(dòng)過(guò)程中默認(rèn)加載,或者在系統(tǒng)啟動(dòng)之后動(dòng)態(tài)加載。

  1. typedef enum {    DEVICE_PRELOAD_ENABLE = 0,    DEVICE_PRELOAD_ENABLE_STEP2,    DEVICE_PRELOAD_DISABLE,    DEVICE_PRELOAD_INVALID} DevicePreload; 
  2. 1. 
  3. 1. 
  4. 1. 

復(fù)制配置文件中preload 字段配成 0 (DEVICE_PRELOAD_ENABLE ),則系統(tǒng)啟動(dòng)過(guò)程中默認(rèn)加載;配成1(DEVICE_PRELOAD_ENABLE_STEP2),當(dāng)系統(tǒng)支持快啟的時(shí)候,則在系統(tǒng)系統(tǒng)完成之后再加載這一類驅(qū)動(dòng),否則和DEVICE_PRELOAD_ENABLE 含義相同;

配成2(DEVICE_PRELOAD_DISABLE),則系統(tǒng)啟動(dòng)過(guò)程中默認(rèn)不加載,支持后續(xù)動(dòng)態(tài)加載,當(dāng)用戶態(tài)獲取驅(qū)動(dòng)服務(wù)(參考消息機(jī)制)時(shí),如果驅(qū)動(dòng)服務(wù)不存在時(shí),HDF框架會(huì)嘗試動(dòng)態(tài)加載該驅(qū)動(dòng)。

  • 按序加載

HDF框架支持驅(qū)動(dòng)在系統(tǒng)啟動(dòng)的過(guò)程中按照驅(qū)動(dòng)的優(yōu)先級(jí)進(jìn)行加載。

配置文件中的priority(取值范圍為整數(shù)0到200)是用來(lái)表示host和驅(qū)動(dòng)的優(yōu)先級(jí),不同的host內(nèi)的驅(qū)動(dòng),host的priority值越小,驅(qū)動(dòng)加載優(yōu)先級(jí)越高;同一個(gè)host內(nèi)驅(qū)動(dòng)的priority值越小,加載優(yōu)先級(jí)越高。

3、驅(qū)動(dòng)服務(wù)管理

HDF框架可以集中管理驅(qū)動(dòng)服務(wù),開(kāi)發(fā)者可直接通過(guò)HDF框架對(duì)外提供的能力接口獲取驅(qū)動(dòng)相關(guān)的服務(wù)。

4、驅(qū)動(dòng)消息機(jī)制

HDF框架提供統(tǒng)一的驅(qū)動(dòng)消息機(jī)制,支持用戶態(tài)應(yīng)用向內(nèi)核態(tài)驅(qū)動(dòng)發(fā)送消息,也支持內(nèi)核態(tài)驅(qū)動(dòng)向用戶態(tài)應(yīng)用發(fā)送消息。

驅(qū)動(dòng)開(kāi)發(fā)步驟

驅(qū)動(dòng)實(shí)現(xiàn)

驅(qū)動(dòng)實(shí)現(xiàn)包含驅(qū)動(dòng)業(yè)務(wù)代碼和驅(qū)動(dòng)入口注冊(cè),具體寫(xiě)法如下:

驅(qū)動(dòng)業(yè)務(wù)代碼

  1. #include "hdf_device_desc.h"  // HDF框架對(duì)驅(qū)動(dòng)開(kāi)放相關(guān)能力接口的頭文件#include "hdf_log.h"          // HDF 框架提供的日志接口頭文件#define HDF_LOG_TAG "sample_driver"   // 打印日志所包含的標(biāo)簽,如果不定義則用默認(rèn)定義的HDF_TAG標(biāo)簽//驅(qū)動(dòng)對(duì)外提供的服務(wù)能力,將相關(guān)的服務(wù)接口綁定到HDF框架int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject){    HDF_LOGD("Sample driver bind success");    return 0;}// 驅(qū)動(dòng)自身業(yè)務(wù)初始的接口int32_t HdfSampleDriverInit(struct HdfDeviceObject *deviceObject){    HDF_LOGD("Sample driver Init success");    return 0;}// 驅(qū)動(dòng)資源釋放的接口void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject){    HDF_LOGD("Sample driver release success");    return;} 

驅(qū)動(dòng)入口注冊(cè)到HDF框架

  1. // 定義驅(qū)動(dòng)入口的對(duì)象,必須為HdfDriverEntry(在hdf_device_desc.h中定義)類型的全局變量struct HdfDriverEntry g_sampleDriverEntry = {    .moduleVersion = 1,    .moduleName = "sample_driver",    .Bind = HdfSampleDriverBind,    .Init = HdfSampleDriverInit,    .Release = HdfSampleDriverRelease,};// 調(diào)用HDF_INIT將驅(qū)動(dòng)入口注冊(cè)到HDF框架中,在加載驅(qū)動(dòng)時(shí)HDF框架會(huì)先調(diào)用Bind函數(shù),再調(diào)用Init函數(shù)加載該驅(qū)動(dòng),當(dāng)Init調(diào)用異常時(shí),HDF框架會(huì)調(diào)用Release釋放驅(qū)動(dòng)資源并退出。HDF_INIT(g_sampleDriverEntry); 

驅(qū)動(dòng)編譯

驅(qū)動(dòng)代碼的編譯必須要使用HDF框架提供的Makefile模板進(jìn)行編譯。

  1. include $(LITEOSTOPDIR)/../../drivers/adapter/lite/khdf/lite.mk #導(dǎo)入hdf預(yù)定義內(nèi)容,必需MODULE_NAME :=    #生成的結(jié)果文件LOCAL_INCLUDE :=  #本驅(qū)動(dòng)的頭文件目錄LOCAL_SRCS :=     #本驅(qū)動(dòng)的源代碼文件LOCAL_CFLAGS :=  #自定義的編譯選項(xiàng)include $(HDF_DRIVER) #導(dǎo)入模板makefile完成編譯 

編譯結(jié)果文件鏈接到內(nèi)核鏡像,添加到device目錄下的lite.mk里面,示例如下:

  1. LITEOS_BASELIB +=  -lxxx  #鏈接生成的靜態(tài)庫(kù)LIB_SUBDIRS    +=         #驅(qū)動(dòng)代碼Makefile的目錄 

驅(qū)動(dòng)配置

HDF使用HCS作為配置描述源碼,HCS詳細(xì)介紹參考配置管理介紹。

驅(qū)動(dòng)配置包含兩部分,HDF框架定義的驅(qū)動(dòng)設(shè)備描述和驅(qū)動(dòng)的私有配置信息,具體寫(xiě)法如下:

  • 驅(qū)動(dòng)設(shè)備描述(必選)

HDF框架加載驅(qū)動(dòng)所需要的信息來(lái)源于HDF框架定義的驅(qū)動(dòng)設(shè)備描述,因此基于HDF框架開(kāi)發(fā)的驅(qū)動(dòng)必須要在HDF框架定義的device_info.hcs配置文件中添加對(duì)應(yīng)的設(shè)備描述,驅(qū)動(dòng)的設(shè)備描述填寫(xiě)如下所示:

  1. root {    device_info {        match_attr = "hdf_manager";        template host {       // host模板,繼承該模板的節(jié)點(diǎn)(如下sample_host)如果使用模板中的默認(rèn)值,則節(jié)點(diǎn)字段可以缺省            hostName = "";            priority = 100;            template device {                template deviceNode {                    policy = 0;                    priority = 100;                    preload = 0;                    permission = 0664;                    moduleName = "";                    serviceName = "";                    deviceMatchAttr = "";                }            }        }        sample_host :: host{            hostName = "host0";    // host名稱,host節(jié)點(diǎn)是用來(lái)存放某一類驅(qū)動(dòng)的容器            priority = 100;        // host啟動(dòng)優(yōu)先級(jí)(0-200),值越大優(yōu)先級(jí)越低,建議默認(rèn)配100,優(yōu)先級(jí)相同則不保證host的加載順序            device_sample :: device {        // sample設(shè)備節(jié)點(diǎn)                device0 :: deviceNode {      // sample驅(qū)動(dòng)的DeviceNode節(jié)點(diǎn)                    policy = 1;              // policy字段是驅(qū)動(dòng)服務(wù)發(fā)布的策略,在驅(qū)動(dòng)服務(wù)管理章節(jié)有詳細(xì)介紹                    priority = 100;          // 驅(qū)動(dòng)啟動(dòng)優(yōu)先級(jí)(0-200),值越大優(yōu)先級(jí)越低,建議默認(rèn)配100,優(yōu)先級(jí)相同則不保證device的加載順序                    preload = 0;             // 驅(qū)動(dòng)按需加載字段,在本章節(jié)最后的說(shuō)明有詳細(xì)介紹                    permission = 0664;       // 驅(qū)動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn)權(quán)限                    moduleName = "sample_driver";   // 驅(qū)動(dòng)名稱,該字段的值必須和驅(qū)動(dòng)入口結(jié)構(gòu)的moduleName值一致                    serviceName = "sample_service";    // 驅(qū)動(dòng)對(duì)外發(fā)布服務(wù)的名稱,必須唯一                    deviceMatchAttr = "sample_config"; // 驅(qū)動(dòng)私有數(shù)據(jù)匹配的關(guān)鍵字,必須和驅(qū)動(dòng)私有數(shù)據(jù)配置表中的match_attr值相等                }            }        }    }} 
  • 驅(qū)動(dòng)私有配置信息(可選)

如果驅(qū)動(dòng)有私有配置,則可以添加一個(gè)驅(qū)動(dòng)的配置文件,用來(lái)填寫(xiě)一些驅(qū)動(dòng)的默認(rèn)配置信息,HDF框架在加載驅(qū)動(dòng)的時(shí)候,會(huì)將對(duì)應(yīng)的配置信息獲取并保存在HdfDeviceObject 中的property里面,通過(guò)Bind和Init(參考驅(qū)動(dòng)開(kāi)發(fā))傳遞給驅(qū)動(dòng),驅(qū)動(dòng)的配置信息示例如下:

  1. root {    SampleDriverConfig {        sample_version = 1;        sample_bus = "I2C_0";        match_attr = "sample_config";   //該字段的值必須和device_info.hcs中的deviceMatchAttr值一致    }} 

 配置信息定義之后,需要將該配置文件添加到板級(jí)配置入口文件hdf.hcs(這一塊可以通過(guò)OpenHarmony驅(qū)動(dòng)子系統(tǒng)在DevEco集成驅(qū)動(dòng)開(kāi)發(fā)套件工具一鍵式配置,具體使用方法參考驅(qū)動(dòng)開(kāi)發(fā)套件中的介紹),示例如下:

  1. #include "device_info/device_info.hcs"#include "sample/sample_config.hcs" 

驅(qū)動(dòng)開(kāi)發(fā)示例

下面基于HDF框架,提供一個(gè)簡(jiǎn)單的UART(Universal Asynchronous Receiver/Transmitter)平臺(tái)驅(qū)動(dòng)開(kāi)發(fā)樣例,包含配置文件的添加,驅(qū)動(dòng)代碼的實(shí)現(xiàn)以及用戶態(tài)程序和驅(qū)動(dòng)交互的流程。驅(qū)動(dòng)程序源碼位于vendor/huawei/hdf/sample目錄

添加配置

HCS(HDF Configuration Source)是HDF驅(qū)動(dòng)框架的配置描述源碼,內(nèi)容以Key-Value為主要形式。它實(shí)現(xiàn)了配置代碼與驅(qū)動(dòng)代碼解耦,便于開(kāi)發(fā)者進(jìn)行配置管理。

HC-GEN**(HDF Configuration Generator)**是HCS配置轉(zhuǎn)換工具,可以將HDF配置文件轉(zhuǎn)換為軟件可讀取的文件格式:

在弱性能環(huán)境中,轉(zhuǎn)換為配置樹(shù)源碼,驅(qū)動(dòng)可直接調(diào)用C代碼獲取配置。

在高性能環(huán)境中,轉(zhuǎn)換為HCB(HDF Configuration Binary)二進(jìn)制文件,驅(qū)動(dòng)可使用HDF框架提供的配置解析接口獲取配置。

設(shè)備配置文件和驅(qū)動(dòng)配置文件的路徑定義在板級(jí)配置入口文件hdf.hcs(vendor\hisilicon\hispark_taurus\config\hdf.hcs)

  1. #include "../../../../device/hisilicon/hispark_taurus/sdk_liteos/config/i2c/i2c_config.hcs"#include "../../../../device/hisilicon/hispark_taurus/sdk_liteos/config/gpio/gpio_config.hcs"#include "../../../../device/hisilicon/hispark_taurus/sdk_liteos/config/uart/uart_config.hcs"#include "../../../../device/hisilicon/hispark_taurus/sdk_liteos/config/sdio/sdio_config.hcs"#include "../../../../device/hisilicon/hispark_taurus/sdk_liteos/config/emmc/emmc_config.hcs"#include "../../../../device/hisilicon/hispark_taurus/sdk_liteos/config/watchdog/watchdog_config.hcs"#include "../../../../device/hisilicon/hispark_taurus/sdk_liteos/config/usb/usb_config.hcs"#include "../../../../device/hisilicon/hispark_taurus/sdk_liteos/config/rtc/rtc_config.hcs"#include "../../../../device/hisilicon/hispark_taurus/sdk_liteos/config/spi/spi_config.hcs"#include "../../../../device/hisilicon/hispark_taurus/sdk_liteos/config/pwm/pwm_config.hcs"#include "../../../../device/hisilicon/hispark_taurus/sdk_liteos/config/dmac/dmac_config.hcs"#include "device_info/device_info.hcs"#include "wifi/wlan_platform.hcs"#include "wifi/wlan_chip_hi3881.hcs"#include "lcd/lcd_config.hcs"#include "input/input_config.hcs"#include "sensor/sensor_config.hcs"root {    module = "hisilicon,hi35xx_chip";} 

 1、在HDF框架的驅(qū)動(dòng)配置文件(例如device\hisilicon\hispark_taurus\sdk_liteos\config\uart\uart_config.hcs)中添加該驅(qū)動(dòng)的配置信息,如下所示:

  1. root {    platform {        uart_sample {            num = 5;            base = 0x120a0000;  // UART base register address            irqNum = 38;            baudrate = 115200;            uartClk = 24000000; // 24 M            wlen = 0x60;        // 8 bit width            parity = 0;            stopBit = 0;            match_attr = "sample_uart_5";        }    }} 

 2、在HDF框架的設(shè)備配置文件(例如vendor\hisilicon\hispark_taurus\config\device_info\device_info.hcs)中添加該驅(qū)動(dòng)的設(shè)備節(jié)點(diǎn)信息,如下所示:

  1. root {    device_info {        platform :: host {            hostName = "platform_host";            priority = 50;            device_uart :: device {                device5 :: deviceNode {                    policy = 2;                    priority = 10;                    permission = 0660;                    moduleName = "UART_SAMPLE";                      serviceName = "HDF_PLATFORM_UART_5";                    deviceMatchAttr = "sample_uart_5";                }            }        }    }} 

注冊(cè)u(píng)art驅(qū)動(dòng)入口

基于HDF框架注冊(cè)UART驅(qū)動(dòng)的入口HdfDriverEntry,代碼如下:

  1. // 綁定UART驅(qū)動(dòng)接口到HDF框架static int32_t SampleUartDriverBind(struct HdfDeviceObject *device){    struct UartHost *uartHost = NULL;    if (device == NULL) {        return HDF_ERR_INVALID_OBJECT;    }    HDF_LOGI("Enter %s:", __func__);    uartHost = UartHostCreate(device);    if (uartHost == NULL) {        HDF_LOGE("%s: UartHostCreate failed", __func__);        return HDF_FAILURE;    }    uartHost->service.Dispatch = SampleDispatch;    return HDF_SUCCESS;} // 從UART驅(qū)動(dòng)的HCS中獲取配置信息static uint32_t GetUartDeviceResource(    struct UartDevice *device, const struct DeviceResourceNode *resourceNode){    struct UartResource *resource = &device->resource;    struct DeviceResourceIface *dri = NULL;    dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);    if (dri == NULL || dri->GetUint32 == NULL) {        HDF_LOGE("DeviceResourceIface is invalid");        return HDF_FAILURE;    }    if (dri->GetUint32(resourceNode, "num", &resource->num, 0) != HDF_SUCCESS) {        HDF_LOGE("uart config read num fail");        return HDF_FAILURE;    }    if (dri->GetUint32(resourceNode, "base", &resource->base, 0) != HDF_SUCCESS) {        HDF_LOGE("uart config read base fail");        return HDF_FAILURE;    }    resource->physBase = (unsigned long)OsalIoRemap(resource->base, 0x48);    if (resource->physBase == 0) {        HDF_LOGE("uart config fail to remap physBase");        return HDF_FAILURE;    }    if (dri->GetUint32(resourceNode, "irqNum", &resource->irqNum, 0) != HDF_SUCCESS) {        HDF_LOGE("uart config read irqNum fail");        return HDF_FAILURE;    }    if (dri->GetUint32(resourceNode, "baudrate", &resource->baudrate, 0) != HDF_SUCCESS) {        HDF_LOGE("uart config read baudrate fail");        return HDF_FAILURE;    }    if (dri->GetUint32(resourceNode, "wlen", &resource->wlen, 0) != HDF_SUCCESS) {        HDF_LOGE("uart config read wlen fail");        return HDF_FAILURE;    }    if (dri->GetUint32(resourceNode, "parity", &resource->parity, 0) != HDF_SUCCESS) {        HDF_LOGE("uart config read parity fail");        return HDF_FAILURE;    }    if (dri->GetUint32(resourceNode, "stopBit", &resource->stopBit, 0) != HDF_SUCCESS) {        HDF_LOGE("uart config read stopBit fail");        return HDF_FAILURE;    }    if (dri->GetUint32(resourceNode, "uartClk", &resource->uartClk, 0) != HDF_SUCCESS) {        HDF_LOGE("uart config read uartClk fail");        return HDF_FAILURE;    }    return HDF_SUCCESS;} // 將UART驅(qū)動(dòng)的配置和接口附加到HDF驅(qū)動(dòng)框架static int32_t AttachUartDevice(struct UartHost *host, struct HdfDeviceObject *device){    int32_t ret;    struct UartDevice *uartDevice = NULL;    if (device->property == NULL) {        HDF_LOGE("%s: property is NULL", __func__);        return HDF_FAILURE;    }    uartDevice = (struct UartDevice *)OsalMemCalloc(sizeof(struct UartDevice));    if (uartDevice == NULL) {        HDF_LOGE("%s: OsalMemCalloc uartDevice error", __func__);        return HDF_ERR_MALLOC_FAIL;    }    ret = GetUartDeviceResource(uartDevice, device->property);    if (ret != HDF_SUCCESS) {        (void)OsalMemFree(uartDevice);        return HDF_FAILURE;    }    host->num = uartDevice->resource.num;    host->priv = uartDevice;    AddUartDevice(host);    return InitUartDevice(uartDevice);} // 初始化UART驅(qū)動(dòng)static int32_t SampleUartDriverInit(struct HdfDeviceObject *device){    int32_t ret;    struct UartHost *host = NULL;    if (device == NULL) {        HDF_LOGE("%s: device is NULL", __func__);        return HDF_ERR_INVALID_OBJECT;    }    HDF_LOGI("Enter %s:", __func__);    host = UartHostFromDevice(device);    if (host == NULL) {        HDF_LOGE("%s: host is NULL", __func__);        return HDF_FAILURE;    }    ret = AttachUartDevice(host, device);    if (ret != HDF_SUCCESS) {        HDF_LOGE("%s: attach error", __func__);        return HDF_FAILURE;    }    host->method = &g_sampleUartHostMethod;    return ret;} static void DeinitUartDevice(struct UartDevice *device){    struct UartRegisterMap *regMap = (struct UartRegisterMap *)device->resource.physBase;    /* wait for uart enter idle. */    while (UartPl011IsBusy(regMap));    UartPl011ResetRegisters(regMap);    uart_clk_cfg(0, false);    OsalIoUnmap((void *)device->resource.physBase);    device->state = UART_DEVICE_UNINITIALIZED;} // 解綁并釋放UART驅(qū)動(dòng)static void DetachUartDevice(struct UartHost *host){    struct UartDevice *uartDevice = NULL;    if (host->priv == NULL) {        HDF_LOGE("%s: invalid parameter", __func__);        return;    }    uartDevice = host->priv;    DeinitUartDevice(uartDevice);    (void)OsalMemFree(uartDevice);    host->priv = NULL;} // 釋放UART驅(qū)動(dòng)static void SampleUartDriverRelease(struct HdfDeviceObject *device){    struct UartHost *host = NULL;    HDF_LOGI("Enter %s:", __func__);    if (device == NULL) {        HDF_LOGE("%s: device is NULL", __func__);        return;    }    host = UartHostFromDevice(device);    if (host == NULL) {        HDF_LOGE("%s: host is NULL", __func__);        return;    }    if (host->priv != NULL) {        DetachUartDevice(host);    }    UartHostDestroy(host);} struct HdfDriverEntry g_sampleUartDriverEntry = {    .moduleVersion = 1,    .moduleName = "UART_SAMPLE",    .Bind = SampleUartDriverBind,    .Init = SampleUartDriverInit,    .Release = SampleUartDriverRelease,}; HDF_INIT(g_sampleUartDriverEntry); 

注冊(cè)u(píng)art驅(qū)動(dòng)接口

HDF框架提供了UART驅(qū)動(dòng)接口的模板方法UartHostMethod,實(shí)現(xiàn)UART驅(qū)動(dòng)接口的代碼如下:

  1. static int32_t SampleUartHostInit(struct UartHost *host){    HDF_LOGI("%s: Enter", __func__);    if (host == NULL) {        HDF_LOGE("%s: invalid parameter", __func__);        return HDF_ERR_INVALID_PARAM;    }    return HDF_SUCCESS;}static int32_t SampleUartHostDeinit(struct UartHost *host){    HDF_LOGI("%s: Enter", __func__);    if (host == NULL) {        HDF_LOGE("%s: invalid parameter", __func__);        return HDF_ERR_INVALID_PARAM;    }    return HDF_SUCCESS;}// 向UART中寫(xiě)入數(shù)據(jù)static int32_t SampleUartHostWrite(struct UartHost *host, uint8_t *data, uint32_t size){    HDF_LOGI("%s: Enter", __func__);    uint32_t idx;    struct UartRegisterMap *regMap = NULL;    struct UartDevice *device = NULL;    if (host == NULL || data == NULL || size == 0) {        HDF_LOGE("%s: invalid parameter", __func__);        return HDF_ERR_INVALID_PARAM;    }    device = (struct UartDevice *)host->priv;    if (device == NULL) {        HDF_LOGE("%s: device is NULL", __func__);        return HDF_ERR_INVALID_PARAM;    }    regMap = (struct UartRegisterMap *)device->resource.physBase;    for (idx = 0; idx < size; idx++) {        UartPl011Write(regMap, data[idx]);    }    return HDF_SUCCESS;} // 設(shè)置UART的波特率static int32_t SampleUartHostSetBaud(struct UartHost *host, uint32_t baudRate){    HDF_LOGI("%s: Enter", __func__);    struct UartDevice *device = NULL;    struct UartRegisterMap *regMap = NULL;    UartPl011Error err;    if (host == NULL) {        HDF_LOGE("%s: invalid parameter", __func__);        return HDF_ERR_INVALID_PARAM;    }    device = (struct UartDevice *)host->priv;    if (device == NULL) {        HDF_LOGE("%s: device is NULL", __func__);        return HDF_ERR_INVALID_PARAM;    }    regMap = (struct UartRegisterMap *)device->resource.physBase;    if (device->state != UART_DEVICE_INITIALIZED) {        return UART_PL011_ERR_NOT_INIT;    }    if (baudRate == 0) {        return UART_PL011_ERR_INVALID_BAUD;    }    err = UartPl011SetBaudrate(regMap, device->uartClk, baudRate);    if (err == UART_PL011_ERR_NONE) {        device->baudrate = baudRate;    }    return err;} // 獲取UART的波特率static int32_t SampleUartHostGetBaud(struct UartHost *host, uint32_t *baudRate){    HDF_LOGI("%s: Enter", __func__);    struct UartDevice *device = NULL;    if (host == NULL) {        HDF_LOGE("%s: invalid parameter", __func__);        return HDF_ERR_INVALID_PARAM;    }    device = (struct UartDevice *)host->priv;    if (device == NULL) {        HDF_LOGE("%s: device is NULL", __func__);        return HDF_ERR_INVALID_PARAM;    }    *baudRate = device->baudrate;    return HDF_SUCCESS;} // 在HdfUartSampleInit方法中綁定struct UartHostMethod g_sampleUartHostMethod = {    .Init = SampleUartHostInit,    .Deinit = SampleUartHostDeinit,    .Read = NULL,    .Write = SampleUartHostWrite,    .SetBaud = SampleUartHostSetBaud,    .GetBaud = SampleUartHostGetBaud,    .SetAttribute = NULL,    .GetAttribute = NULL,    .SetTransMode = NULL,}; 

 uart驅(qū)動(dòng)Makefile如下:

  1. include $(LITEOSTOPDIR)/config.mkinclude $(LITEOSTOPDIR)/../../drivers/adapter/khdf/liteos/lite.mkMODULE_NAME := hdf_uart_sampleLOCAL_CFLAGS += $(HDF_INCLUDE)LOCAL_SRCS += src/uart_sample.c \              src/uart_pl011_sample.c \              src/buf_fifo.c \              src/uart_dev_sample.c \              src/uart_dispatch_sample.c \LOCAL_INCLUDE := ./includeLOCAL_CFLAGS += -fstack-protector-stronginclude $(HDF_DRIVER) 

 在device/hisilicon/drivers/lite.mk編譯腳本中增加示例UART驅(qū)動(dòng)模塊,代碼如下: 

  1. LITEOS_BASELIB += -lhdf_uart_sampleLIB_SUBDIRS += $(LITEOS_SOURCE_ROOT)/vendor/huawei/hdf/sample/platform/uart 

用戶程序和驅(qū)動(dòng)交互代碼

UART驅(qū)動(dòng)成功初始化后,會(huì)創(chuàng)建/dev/uartdev-5設(shè)備節(jié)點(diǎn),通過(guò)設(shè)備節(jié)點(diǎn)與UART驅(qū)動(dòng)交互的代碼如下:

  1. #include #include #include #include "hdf_log.h"#define HDF_LOG_TAG "hello_uart"#define INFO_SIZE 16int main(void){ int ret; int fd; const char info[INFO_SIZE] = {" HELLO UART! "}; fd = open("/dev/uartdev-5", O_RDWR); if (fd < 0) { HDF_LOGE("hello_uart uartdev-5 open failed %d", fd); return -1; } ret = write(fd, info, INFO_SIZE); if (ret != 0) { HDF_LOGE("hello_uart write uartdev-5 ret is %d", ret); } ret = close(fd); if (ret != 0) { HDF_LOGE("hello_uart uartdev-5 close failed %d", fd); return -1; } return ret;} 

將應(yīng)用程序編譯進(jìn)hello_uart_sample組件,應(yīng)用的編譯文件:

(1)vendor/huawei/hdf/sample/platform/uart/BUILD.gn

  1. import("//build/lite/config/component/lite_component.gni")lite_component("hello_uart_sample") { features = [ "dev:hello_uart""dispatch:hello_uart_dispatch", ]} 

(2)vendor/huawei/hdf/sample/platform/uart/dev/BUILD.gn:

  1. HDF_FRAMEWORKS = "//drivers/framework"executable("hello_uart") { sources = [ "hello_uart_dev.c" ] include_dirs = [ "$HDF_FRAMEWORKS/ability/sbuf/include""$HDF_FRAMEWORKS/core/shared/include""$HDF_FRAMEWORKS/core/host/include""$HDF_FRAMEWORKS/core/master/include""$HDF_FRAMEWORKS/include/core""$HDF_FRAMEWORKS/include/utils""$HDF_FRAMEWORKS/utils/include""$HDF_FRAMEWORKS/include/osal""//drivers/adapter/uhdf/posix/include""//third_party/bounds_checking_function/include""//base/hiviewdfx/hilog_lite/interfaces/native/innerkits", ] deps = [ "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared""//drivers/adapter/uhdf/manager:hdf_core""//drivers/adapter/uhdf/posix:hdf_posix_osal", ] public_deps = [ "//third_party/bounds_checking_function:libsec_shared" ] defines = [ "__USER__" ] cflags = [ "-Wall""-Wextra""-Wno-format""-Wno-format-extra-args", ]} 

在build/lite/components/drivers.json驅(qū)動(dòng)配置中hdf_hi3516dv300_liteos_a組件下的targets中增加hello_uart_sample組件,代碼如下:

  1. "components": [ { "component""hdf_hi3516dv300_liteos_a""description""""optional""false""dirs": ["vendor/huawei/hdf/sample/platform/uart"], "targets": [ "//vendor/huawei/hdf/sample/platform/uart:hello_uart_sample" ], "rom""""ram""""output": [], "adapted_board": [], "adapted_kernel": [ "liteos_a" ], "features": [], "deps": { "third_party": [ "bounds_checking_function" ], "components": [ "hilog" ] } } ]} 

修改單板配置文件(vendor/hisilicon/hispark_taurus/config.json),新增hdf_hi3516dv300_liteos_a組件的條目,如下所示代碼片段為driver子系統(tǒng)配置

  1. "subsystem""drivers""components": [ { "component""adapter_uhdf""features":[] }, { "component""peripheral_display""features":[] }, { "component""hdf_hi3516dv300_liteos_a""features":[] }, { "component""peripheral_input""features":[] }, { "component""peripheral_sensor""features":[] }, { "component""peripheral_wlan""features":[] } ] }, 

編譯

如果Linux編譯環(huán)境通過(guò)Docker方式安裝,具體編譯過(guò)程請(qǐng)參見(jiàn)Docker方式獲取編譯環(huán)境的編譯操作。如果Linux編譯環(huán)境通過(guò)軟件包方式安裝,請(qǐng)進(jìn)入源碼根目錄,執(zhí)行如下命令進(jìn)行編譯:

  1. hb set(設(shè)置編譯路徑).(選擇當(dāng)前路徑)選擇ipcamera_hispark_taurus并回車hb build -f(執(zhí)行編譯) 

運(yùn)行

燒錄成功之后,可執(zhí)行文件在bin目錄下(/bin/hello_uart),運(yùn)行:

Hi3516驅(qū)動(dòng)開(kāi)發(fā)-鴻蒙HarmonyOS技術(shù)社區(qū)

想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來(lái)源: 鴻蒙社區(qū)
相關(guān)推薦

2021-05-25 14:47:43

鴻蒙HarmonyOS應(yīng)用

2022-04-15 14:45:49

Hi3516系統(tǒng)類型燒錄鴻蒙

2021-06-25 09:28:46

鴻蒙HarmonyOS應(yīng)用

2021-03-29 15:36:46

鴻蒙HarmonyOS應(yīng)用

2021-04-09 09:45:21

鴻蒙HarmonyOS應(yīng)用

2021-03-16 09:49:16

鴻蒙HarmonyOS應(yīng)用

2021-11-09 15:28:41

鴻蒙HarmonyOS應(yīng)用

2021-09-24 10:20:42

鴻蒙HarmonyOS應(yīng)用

2022-02-16 16:01:02

Hi3516開(kāi)發(fā)板鴻蒙

2021-12-03 09:50:39

鴻蒙HarmonyOS應(yīng)用

2021-08-06 15:09:22

鴻蒙HarmonyOS應(yīng)用

2021-07-19 15:34:05

鴻蒙HarmonyOS應(yīng)用

2022-08-10 15:58:54

LED燈鴻蒙

2021-07-21 09:58:50

鴻蒙HarmonyOS應(yīng)用

2021-03-02 14:30:20

鴻蒙HarmonyOS應(yīng)用

2021-10-09 10:12:39

鴻蒙HarmonyOS應(yīng)用

2022-04-02 20:45:04

Hi3516開(kāi)發(fā)板操作系統(tǒng)鴻蒙

2021-07-05 09:35:36

鴻蒙HarmonyOS應(yīng)用

2021-09-02 15:27:54

鴻蒙HarmonyOS應(yīng)用

2022-03-14 15:26:59

Hi3516Ark子系統(tǒng)鴻蒙
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)