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

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