十二、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位寄存器联想起来。
        – 后面跟着我依葫芦画瓢,不影响大家实际写程序,有兴趣再回过头理解

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello Jason

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值