天天看點

Kernel 中的 GPIO 定義和控制

最近要深一步用到GPIO口控制,寫個部落格記錄下Kernel層的GPIO學習過程!

一、概念

     General Purpose Input Output (通用輸入/輸出)簡稱為GPIO,或 總線擴充器。也就是晶片的引腳,當微控制器或晶片組沒有足夠的I/O端口,或當系統需要采用遠端串行通信或控制時,GPIO産品能夠提供額外的控制和監視功能。通常在ARM裡,所有I/O都是通用的,

每個GPIO端口包含8個管腳,如PA端口是PA0~PA7,而且GPIO口至少有兩個寄存器,即"通用IO控制寄存器"與"通用IO資料寄存器"。資料寄存器的各位都直接引到晶片外部,而對這種寄存器中每一位的作用,即每一位的信号流通方向,則可以通過控制寄存器中對應位獨立地加以設定。比如,可以設定某個引腳的屬性為輸入、輸出或其他特殊功能。

常用的應該是:高阻輸入、推挽輸出、開漏輸出。

通俗了解為 :

高阻輸入—— 保持高阻抗狀态,徹底斷開輸出,避免幹擾,對總線狀态不起作用,此時總線可由其他器件占用。

推挽輸出——可以輸出高,低電平,連接配接數字器件。

開漏輸出——輸出端相當于三極管的集電極. 要得到高電平狀态需要上拉電阻才行。

軟體上就是通過設定IO口的模式,然後控制IO的上拉下拉,寫入對應寄存器,通過寄存器控制電路:

上拉寄存器是控制對應端口上拉使能(DE)的。當對應位為0時,設定對應引腳上拉使能,為1時,禁止對應引腳上拉使能。如果上拉寄存器使能,無論引腳功能寄存器如何設定(輸入,輸出,資料,中斷等),對應引腳輸出高電平。

上拉是一個電阻接到一個電壓,其實就是增強IO的驅動能力,IO口是高電平。

下拉是一個電阻接到地,保證IO口是低電平。

二、kernel層調用接口實作

GPIO操作,在Kernel 2.6.32版本以上提供了gpio口管理的庫檔案/kernel/drivers/gpio/gpiolib.c,裡面就是我們需要的接口函數實作!

幾個主要的方法:

申請一個pin腳作為gpio口,命名為 * label,如果經過判斷空閑的 申請成功了做一些初始的bit位設定。

釋放這個gpio口,還原bit。

設定gpio口為輸入模式:

其中的chip->direction_input(chip, gpio)為實作!

設定gpio口為輸出模式 value為初始值 0為高電平/1為低電平:

其中的chip->direction_output(chip, gpio, value)為實作!

設定gpio口的值:

擷取gpio口的值:

 對于有些挂載在I2C,SPI總線上的擴充GPIO,讀寫操作可能會導緻睡眠,是以不能在中斷函數中

  使用。使用下面的函數以差別于正常的GPIO

三、gpiolib.c關聯晶片接口

以上為gpiolib.c的基本方法都是向下調用到對應晶片的gpio實作!

是以每個方法裡面的實作都是通過 struct gpio_chip*chip 這個指針調用結構體中關聯的相關接口!

下面是gplolib怎麼關聯到特定的晶片(mach-at91)的幾個主要方法:

mach-at91的/kernel/arch/arm/mach-at91/gpio.c中的

gpiolib.c中的接口與mach-at91函數接口對應關系如下:

從上面可以看到 在gpiolib.c中的方法調用晶片(mach-at91)的映射關系:

比如:gpio_direction_output() 設定gpio口為輸出模式中最終的實作調用chip->direction_output(chip, gpio, value)。

從上面可以看出來,也就是調用mach-at91的at91_gpiolib_direction_output()!

其它的類似。

gpiolib.c中的

添加到結構體:

這就儲存到了 chip 指針。

這一部分在Kernel初始化的時候調用執行!

四、晶片(mach-at91)gpio口的接口

由gpiolib.c根據映射調用對應接口

定義為輸出模式,初始設定val 上拉還是下拉 , 寫入資料寄存器。

同樣設定為輸入:

設定GPIO口的value 值 0或者1,已經設定為輸出模式下:

讀寄存器擷取該GPIO口的值:

大體流程就這樣了。

繼續閱讀