Linux内核gpio

Linux内核gpio,第1张

本文基于 RockPI 4A 单板 Linux 4.4 内核介绍 RK3399 Linux GPIO 功能。

GPIO(General Purpose Input/Output Port) :通用输入输出端口。

除作为一般的输入/输出功能外,还可以配置为中断和模拟 PWM、I2C 等接口功能。

RK3399 GPIO 属性如下:

1、一共有5组 GPIO(GPIO0~4) ,每组 GPIO 为一个 Bank ,共32个引脚。每个 Bank 包括4个 Group (GPIOA(0~7) ~ D(0~7)) 。不是所有 Bank 都有 GPIOA~D 的编号, RK3399 共122个 GPIO 引脚。

2、所有 GPIO 都可被配置为 CA55或CA53 的中断功能,且 GPIO0 和 GPIO1 可用于系统低功耗唤醒模式。

3、在上电复位后,所有 GPIO 默认输入状态。

4、软件可配置 GPIO 驱动强度。

RK3399 引脚在系统中显示如下:

RK3399 GPIO 引脚号计算方式:

例:

以 ROCKPI 4A 单板 WIFI 模块电源( GPIO0_B2 )为例,介绍 DTS 中 GPIO 配置。

在系统启动后,可以查看 GPIO ,命令如下:

注:

如果debugfs没有挂载,使用下面命令挂载

Linux 内核 GPIO 主要实现文件:

GPIO 子系统有两套 API :

1、基于描述符(descriptor-based)

前缀为: gpiod_ 。

参考: Documentation/gpio/consumer.txt

2、老版本接口(legacy)

前缀为: gpio_ 。

参考: Documentation/gpio/gpio-legacy.txt

3、常用API

GPIO 还有很多接口,就不一一列举了。

RK3399 GPIO 控制器驱动实现文件: drivers/pinctrl/pinctrl-rockchip.c ,涉及主要函数:

所有 GPIO 子系统的 API 最终都会调到 SOC 的 GPIO 控制器驱动函数。

ROCKPi 4A 单板有个40个引脚的扩展口,引用 radxa 图片,见下图。

1、进入测试目录

2、导出GPIO

在使用 GPIO2_A7 前,需要导出该引脚。方法:配置 export 后,会出现 gpio71 节点。

测试时,注意不要使用在程序中已经申请过或配置为其它功能的 GPIO 引脚。

3、配置GPIO方向

设置 GPIO2_A7 的输入/输出方向。

in :表示输入。

out :表示输出。

active_low :用于中断配置中高电平或低电平有效。

edge :用于中断配置中上升沿或下降沿有效。

4、配置GPIO输出值

在 GPIO 为输入时,通过 value 查询 GPIO 的输入电平(高或低电平)。

在 GPIO 为输出时,通过 value 配置 GPIO 的输出电平(高或低电平)。

5、查看GPIO

查看已经导出的 GPIO71 。

6、取消导出

使用完 GPIO2_A7 后,需要进行释放。方法:配置 unexport 后, gpio71 节点会消失。

中断的触发来自很多地方,包括事件和信号,外部信号的触发中断有两种方式实现,GPIO和EIC,即可以将信号输入的PAD配给GPIO controller或者EIC controller,在IO function配置里面也是不同的function。

GPIO支持边沿和电平中断和边沿中断,后来的GPIO plus又增加了latch和debounce

EIC支持 debounce,latch,ASYNC和SYNC四种中断

也就是说在支持GPIO plus的平台上有8种外部中断触发方式,4种来自EIC,4种来自GPIO。但是GPIO 和EIC的时钟源不同,GPIO的时钟源来自pclk,EIC可以来自RTC,不同模式对时钟的需求也不尽相同

EIC(External Interrupt Controller)模块包括四个子模块:EIC_DBNC, EIC_LATCH, EIC_ASYNC and EIC_SYNC.

EIC_DBNC子模块提供8个源信号输入连接。有一个去抖动机制用来捕捉输入信号的稳定状态,这个子模块还引入了一个单触发机制,用来提升输入事件的检测稳定性。另外,这个子模块的时钟可以自动关闭,以降低功耗。去抖动的范围是1ms到4秒(1ms步进)。小于1ms的输入信号将被子模块忽略。(因为使用的时钟是RTC 1K,所以最小要1ms)

EIC_LATCH子模块用于锁住一些特殊的输入信号,然后通过通道发送中断给MCU核,它能提供8个EIC_LATCH源输入信号连接。不需要时钟,相当于边沿触发,没有debounce时间

EIC_ASYNC 用于脉冲触发,检测脉冲最小需要维持61us,因为用的时钟是 RTC32K,最小需要2个circle

EIC_SYNC 用于脉冲触发检测,检测脉冲最小维持时间根据apbclk而定

一点小问题:不开debounce会无法滤除glitch,开了debounce如果需要的有效信号脉冲很短,小于debounce时钟源的一个最小周期,也会被滤掉,在新平台设计时,需要明确的各种输入信号具体情况,选择合适的时钟源

1、 GIC接收众多的外部中断,最终只有4个信号报给ARM内核。

VFIQ:虚拟快速 FIQ。

VIRQ:虚拟快速 IRQ

FIQ:快速中断 IRQ。

IRQ:外部中断 IR

2、GICV2 总体框图

主要是使能或者禁止MMU、I/D Cache等

IRQ和FIQ总中断使能

ID0~ID1019中断使能和禁止

GIC寄存器GICD_ISENABLERn和GICD_ICENABLERn用来完成外部中断的使能和禁止,对于Cortex-A7内核来说中断ID只能使用512个。一个bit控制一个中断ID的使能,那么就需要512/32=16个GICD_ISENABLERn寄存器来完成中断的使能。同理,也需要16个GICD_ICENABLERn寄存器来完成中断的禁止。其中GICD_ISENABLERn的bit[15:0]对应ID15~0de SGI中断,GICD_ISENABLERn的bit[31:16]对应ID31~16的PPI中断。剩下的GICD_ISENABLERn就是控制SPI中断的。

优先级数配置

GICC_PMR寄存器只有低8位有效,这个8位最多可以设置256个优先级,其他优先级数设置如下表

抢占优先级和子优先级位数设置

抢占优先级和子优先级各占多少位是由寄存器GICC_BPPR来决定的,GICC_BPR寄存器结构如下:

GICC_BPR只有低3位有效,其值不同,抢占优先级和子优先级占用的位数也不同,配置如下:

为了简单起见,一般将所有的中断优先级位都配置为抢占优先级,比如6U的优先级位数为5(32个优先级),所以可以设置Binary poin为2,表示5个优先级位全部为抢占优先级。

优先级设置

Cortex-A7使用了512个中断ID,每个中断ID配有一个优先级寄存器,所以一共有512个D_IPRIORITYR寄存器。如果优先级个数为32的话,使用寄存器D_IPRIORITYR的bit7:4来设置优先级。

优先级设置主要有三部分:

①设置寄存器GICC_PMR,配置优先级个数,比如I.MX6U支持32级优先级

②设置抢占优先级和子优先级位数,一般为了简单起见,会将所有的位数都设置为抢占优先级

③设置指定中断的ID的优先级,也就是设置外设优先级

简单总结:

1、 6U有8中中断类型

2、 GIC控制器有三类中断源,SPI、PPI、SGI;能设置中断优先级,抢占优先级和子优先级。

3、 CP15协处理器是开关I/D cache、MMU、获取GIC寄存器


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/8927804.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-23
下一篇2023-04-23

发表评论

登录后才能评论

评论列表(0条)

    保存