zoukankan      html  css  js  c++  java
  • 迅为4412开发板Linux驱动教程之GPIO的初始化

    视频下载地址:http://pan.baidu.com/s/1c06oiti

    GPIO的初始化

    • 在内核源码目录下使用命令“ls drivers/gpio/*.o”,可以看到“gpio-exynos4”被编译进了内核

    – 生成.o文件代表最终被编译进了内核

    – 除了menuconfig配置文件,还可以通过.o文件来判定该文件是否编译进了

    内核

    • 在“gpio-exynos4.c”文件最下面一行

    – core_initcall(exynos4_gpiolib_init);

    – core_initcall代表在linux初始化过程中会调用

    – 初始化函数是在源码目录下“include/linux/init.h”文件中定义的,该头文件

    中定义了一系列的初始化函数,在linux启动的过程中会按等级

    结构体exynos4_gpio_common_4bit

    • 以有带有label= "GPL2"的结构体为例

     

    • .base = (S5P_VA_GPIO2 + 0x100)

    – 表示偏移地址和虚拟地址相加

    • .eint_offset = 0x20

    – 表示中断部分,介绍中断的时候再讲(IO口可以配置为中断模式)

    • .group = 22

    – 给GPIO分组

    • chip.base = EXYNOS4_GPL2(0),

    – 宏定义EXYNOS4_GPL2(0)赋值给初始化函数

    • chip.ngpio = EXYNOS4_GPIO_L2_NR

    – 表示这一小组中有几个GPIO

    • chip.label = "GPL2",

    – 程序员需要关心的标志

    • 宏定义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)

    • GPIO的数量EXYNOS4_GPIO_L2_NR

    – 可以通过手册查到

    • S5P_VA_GPIO2

    – 虚拟地址

    • 查找S5P_VA_GPIO2宏定义,可以看到所有的GPIO被分为4bank,这

    个和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

    中也使用了,这是一个平台文件

     

    • 映射数组如下图所示

     

    • 结构体解释

    – .virtual = (unsigned long)S5P_VA_GPIO2,表示虚拟地址

    – .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO2),表示物理地址

    – .length = SZ_4K,表示映射的宽度

    – .type = MT_DEVICE,

    • 查找到宏定义EXYNOS4_PA_GPIO2

    – #define EXYNOS4_PA_GPIO2 0x11000000

    – 这个物理地址0x11000000就是

    GPIO的初始化流程

    • 初始化过程简单描述

    – 平台文件分别定义好物理地址和虚拟地址

    – 物理地址和虚拟地址之间映射

    • 在初始化中,引入了程序员需要使用的GPIO宏定义,并将宏定义装入

    chip结构体中

    GPIO的调用函数

    • 例如头文件gpio-cfg.hs3c_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只是一个表格,CPUGPIO

    的操作就很好理解了。

    • 内部寄存器不是很快么,CPU为什么不直接读取?

    – 内部寄存器是很快,但是相对于CPU还是非常慢。CPU处理数据是将内存

    中一大段一大段处理,如果单个的读取内部寄存器的值,对CPU是极大的

    浪费。把内部寄存器也看成“特殊的物理地址”即可。

    • 只讲了虚拟地址和物理地址对应数组,怎么没介绍哪里调用了?

    – 大家可以看一下函数ioremaplinux会调用这个函数来实现gpio的映射关

    – 今天讲的已经够多够深入了,大家只要能够理解这么一层意思就可以了

    ,这个东西对我们实际写驱动的帮助其实不是那么大!

    • 如果我还是理解不了“对宏定义EXYNOS4_GPL2(0)的操作就是对4412

    片管脚AC21寄存器的操作”,怎么办?

    – 记住这个结论,能够将宏变量EXYNOS4_GPL2(0)GPL这一组GPIO的第0

    寄存器联想起来。

    – 后面跟着我依葫芦画瓢,不影响大家实际写程序,有兴趣再回过头理解

  • 相关阅读:
    jQuery UI draggable+droppable+resizable+selectable+sortable
    jQuery获取Select选择的Text和 Value(转)
    跨终端跨域的存储方案
    innerHTML 的坑
    几种Css前端框架资料
    分享一个前端框架 builive
    为什么要使用CDN?
    AliCDN,盛开在云端的花朵
    java 和 C# 的访问权限
    线程queue 事件event 协程
  • 原文地址:https://www.cnblogs.com/topeet/p/4757595.html
Copyright © 2011-2022 走看看