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

OpenHarmony:全流程講解如何編寫GPIO平臺(tái)驅(qū)動(dòng)以及應(yīng)用程序

系統(tǒng) OpenHarmony
GPIO(General-purpose input/output)即通用型輸入輸出。通常,GPIO控制器通過分組的方式管理所有GPIO管腳,每組GPIO有一個(gè)或多個(gè)寄存器與之關(guān)聯(lián),通過讀寫寄存器完成對(duì)GPIO管腳的操作。

想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問:

51CTO 開源基礎(chǔ)軟件社區(qū)

https://ost.51cto.com

一、案例簡(jiǎn)介

該程序是基于OpenHarmony標(biāo)準(zhǔn)系統(tǒng)編寫的基礎(chǔ)外設(shè)類:GPIO驅(qū)動(dòng)。

目前已在凌蒙派-RK3568開發(fā)板跑通。詳細(xì)資料請(qǐng)參考官網(wǎng):https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk3568-openharmony/tree/master/samples/b03_platform_device_gpio。

詳細(xì)資料請(qǐng)參考OpenHarmony官網(wǎng):

  • GPIO平臺(tái)驅(qū)動(dòng)開發(fā)
  • GPIO應(yīng)用程序開發(fā)

二、基礎(chǔ)知識(shí)

1、GPIO簡(jiǎn)介

GPIO(General-purpose input/output)即通用型輸入輸出。通常,GPIO控制器通過分組的方式管理所有GPIO管腳,每組GPIO有一個(gè)或多個(gè)寄存器與之關(guān)聯(lián),通過讀寫寄存器完成對(duì)GPIO管腳的操作。

2、GPIO平臺(tái)驅(qū)動(dòng)

GPIO(General-purpose input/output)即通用型輸入輸出。通常,GPIO控制器通過分組的方式管理所有GPIO管腳,每組GPIO有一個(gè)或多個(gè)寄存器與之關(guān)聯(lián),通過讀寫寄存器完成對(duì)GPIO管腳的操作。

GPIO模塊各分層作用:

  • 接口層提供操作GPIO管腳的標(biāo)準(zhǔn)方法。
  • 核心層主要提供GPIO管腳資源匹配,GPIO管腳控制器的添加、移除以及管理的能力,通過鉤子函數(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);
}

GpioMethod結(jié)構(gòu)體成員的鉤子函數(shù)功能說明:

函數(shù)成員

入?yún)?/p>

出參

返回值

功能

write

cntlr:結(jié)構(gòu)體指針,核心層GPIO控制器 local:uint16_t類型,GPIO端口標(biāo)識(shí)號(hào) val:uint16_t類型,電平傳入值

HDF_STATUS相關(guān)狀態(tài)

GPIO引腳寫入電平值

read

cntlr:結(jié)構(gòu)體指針,核心層GPIO控制器 local:uint16_t類型,GPIO端口標(biāo)識(shí)

val:uint16_t類型指針,用于傳出電平值。

HDF_STATUS相關(guān)狀態(tài)

GPIO引腳讀取電平值

setDir

cntlr:結(jié)構(gòu)體指針,核心層GPIO控制器 local:uint16_t類型,GPIO端口標(biāo)識(shí)號(hào) dir:uint16_t類型,管腳方向傳入值

HDF_STATUS相關(guān)狀態(tài)

設(shè)置GPIO引腳輸入/輸出方向

getDir

cntlr:結(jié)構(gòu)體指針,核心層GPIO控制器 local:uint16_t類型,GPIO端口標(biāo)識(shí)號(hào)

dir:uint16_t類型指針,用于傳出管腳方向值

HDF_STATUS相關(guān)狀態(tài)

讀GPIO引腳輸入/輸出方向

setIrq

cntlr:結(jié)構(gòu)體指針,核心層GPIO控制器 local:uint16_t類型,GPIO端口標(biāo)識(shí)號(hào) mode:uint16_t類型,表示觸發(fā)模式(邊沿或電平) func:函數(shù)指針,中斷服務(wù)程序; arg:void指針,中斷服務(wù)程序入?yún)?/p>

HDF_STATUS相關(guān)狀態(tài)

將GPIO引腳設(shè)置為中斷模式

unsetIrq

cntlr:結(jié)構(gòu)體指針,核心層GPIO控制器 local:uint16_t類型,GPIO端口標(biāo)識(shí)號(hào)

HDF_STATUS相關(guān)狀態(tài)

取消GPIO中斷設(shè)置

enableIrq

cntlr:結(jié)構(gòu)體指針,核心層GPIO控制器 local:uint16_t類型,GPIO端口標(biāo)識(shí)號(hào)

HDF_STATUS相關(guān)狀態(tài)

使能GPIO管腳中斷

disableIrq

cntlr:結(jié)構(gòu)體指針,核心層GPIO控制器 local:uint16_t類型,GPIO端口標(biāo)識(shí)號(hào)

HDF_STATUS相關(guān)狀態(tài)

禁止GPIO管腳中斷

3、GPIO應(yīng)用程序

GPIO驅(qū)動(dòng)API接口功能:

接口名

描述

GpioGetByName(const char *gpioName)

獲取GPIO管腳ID

int32_t GpioRead(uint16_t gpio, uint16_t *val)

讀GPIO管腳電平值

int32_t GpioWrite(uint16_t gpio, uint16_t val)

寫GPIO管腳電平值

int32_t GpioGetDir(uint16_t gpio, uint16_t *dir)

獲取GPIO管腳方向

int32_t GpioSetDir(uint16_t gpio, uint16_t dir)

設(shè)置GPIO管腳方向

int32_t GpioUnsetIrq(uint16_t gpio, void *arg);

取消GPIO管腳對(duì)應(yīng)的中斷服務(wù)函數(shù)

int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void *arg)

設(shè)置GPIO管腳對(duì)應(yīng)的中斷服務(wù)函數(shù)

int32_t GpioEnableIrq(uint16_t gpio)

使能GPIO管腳中斷

int32_t GpioDisableIrq(uint16_t gpio)

禁止GPIO管腳中斷

GPIO標(biāo)準(zhǔn)API通過GPIO管腳號(hào)來操作指定管腳,使用GPIO的一般流程如下圖所示:

三、代碼解析

1、準(zhǔn)備工作

查看《凌蒙派-RK3568開發(fā)板_排針說明表_》(即Git倉庫的//docs/board/凌蒙派-RK3568開發(fā)板_排針說明表_v1.0.xlsx),選中0_B5(即GPIO0_B5)。

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)名稱,必須是linux_adc_adapter,與drivers/hdf_core/adapter/khdf/linux/platform/gpio/gpio_adapter.c對(duì)應(yīng)
                    deviceMatchAttr = "";                       // 用于配置控制器私有數(shù)據(jù),不定義
                }
            }
        }
    }
}

注意:

  • device_gpio:為配置樹對(duì)gpio的設(shè)備類結(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的讀寫(即對(duì)Linux Gpio子系統(tǒng)進(jìn)行操作)。

(2)參與配置樹編譯

編輯//vendor/lockzhiner/rk3568/hdf_config/khdf/hdf.hcs,將device_info.hcs添加配置樹中。具體內(nèi)容如下所示:

#include "../../samples/b03_platform_device_gpio/config/device_info.hcs"

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寄存器操作。

4、應(yīng)用程序

(1)gpio_test.c

gpio_test.c主要分為兩個(gè)部分:

  • 對(duì)gpio引腳進(jìn)行讀操作。
  • 對(duì)gpio引腳進(jìn)行寫操作。

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\n", ret);
    return -1;
}

// GPIO輸出電平
ret = GpioWrite(m_gpio_id, m_gpio_value);
if (ret != 0) {
    PRINT_ERROR("GpioWrite failed and ret = %d\n", ret);
    return -1;
}

2.對(duì)gpio引腳進(jìn)行寫操作。

// GPIO設(shè)置為輸出
ret = GpioSetDir(m_gpio_id, GPIO_DIR_IN);
if (ret != 0) {
    PRINT_ERROR("GpioSetDir failed and ret = %d\n", ret);
    return -1;
}

// 讀取GPIO引腳的電平
ret = GpioRead(m_gpio_id, &m_gpio_value);
if (ret != 0) {
    PRINT_ERROR("GpioRead failed and ret = %d\n", ret);
    return -1;
}

printf("GPIO Read Successful and GPIO = %d, value = %d\n", m_gpio_id, m_gpio_value);

(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)參與應(yīng)用程序編譯

編輯//vendor/lockzhiner/rk3568/samples/BUILD.gn,開啟sample編譯。具體如下:

"b03_platform_device_gpio/app:rk3568_gpio_test",

四、編譯說明

建議使用docker編譯方法,運(yùn)行如下:

hb set -root .
hb set
#選擇lockzhiner下的rk3568編譯分支。
hb build -f

五、運(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
#

可將GPIO引腳接入排針中的GND或3V3引腳,查看GPIO輸出結(jié)果。

想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問:

51CTO 開源基礎(chǔ)軟件社區(qū)

https://ost.51cto.com

責(zé)任編輯:jianghua 來源: 51CTO 開源基礎(chǔ)軟件社區(qū)
相關(guān)推薦

2023-09-19 15:21:33

RTC鴻蒙

2023-09-06 15:27:22

ADC鴻蒙

2023-09-19 15:14:59

鴻蒙Watchdog

2021-11-29 07:55:45

Linux GPIO Linux 系統(tǒng)

2022-08-29 17:34:05

鴻蒙操作系統(tǒng)

2009-09-27 17:23:16

Hibernate應(yīng)用

2011-01-28 09:12:53

jQuery Mobi

2021-12-06 07:47:36

Linux 驅(qū)動(dòng)程序Linux 系統(tǒng)

2011-04-01 11:01:02

應(yīng)用程序BlackBerryJava

2018-06-22 09:00:00

Java框架Pronghorn

2009-07-03 06:57:32

2011-03-22 14:12:17

LAMP

2022-02-21 14:49:26

OpenHarmon操作系統(tǒng)鴻蒙

2010-02-24 13:25:22

Python線程應(yīng)用程

2011-07-20 15:58:58

iPhone 應(yīng)用程序 生命周期

2009-10-10 13:56:44

IIS應(yīng)用程序VB開發(fā)

2009-12-25 10:39:49

WPF應(yīng)用程序關(guān)閉

2010-02-06 15:26:11

Android應(yīng)用程序

2010-02-07 10:21:27

Android應(yīng)用程序

2023-09-14 15:49:42

PWM鴻蒙
點(diǎn)贊
收藏

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