前面訪問gpio的方法:
request_mem_region申請gpio暫存器的物理記憶體區
ioremap實現io記憶體的動態對映,得到虛擬位址
訪問虛擬位址進而控制硬體
後面的簡單的gpio訪問方法:
gpio是嵌入式平台最常見的乙個硬體模組,所以linux核心將gpio的訪問過程封裝成了標準的介面函式,這些介面函式在呼叫的時候和平台無關的,平常使用iowrite32、ioread32等這些函式有以下優缺點:
優點:能夠對申請到暫存器資源進行訪問,例如gpio暫存器、串列埠暫存器、adc暫存器、i2c暫存器等。
缺點:針對gpio配置與控制有點繁瑣。
因此,gpio標準介面函式就解決了iowrite32與ioread32的缺點,操作gpio更加的簡單。
#include
//linux自帶的
#include
//晶元廠商提供的
單個gpio的申請和釋放
gpio使用之前先申請
int
gpio_request
(unsigned gpio,
const
char
*label)
;
引數:
gpio,引腳的編號,依賴於晶元廠商提供的源**,沒有唯一的。
label:自定義引腳的名字,用於除錯資訊列印,gpio_request函式體裡面有以下**:
int
gpio_request
(unsigned gpio,
const
char
*label)
返回值:
成功,0
失敗,錯誤碼
2. 單個gpio的釋放(gpio使用之後需要釋放)
void gpio_free(unsigned gpio);
引數:引腳的編號
配置gpio為輸出模式
int
gpio_direction_output
(unsigned gpio,
int value)
;
引數:
gpio,引腳的編號
value,1 輸出高電平;0 輸出低電平
返回值:
成功,0
失敗,錯誤碼
配置gpio為輸入模式
int
gpio_direction_input
(unsigned gpio)
;
引數:
gpio,引腳的編號
返回值:
成功,0
失敗,錯誤碼
設定gpio的輸出值
void
gpio_set_value
(unsigned gpio,
int value)
;
引數:
gpio,引腳的編號
value,1 輸出高電平;0 輸出低電平
獲取gpio的輸入值
int
gpio_get_value
(unsigned gpio)
;
引數:
gpio,引腳的編號
返回值:
引腳的電平
注意:上述這些函式是通用的,是與平台無關的。
原始碼路徑:drivers/char/humity/gec6818_humity.c
關鍵**
#define cfg_io_x6818_humity (pad_gpio_c + 29)
static
int __init gec6818_humidity_dev_init
(void
)gpio_direction_output
(cfg_io_x6818_humity,1)
; ret =
misc_register
(&gec6818_humidity_dev)
;printk
(device_name"\tinitialized\n");
return ret;
}
gpio號是與硬體相關的
每個gpio都有乙個gpio口號的,使用gpio口號還識別/區分乙個具體的gpio。gpio號是與硬體相關的。
gpio號的定義
/kernel/arch/arm/plat-s5p6818/common/cfg_type.h
enum
;
例子:
d8 --
-> gpioc17 --
->pad_gpio_c+
17d9 --
-> gpioc8 --
->pad_gpio_c+
8d10 --
-> gpioc7 --
->pad_gpio_c+
7d11 --
-> gpioc12 --
->pad_gpio_c+
12
注意:使用裝置樹的方法來操作的方法如下:
關鍵**:
/* gpioled裝置結構體 */
struct gpioled_dev
;struct gpioled_dev gpioled;
/* led裝置 */
/* 1、獲取裝置節點:gpioled */
gpioled.nd =
of_find_node_by_path
("/gpioled");
/* 2、 獲取裝置樹中的gpio屬性,得到led所使用的led編號 */
gpioled.led_gpio =
of_get_named_gpio
(gpioled.nd,
"led-gpio",0
);/* 3、設定gpio1_io03為輸出,並且輸出高電平,預設關閉led燈 */
ret =
gpio_direction_output
(gpioled.led_gpio,1)
;
這一點非常重要!!!
很多初次接觸裝置樹的驅動開發人員很容易因為這個小問題栽了大跟頭!因為我們所使用的裝置樹基本都是在半導體廠商提供的裝置樹檔案基礎上修改而來的,而半導體廠商提供的裝置樹是根據自己官方開發板編寫的,很多 pin 的配置和我們所使用的開發板不一樣。比如 a 這個引腳在官方開發板接的是 i2c 的 sda,而我們所使用的硬體可能將 a 這個引腳接到了其他的外設,比如 led 燈上,接不同的外設,a 這個引腳的配置就不同。乙個引腳一次只能實現乙個功能,如果a引腳在裝置樹中配置為了i2c的sda訊號,那麼a引腳就不能再配置為gpio,否則的話驅動程式在申請 gpio 的時候就會失敗。檢查 pin 有沒有被其他外設使用包括兩個方面:
①、檢查 pinctrl 設定。
②、如果這個 pin 配置為 gpio 的話,檢查這個 gpio 有沒有被別的外設使用。
在本章實驗中 led 燈使用的 pin 為 gpio1_io03,因此先檢查 gpio_io03 這個 pin 有沒有被其他的 pinctrl 節點使用,在 imx6ull-alientek-emmc.dts 中找到如下內容:
示例** 45.4.1.3 pinctrl_tsc 節點
480 pinctrl_tsc: tscgrp
;
pinctrl_tsc 節點是 tsc(電阻觸控螢幕介面)的 pinctrl 節點,從第 484 行可以看出,預設情況下gpio1_io03 作為了 tsc 外設的 pin。所以我們需要將第 484 行遮蔽掉!和 c 語言一樣,在要遮蔽的內容前後加上「/」和「/」符號即可。其實在 i.mx6u-alpha 開發板上並沒有用到 tsc介面,所以第 482~485 行的內容可以全部遮蔽掉。因為本章實驗我們將 gpio1_io03 這個 pin 配置為了 gpio,所以還需要查詢一下有沒有其他的外設使用了 gpio1_io03,在 imx6ull-alientek-emmc.dts 中搜尋「gpio1 3」,找到如下內
容:
示例** 45.4
.1.4 tsc 節點
723&tsc
;
Linux驅動 GPIO標準介面函式
include 申請gpio介面函式 void gpio request unsigned gpio const char label 引數說明 gpio 引腳的編號。label 自定義引腳的名字。gpio釋放函式 void gpio free unsigned gpio 引數說明 gpio 引腳的...
linux kernel操作GPIO函式
include int gpio request unsigned gpio,const char label 功能 申請乙個gpio 引數 gpio 管腳號 label 管腳名,可以為空 null 返回值 成功返回0,失敗返回錯誤碼 int gpio direction output unsign...
核心GPIO操作庫函式
gpio request int gpio,char name 函式作用 明確 硬體gpio對於核心來說像記憶體一樣,都是一種寶貴的資源,所以如果軟體要訪問,首先應該向核心去申請硬體gpio資源 明確 每乙個硬體gpio由廠家定義好了乙個名稱,例如gpc0 3,但是在核心中,核心會重新給這個硬體gp...