鴻蒙(HarmonyOS)sample_test Demo
1.?目標(biāo)
理解HarmonyOS驅(qū)動框架,用戶態(tài)APP和內(nèi)核態(tài)驅(qū)動之間的通信機(jī)制。
具體運(yùn)行結(jié)果為用戶態(tài)APP向驅(qū)動發(fā)送123號cmd,內(nèi)核態(tài)讀取該cmd對應(yīng)的字符串data,并打印出來。然后內(nèi)核態(tài)驅(qū)動程序向用戶態(tài)發(fā)送事件,傳遞的參數(shù)為reply。用戶態(tài)APP通過事件監(jiān)聽函數(shù)獲取內(nèi)核態(tài)發(fā)送的消息打印出來。
2.?編寫驅(qū)動程序
這跟Linux的驅(qū)動框架不一樣,在Linux中,APP打開設(shè)備節(jié)點(diǎn)后,APP調(diào)用的read函數(shù)會直接進(jìn)入內(nèi)核態(tài)調(diào)用驅(qū)動的read函數(shù)。
?
在liteos-a中使用HDF時,APP需要先獲得服務(wù),然后調(diào)用服務(wù)的Dispatch函數(shù):它可以向驅(qū)動發(fā)送數(shù)據(jù)、獲得返回結(jié)果。
? ?2.1?編寫驅(qū)動
在HDF中,一個驅(qū)動被抽象為“HdfDriverEntry”,代碼如下:

?
上述代碼中,使用HDF_INIT定義了某些段屬性的結(jié)構(gòu)體,內(nèi)核啟動后會注冊這個HdfDriverEntry。
?
重要的是其中的Bind函數(shù),Init和Release函數(shù)顧名思義就是初始化和釋放相關(guān)資源,這里好像和HDF_INIT有些沖突,示例函數(shù)用空函數(shù)來替代它們了。代碼如下:

?
? ?2.2?驅(qū)動服務(wù)函數(shù)的實(shí)現(xiàn)
在驅(qū)動初始化函數(shù)HdfSampleDriverBind中會綁定一個服務(wù)函數(shù),這個服務(wù)函數(shù)用來處理用戶態(tài)APP發(fā)送過來的消息。綁定過程是給IDeviceIoService這個結(jié)構(gòu)體的Dispatch元素賦值來實(shí)現(xiàn)的。如圖所示:

?
你可以認(rèn)為Dispatch函數(shù)相當(dāng)于ioctl,在Linux中通過ioctl(fd, cmd, arg)來操作驅(qū)動。
在liteos-a中通過service->>dispatcher->Dispatch(ojb, cmd, data, replay)來操作驅(qū)動。把驅(qū)動放入內(nèi)核
3.?把驅(qū)動源碼放入內(nèi)核
3.1?驅(qū)動代碼放進(jìn)目錄
3.1.1?把代碼放入目錄:
vendor/huawei/hdf/sample

?
Kconfig如下:

?
Makefile如下:
?????

如下圖增加最后一行:
?


上一級的Kconfig:
# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
?
source "../../vendor/hisi/hi35xx/platform/Kconfig"
source "../../vendor/huawei/hdf/wifi/driver/Kconfig"
source "../../vendor/huawei/hdf/input/driver/Kconfig"
source "../../vendor/huawei/hdf/display/driver/Kconfig"
source "../../vendor/huawei/hdf/sample/Kconfig"
3.2?修改hcs文件
3.2.1?增加sample_config.hcs文件
目錄:vendor/hisi/hi35xx/ hi3516dv300/config /sample/sample_config.hcs:
?


?
?
源碼:
root {
????module = "sample_driver";
????author = "zhangfeidz for test";
????serviceName = "sample_service";
}
3.2.2?在上級hcs中引用sample_config.hcs文件
?


?
3.2.3?在全局設(shè)備節(jié)點(diǎn)中增加device_sample節(jié)點(diǎn)
目錄:vendor/hisi/hi35xx/ hi3516dv300/config /device_info/device_info.hcs:
?


?
3.3?修改mk文件
目錄:vendor/huawei/hdf/hdf_vendor.mk:
?

增加兩行:
?

3.4?內(nèi)核態(tài)源碼:
?
4.?編寫APP
APP先獲得服務(wù),在調(diào)用Dispatch即可。需要注意的是里面用的是HdfSBuf傳遞數(shù)據(jù)。
一下是hello_test.c的源碼。
? ? ? 4.1?綁定服務(wù)
?

4.2?注冊監(jiān)聽機(jī)制及設(shè)置回調(diào)函數(shù)
?


4.3?調(diào)用內(nèi)核服務(wù)函數(shù)
要分配兩個HdfBuf:data、reply。data用于向驅(qū)動傳參數(shù),reply用來保存驅(qū)動返回的數(shù)據(jù)。
代碼如下:
?

4.4?取出內(nèi)核發(fā)送過來的數(shù)據(jù)
?

4.5?內(nèi)核驅(qū)動初始化(綁定)服務(wù)程序
?

4.6?讀取用戶態(tài)程序(sample_test)發(fā)送過來的消息并向用戶態(tài)發(fā)送響應(yīng)消息
?

4.7?源碼
?

5.?把APP源碼放入BUILD.gn文件
?


先在整個系統(tǒng)源碼的根目錄下創(chuàng)建一個子目錄,比如myapp,在里面放入sample_test.c。
再修改drivers/hdf/lite/manager/BUILD.gn。
?
源碼如下:
import("//build/lite/config/component/lite_component.gni")
?
HDF_FRAMEWORKS = "//drivers/hdf/frameworks"
?
shared_library("hdf_core") {
????sources = [
????????"$HDF_FRAMEWORKS/core/shared/src/hdf_io_service.c",
????????"$HDF_FRAMEWORKS/ability/sbuf/src/hdf_sbuf.c",
????????"../adapter/syscall/src/hdf_syscall_adapter.c"
????]
?
????include_dirs = [
????????"../adapter/syscall/include",
????????"../adapter/vnode/include",
????????"$HDF_FRAMEWORKS/core/shared/include",
????????"$HDF_FRAMEWORKS/core/host/include",
????????"$HDF_FRAMEWORKS/core/manager/include",
????????"$HDF_FRAMEWORKS/ability/sbuf/include",
????????"$HDF_FRAMEWORKS/include/core",
????????"$HDF_FRAMEWORKS/include/utils",
????????"$HDF_FRAMEWORKS/utils/include",
????????"$HDF_FRAMEWORKS/include/osal",
????????"//third_party/bounds_checking_function/include",
????]
?
????deps = [
????????"//drivers/hdf/lite/adapter/osal/posix:hdf_posix_osal",
????????"//third_party/bounds_checking_function:libsec_shared",
????]
?
????defines = [
????????"__USER__",
????]
?
????cflags = [
????????"-Wall",
????????"-Wextra",
????????"-Werror",
????????"-fsigned-char",
????????"-fno-common",
????????"-fno-strict-aliasing",
????]
}
?
?
executable("sample_test") {
????sources = [
????????"//myapp/sample_test.c"
????]
?
????include_dirs = [
????????"../adapter/syscall/include",
????????"../adapter/vnode/include","$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",
????????"//third_party/bounds_checking_function/include",
????]
?
????deps = [
????????"//drivers/hdf/lite/manager:hdf_core",
????????"//drivers/hdf/lite/adapter/osal/posix:hdf_posix_osal",
????]
?
????public_deps = [
????????"//third_party/bounds_checking_function:libsec_shared",
????]
????defines = [
????????"__USER__",
????]
?
????cflags = [
????????"-Wall",
????????"-Wextra",
????????"-Werror",
????]
}
?
lite_component("hdf_manager") {
????features = [
????????":hdf_core",
????????":sample_test",
????]
}
sample_test.c文件信息加入BUILD.gn文件后,編譯系統(tǒng)時,就會按照指定的規(guī)則(程序源碼,編譯依賴,生成可執(zhí)行程序的名字,以及可執(zhí)行程序在HarmonyOS系統(tǒng)中的目錄)進(jìn)行編譯。
6.?編譯、燒寫、測試
6.1?編譯
Hi3516dv300開發(fā)板:python build.py ipcamera_hi3516dv300 -b debug
Hi3518ev300開發(fā)板:python build.py ipcamera_hi3518ev300 -b debug
Hi3516dv300開發(fā)板:python build.py ipcamera –p hi3516dv300_liteos_a
Hi3518ev300開發(fā)板:python build.py ipcamera –p hi3518ev300_liteos_a
?
6.1?燒寫
6.1.1?燒寫文件所在目錄:out/ipcamera_hi3516dv300_liteos_a/
6.1.2?燒寫文件
6.1.2.1?操作系統(tǒng)文件:OHOS_Image.bin
6.1.2.2?文件系統(tǒng)文件(光盤鏡像文件):rootfs
6.1.2.3?用戶文件(光盤鏡像文件):userfs
?

網(wǎng)口燒錄配置

?
6.2?測試
6.2.1?Uboot設(shè)置
在uboot里面輸入命令,配置啟動設(shè)置,具體方法如下。
命令1:
Hi3516dv300開發(fā)板:
setenv bootcmd 'sf probe 0;sf read 0x80000000 0x100000 0x600000;go 0x80000000';saveenv;
Hi3518ev300開發(fā)板:
setenv bootcmd 'sf probe 0;sf read 0x40000000 0x100000 0x600000;go 0x40000000';saveenv;
?
這條命令作用是選擇從0x80000000(或者0x40000000)這個地址啟動HarmonyOS。在flash內(nèi)部,0x100000是起始地址,0x6000000是OHOS_Image.bin的大?。ū臼纠校撐臋n大小為6M)
?
命令2:
setenv bootargs "ttyAMA0,115200n8 root=flash fstype=jffs2 rw rootaddr=7M rootsize=8M";saveenv;
該命令的作用是進(jìn)行串口配置。rootaddr是文件系統(tǒng)的起始地址,rootsize是文件的大小。實(shí)際開發(fā)時,請具體情況具體分析。
?
配置完成后,輸入命令?go?0x80000000,就可以進(jìn)入鴻蒙系統(tǒng)了。
6.2.2?測試結(jié)果
鴻蒙系統(tǒng)目錄結(jié)構(gòu)如下:
?

進(jìn)入bin文件夾,運(yùn)行sample_test程序:
?
