瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工藝,搭載一顆四核Cortex-A55處理器和Mali G52 2EE圖形處理器。RK3568支持4K解碼和1080P編碼,支持SATA/PCIE/USB3.0外圍接口。RK3568內(nèi)置獨(dú)立NPU,可用于輕量級(jí)人工智能應(yīng)用。RK3568支持安卓11和linux系統(tǒng),主要面向物聯(lián)網(wǎng)網(wǎng)關(guān)、NVR存儲(chǔ)、工控平板、工業(yè)檢測(cè)、工控盒、卡拉OK、云終端、車載中控等行業(yè)。
?
迅為RK3568開發(fā)板瑞芯微Linux安卓鴻蒙ARM核心板人工智能AI主板

第131章GPIO子系統(tǒng)API函數(shù)的引入
事實(shí)上,在前面中斷課程中,已經(jīng)簡(jiǎn)單接觸到了GPIO子系統(tǒng)中的API函數(shù),其中用來獲取gpio中斷編號(hào)的gpio_to_irq函數(shù)就屬于GPIO子系統(tǒng)中的API函數(shù),在本章節(jié)中將對(duì)GPIO子系統(tǒng)進(jìn)行簡(jiǎn)單的介紹。
在目前的Linux內(nèi)核主線中,GPIO(通用輸入/輸出)子系統(tǒng)存在兩個(gè)版本,這里將兩個(gè)版本區(qū)分為新版本和舊版本。新版本GPIO子系統(tǒng)接口是基于描述符(descriptor-based)來實(shí)現(xiàn)的,而舊版本的GPIO子系統(tǒng)接口是基于整數(shù)(integer-based)來實(shí)現(xiàn)的,在Linux內(nèi)核中為了保持向下的兼容性,舊版本的接口在最新的內(nèi)核版本中仍然得到支持,而隨著時(shí)間的推移,新版本的GPIO子系統(tǒng)接口會(huì)越來越完善,最終完全取代舊版本,所以在本課程中主要講解新版本的GPIO子系統(tǒng)接口。
新的GPIO子系統(tǒng)接口需要與與設(shè)備樹(Device Tree)結(jié)合使用。使用設(shè)備樹和新的GPIO接口可以更加靈活地配置和管理系統(tǒng)中的GPIO資源,提供了更好的可擴(kuò)展性和可移植性。所以如果沒有設(shè)備樹,就無法使用新的GPIO接口。
那要如何對(duì)新舊GPIO子系統(tǒng)接口進(jìn)行區(qū)分呢,一個(gè)明顯的區(qū)別是新的GPIO子系統(tǒng)接口使用了以"gpiod_"作為前綴的函數(shù)命名約定,而舊的GPIO子系統(tǒng)接口使用了以"gpio_"作為前綴的函數(shù)命名約定。
一些區(qū)分新舊 GPIO子系統(tǒng)接口的示例如下所示:
新的 GPIO子系統(tǒng)接口示例如下所示:
gpiod_set_value()
gpiod_direction_input()
gpiod_direction_output()
gpiod_get_value()
gpiod_request()
AI寫代碼
cpp
舊的 GPIO子系統(tǒng)接口示例:
gpio_set_value()
gpio_direction_input()
gpio_direction_output()
gpio_get_value()
gpio_request()
AI寫代碼
cpp
上面也提到了新的 GPIO子系統(tǒng)接口是基于描述符(descriptor-based)來實(shí)現(xiàn)的,由struct gpio_desc結(jié)構(gòu)體來表示,該結(jié)構(gòu)體定義在內(nèi)核源碼的“drivers/gpio/gpiolib.h”目錄下。具體內(nèi)容如下所示:
struct gpio_desc {
struct gpio_device gdev; // GPIO設(shè)備結(jié)構(gòu)體
unsigned long flags; //標(biāo)志位,用于表示不同的屬性
/*標(biāo)志位符號(hào)對(duì)應(yīng)的位號(hào)*/
#define FLAG_REQUESTED 0 // GPIO已請(qǐng)求
#define FLAG_IS_OUT 1 // GPIO用作輸出
#define FLAG_EXPORT 2 //受sysfs_lock保護(hù)的導(dǎo)出標(biāo)志
#define FLAG_SYSFS 3 //通過/sys/class/gpio/control導(dǎo)出的標(biāo)志
#define FLAG_ACTIVE_LOW 6 // GPIO值為低電平時(shí)激活
#define FLAG_OPEN_DRAIN 7 // GPIO為開漏類型
#define FLAG_OPEN_SOURCE 8 // GPIO為開源類型
#define FLAG_USED_AS_IRQ 9 // GPIO連接到中斷請(qǐng)求(IRQ)
#define FLAG_IS_HOGGED 11 // GPIO被獨(dú)占占用
#define FLAG_TRANSITORY 12 // GPIO在休眠或復(fù)位時(shí)可能失去值
/*連接標(biāo)簽*/
const char *label; // GPIO的名稱
const char *name; // GPIO的名稱
};
AI寫代碼
cpp
(1)struct gpio_device gdev是一個(gè)struct gpio_device類型的字段,用于表示GPIO設(shè)備的相關(guān)信息。struct gpio_device結(jié)構(gòu)體通常包含設(shè)備的底層硬件控制器等信息。
(2)unsigned long flags:用于表示GPIO的標(biāo)志位,以表示不同的屬性。通過使用位操作,每個(gè)標(biāo)志位可以單獨(dú)設(shè)置或清除。
(3)第5-14行用于表示不同標(biāo)志位的符號(hào)常量,與flags字段中的位號(hào)相對(duì)應(yīng)。例如,在flags字段中的第0位表示FLAG_REQUESTED,第1位表示FLAG_IS_OUT,以此類推
(4)const char *label:這是一個(gè)指向字符串的指針,表示GPIO的標(biāo)簽或名稱。
(5)const char *name:這是一個(gè)指向字符串的指針,表示GPIO的名稱。
上面需要重點(diǎn)關(guān)注的是然后struct gpio_device結(jié)構(gòu)體,該結(jié)構(gòu)體同樣定義在內(nèi)核源碼的“drivers/gpio/gpiolib.h”目錄下,具體內(nèi)容如下所示:
struct gpio_device {
int id; // GPIO設(shè)備ID
struct device *dev; //對(duì)應(yīng)的設(shè)備結(jié)構(gòu)體指針
struct cdev chrdev; //字符設(shè)備結(jié)構(gòu)體
struct device *mockdev; //模擬設(shè)備結(jié)構(gòu)體指針
struct module *owner; //擁有該GPIO設(shè)備的內(nèi)核模塊指針
struct gpio_chip *chip; //對(duì)應(yīng)的GPIO芯片結(jié)構(gòu)體指針
struct gpio_desc *descs; // GPIO描述符數(shù)組指針
int base; // GPIO編號(hào)的起始值
u16 ngpio; // GPIO的數(shù)量
const char *label; // GPIO設(shè)備的標(biāo)簽
void *data; //與GPIO設(shè)備相關(guān)的數(shù)據(jù)指針
struct list_head list; //用于將GPIO設(shè)備結(jié)構(gòu)體連接到鏈表中
#ifdef CONFIG_PINCTRL
/*
*如果啟用了CONFIG_PINCTRL選項(xiàng),GPIO控制器可以選擇描述它們?cè)赟oC中服務(wù)的實(shí)際引腳范圍。
*此信息將由pinctrl子系統(tǒng)用于配置相應(yīng)的GPIO引腳。
*/
struct list_head pin_ranges; //描述GPIO控制器引腳范圍的鏈表
#endif
};
AI寫代碼
cpp
該結(jié)構(gòu)體是用來描述GPIO設(shè)備的數(shù)據(jù)結(jié)構(gòu),關(guān)于該結(jié)構(gòu)體的參數(shù)介紹如下所示:
(1)int id:整型字段,表示GPIO設(shè)備的ID。每個(gè)GPIO設(shè)備可以有一個(gè)唯一的ID。
(2)struct device *dev:指向struct device的指針,表示與GPIO設(shè)備相關(guān)聯(lián)的設(shè)備結(jié)構(gòu)體。
(3)struct cdev chrdev:字符設(shè)備結(jié)構(gòu)體,用于實(shí)現(xiàn)GPIO設(shè)備的字符設(shè)備接口。
(4)struct device *mockdev:指向struct device的指針,用于表示GPIO設(shè)備的模擬設(shè)備結(jié)構(gòu)體。
(5)struct module *owner:指向擁有該GPIO設(shè)備的內(nèi)核模塊的指針。
(6)struct gpio_chip *chip:指向struct gpio_chip的指針,表示與GPIO設(shè)備關(guān)聯(lián)的GPIO芯片(GPIO控制器)結(jié)構(gòu)體。
(7)struct gpio_desc *descs:指向struct gpio_desc數(shù)組的指針,表示與GPIO設(shè)備關(guān)聯(lián)的GPIO描述符。每個(gè)GPIO描述符用于描述GPIO的屬性和狀態(tài)。
(8)int base:表示GPIO編號(hào)的起始值。
(9)u16 ngpio: 16位無符號(hào)整型字段,表示GPIO的數(shù)量。
(10)const char *label:指向字符串的指針,表示GPIO設(shè)備的標(biāo)簽或名稱。
(11)void *data:指向與GPIO設(shè)備相關(guān)的數(shù)據(jù)的指針,用于存儲(chǔ)和訪問與GPIO設(shè)備相關(guān)的自定義數(shù)據(jù)。
(12)struct list_head list:將GPIO設(shè)備結(jié)構(gòu)體連接到鏈表中的字段,用于管理多個(gè)GPIO設(shè)備的列表。
(13)struct list_head pin_ranges (僅在啟用CONFIG_PINCTRL選項(xiàng)時(shí)存在):用于描述GPIO控制器引腳范圍的鏈表。如果配置了GPIO控制器的引腳范圍,該鏈表將包含描述每個(gè)范圍的元素。
在上面一系列的參數(shù)中,要重點(diǎn)關(guān)注的是struct gpio_chip *chip這一結(jié)構(gòu)體,表示與GPIO設(shè)備關(guān)聯(lián)的GPIO芯片(GPIO控制器)結(jié)構(gòu)體,該結(jié)構(gòu)體定義在內(nèi)核源碼目錄下的“include/linux/gpio/driver.h”文件中,具體內(nèi)容如下所示
struct gpio_chip {
const char *label; // GPIO芯片標(biāo)簽
struct gpio_device gpiodev; // GPIO設(shè)備
struct device *parent; //父設(shè)備指針
struct module *owner; //擁有者模塊指針
int (*request)(struct gpio_chip *chip, unsigned offset);//請(qǐng)求GPIO
void (*free)(struct gpio_chip *chip, unsigned offset); //釋放GPIO
int (*get_direction)(struct gpio_chip *chip, unsigned offset); //獲取GPIO方向
int (*direction_input)(struct gpio_chip *chip, unsigned offset); //設(shè)置GPIO為輸入
int (*direction_output)(struct gpio_chip *chip, unsigned offset, int value); //設(shè)置GPIO為輸出
int (*get)(struct gpio_chip chip, unsigned offset); //獲取GPIO值
int (*get_multiple)(struct gpio_chip chip, unsigned long *mask, unsigned long *bits); //獲取多個(gè)GPIO的值
void (*set)(struct gpio_chip chip, unsigned offset, int value); //設(shè)置GPIO值
void (*set_multiple)(struct gpio_chip chip, unsigned long mask, unsigned long *bits); //設(shè)置多個(gè)GPIO的值
int (*set_config)(struct gpio_chip *chip, unsigned offset, unsigned long config); //設(shè)置GPIO配置
int (*to_irq)(struct gpio_chip chip, unsigned offset); //將GPIO轉(zhuǎn)換為中斷
void (*dbg_show)(struct seq_file *s, struct gpio_chip chip); //在調(diào)試信息中顯示GPIO
int base; // GPIO編號(hào)的基準(zhǔn)值
u16 ngpio; // GPIO的數(shù)量
const char *const *names; // GPIO的名稱數(shù)組
..........
};
AI寫代碼
cpp
struct gpio_chip *chip這一結(jié)構(gòu)體用于描述GPIO芯片的屬性和操作函數(shù),可以通過函數(shù)指針調(diào)用相應(yīng)的函數(shù)來請(qǐng)求、釋放、設(shè)置、獲取GPIO的狀態(tài)和數(shù)值等操作,從而實(shí)現(xiàn)對(duì)GPIO的控制和管理,需要注意的是這個(gè)結(jié)構(gòu)體中的一系列函數(shù)都不需要我們來填充,這些工作都是由芯片原廠工程師來完成的,我們只需要學(xué)會(huì)新gpio子系統(tǒng)相應(yīng)API函數(shù)的使用即可。
在接下來的章節(jié)中將對(duì)常用的新gpio子系統(tǒng)API函數(shù)進(jìn)行講解。
————————————————
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。
原文鏈接:https://blog.csdn.net/BeiJingXunWei/article/details/135569658
-
開發(fā)板
+關(guān)注
關(guān)注
25文章
5499瀏覽量
102023 -
GPIO
+關(guān)注
關(guān)注
16文章
1269瀏覽量
53524 -
RK3568
+關(guān)注
關(guān)注
5文章
575瀏覽量
6049 -
迅為電子
+關(guān)注
關(guān)注
0文章
55瀏覽量
139
發(fā)布評(píng)論請(qǐng)先 登錄
迅為RK3568開發(fā)板驅(qū)動(dòng)指南Linux中通用SPI設(shè)備驅(qū)動(dòng)

北京迅為RK3568開發(fā)板OpenHarmony系統(tǒng)南向驅(qū)動(dòng)開發(fā)內(nèi)核HDF驅(qū)動(dòng)框架架構(gòu)

迅為RK3568驅(qū)動(dòng)指南GPIO子系統(tǒng)實(shí)戰(zhàn):實(shí)現(xiàn)動(dòng)態(tài)切換引腳復(fù)用功能

迅為RK3568開發(fā)板驅(qū)動(dòng)指南GPIO子系統(tǒng)三級(jí)節(jié)點(diǎn)操作函數(shù)實(shí)驗(yàn)

更新 | 持續(xù)開源 迅為RK3568驅(qū)動(dòng)指南第十一篇-pinctrl子系統(tǒng)
RK3568pinctrl 和 gpio 子系統(tǒng)詳解

迅為基于RK3568開發(fā)板的嵌入式學(xué)習(xí)之Linux驅(qū)動(dòng)視頻

迅為RK3568開發(fā)板Debian系統(tǒng)使用python 進(jìn)行攝像頭開發(fā)

迅為RK3568開發(fā)板SPI驅(qū)動(dòng)指南-mcp2515驅(qū)動(dòng)編寫:讀寄存器函數(shù)

【北京迅為】iTOP-RK3568OpenHarmony系統(tǒng)南向驅(qū)動(dòng)開發(fā)GPIO基礎(chǔ)知識(shí)

RK3568驅(qū)動(dòng)指南|第十二篇 GPIO子系統(tǒng)-第135章 GPIO子系統(tǒng)與pinctrl子系統(tǒng)相結(jié)合實(shí)驗(yàn)

評(píng)論