[gpio]Linux GPIO简单使用方式1-sysfs
转自:http://blog.csdn.net/drivermonkey/article/details/20132241
1.1.References
1.2.GPIO Usage from a Linux Application
1.2.1Overview
1.2.2.Configure the kernel for GPIO support in sysfs
1.2.3.Enable GPIO access from user space
1.2.4.GPIO interrupts from user space
1.2.4.1.Reference
1.2.4.2.LeopoardBoard 365 GPIO 0 connection
1.2.4.3.Using poll to monitor for GPIO 0 change
3.Example shell script making it easy to set GPIOs from the command line
1.1.References
1.2.GPIO Usage from a Linux Application
1.2.1.Overview
The following table summarizes the steps to configuring and using GPIO signals from a Linux application.
| Step | Action | Description |
|---|---|---|
| 1 | Configure the kernel for GPIO support in sysfs | Allow GPIO configuration and control from Linux applications (user space). The GPIO shoulw up in the system file system, sysfs, at /sys/class/gpio |
| 2 | Export GPIO to user space | Each GPIO is are not accessible from user space until the GPIO has been exported. You can only export a GPIO that isn't owned by a Linux kernel driver |
| 3 | Configure GPIO for input or output | To avoid hardware issues where two devices are driving the same signal, GPIOs default to be configured as an input. If you want to use the GPIO as an output, you need to change the configuration |
| 4 | Configure GPIO an an interrupt source | If you have a GPIO that is an input, and you have an application you want to block waiting for the GPIO to change level, you can configure the GPIO as an interrupt source. You also need to configure if the interrupt occurs when the GPIO signal has a rising edge, a falling edge, or interrupts on both rising and falling edges. Once configured as an interrupt, your application can read the value file and the read will block until the interrupt occurs, then your application will return from the read system call and continue running. |
The sysfs directory /sys/class/gpio contains subdirectories and files that are used for configuring and using GPIO signals from a Linux application.
| File or directory |
Meaning | Notes |
|---|---|---|
| /sys/class/gpio | sysfs GPIO subdirectory | Linux applications can configuration and use GPIO signals by accessing files in this subdirectory. |
| /sys/class/gpio/export | Write-only file to expose a GPIO | Before a Linux application can configuration and use a GPIO, the GPIO first has to beexported to user space by writing the GPIO number to this file. |
| /sys/class/gpio/gpio<<<number>>> | Subdirectory for configuring and reading a specific GPIO signal | Once a GPIO has been exported to user space, a new directory appears with a set of files that allow the GPIO to be configured and used by a Linux application |
| /sys/class/gpio/gpio<<<number>>>/direction | Read-write supporting values of inand out | |
| /sys/class/gpio/gpio<<<number>>>/value | Read-write supporting values of 0 and1 | |
| /sys/class/gpio/gpio<<<number>>>/edge | Read-write supporting values ofrising, falling, and both | Check your processor documentation. Not all GPIO pins support interrupts. |
1.2.2.Configure the kernel for GPIO support in sysfs
Symbol: GPIO_SYSFS [=y]
Prompt: /sys/class/gpio/... (sysfs interface)
Defined at drivers/gpio/Kconfig:
Depends on: GPIOLIB && SYSFS && EXPERIMENTAL
Location:
-> Kernel configuration
-> Device Drivers
-> GPIO Support (GPIOLIB [=y])
1.2.3.Enable GPIO access from user space
GPIO= cd /sys/class/gpio
ls
echo $GPIO > export
ls
Notice on the first ls that gpio22 doesn't exist, but does after you export GPIO 22 to user space.
cd /sys/class/gpio/gpio$GPIO
ls
There are files to set the direction and retrieve the current value.
echo "in" > direction
cat value
You can configure the GPIO for output and set the value as well.
echo "out" > direction
echo > value
1.2.4.PIO interrupts from user space
1.2.4.1.Reference
- http://bec-systems.com/site/281/how-to-implement-an-interrupt-driven-gpio-input-in-linux
- http://www.spinics.net/lists/linux-newbie/msg01028.html
- elinux.org/images/d/d4/Celf-gpio.odp
- http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:gpio-sysfs
1.2.4.2.eopoardBoard 365 GPIO 0 connection
On the LeopardBoard 365, the only GPIO I could find that was usable for interrupt input is GPIO0, also called CMOS_TRIGGER in the schematics. In looking at the schematics resistor R12 is not loaded and one of the pads connects to CMOS_TRIGGER. This R12 pad is the one closest to R11. If you hold the leopardboard 365 with the SD card slot facing you and rotate the board until the SD card slot is on the bottom edge, the the R12 pads are to the right of J6 and to the left of the SD card slot upper left corner.
![]()
1.2.4.3.sing poll() to monitor for GPIO 0 change
The gpio-int-test.c program (or gpiopin.cpp for those who prefer C++) shows one way of using the sysfs file /sys/class/gpio/gpio0/value to block program execution using poll() until the input level on GPIO0 changes. The tricky part was figuring out to use POLLPRI instead of POLLIN as the event to monitor. You must have GPIO support in sysfs for this program to work (or you will not see the /sys/class/gpio directory).
The gpio-int-test.c program uses poll() to wake up every 3 seconds (using poll() timeout mechanism) at which time it prints a period. The poll() function is also watching for input from stdin and for an interrupt from GPIO 0.
Here is an example output. I started gpio-int to watch GPIO 0. I waited around 12 seconds (4 timeout periods), then pressed the letter 'a' twice followed by enter key. Then I shorted the haywire to 3.3V that is accessible on pin 5 on the JTAG connector. JTAG pin 5 is across from the JTAG missing pin). I exited the program using cntl-C.
/root # gpio-int ....aa poll() stdin read 0xA61 poll() stdin read 0xA61 poll() stdin read 0xA0A
..
poll() GPIO interrupt occurred (len ) poll() GPIO interrupt occurred (len ) poll() GPIO interrupt occurred (len ) poll() GPIO interrupt occurred (len )
..^C
2.Viewing GPIO Configuration
You can use debugfs to videw the current GPIO configuration. You may also be able to use debugfs to see if the GPIO pin is multiplex as a GPIO or is dedicated to some other function.
Configure the kernel to enable debugfs:
Symbol: DEBUG_FS [=y]
Prompt: Debug Filesystem
Defined at lib/Kconfig.debug:
Depends on: SYSFS
Location:
-> Kernel configuration
-> Kernel hacking
Boot the target hardware and mount debugfs:
mount -t debugfs none /sys/kernel/debug
Dump the GPIO configuration.
cat /sys/kernel/debug/gpio
Dump the pin multiplexing configuration.
cat /sys/kernel/debug/omap_mux/board # for OMAP
cat /sys/kernel/debug/dm365_mux # for DM36x
3.Example shell script making it easy to set GPIOs from the command line
If you want to have a simple way to control a GPIO signal from the Linux command line, try the gpio.sh script below.
For examaple, if you want to read the value of GPIO 72 without setting its direction, try
gpio.sh
If you want to force GPIO 35 to be in input and read the current value, try
gpio.sh in
If you want to configure GPIO 4 to be an output and set the value high, try
gpio.sh out
For the script below to work, you need to first make sure you have build busybox with printf enabled.
#!bin/sh show_usage()
{
printf "\ngpio.sh <gpio pin number> [in|out [<value>]]\n"
} if [ \( $# -eq \) -o \( $# -gt \) ] ; then
show_usage
printf "\n\nERROR: incorrect number of parameters\n"
exit
fi #doesn't hurt to export a gpio more than once
echo $ > /sys/class/gpio/export if [ $# -eq ] ; then
cat /sys/class/gpio/gpio$/value
exit
fi if [ \( "$2" != "in" \) -a \( "$2" != "out" \) ] ; then
show_usage
printf "\n\nERROR: second parameter must be 'in' or 'out'\n"
exit
fi echo $ > /sys/class/gpio/gpio$/direction if [ $# -eq ] ; then
cat /sys/class/gpio/gpio$/value
exit
fi VAL=$ if [ $VAL -ne ] ; then
VAL=
fi echo $VAL > /sys/class/gpio/gpio$/value
4.Example of C/C++ code making it easier to set GPIOs
/* Copyright (c) 2011, RidgeRun
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the RidgeRun.
* 4. Neither the name of the RidgeRun nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY RIDGERUN ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL RIDGERUN BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h> /****************************************************************
* Constants
****************************************************************/ #define SYSFS_GPIO_DIR "/sys/class/gpio"
#define POLL_TIMEOUT (3 * 1000) /* 3 seconds */
#define MAX_BUF 64 /****************************************************************
* gpio_export
****************************************************************/
int gpio_export(unsigned int gpio)
{
int fd, len;
char buf[MAX_BUF]; fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY);
if (fd < ) {
perror("gpio/export");
return fd;
} len = snprintf(buf, sizeof(buf), "%d", gpio);
write(fd, buf, len);
close(fd); return ;
} /****************************************************************
* gpio_unexport
****************************************************************/
int gpio_unexport(unsigned int gpio)
{
int fd, len;
char buf[MAX_BUF]; fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY);
if (fd < ) {
perror("gpio/export");
return fd;
} len = snprintf(buf, sizeof(buf), "%d", gpio);
write(fd, buf, len);
close(fd);
return ;
} /****************************************************************
* gpio_set_dir
****************************************************************/
int gpio_set_dir(unsigned int gpio, unsigned int out_flag)
{
int fd, len;
char buf[MAX_BUF]; len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", gpio); fd = open(buf, O_WRONLY);
if (fd < ) {
perror("gpio/direction");
return fd;
} if (out_flag)
write(fd, "out", );
else
write(fd, "in", ); close(fd);
return ;
} /****************************************************************
* gpio_set_value
****************************************************************/
int gpio_set_value(unsigned int gpio, unsigned int value)
{
int fd, len;
char buf[MAX_BUF]; len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio); fd = open(buf, O_WRONLY);
if (fd < ) {
perror("gpio/set-value");
return fd;
} if (value)
write(fd, "", );
else
write(fd, "", ); close(fd);
return ;
} /****************************************************************
* gpio_get_value
****************************************************************/
int gpio_get_value(unsigned int gpio, unsigned int *value)
{
int fd, len;
char buf[MAX_BUF];
char ch; len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio); fd = open(buf, O_RDONLY);
if (fd < ) {
perror("gpio/get-value");
return fd;
} read(fd, &ch, ); if (ch != '') {
*value = ;
} else {
*value = ;
} close(fd);
return ;
} /****************************************************************
* gpio_set_edge
****************************************************************/ int gpio_set_edge(unsigned int gpio, char *edge)
{
int fd, len;
char buf[MAX_BUF]; len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio); fd = open(buf, O_WRONLY);
if (fd < ) {
perror("gpio/set-edge");
return fd;
} write(fd, edge, strlen(edge) + );
close(fd);
return ;
} /****************************************************************
* gpio_fd_open
****************************************************************/ int gpio_fd_open(unsigned int gpio)
{
int fd, len;
char buf[MAX_BUF]; len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio); fd = open(buf, O_RDONLY | O_NONBLOCK );
if (fd < ) {
perror("gpio/fd_open");
}
return fd;
} /****************************************************************
* gpio_fd_close
****************************************************************/ int gpio_fd_close(int fd)
{
return close(fd);
} /****************************************************************
* Main
****************************************************************/
int main(int argc, char **argv, char **envp)
{
struct pollfd fdset[];
int nfds = ;
int gpio_fd, timeout, rc;
char *buf[MAX_BUF];
unsigned int gpio;
int len; if (argc < ) {
printf("Usage: gpio-int <gpio-pin>\n\n");
printf("Waits for a change in the GPIO pin voltage level or input on stdin\n");
exit(-);
} gpio = atoi(argv[]); gpio_export(gpio);
gpio_set_dir(gpio, );
gpio_set_edge(gpio, "rising");
gpio_fd = gpio_fd_open(gpio); timeout = POLL_TIMEOUT; while () {
memset((void*)fdset, , sizeof(fdset)); fdset[].fd = STDIN_FILENO;
fdset[].events = POLLIN; fdset[].fd = gpio_fd;
fdset[].events = POLLPRI; rc = poll(fdset, nfds, timeout); if (rc < ) {
printf("\npoll() failed!\n");
return -;
} if (rc == ) {
printf(".");
} if (fdset[].revents & POLLPRI) {
len = read(fdset[].fd, buf, MAX_BUF);
printf("\npoll() GPIO %d interrupt occurred\n", gpio);
} if (fdset[].revents & POLLIN) {
(void)read(fdset[].fd, buf, );
printf("\npoll() stdin read 0x%2.2X\n", (unsigned int) buf[]);
} fflush(stdout);
} gpio_fd_close(gpio_fd);
return ;
}
[gpio]Linux GPIO简单使用方式1-sysfs的更多相关文章
- [gpio]Linux GPIO简单使用方式2-sysfs
转自:http://blog.csdn.net/cjyusha/article/details/50418862 在Linux嵌入式设备开发中,对GPIO的操作是最常用的,在一般的情况下,一般都有对应 ...
- linux磁盘简单分区方式
1:分区 fdisk /dev/sdb 2:格式化 mkfs -t ext3 /dev/sdb1 或者 mke2fs -t ext4 /dev/sdb2 3:挂载 mount /dev/sdb1 ...
- Linux GPIO子系统
一 概述 Linux内核中gpio是最简单,最常用的资源(和 interrupt ,dma,timer一样)驱动程序,应用程序都能够通过相应的接口使用gpio,gpio使用0-MAX_INT之间的整数 ...
- Linux GPIO 注册和应用
Linux GPIO 注册和应用 Linux Kernel, GPIO, ARM 于Linux kernel代码.经常使用 GPIO 作为一个特殊的信号,如芯片片选信号. GPIO 功能应用,我们经常 ...
- Linux GPIO控制方法
Linux GPIO控制方法 kernel version 4.4.12 在文件系统层: 1. 进入 /sys/class/gpio/ 目录 2. 假设你想控制的GPIO0_29,步骤如下: 1. e ...
- Linux GPIO键盘驱动开发记录_OMAPL138
Linux GPIO键盘驱动开发记录_OMAPL138 Linux基本配置完毕了,这几天开始着手Linux驱动的开发,从一个最简单的键盘驱动开始,逐步的了解开发驱动的过程有哪些.看了一下Linux3. ...
- Linux内核调试的方式以及工具集锦【转】
转自:https://blog.csdn.net/gatieme/article/details/68948080 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原 ...
- Linux内核调试的方式以及工具集锦
原文:https://blog.csdn.net/gatieme/article/details/68948080 CSDN GitHubLinux内核调试的方式以及工具集锦 LDD-LinuxDev ...
- Linux的简单介绍和常用命令的介绍
Linux的简单介绍和常用命令的介绍 本说明以Ubuntu系统为例 Ubuntu系统的安装自行百度,或者参考http://www.cnblogs.com/CoderJYF/p/6091068.html ...
随机推荐
- Hibernate 延迟载入
一.延迟载入定义 延迟载入,也叫懒载入,它是Hibernate为提高程序运行效率而提供的一种机制,即当仅仅有真正使用该对象的数据时才会创建. 说白了,所谓的延迟载入不是 ...
- 将项目的版本控制从Vss迁移到Git
之前在Vs2008上一直使用的是Vss版本控制,现在将版本控制更改为Git 迁移原因是其他公司想要在我们公司开发的一个CRM系统做一些定制(个性化需求,将软件上的公司名称和链接更改为他们的或一些跟我们 ...
- Hidden Markov Model Toolbox for Matlab
官网:http://www.cs.ubc.ca/~murphyk/Software/HMM/hmm.html Download Click here. Unziping creates a direc ...
- Web版RSS阅读器(五)——初步完成阅读功能
上一篇博文<Web版RSS阅读器(四)——定制自己的Rss解析库myrsslib4j>中,已经分享给大家制作自己的rss解析库.稍微有点遗憾的是,它仅仅支持rss格式的博客.现在给大家分享 ...
- UNIX网络编程读书笔记:readv和writev函数
这两个函数类似于read和write,不过readv和writev允许单个系统调用读入到或写出自一个或多个缓冲区.这些操作分别称为分散读(scatter read)和集中写(gather write) ...
- 算法笔记_020:深度优先查找(Java)
目录 1 问题描述 2 解决方案 2.1 蛮力法 1 问题描述 深度优先查找(depth-first search,DFS)可以从任意顶点开始访问图的顶点,然后把该顶点标记为已访问.在每次迭代的时候, ...
- Php自动备份数据库实现方法
然后再服务器开启 定时任务执行这个方法即可.
- 关于索引的sql语句优化之降龙十八掌
1 前言 客服业务受到SQL语句的影响非常大,在规模比较大的局点,往往因为一个小的SQL语句不够优化,导致数据库性能急剧下降,小型机idle所剩无几,应用服务器断连.超时,严重影响业务的正 ...
- js 字符串indexof与search方法的区别
1.indexof方法 indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置. 语法: 注意:有可选的参数(即设置开始的检索位置). 2.search方法 search() 方法用 ...
- 查看正在执行的sql语句
;WITH t AS( SELECT [Spid] = session_Id, ecid, [Database] = DB_NAME(sp.dbid), [User] = nt_username, [ ...