Edit online

关键流程设计

20 Nov 2024
Read time: 2 minute(s)

pin 脚功能定义

在 pinctrl 子系统中,有 function 和 group 的概念。function 是指某个具体的功能,如 uart0、spi1、i2c2 等。soc 的几个 pin 脚可以构成一个 group,形成特定的功能,如 PA0 和 PA1 可以组成 uart0。一个 function 往往包含一个或多个 group,例如,uart0 这个 function 可以由 PA0 和 PA1 组成,也可以由 PA2 和 PA3 组成。pinctrl 子系统就是通过 function 和 group 来确定最终需要设置的 pin 脚。

PINCTRL 模块的驱动定义了一个结构体数组,存储每个 pin 脚的所有可复用功能。如下所示,PA0 是该 pin 脚的名称,下面依次是 PA0 可实现的功能复用。AIC_FUNCTION(index, func_name)用来定义 pin 脚功能复用时所对应的索引值。即 PA0 作为 GPIOA0 时,是使用的 function 1。作为 uart0 时,是使用的 function 5。驱动中并不会区分该 pin 脚是 uart0 的 RX 还是 TX 这些细节。

static struct aic_desc_pin aic_pins_v1[] = {
    AIC_PIN(
        PINCTRL_PIN(0, "PA0"),
        AIC_FUNCTION(1, "GPIOA0"),
        AIC_FUNCTION(2, "GPAI0"),
        AIC_FUNCTION(3, "jtag"),
        AIC_FUNCTION(5, "uart0")
    ),
    AIC_PIN(
        PINCTRL_PIN(1, "PA1"),
        AIC_FUNCTION(1, "GPIOA1"),
        AIC_FUNCTION(2, "GPAI1"),
        AIC_FUNCTION(3, "jtag"),
        AIC_FUNCTION(5, "uart0")
    ),
    /* 此处省略其它pin脚配置 */
}

在 pinctrl 子系统中,一个 group 一般会包含多个 pin 脚。而在 PINCTRL 模块实现的驱动中,是将每个 pin 脚都看作一个 group,这样做的优点是:

  • 不需要再单独定义每个 group 的 pin 脚组成情况,

  • 不需要再定义 function 与 group 的对应关系

  • 驱动源码简单明了,由上面的数组可以快速直观的了解到每个 pin 脚可复用的功能

注:

按照 pinctrl 子系统对 function 和 group 的定义,gpio 模块的 uart0 包含 2 个 group,每个 group 包含 2 个 pin 脚,通过 uart0 可以找到这 4 个 pin 脚。而按照 gpio 模块实现的驱动,uart0 包含 4 个 group,每个 group 包含 1 个 pin 脚,最终通过 uart0 也可以找到 4 个 pin 脚。

初始化流程

  1. 释放 reset 和 clock

  2. 调用 state,构建 function 与 group 的关系

  3. 初始化 pinctrl 结构体变量

  4. 注册 controller 设备

  5. 调用 bank,注册各个 gpio bank

  6. 初始化完成

设备 pinmux 配置流程

在各个外设的驱动中,并没有调用与 pin 脚复用相关的接口,那么各个外设的 pin 脚复用功能是什么时候生效的呢?pin 脚复用功能是如何进行初始化的?了解这个过程,有助于加深对 pinctrl 子系统的了解。外设的 pin 脚复用初始化流程如下:


pinmux_initialize

中断处理流程


irq_flow1