1、案例簡介
該程序是基于OpenHarmony標準系統編寫的基礎外設類:GPIO驅動。
目前已在凌蒙派-RK3568開發板跑通。詳細資料請參考官網
詳細資料請參考OpenHarmony官網:
GPIO平臺驅動開發
GPIO應用程序開發
2、基礎知識
2.1、GPIO簡介
GPIO(General-purpose input/output)即通用型輸入輸出。通常,GPIO控制器通過分組的方式管理所有GPIO管腳,每組GPIO有一個或多個寄存器與之關聯,通過讀寫寄存器完成對GPIO管腳的操作。
2.2、GPIO平臺驅動
GPIO(General-purpose input/output)即通用型輸入輸出。通常,GPIO控制器通過分組的方式管理所有GPIO管腳,每組GPIO有一個或多個寄存器與之關聯,通過讀寫寄存器完成對GPIO管腳的操作。
GPIO模塊各分層作用:
接口層提供操作GPIO管腳的標準方法。
核心層主要提供GPIO管腳資源匹配,GPIO管腳控制器的添加、移除以及管理的能力,通過鉤子函數與適配層交互,供芯片廠家快速接入HDF框架。
適配層主要是將鉤子函數的功能實例化,實現具體的功能。
GPIO統一服務模式結構圖:
為了保證上層在調用GPIO接口時能夠正確的操作GPIO管腳,核心層在//drivers/hdf_core/framework/support/platform/include/gpio/gpio_core.h中定義了以下鉤子函數,驅動適配者需要在適配層實現這些函數的具體功能,并與鉤子函數掛接,從而完成適配層與核心層的交互。
GpioMethod定義:
struct GpioMethod { int32_t (*request)(struct GpioCntlr *cntlr, uint16_t local); // 【預留】 int32_t (*release)(struct GpioCntlr *cntlr, uint16_t local); // 【預留】 int32_t (*write)(struct GpioCntlr *cntlr, uint16_t local, uint16_t val); int32_t (*read)(struct GpioCntlr *cntlr, uint16_t local, uint16_t *val); int32_t (*setDir)(struct GpioCntlr *cntlr, uint16_t local, uint16_t dir); int32_t (*getDir)(struct GpioCntlr *cntlr, uint16_t local, uint16_t *dir); int32_t (*toIrq)(struct GpioCntlr *cntlr, uint16_t local, uint16_t *irq); // 【預留】 int32_t (*setirq)(struct GpioCntlr *cntlr, uint16_t local, uint16_t mode, GpioIrqFunc func, void *arg); int32_t (*unsetIrq)(struct GpioCntlr *cntlr, uint16_t local); int32_t (*enableIrq)(struct GpioCntlr *cntlr, uint16_t local); int32_t (*disableIrq)(struct GpioCntlr *cntlr, uint16_t local); }
(左右移動查看全部內容)
GpioMethod結構體成員的鉤子函數功能說明:
2.3、GPIO應用程序
GPIO驅動API接口功能:
GPIO標準API通過GPIO管腳號來操作指定管腳,使用GPIO的一般流程如下圖所示:
3、代碼解析
3.1、準備工作
查看《凌蒙派-RK3568開發板_排針說明表_》(即Git倉庫的//docs/board/凌蒙派-RK3568開發板_排針說明表_v1.0.xlsx),選中0_B5(即GPIO0_B5)。
3.2、配置文件
3.2.1、device_info.hcs
創建config/device_info.hcs,用于GPIO驅動設備描述,具體內容如下:
root { device_info { platform :: host { device_gpio :: device { device0 :: deviceNode { // GPIO控制器信息描述 policy = 2; // 對外發布服務,必須為2,用于定義GPIO管理器的服務 priority = 50; permission = 0644; moduleName = "HDF_PLATFORM_GPIO_MANAGER"; // 這與drivers/hdf_core/framework/support/platform/src/gpio/gpio_service.c的g_gpioServiceEntry.moduleName對應,它主要負責GPIO引腳的管理 serviceName = "HDF_PLATFORM_GPIO_MANAGER"; } device1 :: deviceNode { policy = 0; // 等于0,不需要發布服務 priority = 55; // 驅動驅動優先級 permission = 0644; // 驅動創建設備節點權限 moduleName = "linux_gpio_adapter"; // 用于指定驅動名稱,必須是linux_adc_adapter,與drivers/hdf_core/adapter/khdf/linux/platform/gpio/gpio_adapter.c對應 deviceMatchAttr = ""; // 用于配置控制器私有數據,不定義 } } } } }
(左右移動查看全部內容)
注意:
device_gpio:為配置樹對gpio的設備類結點。
device0:是用于啟用HDF_PLATFORM_GPIO_MANAGER驅動的,它負責對GPIO進行對外接口管理。
device1:是用于啟用linux_gpio_adapter驅動的,它負責對Linux GPIO的讀寫(即對Linux Gpio子系統進行操作)。
3.2.3、參與配置樹編譯
編輯//vendor/lockzhiner/rk3568/hdf_config/khdf/hdf.hcs,將device_info.hcs添加配置樹中。具體內容如下所示:
#include "../../samples/b03_platform_device_gpio/config/device_info.hcs"
(左右移動查看全部內容)
3.3、HDF驅動//drivers/hdf_core/adapter/khdf/linux/platform/gpio/gpio_adapter.c已對Linux Gpio子系統進行規范化操作。因此,我們不需要額外的GPIO寄存器操作。
3.4、應用程序
3.4.1、gpio_test.c
gpio_test.c主要分為兩個部分:
對gpio引腳進行讀操作。
對gpio引腳進行寫操作。
(1)對gpio引腳進行讀操作
// GPIO設置為輸出 ret = GpioSetDir(m_gpio_id, GPIO_DIR_OUT); if (ret != 0) { PRINT_ERROR("GpioSetDir failed and ret = %d ", ret); return -1; } // GPIO輸出電平 ret = GpioWrite(m_gpio_id, m_gpio_value); if (ret != 0) { PRINT_ERROR("GpioWrite failed and ret = %d ", ret); return -1; }
(左右移動查看全部內容)
(2)對gpio引腳進行寫操作
// GPIO設置為輸出 ret = GpioSetDir(m_gpio_id, GPIO_DIR_IN); if (ret != 0) { PRINT_ERROR("GpioSetDir failed and ret = %d ", ret); return -1; } // 讀取GPIO引腳的電平 ret = GpioRead(m_gpio_id, &m_gpio_value); if (ret != 0) { PRINT_ERROR("GpioRead failed and ret = %d ", ret); return -1; } printf("GPIO Read Successful and GPIO = %d, value = %d ", m_gpio_id, m_gpio_value);
(左右移動查看全部內容)
3.4.2、BUILD.gn
import("http://build/ohos.gni") import("http://drivers/hdf_core/adapter/uhdf2/uhdf.gni") ohos_executable("rk3568_gpio_test") { sources = [ "gpio_test.c" ] include_dirs = [ "$hdf_framework_path/include", "$hdf_framework_path/include/core", "$hdf_framework_path/include/osal", "$hdf_framework_path/include/platform", "$hdf_framework_path/include/utils", "$hdf_uhdf_path/osal/include", "$hdf_uhdf_path/ipc/include", "http://base/hiviewdfx/hilog/interfaces/native/kits/include", "http://third_party/bounds_checking_function/include", ] deps = [ "$hdf_uhdf_path/platform:libhdf_platform", "$hdf_uhdf_path/utils:libhdf_utils", "http://base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", ] cflags = [ "-Wall", "-Wextra", "-Werror", "-Wno-format", "-Wno-format-extra-args", ] part_name = "product_rk3568" install_enable = true }
(左右移動查看全部內容)
3.4.3、參與應用程序編譯
編輯//vendor/lockzhiner/rk3568/samples/BUILD.gn,開啟sample編譯。具體如下:
"b03_platform_device_gpio/app:rk3568_gpio_test",
(左右移動查看全部內容)
4、編譯說明
建議使用docker編譯方法,運行如下:
hb set -root . hb set #選擇lockzhiner下的rk3568編譯分支。 hb build -f
(左右移動查看全部內容)
5、運行結果
該程序運行結果如下所示:
# rk3568_gpio_test -g 13 -i gpio id: 13 gpio dir: in gpio value: 0 GPIO Read Successful and GPIO = 13, value = 1 # # # rk3568_gpio_test -g 13 -o gpio id: 13 gpio dir: out gpio value: 0 #
(左右移動查看全部內容)
可將GPIO引腳接入排針中的GND或3V3引腳,查看GPIO輸出結果。
審核編輯:湯梓紅
-
開源
+關注
關注
3文章
3412瀏覽量
42738 -
應用程序
+關注
關注
38文章
3296瀏覽量
57946 -
GPIO
+關注
關注
16文章
1217瀏覽量
52434 -
OpenHarmony
+關注
關注
25文章
3753瀏覽量
16661
原文標題:【開源教程】OpenHarmony:如何編寫GPIO平臺驅動及應用程序
文章出處:【微信號:gh_9b9470648b3c,微信公眾號:電子發燒友論壇】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
OpenHarmony應用程序集成AGC云存儲
![<b class='flag-5'>OpenHarmony</b><b class='flag-5'>應用程序</b>集成AGC云存儲](https://file.elecfans.com/web2/M00/94/A5/pYYBAGP8aD-AaUnlAAEfkuOOzz4391.png)
OpenHarmony:全流程講解如何編寫ADC平臺驅動以及應用程序
OpenHarmony:全流程講解如何編寫GPIO平臺驅動以及應用程序
OpenHarmony:全流程講解如何編寫RTC平臺驅動以及應用程序
OpenHarmony:全流程講解如何編寫Watchdog平臺驅動以及應用程序
OpenHarmony應用程序包整體說明
Windows CE下GPIO驅動程序的設計與應用
OpenHarmony:全流程講解如何編寫ADC平臺驅動以及應用程序
![<b class='flag-5'>OpenHarmony</b>:全流程講解如何<b class='flag-5'>編寫</b>ADC<b class='flag-5'>平臺</b><b class='flag-5'>驅動</b>以及<b class='flag-5'>應用程序</b>](https://file.elecfans.com/web2/M00/26/21/pYYBAGG5jjSALfrEAAAwAa9Oig8799.png)
評論