嵌入式Linux系列第6篇:操作GPIO(嵌入式linux视频教程)
sinye56 2024-11-11 13:35 10 浏览 0 评论
1.引言
学习单片机的第一个例子通常都是点亮LED灯,对于Linux应用,我们也从LED入手,我就记得自己刚开始学的时候查了好多资料才勉强能控制一个灯亮,当时就感受到了Linux和单片机裸机有很大的差异。这里做个总结,希望对大家有所帮助。
2.环境介绍
2.1.硬件
NUC972开发板
要控制的是板子底板上的D2 和D3 两个LED指示灯
对应NUC972的PB4和PB5引脚。
2.2.软件
1)需要在上一篇《Linux学习系列五:Nand Flash根文件系统制作》的基础上改动下Linux内核配置,生成新的970uimage并烧写到板子里。
2)uboot、rootfs使用板子里默认的,板子厂家发货时里面已经烧录过了。
3)板子厂家使用的交叉工具链arm_linux_4.8.tar.gz。
3.内核配置
1)为了让NUC972芯片支持GPIO控制,需要在内核中使能"/sys/class/gpio…",如下所示
Device Drivers --->
-*- GPIO Support --->
[*] /sys/class/gpio/... (sysfs interface)unzip
保存生成新的.config 文件。
2)make uImage,生成970uimage文件,将其单独下载到板子里即可,其他Uboot、Rootfs等就不需要再下载了。
4.GPIO操作
4.1.使用命令行操作GPIO
GPIO驱动程序将NUC970芯片的IO口,从GPIOA~GPIOJ每组IO都保留32个号码,所以GPIOA编号0x000~0x01F,GPIOB编号0x020~0x03F,GPIOC编号0x040~0x05F, GPIOD编号0x060~0x07F, GPIOE编号0x080~0x09F,GPIOF编号0x0A0~0x0BF,GPIOG编号0x0C0~0x0DF, GPIOH编号0x0E0~0x0FF, GPIOI编号0x100~0x11F,GPIOJ编号0x120~0x13F。
用户可以通过文件系统/sys/class/gpio/…路径下的文件节点来操作对应的IO口
/sys/class/gpio/export :来告诉系统需要控制哪个GPIO
/sys/class/gpio/unexport:可以取消相应的GPIO控制
/sys/class/gpio/gpio0/direction:控制GPIO in 或 out
/sys/class/gpio/gpio0/value: 控制GPIO输出1 或 0,也可查看输入状态下当前GPIO的输入值。
LED D2对应GPIO PB4,编号0x24,对应十进制36,要控制它的话可在命令行中依次输入下面指令:
echo 36 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio36/direction
echo 0 > /sys/class/gpio/gpio36/value
echo 1 > /sys/class/gpio/gpio36/value
4.2.使用shell脚本操作GPIO
一句句的敲打上述代码显然是比较麻烦的,方便的办法是写到一个shell脚本里,这样的话只要执行shell脚本就可以控制LED了。实际产品中这个也是比较有用的,比如可以在系统启动后,实现LED D2亮灭各1s循环,这样LED 就可以作为系统状态指示灯,我们可以通过判断LED D2是否正常闪烁来判断系统是否在正常工作。实现方法如下:
1)在板子的/opt目录(默认没有此目录,自己新建下即可)下,新建一个gpio.sh脚本,里面内容如下:
#!/bin/sh echo 36 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio36/direction while true do echo 0 > /sys/class/gpio/gpio36/value sleep 1 echo 1 > /sys/class/gpio/gpio36/value done
其中第一行#!/bin/sh是指此脚本使用/bin/sh来解释执行。
其中,#!是一个特殊的表示符,其后,跟着解释此脚本的shell路径。
sh只是shell的一种,还有很多其它shell,如:bash,csh,zsh,tcsh,...
这里用到一个while 循环语句,大家注意下格式即可。
2)利用这个脚本,实现开机自启动,方法是vi /etc/init.d/rcS
在里面添加一句话
./opt/gpio.sh &
因为在Linux系统起来后会执行/etc/init.d/rcS 这个文件,所以我们在这里添加上面那句话就可以实现开机后自动控制LED了。
大家可以执行reboot指令或者断电再重新上电看一下效果。shell脚本因为不需要编译即可执行,所以使用非常方便,大家平时可以多用用。
4.3.C语言代码里操作GPIO
实际项目中,你可能得在C代码里去控制GPIO,这里实现的功能是让LED D3循环闪烁,具体步骤如下:
1)编写gpio_demo.c ,代码如下:
/*********************************************** * @{ * @file : gpio_demo.c * @brief : * @author: Wenxue Wang * @email : topsemic@sina.com * @wechat : wangwenxue1989 * @date : 2019-05-25 ***********************************************/ //-------------------------------------------------- // Copyright (c) Topsemic //-------------------------------------------------- #include <stdio.h> // Operation of LED D2 #define EXPORT_GPIO "echo 37 > /sys/class/gpio/export" #define GPIO_OUTPUT "echo out > /sys/class/gpio/gpio37/direction" #define TURNON_LED "echo 0 > /sys/class/gpio/gpio37/value" #define TURNOFF_LED "echo 1 > /sys/class/gpio/gpio37/value" void InitLED() { system(EXPORT_GPIO); system(GPIO_OUTPUT); } void TurnOnLED() { system(TURNON_LED); } void TurnOffLED() { system(TURNOFF_LED); } int main(void) { InitLED(); while(1) { TurnOnLED(); sleep(1); TurnOffLED(); sleep(1); } return 0; }
上述代码里说明两处:
i) system()函数,它是调用"/bin/sh -c command"执行特定的命令,阻塞当前进程直到command命令执行完毕
ii) sleep()函数,单位是s,还有个usleep()函数,它的单位us。在这里用来做延时。当执行这个函数后,程序就不往下走了,当指定时间结束后,继续执行下面的语句。
2)先使用我们之前的交叉工具链去编译上述代码
arm-none-linux-gnueabi-gcc gpio_demo.c -o gpio_demo
将生成的gpio_demo放到板子里去运行,提示如下错误
原因是因为板子里文件系统和我们用的交叉工具链不匹配。
解决方法是用和板子里默认文件系统对应的交叉工具链来编译,具体操作就不详细介绍了。
3)使用和板子里自带文件系统匹配的交叉工具链来重新编译
arm-linux-gcc gpio_demo.c -o gpio_demo
这时它会报一个错误:
解决方法是需要安装 32 位兼容包
sudo apt-get install lib32stdc++6 libc6:i386
之后就可以编译成功了。
再次将gpio_demo放到板子上,运行,就不再报错了,可以看到LED D3灯在不断的闪烁。
5.结束语
本篇为大家介绍了Linux下GPIO的使用,同时也穿插着介绍shell脚本的些许知识。
相关推荐
- 程序员:JDK的安装与配置(完整版)_jdk的安装方法
-
对于Java程序员来说,jdk是必不陌生的一个词。但怎么安装配置jdk,对新手来说确实头疼的一件事情。我这里以jdk10为例,详细的说明讲解了jdk的安装和配置,如果有不明白的小伙伴可以评论区留言哦下...
- Linux中安装jdk并配置环境变量_linux jdk安装教程及环境变量配置
-
一、通过连接工具登录到Linux(我这里使用的Centos7.6版本)服务器连接工具有很多我就不一一介绍了今天使用比较常用的XShell工具登录成功如下:二、上传jdk安装包到Linux服务器jdk...
- 麒麟系统安装JAVA JDK教程_麒麟系统配置jdk
-
检查检查系统是否自带java在麒麟系统桌面空白处,右键“在终端打开”,打开shell对话框输入:java–version查看是否自带java及版本如图所示,系统自带OpenJDK,要先卸载自带JDK...
- 学习笔记-Linux JDK - 安装&配置
-
前提条件#检查是否存在JDKrpm-qa|grepjava#删除现存JDKyum-yremovejava*安装OracleJDK不分系统#进入安装文件目...
- Linux新手入门系列:Linux下jdk安装配置
-
本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...
- 测试员必备:Linux下安装JDK 1.8你必须知道的那些事
-
1.简介在Oracle收购Sun后,Java的一系列产品就被整合到Oracle官网中,打开官网乍眼一看也不知道去哪里下载,还得一个一个的摸索尝试,而且网上大多数都是一些Oracle收购Sun前,或者就...
- Linux 下安装JDK17_linux 安装jdk1.8 yum
-
一、安装环境操作系统:JDK版本:17二、安装步骤第一步:下载安装包下载Linux环境下的jdk1.8,请去官网(https://www.oracle.com/java/technologies/do...
- 在Ubuntu系统中安装JDK 17并配置环境变量教程
-
在Ubuntu系统上安装JDK17并配置环境变量是Java开发环境搭建的重要步骤。JDK17是Oracle提供的长期支持版本,广泛用于开发Java应用程序。以下是详细的步骤,帮助你在Ubuntu系...
- 如何在 Linux 上安装 Java_linux安装java的步骤
-
在桌面上拥抱Java应用程序,然后在所有桌面上运行它们。--SethKenlon(作者)无论你运行的是哪种操作系统,通常都有几种安装应用程序的方法。有时你可能会在应用程序商店中找到一个应用程序...
- Windows和Linux环境下的JDK安装教程
-
JavaDevelopmentKit(简称JDK),是Java开发的核心工具包,提供了Java应用程序的编译、运行和开发所需的各类工具和类库。它包括了JRE(JavaRuntimeEnviro...
- linux安装jdk_linux安装jdk软连接
-
JDK是啥就不用多介绍了哈,外行的人也不会进来看我的博文。依然记得读大学那会,第一次实验课就是在机房安装jdk,编写HelloWorld程序。时光飞逝啊,一下过了十多年了,挣了不少钱,买了跑车,娶了富...
- linux安装jdk,全局配置,不同用户不同jdk
-
jdk1.8安装包链接:https://pan.baidu.com/s/14qBrh6ZpLK04QS8ogCepwg提取码:09zs上传文件解压tar-zxvfjdk-8u152-linux-...
- 运维大神教你在linux下安装jdk8_linux安装jdk1.7
-
1.到官网下载适合自己机器的版本。楼主下载的是jdk-8u66-linux-i586.tar.gzhttp://www.oracle.com/technetwork/java/javase/downl...
- window和linux安装JDK1.8_linux 安装jdk1.8.tar
-
Windows安装JDK1.8的步骤:步骤1:下载JDK打开浏览器,找到JDK下载页面https://d.injdk.cn/download/oraclejdk/8在页面中找到并点击“下载...
- 最全的linux下安装JavaJDK的教程(图文详解)不会安装你来打我?
-
默认已经有了linux服务器,且有root账号首先检查一下是否已经安装过java的jdk任意位置输入命令:whichjava像我这个已经安装过了,就会提示在哪个位置,你的肯定是找不到。一般我们在...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle忘记用户名密码 (59)
- oracle11gr2安装教程 (55)
- mybatis调用oracle存储过程 (67)
- oracle spool的用法 (57)
- oracle asm 磁盘管理 (67)
- 前端 设计模式 (64)
- 前端面试vue (56)
- linux格式化 (55)
- linux图形界面 (62)
- linux文件压缩 (75)
- Linux设置权限 (53)
- linux服务器配置 (62)
- mysql安装linux (71)
- linux启动命令 (59)
- 查看linux磁盘 (72)
- linux用户组 (74)
- linux多线程 (70)
- linux设备驱动 (53)
- linux自启动 (59)
- linux网络命令 (55)
- linux传文件 (60)
- linux打包文件 (58)
- linux查看数据库 (61)
- linux获取ip (64)
- linux进程通信 (63)