HDF驅(qū)動框架探路(二):openharmony最新源碼,打通應用態(tài)到內(nèi)核態(tài)
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
老規(guī)矩還是將最終希望跑出來的效果放出來。如下:
HDF驅(qū)動框架探路2:
前言
1.首先本文章的源碼是2021.11.25拉的openharmony的master分支。之前也有一些大神基于3516應用態(tài)打通到了內(nèi)核態(tài),不過都很久遠了,尤其是3.0LTS發(fā)布之后,整個框架都改動過了,按照大神們的操作我這邊基于最新的源碼都沒有測試成功。有大佬可以留言指導一撥兒。
2.本文章是基于Hi3516輕量系統(tǒng)來打造的。
應用態(tài)打通內(nèi)核態(tài)的總體框架圖
從上圖可以很直觀的看出驅(qū)動開發(fā)的過程中基于linux開發(fā)和基于openharmony開發(fā)的最大區(qū)別
1.linux驅(qū)動開發(fā)中會涉及到應用層的glic等,以及驅(qū)動層的內(nèi)核函數(shù)調(diào)用,但是在openharmony這些以及都被HDF框架給隱藏起來了,所以我們只需要根據(jù)HDF框架來進行openharmony框架開發(fā),就可以了。
2.openharmony應用層其實是調(diào)用了HDF框架的驅(qū)動消息機制
1.應用程序
1.1 應用層業(yè)務代碼
1.在源碼根目錄下新建myapp目錄
2.然后進入myapp目錄新建helloworld_test.c,然后將下列代碼拷貝入內(nèi)
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <sys/ioctl.h>
- #include <unistd.h>
- #include "hdf_log.h"
- #include "hdf_sbuf.h"
- #include "hdf_io_service_if.h"
- #define HDF_LOG_TAG "sample_test"
- #define SAMPLE_SERVICE_NAME "GPIO_TEST"
- #define SAMPLE_WRITE_READ 0
- int g_replyFlag = 0;
- static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data)
- {
- const char *string = HdfSbufReadString(data);
- if (string == NULL) {
- HDF_LOGE("fail to read string in event data");
- g_replyFlag = 1;
- return HDF_FAILURE;
- }
- HDF_LOGE("%s: dev event received: %u %s", (char *)priv, id, string);
- g_replyFlag = 1;
- return HDF_SUCCESS;
- }
- static int SendEvent(struct HdfIoService *serv, char *eventData)
- {
- int ret = 0;
- struct HdfSBuf *data = HdfSBufObtainDefaultSize();
- if (data == NULL) {
- HDF_LOGE("fail to obtain sbuf data");
- return 1;
- }
- struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
- if (reply == NULL) {
- HDF_LOGE("fail to obtain sbuf reply");
- ret = HDF_DEV_ERR_NO_MEMORY;
- goto out;
- }
- if (!HdfSbufWriteString(data, eventData)) {
- HDF_LOGE("fail to write sbuf");
- ret = HDF_FAILURE;
- goto out;
- }
- ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply);
- if (ret != HDF_SUCCESS) {
- HDF_LOGE("fail to send service call");
- goto out;
- }
- int replyData = 0;
- if (!HdfSbufReadInt32(reply, &replyData)) {
- HDF_LOGE("fail to get service call reply");
- ret = HDF_ERR_INVALID_OBJECT;
- goto out;
- }
- HDF_LOGE("Get reply is: %d", replyData);
- out:
- HdfSBufRecycle(data);
- HdfSBufRecycle(reply);
- return ret;
- }
- int main()
- {
- char *sendData = "hi";
- struct HdfIoService *serv = HdfIoServiceBind(SAMPLE_SERVICE_NAME);
- if (serv == NULL) {
- HDF_LOGE("fail to get service %s", SAMPLE_SERVICE_NAME);
- return HDF_FAILURE;
- }
- HDF_LOGE("success to get service %s", SAMPLE_SERVICE_NAME);
- static struct HdfDevEventlistener listener = {
- .callBack = OnDevEventReceived,
- .priv ="Service0"
- };
- if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS) {
- HDF_LOGE("fail to register event listener");
- return HDF_FAILURE;
- }
- HDF_LOGE("success to register event listener");
- if (SendEvent(serv, sendData)) {
- HDF_LOGE("fail to send event");
- return HDF_FAILURE;
- }
- /* wait for event receive event finishing */
- while (g_replyFlag == 0) {
- sleep(1);
- }
- if (HdfDeviceUnregisterEventListener(serv, &listener)) {
- HDF_LOGE("fail to unregister listener");
- return HDF_FAILURE;
- }
- HdfIoServiceRecycle(serv);
- return HDF_SUCCESS;
- }
1.2 應用層業(yè)務代碼以可執(zhí)行文件編譯進系統(tǒng)
進入源碼目錄找到drivers/adapter/uhdf/manager/BUILD.gn 文件,然后在文件末尾拷貝下述代碼。
- HDF_FRAMEWORKS = "//drivers/framework"
- executable("helloworld_test") {
- sources = ["//myapp/helloworld_test.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",
- ]
- }
2.驅(qū)動代碼
這里驅(qū)動是直接引用了源碼中已經(jīng)存在的一個驅(qū)動程序:GPIO_TEST
2.1 驅(qū)動業(yè)務層代碼
進入源碼目錄,找到drivers/framework/test/unittest/platform/common/gpio_driver_test.c文件,然后對比下圖進行修改。
執(zhí)行hb build -f進行編譯,然后燒錄,接著打開串口就可以看到效果了
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)