EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
01硬件原理分析 以点灯和按键为例,打开飞凌嵌入式OK-MX9352-C开发板的原理图,可以看到一颗LED灯,它由MX93_PAD_CCM_CLKO4控制。由于这一个GPIO属于1.8V电平域,所以在OK-MX9352-C开发板的底板上并没有直接将GPIO接到LED上,而是用GPIO控制了一个MOS管,再由MOS管去控制LED的亮灭——当GPIO电平为高时,MOS导通,LED点亮;当GPIO电平为低时,MOS关断,LED熄灭。 ![]()
1 K, c( g/ T0 K0 S0 ?+ X" t; G0 |![]()
3 q3 n+ H0 u, u! E# U8 ?9 ^- o
02设备树引脚复用 打开飞凌嵌入式OK-MX9352-C开发板的设备树: OKMX93-linux-kernel/arch/ARM64/boot/dts/freescale/OK-MX93-C.dts 在iomuxc节点下新建一组引脚复用,复用的两个GPIO分别是底板上的LED灯D6和按键K1。 ![]()
: {) r- Q) C# B2 c& y2 g& r+ p接下来新建一个GPIO节点,内容如下:
7 V9 |7 q( _: N. n/ j+ R![]()
3 \+ k/ j% c& C; ?注释掉LED和KEY部分,防止复用冲突:
, g4 |: g4 J m) _# m![]()
- d- A2 W- Z1 P$ L
保存退出后重新编译设备树。 执行环境变量: forlinx@ubuntu:~/ok-mx93/OKMX93-linux-sdk$ . environment-setup-aarch64-toolchain 单独编译设备树: forlinx@ubuntu:~/ok-mx93/OKMX93-linux-sdk/OKMX93-linux-kernel$ make ARCH=arm64 CROSS_COMPILE=aarch64-poky-linux- dtbs 编译完成后,单独更新设备树。首先将U盘插到虚拟机上,将生成的设备树文件拷贝到U盘: forlinx@ubuntu:~/ok-mx93/OKMX93-linux-sdk/OKMX93-linux-kernel$ cp arch/arm64/boot/dts/freescale/OK-MX93-C.dtb /media/forlinx/2075-A0A7/
, J/ L, n. ~ B3 D, ` q将生成的dtb文件使用U盘拷贝到OK-MX9352-C开发板上,替换掉:/run/media/Boot-mmcblk0p1/OK-MX93-C.dtb root@ok-mx93:/run/media/Boot-mmcblk0p1# cp /run/media/sda/OK-MX93-C.dtb ./ 重启OK-MX9352-C开发板。 03通过命令测试 在OKMX6ULL-S开发板中,操作GPIO的方式是通过操作/sys/class/gpio下的文件来实现的。而在OK-MX9352-C上,引入了新的Lingpiod的方式,而原有的基于sysfs的操作方式已经不再被支持。 Libgpiod是一种字符设备接口,GPIO访问控制是通过操作字符设备文件(比如/dev/gpiodchip0)实现的。OK-MX9352-C共有4组GPIO,可以在/dev下查看GPIO设备文件。 Libgpiod可以通过shell终端和C库两种方式使用,本节介绍在shell终端控制GPIO的方法,下一节我们将会介绍使用C库的方式控制GPIO。 ![]()
3 i7 K1 s! M; p3 ^+ D& ^7 l
; S4 {6 W- Q1 I1 }( e( |$ o
3.1 gpiodetect 查看所有GPIO设备 ![]() * X/ j- d9 t# C
这里的gpiochip0- gpiochip4分别对应的是设备树当中的GPIO1-GPIO4这四组GPIO,但是顺序并不是一一对应的,这是由于对应的寄存器地址顺序问题导致的。那么goiochip0如何跟设备树对应起来呢?我们可以打开设备树当中的dtsi文件,文件路径为: OKMX93-linux-kernel/arch/arm64/boot/dts/freescale/imx93.dtsi forlinx@ubuntu:~/ok-mx93/OKMX93-linux-sdk$ vi OKMX93-linux-kernel/arch/arm64/boot/dts/freescale/imx93.dtsi ; q k' \2 B3 {
查看GPIO3的寄存器基地址为:gpio3: gpio@43820080,对应的是gpiochip1,而GPIO4对应的是gpiochip2。
2 }& e4 z0 g0 b2 r) m$ V) V![]()
, g; p/ }% F0 a0 {# }3 P2 B1 C* W
其余GPIO的对应关系如下,可供大家参考:
- O7 ]6 `; m& w! R% c# l7 h![]() ' {5 b, G* b) F' ~8 z/ I& F* f! F
" |" G8 O8 C* R9 R c" G$ T1 h) U+ _) a$ T9 M6 T7 J+ X
3.2 gpioinfo 由3.1可知,LED灯对应的是GPIO4,即gpiochip2;按键对应的是GPIO3,即gpiochip1。列出gpiochip2控制器的引脚情况: ![]()
( y$ F ?: n# D2 j3.3 gpioset 该命令用于设置GPIO电平,2代表gpiochip2,即GPIO4,28是GPIO pin,当设置该GPIO为1时,底板上的D6点亮。 ![]()
6 X* B! P9 ^. ^3 |2 b* {
! q) t+ Y8 _6 ~3 i) W3 I3.4 gpioget 该命令用于获取GPIO引脚状态,以按键为例,按键对应的是GPIO3-27,即gpiochip1 27。按键没有按下时,读取到按键状态为1,当按键按下时,读到按键状态为0。
) L4 I [' g, L% H, M1 [8 \![]()
7 e. s- l A( v4 u3.5 gpiomon 监控GPIO的状态是否发生变化,同样以按键为例,当按键按下时: ![]()
! k4 q2 w# V! A- c6 x9 D- I; c5 {* u! G$ d: [# {, p4 P% _7 t
04使用Libgpiod库编程 Libgpiod是用于与Linux GPIO交互的C库和工具,Linux官方于Linux 4.8 版本引入了Libgpiod的功能。而在OK-MX9352-C开发板搭载的Linux5.15内核版本中,已经不再支持sysfs的方式操作GPIO。与sysfs相比,Libgpiod更加可靠,具备更多功能,例如,可一次读写多个GPIO值。 4.1 源码获取 如果想要在PC上交叉编译出能够在开发板上运行的应用,则交叉编译时链接的库文件应该与开发板上的保持一致,可以直接把开发板上的库拷贝到开发环境进行使用。该库文件在开发板上的路径为: ![]() 6 W: {$ _. |+ h' y/ i' G0 t
从上图可以看出,Libgpiod库的版本为libgpiod.so.2.2.2,软链接到libgpiod.so.2。 在飞凌嵌入式提供的OK-MX9352-C开发板资料中,已经将所需的库文件、头文件以及相关例程进行了打包,用户可以直接使用。资料路径为:用户资料/应用笔记/ OK-MX9352-C-GPIO接口_Linux应用笔记/Libgpiod测试源码。咨询在线客服即可获取资料。 4.2 编译测试例程 将Libgpiod测试源码目录下的gpIoTest.c、gpio-toggle.c、lib.tar.bz2拷贝到开发环境中: ![]()
" F. H7 j8 |6 A5 [* I& y将lib.tar.bz2解压到本目录下,编译时会使用到里边的gpiod.h文件和Libgpiod库文件: ![]()
$ P1 \& C0 O3 R- A示例1循环控制LED亮和灭,时间间隔为1s 交叉编译gpio-toggle.c 设置环境变量(注意 . 后边有空格)
6 _+ W/ H) Y; u4 X v" V![]()
; H$ E$ M3 |/ Q& r0 |: \
交叉编译 ![]() 6 S. h+ C' K! U
4 S& X# P7 A; @% J8 b6 k) B2 Z( ^将可执行文件gpio-toggle拷贝到开发板中并执行可看到LED(D6)灯1s亮,1s灭。其中输入参数2、28为:gpiochip2 line28。 ![]()
" X+ P# E8 [1 ?) H" b示例2按键控制LED亮灭,每按一次状态翻转 交叉编译gpio-test.c 设置环境变量(注意点后边有空格) 1 H& S/ N; U" u9 y3 u f
![]()
" G. a1 Q2 `6 q1 S+ U' q- c
交叉编译 ![]()
% J) h; `+ I3 \& b, \$ y
将可执行文件gpio-test拷贝到OK-MX9352-C开发板中并执行,可看到每按一次按键,LED灯的状态就翻转一次,其中输入参数1、27为:gpiochip1 line27 ;2、28为:gpiochip2 line28。 ![]() 6 Y, F* d7 z2 @" l% z0 H' o7 x
以上就是为OK-MX9352-C开发板配置GPIO的过程,希望能够对屏幕前的各位工程师小伙伴有所帮助。 ' u" ]& [; S# Y* Z# z) ~, y
|