我们拿到板子要做的第一件事,往往是驱动一个gpio,控制其 GPIO 输出高低电平,在有些应用场景中,需要做到开机之后,某个引脚一直输出一个电平来初始化设备,这就不仅需要在内核中配置引脚为GPIO功能,还需要在uboot阶段也配置为GPIO功能。本篇文章就详细的介绍如何配置一个GPIO.以GPIO3_IO00为例:
uboot下修改GPIO:
1.首先需要配置IO口的寄存器
打开arch/arm/include/asm/arch-mx6/mx6q_pins.h文件,搜索EIM_DA0
可以看到mx6q_pins.h文件里已经添加了所有io口的功能定义,我们不需要修改它。
可以点进去查看一下定义
先看1,MX6_PAD_DECL=MX6_PAD_DECLARE,且和第一张图里的参数对应,
再看3,MX6_PAD_DECLARE=prefix##name = IOMUX_PAD(pco, mc, mm, sio, si, pc)
替换之后为
MX6_PAD_##name =IOMUX_PAD(pco, mc, mm, sio, si, pc)
最后替换prefix,传递参数之后
MX6_PAD_EIM_DA0__GPIO3_IO00=IOMUX_PAD(0x0428, 0x0114, 5, 0X0000, 0, 0)
prefix应该是识别标志
之后看参数都去了哪,点开IOMUX_PAD函数定义,
定义对应变量为iomux_v3_cfg_t类型,u64,long long就是64位,即定义了个无符号64位数据类型。
将值传递进去且左移一些位,然后去网上查一下资料,找到对应宏的含义。上图第一个框和第二个框参数有位置颠倒。
上图的值分别左移12 ,0,36,24,60,42 ,
寄存器的值已经变换且放到了一个无符号64位变量的不同位置。
这个函数里面寄存器值分别对应
第四个寄存器没有,后面值都为0
寄存器配置就到这里
2.修改board/freescale/mx6sabresd/mx6sabresd.c文件,我们需要添加引脚配置为GPIO功能:
static iomux_v3_cfg_t const gpio_pads[] = {
MX6_PAD_EIM_DA0__GPIO3_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
MX6_PAD_EIM_DA0__GPIO3_IO00=IOMUX_PAD(0x0428, 0x0114, 5, 0X0000, 0, 0)
点开MUX_PAD_CTRL,定义64位无符号变量 x 左移42位
其实就是之前设置的寄存器,将其做了一个宏。
MUX_PAD_CTRL(NO_PAD_CTRL)=1左移59位
之后再看MX6_PAD_EIM_DA0__GPIO3_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL)
=IOMUX_PAD(0x0428, 0x0114, 5, 0X0000, 0, 0)第60位置1,
下面图为添加位置
3.然后在主函数int board_init(void)中添加具体的输入输出配置:
我们需要用到gpio_direction_output函数控制GPIO输出高电平
我们先找到gpio_direction_output的函数原型,第一个参数是GPIO号,第二个参数是设置的值,1代表高电平,0代表低电平。
然后找到IMX_GPIO_NR的函数原型参数代表GPIOx_IOx 经过公式计算得到GPIO号
在红框位置添加下面代码设置GPIO3_IO00为高电平
gpio_direction_output(IMX_GPIO_NR(3, 0), 1); //输出高电平
gpio_direction_output用到
写入到DR寄存器
之前第一步
MX6_PAD_EIM_DA0__GPIO3_IO00=IOMUX_PAD(0x0428, 0x0114, 5, 0X0000, 0, 0)里面的变量经过移位,到第二步调用经过移位的
IOMUX_PAD(0x0428, 0x0114, 5, 0X0000, 0, 0)
这个值是怎么被写入寄存器的?
可以看 asm/imx-common/iomux-v3.h文件
有两个函数,
点进去
然后分析imx_iomux_v3_multiple_pads()函数
调用了上一个函数
这里将那些寄存器的值初始化,
在看下面的代码,将6个寄存器值写到寄存器
把宏里的这些值写入到对应寄存器里, 这样就设置好我们想要的GPIO了
内核下修改GPIO:
- 把 EIM_DA0 复用成 GPIO3_IO00
- 在 kernel/arch/arm/boot/dts/imx6q-pinfunc.h 中查找
#define MX6QDL_PAD_EIM_DA0__GPIO3_IO00 0x0f0 0x404 0x000 0x5 0x0
- 在设备树中配置为GPIO并且配置其电气参数
Kernel/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
MX6QDL_PAD_EIM_DA0__GPIO3_IO00被配置为0x1b0b0
0x1b0b0意思是推挽输出,即默认配置为高电平
并把其他复用功能去掉,此引脚无复用功能不需要去掉复用,编译生成新的镜像,将
其烧写到开发板上即可。
如果在启动后需要进行GPIO控制,可以使用以下命令进行修改
echo 96 > /sys/class/gpio/export 用于通知系统需要导出控制的 GPIO 引脚编号
echo out > /sys/class/gpio/gpio96/direction 控制为输出
echo 1 > /sys/class/gpio/gpio96/value 输出为高电平
echo 53 > /sys/class/gpio/unexport 通知系统取消导出