十二、linux GPIO初始化
一、如何查看LINUX內核
? ? ? ? 很多人說學習linux最好的方法是看內核源碼,那怎么看呢?總不能通篇看吧,那猴年馬月都看不完。現在我就教大家一個辦法(以GPIO為例):
????????在內核源碼目錄下使用命令“ls drivers/gpio/*.o”,可以看到“gpioexynos4”被編譯進了內核
????????????????– 生成.o文件代表最終被編譯進了內核
????????????????– 除了menuconfig配置文件,還可以通過.o文件來判定該文件是否編譯進了內核,編譯進內核的才是我們需要看的。
在“gpio-exynos4.c”文件最下面一行
????????– core_initcall(exynos4_gpiolib_init);
????????– core_initcall代表在linux初始化過程中會調用
????????– 初始化函數是在源碼目錄下“include/linux/init.h”文件中定義的,該頭文件中定義了一系列的初始化函數,在linux啟動的過程中會按等級。
初始化函數調用了“exynos4_gpiolib_init”
在該函數中引用了chip = exynos4_gpio_common_4bit結構體
?
結構體exynos4_gpio_common_4bit
?宏定義EXYNOS4_GPL2(0)分析
– EXYNOS4_GPL2(_nr)? (EXYNOS4_GPIO_L2_START + (_nr))
– 枚舉GPIO
– EXYNOS4_GPIO_L2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L1)
– EXYNOS4_GPIO_NEXT宏定義
– #define EXYNOS4_GPIO_NEXT(__gpio) \ ((__gpio##_START) + (__gpio##_NR)
+ CONFIG_S3C_GPIO_SPACE + 1)
?S5P_VA_GPIO2
????????– 虛擬地址
? 查找S5P_VA_GPIO2宏定義,可以看到所有的GPIO被分為4個bank,這個和datasheet上面是一致的。
????????– S5P_VA_GPIO1
????????– S5P_VA_GPIO2 S3C_ADDR(0x02240000)
????????– S5P_VA_GPIO3
????????– S5P_VA_GPIO4
? 查找到S3C_ADDR宏定義
????????– #define S3C_ADDR(x) (S3C_ADDR_BASE + (x))
? 查找到S3C_ADDR_BASE宏定義,這是一個虛擬地址,可以看出,地址范圍超出了1G或者2G內存的范圍
????????– #define S3C_ADDR_BASE 0xF6000000
物理地址和虛擬地址的映射關系
? 虛擬地址和物理地址映射
????????– 虛擬地址一般很好查找,一般在平臺相關gpio的文件中就可以找到宏定義
? 在source insight中搜索關鍵字“S5P_VA_GPIO2”,看看那里用到了這個宏定義。搜索時間會比較長,1-5分鐘吧。
? 搜索出來之后,可以看到除了gpio-exynos4.c文件中使用,cpu-exynos中也使用了,這是一個平臺文件
查找到宏定義EXYNOS4_PA_GPIO2
– #define EXYNOS4_PA_GPIO2? ? 0x11000000
– 這個物理地址0x11000000就是CPU手冊上面的實際地址
二、 GPIO的初始化流程
? 初始化過程簡單描述
????????– 平臺文件分別定義好物理地址和虛擬地址
????????– 物理地址和虛擬地址之間映射
? 在初始化中,引入了程序員需要使用的GPIO宏定義,并將宏定義裝入chip結構體中
?
三、GPIO的調用函數
?? 例如頭文件gpio-cfg.h中s3c_gpio_cfgpin函數。這個函數是給GPIO做配置,第一個參數是宏EXYNOS4_GPL2(0),第二個是配置的狀態參數
????????– 配置頭文件在arm/arm/plat-samsung/include/plat/gpio-cfg.h
? 查找該函數,可以看到進入函數就會調用chip結構體
????????– s3c_gpiolib_getchip,這個函數通過pin調用之后,會返回s3c_gpios[chip] 的參數
????????– exynos4_gpio_common_4bit[]和s3c_gpios都是結構體s3c_gpio_chip類型的數據
????????– 然后計算偏移地址等等一系列操作,這一部分是linux內核以及三星平臺完成的,具體細節不用管。
? 也就是我們控制GPIO的時候,可以通過GPIO的一些處理函數加上類似EXYNOS4_GPL2(0)的宏定義,就可以操作GPIO
? 后面再具體介紹GPIO操作中,常用函數的使用
?
四、常見問題
? 不是說好的分頁大小要一樣,怎么GPIO經過mmu處理的時候,又有SZ_256又有SZ_4K?
????????– 實際上CPU查找地址的時候,仍舊是通過內存。mmu本身不保存具體的數據,主要是提供一個虛擬地址和物理地址的表格,表格中還有字段的長度。這個分頁和mmu沒什么關系,是CPU內存以及物理地址之間通信使用的概念。這個只是一個抽象的概念,理解mmu只是一個表格,CPU對GPIO的操作就很好理解了。
?
? 內部寄存器不是很快么,CPU為什么不直接讀取?
????????– 內部寄存器是很快,但是相對于CPU還是非常慢。CPU處理數據是將內存中一大段一大段處理,如果單個的讀取內部寄存器的值,對CPU是極大的浪費。把內部寄存器也看成“特殊的物理地址”即可。
? 只講了虛擬地址和物理地址對應數組,怎么沒介紹哪里調用了?
????????– 大家可以看一下函數ioremap,linux會調用這個函數來實現gpio的映射關系
????????– 今天講的已經夠多夠深入了,大家只要能夠理解這么一層意思就可以了,這個東西對我們實際寫驅動的幫助其實不是那么大!
? 如果我還是理解不了“對宏定義EXYNOS4_GPL2(0)的操作就是對4412芯片管腳AC21寄存器的操作”,怎么辦?
????????– 記住這個結論,能夠將宏變量EXYNOS4_GPL2(0)和GPL這一組GPIO的第0位寄存器聯想起來。
????????– 后面跟著我依葫蘆畫瓢,不影響大家實際寫程序,有興趣再回過頭理解
總結
以上是生活随笔為你收集整理的十二、linux GPIO初始化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 十一、linux物理地址虚拟地址
- 下一篇: 十二、linux LED初始化