linux内核中的GPIO系统之(1):软件框架
一、前言
作为一个工作多年的系统工程师,免不了做两件事情:培训新员工和给新员工分配任务。对于那些刚刚从学校出来的学生,一般在开始的时候总是分配一些非常简单的任务,例如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 interface)。pin control core模块是一个硬件无关模块,它抽象了所有pin controller的硬件特性,仅仅从用户(各个driver就是pin control subsystem的用户)角度给出了top level的接口函数,这样,各个driver不需要关注pin controller的底层硬件相关的内容。
2、GPIO subsystem block diagram
下图描述了GPIO subsystem的模块图:
基本上这个软件框架图和pin control subsystem是一样的,其软件抽象的思想也是一样的,当然其内部具体的实现不一样,我们会在后续的文章中描述。
原创文章,转发请注明出处。蜗窝科技。http://www.wowotech.net/io-port-control.html
linux内核中的GPIO系统之(1):软件框架的更多相关文章
- Linux内核中的GPIO系统之(3):pin controller driver代码分析
一.前言 对于一个嵌入式软件工程师,我们的软件模块经常和硬件打交道,pin control subsystem也不例外,被它驱动的硬件叫做pin controller(一般ARM soc的datash ...
- Linux内核中的GPIO系统之(3):pin controller driver代码分析--devm_kzalloc使用【转】
转自:http://www.wowotech.net/linux_kenrel/pin-controller-driver.html 一.前言 对于一个嵌入式软件工程师,我们的软件模块经常和硬件打交道 ...
- linux内核中的GPIO系统之(2):pin control subsystem
一.前言 在linux2.6内核上工作的嵌入式软件工程师在pin control上都会遇到这样的状况: (1)启动一个新的项目后,需要根据硬件平台的设定进行pin control相关的编码.例如:在b ...
- 向linux内核中添加外部中断驱动模块
本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内 ...
- Linux内核中SPI总线驱动分析
本文主要有两个大的模块:一个是SPI总线驱动的分析 (研究了具体实现的过程): 另一个是SPI总线驱动的编写(不用研究具体的实现过程). 1 SPI概述 SPI是英语Serial Peripheral ...
- Linux内核驱动之GPIO子系统(一)GPIO的使用【转】
转自:http://blog.csdn.net/tommy_wxie/article/details/9427047 一 概述 Linux内核中gpio是最简单,最常用的资源(和 interrupt ...
- Linux内核驱动之GPIO子系统API接口概述
1.前言 在嵌入式Linux开发中,对嵌入式SoC中的GPIO进行控制非常重要,Linux内核中提供了GPIO子系统,驱动开发者在驱动代码中使用GPIO子系统提供的API函数,便可以达到对GPIO控制 ...
- Linux 内核中的 Device Mapper 机制
本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...
- Linux内核驱动之GPIO子系统(一)GPIO的使用
转自:http://blog.csdn.net/mirkerson/article/details/8464290 一 概述 Linux内核中gpio是最简单,最常用的资源(和 interrupt , ...
随机推荐
- 动态时间规整(DTW) 转载
Dynamic Time Warping(DTW)诞生有一定的历史了(日本学者Itakura提出),它出现的目的也比较单纯,是一种衡量两个长度不同的时间序列的相似度的方法.应用也比较广,主要是在模板匹 ...
- 给uefi引导的方式安装archlinux
基本就是照着官方的wiki来的,不过官方的wiki的内容太杂了,或许我们需要的是一个瀑布似的流程. 其实大体上与mbr引导的方式类似,只凭借回忆说一下有区别的地方,等下一次有机会的时候再验证一下. 换 ...
- java 网络编程(四)----UDP进阶篇聊天小程序
设计要求:单线程模式,客户端只发送数据,数据的来源为键盘录入,服务器端只接收数据,当客户端发送886的时候,客户端和服务器端都退出. 1. 发送端: public class Send impleme ...
- Mysql 的存储引擎,myisam和innodb的区别
MyISAM 是非事务的存储引擎,innodb是支持事务的存储引擎. innodb的引擎比较适合于插入和更新操作比较多的应用,而MyISAM 则适合用于频繁查询的应用 . MyISAM --表锁,in ...
- Yii2.0 查询(CRUD)
yii2使用中的一些基本的增删改查操作.以用户为例说明: User::find()->all(); //返回所有用户数据: User::findOne($id); //返回 主键 ...
- iOS的第一个习作
首发:个人博客,更新&纠错&回复 代码在这里,对git还是使用不熟练,好在github新建项目后体贴地提示是不是要执行这样两句—— 这两句我肯定是背不住的,所以记一下. git rem ...
- makefile 中 $@ $^ %< 使用【转】
转自:http://blog.csdn.net/kesaihao862/article/details/7332528 这篇文章介绍在LINUX下进行C语言编程所需要的基础知识.在这篇文章当中,我们将 ...
- Java常见编码方式简介
计算机只能识别二进制数据,早期由来是电信号. 为了方便应用计算机,让它可以识别各个国家的文字. 就将各个国家的文字用数字来表示,并一一对应,形成一张表. ASCII:美国标准信息交换码. 用一个字节的 ...
- (转载)CSV 文件处理 PERL
http://cn.perlmaven.com/how-to-read-a-csv-file-using-perl http://search.cpan.org/~hmbrand/Text-CSV_X ...
- React Native 开发笔记
ReactNativeDemo 学习ReactNative开发,搭建ReactNative第一个项目 React Native 开发笔记 1.安装Homebrew $ /usr/bin/ruby -e ...