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

歡迎訪問 生活随笔!

生活随笔

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

linux

linux驱动(七)gpiolib库详解

發布時間:2024/4/17 linux 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux驱动(七)gpiolib库详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

---恢復內容開始---

1:什么是gpiolib,為什么要有gpiolib?

linux中從2.6.35以后就開始有gpiolib庫了,gpiolib的作用是對所有的gpio實行統一管理,因為驅動在工作的時候,會出現好幾個驅動共同使用同一個gpio的情況;

這會造成混亂。所以內核提供了一些方法來管理gpio資源;

2:如何學習gpiolib

第一:gpiolib庫的建立;

第二:gpiolib庫的使用方法:申請、使用、釋放;

3:

  我們首先來看一下這個文件:mach-smdkc110.c這個文件:

smdkc110_map_io

    s5pv210_gpiolib_init ?這個函數是gpiolib的初始化函數

__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; }

gpiolib庫的初始化實質就是對這個結構體數組進行賦值;

下面看一下這個結構體

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_PMu32 pm_save[7]; #endif };

?chpi結構體:為主要結構體

關鍵幾個元素

label

request    //申請gpio

free      //釋放gpio

direction_input    //輸入模式

direction_output    //輸出模式

get          //讀取gpio的值

set          //寫入gpio的值

base        //gpio基地址 端口地址

ngpio        //引腳地址

names        //名字

? struct gpio_chip {const char *label;struct device *dev;struct module *owner;int (*request)(struct gpio_chip *chip,unsigned offset);void (*free)(struct gpio_chip *chip,unsigned offset);int (*direction_input)(struct gpio_chip *chip,unsigned offset);int (*get)(struct gpio_chip *chip,unsigned offset);int (*direction_output)(struct gpio_chip *chip,unsigned offset, int value);int (*set_debounce)(struct gpio_chip *chip,unsigned offset, unsigned debounce);void (*set)(struct gpio_chip *chip,unsigned offset, int value);int (*to_irq)(struct gpio_chip *chip,unsigned offset);void (*dbg_show)(struct seq_file *s,struct gpio_chip *chip);int base;u16 ngpio;const char *const *names;unsigned can_sleep:1;unsigned exported:1; };

?

內核中建立了

static struct s3c_gpio_chip s5pv210_gpio_4bit[] 這個數組,將所有的gpio的.chip結構體中的一些元素初始化

 這個數組的所有元素是與數據手冊中的所有gpio是一一對應的;

?

?我們首先來分析一下.chip->base中的值?通過一下幾個宏定義我們可以知道gpa0中 chip->.chip->base中的值為 0 gpa1中chip->.chip->base中的值為9 這個數字數對應端口的io口的號碼;

#define S5PV210_GPA0(_nr) (S5PV210_GPIO_A0_START + (_nr))
#define S5PV210_GPA1(_nr) (S5PV210_GPIO_A1_START + (_nr))?

S5PV210_GPIO_A0_START = 0,
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)
#define S5PV210_GPIO_A1_NR (4)
#define S5PV210_GPIO_B_NR (8)
#define S5PV210_GPIO_C0_NR (5)

?----------------------------------------------------------------------------------------------------------------------------------------------

?接下來是對

chip->config = &gpio_cfg;

chip->config結構體賦值;

然后是對chip->base 賦值

chip->base = S5PV210_BANK_BASE(i);

?#define S5PV210_BANK_BASE(bank_nr) (S5P_VA_GPIO + ((bank_nr) * 0x20)

?可以看出chip->base是把gpio的虛擬地址賦值給chip->base,每個gpio的地址差0x20;

?下面看一下

samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips); 這個函數

void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,int nr_chips) {for (; nr_chips > 0; nr_chips--, chip++) {samsung_gpiolib_add_4bit(chip);s3c_gpiolib_add(chip);} }

這個函數中調用了兩個函數

samsung_gpiolib_add_4bit_chips

    samsung_gpiolib_add_4bit

    s3c_gpiolib_add

void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip) {chip->chip.direction_input = samsung_gpiolib_4bit_input;chip->chip.direction_output = samsung_gpiolib_4bit_output;chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); }

這個函數的作用是對每個chip->chip的direction_input direction_output兩個函數賦值

下面看一下s3c_gpiolib_add函數都做了什么:

if (!gc->direction_input)gc->direction_input = s3c_gpiolib_input;if (!gc->direction_output)gc->direction_output = s3c_gpiolib_output;if (!gc->set)gc->set = s3c_gpiolib_set;if (!gc->get)gc->get = s3c_gpiolib_get;

繼續對chip->中的元素進行賦值,set get賦值,

ret = gpiochip_add(gc);

最后注冊這些gpio_chip結構體;

注冊的實質是:在linux內核中有一個gpio_desc結構體數組,注冊就是把我們封裝的gpio的所有信息的結構體放到數組的格子中;

static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];   

gpiolib庫是linux內核工程師以及三星芯片廠商工程師共同完成的,內核工程師提供搭建好底層框架,三星工程師

把自己開發板的gpio初始化并注冊到內核提供的數組中去;

---------------------------------------------------------------------------------------------------------------

上面講了gpiolib庫的構建,構建的實質是把所有的gpio結構體進行初始化,并且放到內核中gpio_desc這個結構體數組中;

下面看一下我們在開發驅動的時候如何使用gpiolib庫

首先要了解一下linux內核工程師給我們開發的接口:
文件:/drivers/gpio/gpiolib.c文件中提供所有的接口

1:gpio_request:向內核申請gpio

int gpio_request(unsigned gpio, const char *label)

2:gpio_free對應gpio_request,是使用完gpio以后把gpio釋放掉

void gpio_free(unsigned gpio)

3:gpiochip_add:向內核注冊gpio

int gpiochip_add(struct gpio_chip *chip)

4:gpio_request_one ?申請gpio

int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)

5:gpio_request_one申請gpio

int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)

6:gpiochip_is_requested:用來看gpio是否已經使用

const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset)

7:gpio_direction_input :設置gpio輸入

int gpio_direction_input(unsigned gpio)

8:gpio_direction_output:gpio輸出

int gpio_direction_output(unsigned gpio, int value)

9:__gpio_get_value :獲取寄存器的值 ? ?這里注意由于前面加了__是內核用的函數所以我們不能用這個函數

在/arch/arm/mach-s5pv210/include/mach/gpio.h中定義了以下宏;所以我們使用的時候直接包含這個頭文件使用gpio_get_value 函數即可

#define gpio_get_value __gpio_get_value
#define gpio_set_value __gpio_set_value
#define gpio_cansleep __gpio_cansleep
#define gpio_to_irq __gpio_to_irq

int __gpio_get_value(unsigned gpio)

10:__gpio_get_value :設置寄存器的值

int __gpio_get_value(unsigned gpio)

http://blog.csdn.net/tongxinv/article/details/54790792

---------------------------------------------------------------------------------------------------------------------------------

代碼實戰:

?

轉載于:https://www.cnblogs.com/biaohc/p/6652322.html

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

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

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