1、案例簡(jiǎn)介
該程序是基于OpenHarmony標(biāo)準(zhǔn)系統(tǒng)編寫(xiě)的基礎(chǔ)外設(shè)類(lèi):GPIO驅(qū)動(dòng)。
目前已在凌蒙派-RK3568開(kāi)發(fā)板跑通。詳細(xì)資料請(qǐng)參考官網(wǎng)
詳細(xì)資料請(qǐng)參考OpenHarmony官網(wǎng):
GPIO平臺(tái)驅(qū)動(dòng)開(kāi)發(fā)
GPIO應(yīng)用程序開(kāi)發(fā)
2、基礎(chǔ)知識(shí)
2.1、GPIO簡(jiǎn)介
GPIO(General-purpose input/output)即通用型輸入輸出。通常,GPIO控制器通過(guò)分組的方式管理所有GPIO管腳,每組GPIO有一個(gè)或多個(gè)寄存器與之關(guān)聯(lián),通過(guò)讀寫(xiě)寄存器完成對(duì)GPIO管腳的操作。
2.2、GPIO平臺(tái)驅(qū)動(dòng)
GPIO(General-purpose input/output)即通用型輸入輸出。通常,GPIO控制器通過(guò)分組的方式管理所有GPIO管腳,每組GPIO有一個(gè)或多個(gè)寄存器與之關(guān)聯(lián),通過(guò)讀寫(xiě)寄存器完成對(duì)GPIO管腳的操作。
GPIO模塊各分層作用:
接口層提供操作GPIO管腳的標(biāo)準(zhǔn)方法。
核心層主要提供GPIO管腳資源匹配,GPIO管腳控制器的添加、移除以及管理的能力,通過(guò)鉤子函數(shù)與適配層交互,供芯片廠家快速接入HDF框架。
適配層主要是將鉤子函數(shù)的功能實(shí)例化,實(shí)現(xiàn)具體的功能。
GPIO統(tǒng)一服務(wù)模式結(jié)構(gòu)圖:
為了保證上層在調(diào)用GPIO接口時(shí)能夠正確的操作GPIO管腳,核心層在//drivers/hdf_core/framework/support/platform/include/gpio/gpio_core.h中定義了以下鉤子函數(shù),驅(qū)動(dòng)適配者需要在適配層實(shí)現(xiàn)這些函數(shù)的具體功能,并與鉤子函數(shù)掛接,從而完成適配層與核心層的交互。
GpioMethod定義:
struct GpioMethod { int32_t (*request)(struct GpioCntlr *cntlr, uint16_t local); // 【預(yù)留】 int32_t (*release)(struct GpioCntlr *cntlr, uint16_t local); // 【預(yù)留】 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); // 【預(yù)留】 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); }
(左右移動(dòng)查看全部?jī)?nèi)容)
GpioMethod結(jié)構(gòu)體成員的鉤子函數(shù)功能說(shuō)明:
2.3、GPIO應(yīng)用程序
GPIO驅(qū)動(dòng)API接口功能:
GPIO標(biāo)準(zhǔn)API通過(guò)GPIO管腳號(hào)來(lái)操作指定管腳,使用GPIO的一般流程如下圖所示:
3、代碼解析
3.1、準(zhǔn)備工作
查看《凌蒙派-RK3568開(kāi)發(fā)板_排針說(shuō)明表_》(即Git倉(cāng)庫(kù)的//docs/board/凌蒙派-RK3568開(kāi)發(fā)板_排針說(shuō)明表_v1.0.xlsx),選中0_B5(即GPIO0_B5)。
3.2、配置文件
3.2.1、device_info.hcs
創(chuàng)建config/device_info.hcs,用于GPIO驅(qū)動(dòng)設(shè)備描述,具體內(nèi)容如下:
root { device_info { platform :: host { device_gpio :: device { device0 :: deviceNode { // GPIO控制器信息描述 policy = 2; // 對(duì)外發(fā)布服務(wù),必須為2,用于定義GPIO管理器的服務(wù) priority = 50; permission = 0644; moduleName = "HDF_PLATFORM_GPIO_MANAGER"; // 這與drivers/hdf_core/framework/support/platform/src/gpio/gpio_service.c的g_gpioServiceEntry.moduleName對(duì)應(yīng),它主要負(fù)責(zé)GPIO引腳的管理 serviceName = "HDF_PLATFORM_GPIO_MANAGER"; } device1 :: deviceNode { policy = 0; // 等于0,不需要發(fā)布服務(wù) priority = 55; // 驅(qū)動(dòng)驅(qū)動(dòng)優(yōu)先級(jí) permission = 0644; // 驅(qū)動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn)權(quán)限 moduleName = "linux_gpio_adapter"; // 用于指定驅(qū)動(dòng)名稱(chēng),必須是linux_adc_adapter,與drivers/hdf_core/adapter/khdf/linux/platform/gpio/gpio_adapter.c對(duì)應(yīng) deviceMatchAttr = ""; // 用于配置控制器私有數(shù)據(jù),不定義 } } } } }
(左右移動(dòng)查看全部?jī)?nèi)容)
注意:
device_gpio:為配置樹(shù)對(duì)gpio的設(shè)備類(lèi)結(jié)點(diǎn)。
device0:是用于啟用HDF_PLATFORM_GPIO_MANAGER驅(qū)動(dòng)的,它負(fù)責(zé)對(duì)GPIO進(jìn)行對(duì)外接口管理。
device1:是用于啟用linux_gpio_adapter驅(qū)動(dòng)的,它負(fù)責(zé)對(duì)Linux GPIO的讀寫(xiě)(即對(duì)Linux Gpio子系統(tǒng)進(jìn)行操作)。
3.2.3、參與配置樹(shù)編譯
編輯//vendor/lockzhiner/rk3568/hdf_config/khdf/hdf.hcs,將device_info.hcs添加配置樹(shù)中。具體內(nèi)容如下所示:
#include "../../samples/b03_platform_device_gpio/config/device_info.hcs"
(左右移動(dòng)查看全部?jī)?nèi)容)
3.3、HDF驅(qū)動(dòng)//drivers/hdf_core/adapter/khdf/linux/platform/gpio/gpio_adapter.c已對(duì)Linux Gpio子系統(tǒng)進(jìn)行規(guī)范化操作。因此,我們不需要額外的GPIO寄存器操作。
3.4、應(yīng)用程序
3.4.1、gpio_test.c
gpio_test.c主要分為兩個(gè)部分:
對(duì)gpio引腳進(jìn)行讀操作。
對(duì)gpio引腳進(jìn)行寫(xiě)操作。
(1)對(duì)gpio引腳進(jìn)行讀操作
// GPIO設(shè)置為輸出 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; }
(左右移動(dòng)查看全部?jī)?nèi)容)
(2)對(duì)gpio引腳進(jìn)行寫(xiě)操作
// GPIO設(shè)置為輸出 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);
(左右移動(dòng)查看全部?jī)?nèi)容)
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 }
(左右移動(dòng)查看全部?jī)?nèi)容)
3.4.3、參與應(yīng)用程序編譯
編輯//vendor/lockzhiner/rk3568/samples/BUILD.gn,開(kāi)啟sample編譯。具體如下:
"b03_platform_device_gpio/app:rk3568_gpio_test",
(左右移動(dòng)查看全部?jī)?nèi)容)
4、編譯說(shuō)明
建議使用docker編譯方法,運(yùn)行如下:
hb set -root . hb set #選擇lockzhiner下的rk3568編譯分支。 hb build -f
(左右移動(dòng)查看全部?jī)?nèi)容)
5、運(yùn)行結(jié)果
該程序運(yùn)行結(jié)果如下所示:
# 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 #
(左右移動(dòng)查看全部?jī)?nèi)容)
可將GPIO引腳接入排針中的GND或3V3引腳,查看GPIO輸出結(jié)果。
審核編輯:湯梓紅
-
開(kāi)源
+關(guān)注
關(guān)注
3文章
3215瀏覽量
42327 -
應(yīng)用程序
+關(guān)注
關(guān)注
37文章
3237瀏覽量
57547 -
GPIO
+關(guān)注
關(guān)注
16文章
1188瀏覽量
51832 -
OpenHarmony
+關(guān)注
關(guān)注
25文章
3635瀏覽量
16061
原文標(biāo)題:【開(kāi)源教程】OpenHarmony:如何編寫(xiě)GPIO平臺(tái)驅(qū)動(dòng)及應(yīng)用程序
文章出處:【微信號(hào):gh_9b9470648b3c,微信公眾號(hào):電子發(fā)燒友論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論