GPIO:通用输入输出端口。
gpio的基本输出功能由STM32控制引脚输出高、低电平,实现开关控制。
最基本的输入功能是检测外部输入电平
gpio工作模式:
输入模式:上拉/下拉/浮空。在输入模式中,施密特触发器打开,输出被禁止。数据寄存器每隔1个AHB1时钟周期更新一次,可通过输入数据寄存器GPIOx_IDR读取I/O状态。其中AHB1的时钟默认为180MHz。
输出模式:输出使能,推免模式时双mos管方式工作。输出数据寄存器GPIOx_ODR控制I/O输出高低电平。输出速度可配置,有2/25/50/100MHz。ODR寄存器对应引脚的位为0。
复用功能:输出使能,GPIOx_ODR 无效。输入可用。
模式输入输出:双mos管结构关闭,其他外设通过墨迹通道进行输入输出。
推免:
高电平 P-MOS导通,低电平N-MOS导通
输入电压5v,输出电压3.3v
开漏:
高电平P-MOS不工作,N-MOS管关闭
低电平N-MOS导通,P-MOS管不工作
输入电压5v,输出电压5v
推免电路和推免结构:
推免结构是指两个参数相同的三极管或MOS管分别受两互补信号的控制,总在一个三极管或MOS管导出的时候另一个截至。
推免电路是两个参数相同的三极管或MOSFET,以推免的方式存在于电路中。
相关硬件差异有:
和CPU的连接方式不同。SOC的GPIO controller是通过SOC(片上系统,芯片集成)的总线连接到CPU的。对于嵌入式系统而言,除了SOC的IO port,一些外设(有些key controller芯片,codec或者PMU的芯片,有些专用的IO expander可以扩展16个或32个GPIO)也提供。CPU和IO expander通过I2C连接,访问SOC之外的GPIO需要I2C 的操作,控制SOC上的GPIO只需要写寄存器的操作。
访问方式不同。GPIO controller有的会提供一个寄存器控制输出电平,有的会提供两个。
配置方式不同。在一个系统上配置为输出,在另外上可能配置为输出。
GPIO特性不同(是否能触发中断,该GPIO能否将CPU从sleep状态唤醒,有些有软件可控的上拉或者下拉电阻的)
多功能复用(SOC的某个GPIO除了作为一个普通IO pin脚,还可以时SPI上的clock信号线)
操作GPIO可能导致sleep,同步机制不能采用spinblock(spinlock要求不能sleep)
GPIO controller的相关寄存器
有些硬件逻辑和IO port本身功能设定相关,可称为pin controller。软件通过设定pin controller可以实现引脚功能配置,引脚特性配置(如pull-up/down电阻的设定)。
如果一组GPIO被配置为SPI(串行外设接口),pin脚被连接到了SPI controller,如果配置成GPIO,那么控制引脚的是GPIO controller。通过访问GPIO controller,软件可以配置GPIO的方向,如果是输出可以配置high level或者low level,如果是输入可以获取GPIO引脚上的电平状态。
通过访问GPIO type的中断控制器的寄存器,软件可以中断的enable和disable(mask和unmask),可以触发方式,可以中断状态清除。
新linux kernel的GPIO subsystem则用三个软件模块来对应上面三类硬件功能:pin control subsystem(驱动pin controller硬件的软件子系统),GPIO subsystem(驱动GPIO controller硬件的软件子系统),GPIO interrupt chip driver(模块作为一个interrupt subsystem中的一个底层硬件驱动模块存在。)
底层的pin controller driver是硬件相关的模组,初始化时向pin control core模块注册pin control设备。pin control core模块是一个硬件无关模块,仅仅从用户角度给出了top level的接口函数。
pin controller driver代码分析
主要功能包括:
管理系统中所有可以控制的pin,系统初始化时,枚举所有可以控制的pin并标识。
pin multiplexing(嵌入式处理器提供功能)。管理pin的复用。对于SOC,引脚除了配置成普通的GPIO之外,若干个引脚可以组成一个pin group,形成特定的功能。pin control subsystem要管理所有的pin group。
pin configuration(配置参数包括pull-up/down电阻的设定,tri-state设定,driver-strength的设定)
pin controller相关DTS描述
在pin controller node中定义pin configuration,目的是为了让client device(使用pin controller subsystem提供服务的那些设备)引用。SOC的pin controller的pin configurations包括两类,一类是定义pin bank,另一类时定义功能复用配置。
pin configuration定义
pin configuration是pin controller的child node,描述client device使用的一组pin配置信息。
#gpio-cells属性是一个GPIO controller的属性,描述需要多少个cell描述一个GPIO。
samsung,pin定义了一个pin configuration所设计的引脚定义。
pinctrl-names定义了一个pin state(使用一组pin,同时处于某种状态,始于一个具体的设备功能)。state的定义和电源管理关系密切。state有两种(一种是pinctrl-names定义的字符串列表,一种是ID)。
pinctrl-x是一个句柄(phandle)列表,每个句柄指向一个pin configuration。
pin controller driver初始化
1 注册pin control device
reg属性描述pin controller硬件的地址信息,compatible属性用来描述pin controller的programming model。该属性的值是string list,每个string是一个model。这些字符串列表被操作系统用来选择哪一个pin controller driver来驱动该设备。
软件提供一个方案将各种硬件信息(total有多少个可控的pin,多少bank,pin的复用情况以及pin的配置情况)注册到pin control subsystem
2 注册pin controller driver
__init samsung_pinctrl_drv_register
platform_driver_register()
3 probe过程(driver初始化过程)
bus、driver、device。对于platform类型的bus,铁三角数据(platform_bus_type、struct platform_device、struct platform_driver)。将driver注册到系统,剩余交给统一设备模型完成。
每增加一个platform_driver,platform_bus_type都会启动scan过程,让新加入的driver扫描整个platform bus上的device链表,看是否有device让该driver驱动。
各个具体硬件的pin controller可能各不相同,但是可以抽取拥有共同的部分来形成一个HW independent的数据结构,这个数据就是pin controller描述符,在core driver中用struct pinctrl_desc表示。
初始化过程核心是low level的driver定义一个pinctrl_desc,设定pin的相关定义和callback函数,注册到pin control subsystem。用引脚描述符描述一个pin。在pin control subsystem,struct pinctrl_pin_desc(引脚描述符)用来描述一个可以控制的引脚。
struct device基类,struct pinctrl_dev和struct platform_device是派生类。
对于SOC,其引脚除了配置成普通GPIO外,若干个引脚组成pin group。
pin bank的信息只能封装在low level的samsung pin controller driver中。
ctrl -> base表示本pin controller中的pin ID的起始值。
gpiolib_register函数九十八各个bank代表的gpio chip注册到GPIO subsystem。pinctrl_register函数的主要功能是将本pin controller注册到pin controller subsystem。
pin controller描述符包含三类操作函数:pctlops是全局控制函数,pmxops是复用引脚相关的操作函数,confops操作函数是配置引脚的特性(pull-up/down)。