您的位置:首页 > 其它

驱动开发之gpiolib库的学习及使用

2017-05-17 22:12 351 查看
1.goio库的作用:由于GPIO口较多,当编程人员调用使用GPIO时难免发生不同驱动使用同一个GPIO的情况,因此内核便采用gpio库去帮助统一管理gpio。

2.学习思路:a.了解驱动框架的设置,在内核中提供的接口和在厂商芯片代码的接口。b.以一条主线的方式去追gpio的建立过程,中间涉及的零碎信息也要搞清楚但不要丢失主线。c.区分各结构体信息和作用。d.培养架构思想,因为越复杂的驱动也会有越复杂的架构思想在里面,包含许多软硬件知识。

3.gpio在内核中的建立(以S5PV210为参考):

a.函数s5pv210_gpiolib_init首先设置结构体:





如图为类型为s3c_gpio_chip的结构体数组。其中每一个表示一个GPIO端口的抽象表现,.base返回一个端口的编号,.ngpio接收一个宏,记录该端口的IO口数量,.lable为端口名,.to_irq接收换算得来的中断号。

部分端口在.chip为还有.base(记录端口的起始地址)和.config(配置)等。

for循环将未配置的结构体设为默认配置,将未提供端口起始地址的数组提供起始地址。其中的偏移量为ox20(可对照数据手册验证)。

b.调用samsung_gpiolib_add_4bit_chips函数。

从函数名即可看出此函数由芯片商提供,4bit表示当前的gpio为4位为一IO引脚设置,S5PV210和未来的趋势也均为向4bit方向发展,而2440等采用的为2bit为一引脚的设置。

该函数依次调用函数samsung_gpiolib_add_4bit2(chip)和s3c_gpiolib_add(chip);

samsung_gpiolib_add_4bit2(chip) :设置结构体中的direction_input和direction_output函数,即输入模式和输出模式。

在设置的函数中,首先用了container_of的宏去通过该结构体在s3c_gpio_chip的地址信息反推的得到.chip外的.base的起始地址信息(在上面介绍过),通过这样获得端口起始地址去读寄存器信息,位或更改数值后再写入。这便是我们熟悉的“读写改”三部曲。

s3c_gpiolib_add :检验之前是否初始换输出和输入,若没有采用默认值(追进去发现默认值为2440的方式,即2bit为一个IO口的设置)。由进行了get和set的默认设置。

直到这里便完成了所有gpio的初始化设置,但还没有完成真正的注册。

4.注册:

注册实际上就是gpiochip_add函数将我们完成的整个结构体信息挂接到内核gpio模块的一个gpio_desc数组中去。

从该函数名也可看出这是内核提供的驱动框架,即各家芯片厂商通用的用于向内核注册的接口。

5.驱动框架角度的分析:

4000

之前的函数介绍均为芯片商与内核之间去建立联系。而我们去使用这些则需要gpio_request(gpio申请)、gpio_free(gpio释放)、 gpio_request_one(申请并设置输入输出)、 gpiochip_is_requested(判断gpio是否被成功申请)、 gpio_direction_input/output(设置输入输出模式)等函数对gpio达到操作的目的。、

以上这些函数本身并不直接操控硬件,而是调用芯片商提供的函数去操控。

gpiolib的建立过程还涉及一些电源管理、自旋锁、睡眠唤醒等设置,详见内核代码吧。

涉及的代码目录大多在arm/arm/mach-s5pv210下,可自行查找。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: