NXP iMX8 嵌入式Linux下Libgpiod 应用示例
已有 143 次阅读 2020-07-01 11:39 标签: iMX8 Libgpiod GPIO Linux NXP ARM Toradex ApalisBy
Toradex秦海
1). 简介
NXP iMX8是NXP去年底发布的基于Cortex-A72/A53和Coretex-M4异构多核架构的ARM处理器,本文就基于嵌入式Linux演示GPIO相关应用示例。
本文所演示的ARM平台来自于Toradex 基于NXP iMX8QM ARM处理器的Apalis iMX8QM ARM嵌入式平台。
2). 准备
a). Apalis
iMX8QM ARM核心版配合Apalis
Evaluation Board载板,连接调试串口UART1(载板X29)到开发主机方便调试。
b). Apalis iMX8 Cortex-A核心安装Toradex Ycoto Linux Console image V3.04版本,详细信息请参考这里。
d). Apalis
Evaluation Board GPIO相关硬件连接
X2 MXM_3
<-> X34 LED1
X2 MXM_5
<-> X34 SW5
X2 MXM_11
<-> X34 SW1
3). GPIO 命令行测试
a). 嵌入式Linux系统下之前呗广泛应用的GPIO工具为sysfs GPIO接口(/sys/class/gpio),但是目前这个项目已经处于deprecated状态,经Linux Kernel Community确定其替代者就是GPIO字符设备API Libgpiod。因此,尽管本文测试使用的Toradex Ycoto Linux Console image V3.04版本依然支持sysfs GPIO接口,但是已经不建议使用,如果需要相关说明,可以参考这里。本文接下来的测试都是基于Libgpiod来进行。
b). GPIO 数字编码
./ ARM SOC定义GPIO管脚通常为一串字母数字的组合,之前sysfs API操作时候需要将不同SOC GPIO的字母数字命名转换为纯数字编码,对于不同的SOC转换规则的详细说明请见这里,而本文使用的libgpiod API则直接可以按照GPIO命名进行操作,更为直观和便利。
./ 首先根据 Apalis iMX8 datasheet 4.4章节的表格,找出所需要GPIO管脚的字母数字组合命名,比如本文涉及的三个GPIO管脚;在接下来的Libgpiod API中都需要使用对应的GPIO命名中的<controller>和<gpio>这两个参数来操作对应的GPIO管脚
### GPIO字符数次串命名规则:LSIO.GPIO<controller>.IO<gpio>
X2 MXM_3 -> LSIO.GPIO0.IO09
X2 MXM_5 -> LSIO.GPIO0.IO12
X2 MXM_11 -> LSIO.GPIO4.IO01
c). 在具体调试GPIO之前,还需要确认在Linux kernel device tree中,这个管脚被定义为GPIO且并没有被其他驱动功能占用,否则在具体操作GPIO的时候会出现冲突导致异常,关于device tree的说明本文不赘述,可以参考这里。本文所涉及的三个GPIO管脚默认即配置为GPIO,因此无需修改。
d). 调用Libgpiod API在命令行下进行GPIO测试
./ Apalis iMX8 上电开机进入嵌入式Linux系统,下面操作在调试串口下进行
./ 罗列GPIO banks,也就是对应的上面提到的controller。可以看到有8个banks,每个banks包含32 lines,也就是32 gpio。当然,实际上结合具体的SOC和模块定义,不一定每个banks和lines都有对应的GPIO管脚,有效的肯呢个只是一部分。
-----------------------------------
root@apalis-imx8:~# gpiodetect
gpiochip0 [5d080000.gpio] (32 lines)
gpiochip1 [5d090000.gpio] (32 lines)
gpiochip2 [5d0a0000.gpio] (32 lines)
gpiochip3 [5d0b0000.gpio] (32 lines)
gpiochip4 [5d0c0000.gpio] (32 lines)
gpiochip5 [5d0d0000.gpio] (32 lines)
gpiochip6 [5d0e0000.gpio] (32 lines)
gpiochip7 [5d0f0000.gpio] (32 lines)
-----------------------------------
./ 查看某个bank具体GPIO lines的情况,可以查看系统中当前哪些GPIO被占用了。
-----------------------------------
root@apalis-imx8:~# gpioinfo 0
gpiochip0 - 32 lines:
line 0: unnamed unused
input active-high
line 1: unnamed unused
input active-high
line 2: unnamed unused
input active-high
line 3: unnamed unused
input active-high
line 4: unnamed unused
input active-high
line 5: unnamed unused
input active-high
line 6: unnamed unused
input active-high
line 7: unnamed unused
input active-high
line
8: unnamed unused
output active-high
line 9: unnamed unused
output active-high
line 10: unnamed unused
input active-high
line 11: unnamed unused
input active-high
line 12: unnamed unused
input active-high
line 13: unnamed unused
input active-high
line 14: unnamed unused
input active-high
line 15: unnamed unused
input active-high
line 16: unnamed unused
input active-high
line 17: unnamed unused
input active-high
line 18: unnamed unused
input active-high
line 19: unnamed unused
input active-high
line 20: unnamed unused
input active-high
line 21: unnamed unused
input active-high
line 22: unnamed unused
input active-high
line 23: unnamed unused
input active-high
line 24: unnamed unused
input active-high
line 25: unnamed unused
input active-high
line 26: unnamed unused
input active-high
line 27: unnamed unused
input active-high
line 28: unnamed unused
input active-high
line 29: unnamed unused
input active-high
line 30: unnamed "reset" output
active-low [used]
line 31: unnamed "usb3503 connect"
output active-high [used]
-----------------------------------
./ 测试X2 MXM_3 管脚GPIO output操作,gpioset命令的作用就是设置对应GPIO管脚为输出状态,并输出为设置的高或者低电平。
-----------------------------------
# 设置GPIO输出为高电平驱动LED点亮
root@apalis-imx8:~# gpioset 0 9=1
# 设置GPIO输出为低电平驱动LED熄灭
root@apalis-imx8:~# gpioset 0 9=0
# 通过 gpioinfo查看bank0 可以发现line 9是output状态
root@apalis-imx8:~# gpioinfo 0
gpiochip0 - 32 lines:
……
line 9: unnamed unused
output active-high
……
-----------------------------------
./ 测试X2 MXM_11 管脚GPIO input操作,gpioget命令的作用就是设置对应GPIO管脚为输入状态,并读取当前的GPIO电平。
-----------------------------------
# SW1 拨至低电平位置(靠近载板边缘),读取连接的X2 MXM_11GPIO电平
root@apalis-imx8:~# gpioget 4 1
0
# SW1 拨至高电平位置(远离载板边缘),读取连接的X2 MXM_11GPIO电平
root@apalis-imx8:~# gpioget 4 1
1
# 通过 gpioinfo查看bank4 可以发现line 1是input状态
root@apalis-imx8:~# gpioinfo 4
gpiochip4 - 32 lines:
……
line 1: unnamed unused
input active-high
……
-----------------------------------
./ 测试X2 MXM_5 管脚GPIO 中断操作,gpiomon命令的作用就是设置对应的GPIO为输入状态,并监测对应GPIO管脚的事件(。
-----------------------------------
# 设置X2 MXM_5 管脚中断监测
root@apalis-imx8:~# gpiomon 0 12
# 按下SW5按键
event:
RISING EDGE offset: 12 timestamp: [1609840088.602076625]
# 松开SW5按键
event: FALLING EDGE offset: 12 timestamp:
[1609840089.268163875]
# 通过 gpioinfo查看bank0 可以发现line 12是input状态
root@apalis-imx8:~# gpioinfo 0
gpiochip0 - 32 lines:
……
line 12: unnamed unused
input active-high
……
-----------------------------------
4). GPIO C代码示例程序测试
a). 首先先在开发Linux 主机安装SDK,SDK为按照这里说明通过Ycoto project/OpenEmbedded 环境编译得到,安装过程中根据提示可以自行更改SDK安装目录
-----------------------------------
$ chmod
+x tdx-xwayland-glibc-x86_64-Qt5-Wayland-Image-aarch64-toolchain-2.6.4.sh
$
./tdx-xwayland-glibc-x86_64-Qt5-Wayland-Image-aarch64-toolchain-2.6.4.sh
TDX
Wayland with XWayland SDK installer version 2.6.4
=====================================================
Enter
target directory for SDK (default: /opt/tdx-xwayland/2.6.4):
<SDK_install_dir>
You are
about to install the SDK to "<SDK_install_dir>". Proceed[Y/n]?
Y
…
-----------------------------------
b). c代码示例1 - 测试X2 MXM_3 管脚输出循环驱动LED亮和灭,时间间隔为1s
./ 源代码参考如下
https://github.com/simonqin09/Apalis_iMX8_Libgpiod/blob/master/gpio-toggle/gpio-toggle.c
./ 主要说明如下
-----------------------------------
###
include libgpiod 头文件
#include
<gpiod.h>
### 定义GPIO chip和line 结构体
struct
gpiod_chip *output_chip;
struct
gpiod_line *output_line;
### 配置GPIO为输出
output_chip
= gpiod_chip_open_by_name(chip);
output_line
= gpiod_chip_get_line(output_chip, offset);
gpiod_line_request_output(output_line,
"gpio-toggle", GPIOD_LINE_ACTIVE_STATE_HIGH);
### 切换GPIO输出状态
int
line_value = 0; OR ine_value = 1;
gpiod_line_set_value(output_line,
line_value);
-----------------------------------
./ 编译,本示例使用通过命令行编译方式,详细说明请参考这里
-----------------------------------
### export
SDK 环境变量
$ source
<SDK_install_dir>/environment-setup-aarch64-tdx-linux
### 编译,因为需要gpiod库,因此要再link选项加入 -lgpiod 选项,否则会出现
”undefined reference to …” 错误
$ cd
<work_dir>
$ ${CC}
-Wall -lgpiod -lpthread gpio-toggle.c -o gpio-toggle
### 部署
$ scp
gpio-toggle root@<apalis_imx8_ipaddress>:/home/root
-----------------------------------
./ 测试,在Apalis iMX8上面运行刚编译部署好的 gpio-toggle 二进制程序,载板上面的LED1 LED灯会1s间隔亮和灭
-----------------------------------
root@apalis-imx8:~#
cd /home/root/
root@apalis-imx8:~#
./gpio-toggle
Usage by
bank/pin number:
gpio-toggle OUTPUT-BANK-NUMBER
OUTPUT-GPIO-NUMBER
root@apalis-imx8:~#
./gpio-toggle 0 9
LED
turns ON
LED
turns OFF
LED
turns ON
LED
turns OFF
……
-----------------------------------
c). c代码示例2 - 测试X2 MXM_5 管脚通过按键输入,捕获上升沿事件后切换X2 MXM_3输出状态驱动LED亮和灭
./ 源代码参考如下
https://github.com/simonqin09/Apalis_iMX8_Libgpiod/blob/master/gpiotest/gpiotest.c
./ 主要说明如下
-----------------------------------
###
include libgpiod 头文件
#include
<gpiod.h>
### 定义GPIO chip和line 以及event结构体
struct
gpiod_chip *input_chip;
struct
gpiod_line *input_line;
struct
gpiod_line_event event;
### 配置GPIO为输入,中断事件为上升沿
input_chip
= gpiod_chip_open_by_name(chip);
input_line
= gpiod_chip_get_line(input_chip, offset);
gpiod_line_request_rising_edge_events(input_line,
"gpiotest");
### GPIO输入事件响应
while
(1) {
gpiod_line_event_wait(input_line,
NULL);
if (gpiod_line_event_read(input_line,
&event) != 0)
continue;
/* this should always be a rising event
in our example */
if (event.event_type !=
GPIOD_LINE_EVENT_RISING_EDGE)
continue;
……
}
-----------------------------------
./ 编译,本示例使用通过Eclipse IDE工具进行编译,详细Eclipse IDE 下载安装以及SDK配置说明请参考这里
-----------------------------------
### export
SDK 环境变量
$ source
<SDK_install_dir>/environment-setup-aarch64-tdx-linux
### 在同一个终端中启动Eclopse IDE
$ cd
<Eclipse_install_dir>
$ ./eclipse
### 在Eclipse IDE下参考上面的说明文档创建新的C/cross compile工程,并按照说明文档配置好SDK。同样因为linker需要gpiod相关库,因此要在下面位置增加相关库
菜单:
Project
--> Properties
选项卡:
C/C++
Build --> Settings
选项:
Cross
GCC Linker --> Libraries
Libraries
(-l) 栏目下面增加:
gpiod
###
Eclipse 点击build进行编译,根据选择是Debug还是Release,编译后的二进制文件会在对应的目录,本文使用Debug
### 部署
$ cd
<Eclipse_workspace>/gpiotest/Debug
$ scp
gpiotest root@<apalis_imx8_ipaddress>:/home/root
-----------------------------------
./ 测试,在Apalis iMX8上面运行刚编译部署好的 gpiotest 二进制程序,载板上面的LED1 LED灯初始状态为灭,随着按下SW5按键交替亮和灭
-----------------------------------
root@apalis-imx8:~#
cd /home/root/
root@apalis-imx8:~#
./gpiotest
Usage by
bank/pin number:
gpio-test INPUT-BANK-NUMBER
INPUT-GPIO-NUMBER OUTPUT-BANK-NUMBER OUTPUT-GPIO-NUMBER
root@apalis-imx8:~#
./gpiotest 0 12 0 9
LED
initial status is OFF
button
pressed 1 times
LED turns
ON
button
pressed 2 times
LED
turns OFF
button
pressed 3 times
LED
turns ON
……
-----------------------------------
5). 总结
上一篇: ARM平台设备WinCE下UART配置 下一篇: 通过以太网加载ToradexEasyInstaller并更新系统
发表评论 评论 (0 个评论)