日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux内核的gpiolib

發布時間:2023/12/20 linux 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux内核的gpiolib 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

gpiolib引入
(1)一個事實:很多硬件都要用到GPIO、GPIO會復用
(2)如果同一個GPIO被2個驅動同時控制了,就會出現bug
(3)內核提供gpiolib來統一管理系統中所有GPIO
(4)gpiolib本身屬于驅動框架的一部分


gpiolib學習重點
(1)gpiolib的建立過程
(2)gpiolib的使用方法:申請、使用、釋放
(3)gpiolib的架構:涉及哪些目錄的哪些文件


1.gpiolib的建立
smdkc110_map_io (arch/arm/mach-s5pv210/mach-smdkc110.c)
s5pv210_gpiolib_init 這個函數就是我們gpiolib初始化的函數,在 (arch/arm/mach-s5pv210/gpiolib.c)中。

s5pv210_gpiolib_init函數分析:
__init int s5pv210_gpiolib_init(void)
{
struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
int i = 0;

for (i = 0; i < nr_chips; i++, chip++) {if (chip->config == NULL)chip->config = &gpio_cfg;if (chip->base == NULL)chip->base = S5PV210_BANK_BASE(i); 記錄虛擬首地址的 }samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);return 0;

}
**一個非常重要的結構體:

struct s3c_gpio_chip {
struct gpio_chip chip;
struct s3c_gpio_cfg *config;
struct s3c_gpio_pm pm;
void __iomem base;
int eint_offset;
spinlock_t lock;
#ifdef CONFIG_PM
u32 pm_save[7];
#endif
};
struct s3c_gpio_chip,這個結構體是一個GPIO端口的抽象,這個結構體的一個變量就可以完全的描述一個IO端口。
注意:IO口和IO端口的區別?
我們S5PV210有407個左右的IO口,這些IO口首先被劃分為M個IO端口,每一個IO端口又有N個IO口。所有我們總共是 M * N =407.
GPIOA、GPIOB、GPIOC等等就叫一個個的IO端口。
GPIOA_0、GPIOA_1、GPIOA_2這就是GPIOA端口里面的0 1 2三個GPIO口。
端口和IO口是兩個概念。S5PV210有很多個IO口(407個左右),這些IO口首先被分成N個端口(port group),然后每個端口中又包含了M個IO口。譬如GPA0是一個端口,里面包含了8個IO口,我們一般記作:GPA0_0(或GPA0.0)、GPA0_1、。

s3c_gpio_chip 結構體中的chip成員就是對一個端口信息的具體描述


如何得到GPIO的數量:s5pv210_gpio_4bit數組里面有描述50多個IO端口,每一個IO端口又有4-8個的IO口。所以s5pv210_gpio_4bit這個數組就是對所有的IO端口的描述。這個東西是一個結構體數組,數組中包含了很多個struct s3c_gpio_chip類型的變量。

#define S5PV210_GPIO_A0_NR (8)
#define S5PV210_GPIO_A1_NR (4)
#define S5PV210_GPIO_B_NR (8)
#define S5PV210_GPIO_C0_NR (5)
#define S5PV210_GPIO_C1_NR (5)
#define S5PV210_GPIO_D0_NR (4)
#define S5PV210_GPIO_D1_NR (6)
#define S5PV210_GPIO_E0_NR (8)
#define S5PV210_GPIO_E1_NR (5)
#define S5PV210_GPIO_F0_NR (8)
#define S5PV210_GPIO_F1_NR (8)
#define S5PV210_GPIO_F2_NR (8)
#define S5PV210_GPIO_F3_NR (6)
#define S5PV210_GPIO_G0_NR (7)
#define S5PV210_GPIO_G1_NR (7)
#define S5PV210_GPIO_G2_NR (7)
#define S5PV210_GPIO_G3_NR (7)
#define S5PV210_GPIO_H0_NR (8)
#define S5PV210_GPIO_H1_NR (8)
#define S5PV210_GPIO_H2_NR (8)
#define S5PV210_GPIO_H3_NR (8)
#define S5PV210_GPIO_I_NR (7)
#define S5PV210_GPIO_J0_NR (8)
#define S5PV210_GPIO_J1_NR (6)
#define S5PV210_GPIO_J2_NR (8)
#define S5PV210_GPIO_J3_NR (8)
#define S5PV210_GPIO_J4_NR (5)

#define S5PV210_GPIO_MP01_NR (8)
#define S5PV210_GPIO_MP02_NR (4)
#define S5PV210_GPIO_MP03_NR (8)
#define S5PV210_GPIO_MP04_NR (8)
#define S5PV210_GPIO_MP05_NR (8)
#define S5PV210_GPIO_MP06_NR (8)
#define S5PV210_GPIO_MP07_NR (8)

#define S5PV210_GPIO_MP10_NR (8)
#define S5PV210_GPIO_MP11_NR (8)
#define S5PV210_GPIO_MP12_NR (8)
#define S5PV210_GPIO_MP13_NR (8)
#define S5PV210_GPIO_MP14_NR (8)
#define S5PV210_GPIO_MP15_NR (8)
#define S5PV210_GPIO_MP16_NR (8)
#define S5PV210_GPIO_MP17_NR (8)
#define S5PV210_GPIO_MP18_NR (7)

#define S5PV210_GPIO_MP20_NR (8)
#define S5PV210_GPIO_MP21_NR (8)
#define S5PV210_GPIO_MP22_NR (8)
#define S5PV210_GPIO_MP23_NR (8)
#define S5PV210_GPIO_MP24_NR (8)
#define S5PV210_GPIO_MP25_NR (8)
#define S5PV210_GPIO_MP26_NR (8)
#define S5PV210_GPIO_MP27_NR (8)
#define S5PV210_GPIO_MP28_NR (7)

#define S5PV210_GPIO_ETC0_NR (6)
#define S5PV210_GPIO_ETC1_NR (8)
#define S5PV210_GPIO_ETC2_NR (8)
#define S5PV210_GPIO_ETC4_NR (6)


內核中為每個GPIO分配了一個編號,編號是一個數字(譬如一共有380個IO時編號就可以從1到407連續分布),編號可以讓程序很方便的去識別每一個GPIO


S5PV210_GPA0(0)宏
#define S5PV210_GPA0(_nr) (S5PV210_GPIO_A0_START + (_nr))
S5PV210_GPIO_A0_START = 0,
所以我們分析:
S5PV210_GPA0的base是0。

我們分析一下S5PV210_GPA1(0):
S5PV210_GPA1(0):
調用:
#define S5PV210_GPA1(_nr) (S5PV210_GPIO_A1_START + (_nr))
調用:
S5PV210_GPIO_A1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_A0),
調用:
#define S5PV210_GPIO_NEXT(__gpio)
((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
#define S5PV210_GPIO_A0_NR (8)
所以:
S5PV210_GPA1(0)的base值是9.

我們查看/sys/class/gpio里面的gpiochip0,它的base值剛好是:0。對應的是S5PV210_GPA0。
查看/sys/class/gpio里面的gpiochip9,它的base值剛好是:9.對應的是S5PV210_GPA1


總結一下:/sys/class/gpio/gpiochipx,每一個都是對應一個IO端口的,里面的base就是這個IO端口第一個IO口的編號。gpiochipx的x是和它的base值相同的。ngpio就是代表這個IO端口有多少個IO口。
所以,/sys/class/gpio/gpiochipx是由s5pv210_gpio_4bit這個數組來決定的。
S5PV210_GPA0宏的返回值就是GPA0端口的某一個IO口的編號值,傳參就是我們這個IO口在GPA0端口中的局部編號。
例如:S5PV210_GPA0(0),返回的就是0,所以我們GPIOA_0的編碼號就是0,傳參是0說明這個IO在GPA0端口中的局部編號也是0.
再例如:S5PV210_GPA1(0),返回的就是9,所以我們GPA1_0的編碼號就是9,傳參是0說明這個IO在GPA1端口中的局部編號也是0.

samsung_gpiolib_add_4bit_chips這個函數才是具體進行gpiolib的注冊的。這個函數接收的參數是我們當前文件中定義好的結構體數組s5pv210_gpio_4bit(其實2個參數分別是數組名和數組元素個數),這個數組中其實就包含了當前系統中所有的IO端口的信息(這些信息包含:端口的名字、端口中所有GPIO的編號、端口操作寄存器組的虛擬地址基地址、端口中IO口的數量、端口上下拉等模式的配置函數、端口中的IO口換算其對應的中斷號的函數)。


samsung_gpiolib_add_4bit_chips函數:
在 arch/arm/plat-samsung/gpiolic.c:
函數名中為什么有個4bit:三星的CPU中2440的CON寄存器是2bit對應一個IO口,而6410和210以及之后的系列中CON寄存器是4bit對應1個IO口。所以gpiolib在操作2440和210的CON寄存器時是不同的

函數調用關系
samsung_gpiolib_add_4bit_chips
samsung_gpiolib_add_4bit
s3c_gpiolib_add
經過分析,發現samsung_gpiolib_add_4bit內部其實并沒有做gpiolib的注冊工作,而是還在做填充,填充的是每一個GPIO被設置成輸入模式/輸出模式的操作方法。

s3c_gpiolib_add
首先檢測并完善chip的direction_input/direction_ouput/set/get這4個方法,然后調用gpiochip_add方法進行真正的注冊操作。其實這個注冊就是將我們的封裝了一個GPIO端口的所有信息的chip結構體變量掛接到內核gpiolib模塊定義的一個gpio_desc數組中的某一個格子中。
for (id = base; id < base + chip->ngpio; id++) {
gpio_desc[id].chip = chip;
這里的注冊,每一個IO口都會對應一個chip,同一個IO端口里面的,chip是相同的。


內核開發者提供的驅動框架
之前的分析已經告一段落,截至目前我們已經搞清楚了gpiolib的建立工程。但是這只是整個gpiolib建立的一部分,是廠商驅動工程師負責的那一部分;還有另一部分是內核開發者提供的驅動框架的那一部分,就是我們后面要去分析的第2條主線。
drivers/gpio/gpiolib.c這個文件中所有的函數構成了我們第2部分,也就是內核開發者寫的gpiolib框架部分。這個文件中提供的函數主要有以下部分:
1.gpiochip_add: 是框架開出來的接口,給廠商驅動工程師用,用于向內核注冊我們的gpiolib
2.gpio_request: 是框架開出來的接口,給使用gpiolib來編寫自己的驅動的驅動工程師用的,驅動中要想使用某一個gpio,就必須先調用gpio_request接口來向內核的gpiolib部分申請,得到允許后才可以去使用這個gpio。
3.gpio_free: 對應gpio_request,用來釋放申請后用完了的gpio
4.gpio_request_one/gpio_request_array: 這兩個是gpio_request的變種 gpiochip_is_requested: 接口用來判斷某一個gpio是否已經被申請了gpio_direction_input/gpio_direction_output: 接口用來設置GPIO為輸入/輸出模式,注意該函數內部實際并沒有對硬件進行操作,只是通過chip結構體變量的函數指針調用了將來SoC廠商的驅動工程師寫的真正的操作硬件實現gpio設置成輸出模式的那個函數。

以上的接口屬于一類,這些都是給寫其他驅動并且用到了gpiolib的人使用的
剩下的還有另外一類函數,這類函數是gpiolib內部自己的一些功能實現的代碼

GPIOLIB自己的創建:
status = class_register(&gpio_class);
postcore_initcall(gpiolib_sysfs_init);

static struct class gpio_class = {
.name = “gpio”,
.owner = THIS_MODULE,

.class_attrs = gpio_class_attrs,

};

static struct class_attribute gpio_class_attrs[] = {
__ATTR(export, 0200, NULL, export_store),
__ATTR(unexport, 0200, NULL, unexport_store),
__ATTR_NULL,
};
這個類創建的時候,有兩個屬性文件,export_store和unexport_store。
注意:.class_attrs 是這個類的屬性文件,例如:/sys/class/gpio/export和
/sys/class/gpio/unexport,是這個類的屬性文件。
而:leds_class->dev_attrs = led_class_attrs;這種是將來這個類device_create創建的文件的屬性。一個是屬于類的,一個是屬于類的文件的。

gpiolib初始化函數:
gpiolib_sysfs_init
調用:
class_register 創建gpio類
gpiochip_export 創建gpio類下面的gpiochipn
調用:
status = sysfs_create_group(&dev->kobj,
&gpiochip_attr_group);
去創建gpiochipn下面的屬性文件。
關于GPIO原理本身的一些東西,我們就不去深入研究了


目錄和文件結構:
mach-s5pv210/gpiolib.c s5pv210_gpiolib_init
mach-s5pv210/include/mach/gpio.h #define S5PV210_GPA0(_nr) (S5PV210_GPIO_A0_START + (_nr))
arch/arm/plat-samsung/gpiolib.c 里面是210/6410這種4bit CON寄存器類型的操作方法
arch/arm/plat-samsung/gpio.c 里面是24XX這種2bit CON寄存器類型的操作方法
drivers/gpio/gpiolib.c 里面是內核開發者提供的gpiolib的驅動框架部分

總結

以上是生活随笔為你收集整理的linux内核的gpiolib的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 毛片网在线 | 日韩射| 免费黄色在线观看 | 噼里啪啦国语版在线观看 | 色涩视频在线观看 | 欧美黄色录像片 | 毛片一区二区三区 | 国产女人呻吟高潮抽搐声 | 亚洲欧美日韩一区在线观看 | 夜夜夜久久久 | 深夜视频免费在线观看 | 国产乱淫av片免费 | 精品国产av鲁一鲁一区 | 337p日本欧洲亚洲鲁鲁 | 国产男男gay网站 | 色一情一乱一伦 | 韩国久久久久久 | 国产精品日本 | 你懂的网站在线观看 | av精选| 欧美黑人一级片 | 强伦轩人妻一区二区电影 | 人人看人人干 | 免费九九视频 | 精品成人免费一区二区在线播放 | 日韩激情在线播放 | 67194在线免费观看 | 国产免费一级片 | 黄色性生活一级片 | 欧美一区高清 | 黄色av小说在线观看 | 午夜一区二区三区在线 | 一本在线 | 成人午夜在线视频 | 激情综合五月天 | 成人在线天堂 | 国产综合视频一区二区 | 妺妺窝人体色www婷婷 | 一本色道久久综合亚洲 | 久久精品无码人妻 | 日韩精选 | 成人综合色站 | 午夜激情av | 免费看欧美一级特黄a大片 国产免费的av | 成人h视频在线观看 | 国产无套精品一区二区三区 | 欧美三区视频 | 肉大榛一进一出免费视频 | 中文字幕25页 | 国产精品色 | 国产一区二区三区在线视频 | 147人体做爰大胆图片成人 | 香蕉网在线播放 | 91插插插插 | 女生裸体无遮挡 | 91www在线观看 | 国产精品无码一区二区无人区多人 | 爱涩av | 欧美三级网 | av在线一区二区三区 | 色99色| 婷婷色九月 | 观看av免费 | 国产在线不卡视频 | 91免费看| 哈利波特3在线观看免费版英文版 | 免费网站看av | 亚洲第一色图 | 欧美交| 男女搞黄网站 | 91色网站 | 无码人妻精品一区二区三区温州 | 日本人妻伦在线中文字幕 | 成人污污www网站免费丝瓜 | 麻豆日产六区 | 久久久久人妻一区 | 胖女人做爰全过程 | 久久国产精品免费视频 | 日韩啪啪网站 | 超碰五月天 | 三级黄色片免费观看 | 美乳人妻一区二区三区 | 欧美性视屏 | 久久99精品国产.久久久久久 | 亚洲欧美在线观看视频 | 久久性视频 | 国产激情视频在线 | 午夜激情婷婷 | av特黄 | 日韩插| 啪啪.com| 色哟哟导航 | 中文字幕 人妻熟女 | 美女隐私无遮挡免费 | 无码人妻精品一区二区三区99不卡 | 免费久久一级欧美特大黄 | 国产高清日韩 | 中文字幕1区2区3区 www.com黄色片 | 男人操女人的免费视频 |