一、前言
作為乙個工作多年的系統工程師,免不了做兩件事情:培訓新員工和給新員工分配任務。對於那些剛剛從學校出來的學生,一般在開始的時候總是分配一些非常簡單的任務,例如gpio driver、led driver。往往cpu datasheet的關於gpio或者io ports的章節都是比較簡單的,非常適合剛入行的工程師。雖然gpio子系統相關的硬體比較簡單,沒有複雜的協議,不過,對於軟體抽象而言,其分層次的軟體思想是每個嵌入式軟體工程師需要掌握的內容。
我更傾向使用gpio系統這個名字來代替gpio driver這個名字,gpio driver僅僅包含了pin signal狀態控制和讀取的內容,而gpio系統包括了pin multiplexing、pin configuration、gpio control、gpio interrupt control等內容。本文主要是以3.14核心作為例子,講述linux kernel中gpio系統的軟體框架。
二、gpio相關硬體有哪些差異
嵌入式工程師總是要處理各種各樣的target board,每個target board上的gpio總是存在不同,例如:
1、和cpu的連線方式不同
對於arm的嵌入式硬體平台,soc本身可以提供大量的io port,soc上的gpio controller是通過soc的匯流排(amba)連線到cpu的。對於嵌入式系統而言,除了soc的io port,一些外設晶元也可能會提供io port,例如:
(1)有些key controller晶元、codec或者pmu的晶元會提供i/o port
(2)有些專用的io expander晶元可以擴充套件16個或者32個gpio
從硬體角度看,這些io和soc提供的那些io完全不同,cpu和io expander是通過i2c(也有可能是spi等其他型別的bus)連線的,在這種情況下,訪問這些soc之外的gpio需要i2c的操作,而控制soc上的gpio只需要寫暫存器的操作。不要小看這個不同,寫乙個soc memory map的暫存器非常快,但是通過i2c來操作io就不是那麼快了,甚至,如果匯流排繁忙有可能阻塞當前程序,這種情況下,核心同步機制必須有所區別(如果操作gpio可能導致sleep,那麼同步機制不能採用spinlock)。
2、訪問方式不同
soc片內的gpio controller和soc片外的io expander的訪問當然不一樣,不過,即便都是soc片內的gpio controller,不同的arm晶元,其訪問方式也不完全相同,例如:有些soc的gpio controller會提供乙個暫存器來控制輸出電平。向暫存器寫1就是set high,向暫存器寫0就是set low。但是有些soc的gpio controller會提供兩個暫存器來控制輸出電平。向其中乙個暫存器寫一就是set high,向另外乙個暫存器寫一就是set low。
3、配置方式不同
即便是使用了同樣的硬體(例如都使用同樣的某款soc),不同硬體系統上gpio的配置不同。在乙個系統上配置為輸入,在另外的系統上可能配置為輸出。
4、gpio特性不同。這些特性包括:
(1)是否能觸發中斷。對乙個soc而言,並非所有的io port都支援中斷功能,可能某些處理器只有一兩組gpio有中斷功能。
(2)如果能夠觸發中斷,那麼該gpio是否能夠將cpu從sleep狀態喚醒
(3)有些有軟體可控的上拉或者下拉電阻的特性,有的gpio不支援這種特性。在設定為輸入的時候,有的gpio可以設定debouce的演算法,有的則不可以。
5、多功能復用
有的gpio就是單純的作為乙個gpio出現,有些gpio有其他的復用的功能。例如io expander上的gpio只能是gpio,但是soc上的某個gpio除了做普通的io pin腳,還可以是spi上clock訊號線。
三、硬體功能分類
arm based soc的datasheet中總有乙個章節叫做gpio controller(或者i/o ports)的章節來描述如何配置、使用soc的引腳。雖然gpio controller的硬體描述中充滿了大量的暫存器的描述,但是這些暫存器的功能大概分成下面三個類別:
1、有些硬體邏輯是和io port本身的功能設定相關的,我們稱這個hw block為pin controller。軟體通過設定pin controller這個硬體單元的暫存器可以實現:
(1)引腳功能配置。例如該i/o pin是乙個普通的gpio還是一些特殊功能引腳(例如memeory bank上cs訊號)。
(2)引腳特性配置。例如pull-up/down電阻的設定,drive-strength的設定等。
2、如果一組gpio被配置成spi,那麼這些pin腳被連線到了spi controller,如果配置成gpio,那麼控制這些引腳的就是gpio controller。通過訪問gpio controller的暫存器,軟體可以:
(1)配置gpio的方向
(2)如果是輸出,可以配置high level或者low level
(3)如果是輸入,可以獲取gpio引腳上的電平狀態
3、如果一組gpio有中斷控制器的功能,雖然控制暫存器在datasheet中的i/o ports章節描述,但是實際上這些gpio已經被組織成了乙個interrupt controller的硬體block,它更像是乙個gpio type的中斷控制器,通過訪問gpio type的中斷控制器的暫存器,軟體可以:
(1)中斷的enable和disable(mask和unmask)
(2)觸發方式
(3)中斷狀態清除
四、如何通過軟體抽象來掩蓋硬體差異
傳統的gpio driver是負責上面三大類的控制,而新的linux kernel中的gpio subsystem則用三個軟體模組來對應上面三類硬體功能:
(1)pin control subsystem。驅動pin controller硬體的軟體子系統。
(2)gpio subsystem。驅動gpio controller硬體的軟體子系統。
(3)gpio interrupt chip driver。這個模組是作為乙個interrupt subsystem中的乙個底層硬體驅動模組存在的。本文主要描述前兩個軟體模組,具體gpio interrupt chip driver以及interrupt subsystem請參考本站其他相關文件。
1、pin control subsystem block diagram
下圖描述了pin control subsystem的模組圖:
底層的pin controller driver是硬體相關的模組,初始化的時候會向pin control core模組註冊pin control裝置(通過pinctrl_register這個bootom level inte***ce)。pin control core模組是乙個硬體無關模組,它抽象了所有pin controller的硬體特性,僅僅從使用者(各個driver就是pin control subsystem的使用者)角度給出了top level的介面函式,這樣,各個driver不需要關注pin controller的底層硬體相關的內容。
2、gpio subsystem block diagram
下圖描述了gpio subsystem的模組圖:
基本上這個軟體框架圖和pin control subsystem是一樣的,其軟體抽象的思想也是一樣的,當然其內部具體的實現不一樣,我們會在後續的文章中描述。
原創文章,**請註明出處。蝸窩科技。
linux核心中的GPIO系統之(1) 軟體框架
一 前言 作為乙個工作多年的系統工程師,免不了做兩件事情 培訓新員工和給新員工分配任務。對於那些剛剛從學校出來的學生,一般在開始的時候總是分配一些非常簡單的任務,例如gpio driver led driver。往往cpu datasheet的關於gpio或者io ports的章節都是比較簡單的,非...
Linux系統核心中判斷大小的巨集
min和max巨集 min max macros that also do strict type checking.see the unnecessary pointer comparison.define min x,y define max x,y and if you can t take ...
Linux核心中的list for each
在linux核心原始碼中,經常要對鍊錶進行操作,其中乙個很重要的巨集是list for each entry 意思大體如下 假設只有兩個結點,則第乙個member代表head,list for each entry的作用就是迴圈遍歷每乙個pos中的member子項。巨集list for each e...