Linux 用户态控制GPIO

一.通过过sysfs方式控制GPIO
通过sysfs方式控制GPIO,先访问/sys/class/gpio目录,向export文件写入GPIO编号,使得该GPIO的操作接口从内核空间暴露到用户空间,GPIO的操作接口包括direction和value等,direction控制GPIO方向,而value可控制GPIO输出或获得GPIO输入。文件IO方式操作GPIO,使用到了4个函数open、close、read、write。
 
1. 首先,看看系统中有没有“/sys/class/gpio”这个文件夹
如果没有请在编译内核的时候加入 Device Drivers-> GPIO Support ->/sys/class/gpio/… (sysfs interface)。
 
2./sys/class/gpio 的使用说明:
gpio_operation 通过/sys/文件接口操作IO端口 GPIO到文件系统的映射
◇ 控制GPIO的目录位于/sys/class/gpio
◇ /sys/class/gpio/export 文件用于通知系统需要导出控制的GPIO引脚编号
◇ /sys/class/gpio/unexport 用于通知系统取消导出
◇ /sys/class/gpio/gpiochipX目录保存系统中GPIO寄存器的信息,包括每个寄存器控制引脚的起始编号base,寄存器名称,引脚总数 导出一个引脚的
 
 
二.操作步骤
◇ 首先计算此引脚编号,引脚编号 = 控制引脚的寄存器基数 + 控制引脚寄存器位数
◇ 向/sys/class/gpio/export写入此编号,比如12号引脚,在shell中可以通过以下命令实现,命令成功后生成/sys/class/gpio/gpio12目录,如果没有出现相应的目录,说明此引脚不可导出
◇ direction文件,定义输入输入方向,可以通过下面命令定义为输出。direction接受的参数:in, out, high, low。high/low同时设置方向为输出,并将value设置为相应的1/0
◇ value文件是端口的数值,为1或0
 
1. 导出
/sys/class/gpio# echo 44 > export
2. 设置方向
/sys/class/gpio/gpio44# echo out > direction
3. 查看方向
/sys/class/gpio/gpio44# cat direction
4. 设置输出
/sys/class/gpio/gpio44# echo 1 > value
5. 查看输出值
/sys/class/gpio/gpio44# cat value
6. 取消导出
/sys/class/gpio# echo 44 > unexport
 
 
三.在Gpiolib.c (drivers\gpio)下有源文件,通过iotctl来访问。
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 //error相关头文件
  5 #include <string.h>
  6 #include <errno.h>
  7 
  8 //access所需头文件
  9  #include <unistd.h>
 10 
 11 //open()相关头文件
 12 #include <sys/types.h>
 13 #include <sys/stat.h>
 14 #include <fcntl.h>
 15 #include <sys/ioctl.h>
 16 #include <stdint.h>
 17 
 18 #define LEDS_MULTI_CTRL_FILE    "/dev/gpiochip5"
 19 /* Maximum number of requested handles */
 20 #define GPIOHANDLES_MAX 64
 21 
 22 /* Linerequest flags */
 23 #define GPIOHANDLE_REQUEST_INPUT    (1UL << 0)
 24 #define GPIOHANDLE_REQUEST_OUTPUT    (1UL << 1)
 25 #define GPIOHANDLE_REQUEST_ACTIVE_LOW    (1UL << 2)
 26 #define GPIOHANDLE_REQUEST_OPEN_DRAIN    (1UL << 3)
 27 #define GPIOHANDLE_REQUEST_OPEN_SOURCE    (1UL << 4)
 28 
 29 int leds_multi_init(void);
 30 
 31 struct gpiochip_info {
 32     char name[32];
 33     char label[32];
 34     unsigned int lines;
 35 };
 36 
 37 struct gpioline_info {
 38     unsigned int line_offset;
 39     unsigned int flags;
 40     char name[32];
 41     char consumer[32];
 42 };
 43 
 44 struct gpiohandle_request {
 45     unsigned int lineoffsets[GPIOHANDLES_MAX];
 46     unsigned int flags;
 47     unsigned char default_values[GPIOHANDLES_MAX];
 48     char consumer_label[32];
 49     unsigned int lines;
 50     int fd;
 51 };
 52 
 53 /**
 54  * struct gpiohandle_data - Information of values on a GPIO handle
 55  * @values: when getting the state of lines this contains the current
 56  * state of a line, when setting the state of lines these should contain
 57  * the desired target state
 58  */
 59 struct gpiohandle_data {
 60     unsigned char values[GPIOHANDLES_MAX];
 61 };
 62 
 63 #define GPIO_GET_CHIPINFO_IOCTL  2151986177    //_IOR(0xB4, 0x01, struct gpiochip_info)
 64 #define GPIO_GET_LINEINFO_IOCTL  3225990146    //_IOWR(0xB4, 0x02, struct gpioline_info)
 65 #define GPIO_GET_LINEHANDLE_IOCTL  3245126659  //_IOWR(0xB4, 0x03, struct gpiohandle_request)
 66 
 67 #define GPIOHANDLE_GET_LINE_VALUES_IOCTL  3225465864  //_IOWR(0xB4, 0x08, struct gpiohandle_data)
 68 #define GPIOHANDLE_SET_LINE_VALUES_IOCTL  3225465865  //_IOWR(0xB4, 0x09, struct gpiohandle_data)
 69 
 70 struct gpiochip_info gpioinfo;
 71 struct gpioline_info gpioline;
 72 struct gpiohandle_request gpiohandle;
 73 static int multi_ctrl_fd = -1;
 74 struct gpiohandle_data gpiohandledata;
 75 
 76 int gpio_leds_init(void);
 77 int gpio_leds_state_get(void);
 78 int gpio_leds_state_set(unsigned char value);
 79 
 80 int main(int argc, char** argv)
 81 {
 82     //gpio_leds_init();
 83     /*
 84     printf("cxw GPIO_GET_CHIPINFO_IOCTL =%ld\n", GPIO_GET_CHIPINFO_IOCTL);
 85     printf("cxw GPIO_GET_LINEINFO_IOCTL =%ld\n", GPIO_GET_LINEINFO_IOCTL);
 86     printf("cxw GPIO_GET_LINEHANDLE_IOCTL =%ld\n", GPIO_GET_LINEHANDLE_IOCTL);
 87     printf("cxw GPIOHANDLE_GET_LINE_VALUES_IOCTL =%ld\n", GPIOHANDLE_GET_LINE_VALUES_IOCTL);
 88     printf("cxw GPIOHANDLE_SET_LINE_VALUES_IOCTL =%ld\n", GPIOHANDLE_SET_LINE_VALUES_IOCTL);
 89     */
 90     
 91     gpio_leds_init();
 92     printf("gpio_leds_state_get gpiohandledata.values[0] = %d\n", gpio_leds_state_get());
 93     gpio_leds_state_set(1);
 94     sleep(5);
 95     gpio_leds_state_set(0);
 96 
 97     return 0;
 98 }
 99 
100 int gpio_leds_init(void)
101 {
102     int ret = -1;
103     
104     multi_ctrl_fd = open(LEDS_MULTI_CTRL_FILE, O_RDONLY);
105     if (multi_ctrl_fd < 0) {
106         fprintf(stderr,"%s,can't open file %s\n",__func__, LEDS_MULTI_CTRL_FILE);
107         return -1;
108     }
109 
110     if ((ret = ioctl(multi_ctrl_fd, GPIO_GET_CHIPINFO_IOCTL, &gpioinfo)) < 0){
111         printf("LEDS_MULTI_CTRL_IOCTL_MULTI_SET failed\n");
112         return -errno;
113     }
114     printf("cxw gpioinfo.name = %s, gpioinfo.label = %s, gpioinfo.lines = %d\n", gpioinfo.name, gpioinfo.label, gpioinfo.lines);
115     
116     gpioline.line_offset = 11;
117     if ((ret = ioctl(multi_ctrl_fd, GPIO_GET_LINEINFO_IOCTL, &gpioline)) < 0){
118         printf("LEDS_MULTI_CTRL_IOCTL_MULTI_SET failed\n");
119         return -errno;
120     }
121     printf("cxw gpioline.line_offset = %d, gpioline.flags = %d, gpioline.name = %s, gpioline.consumer = %s\n", gpioline.line_offset, gpioline.flags, gpioline.name, gpioline.consumer);
122     
123     gpiohandle.lineoffsets[0] = 11;
124     gpiohandle.lines = 1;
125     gpiohandle.flags = GPIOHANDLE_REQUEST_OUTPUT;
126     gpiohandle.default_values[0] = 0;
127     if ((ret = ioctl(multi_ctrl_fd, GPIO_GET_LINEHANDLE_IOCTL, &gpiohandle)) < 0){
128         printf("LEDS_MULTI_CTRL_IOCTL_MULTI_SET failed\n");
129         return -errno;
130     }
131    
132     return 0;
133 }
134 
135 int gpio_leds_state_get(void)
136 {
137     int ret = -1;
138     
139     if ((ret = ioctl(gpiohandle.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &gpiohandledata)) < 0){
140         printf("LEDS_MULTI_CTRL_IOCTL_MULTI_SET failed\n");
141         return -errno;
142     }
143     printf("gpio_leds_state_get gpiohandledata.values[0] = %d\n", gpiohandledata.values[0]);
144     return gpiohandledata.values[0];
145 }
146 
147 int gpio_leds_state_set(unsigned char value)
148 {
149     int ret = -1;
150     
151     gpiohandledata.values[0] = value;
152     if ((ret = ioctl(gpiohandle.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &gpiohandledata)) < 0){
153         printf("LEDS_MULTI_CTRL_IOCTL_MULTI_SET failed\n");
154         return -errno;
155     }
156     
157     return 0;
158 }

 

 

 

posted @ 2020-11-27 11:10  luoyuna  阅读(2168)  评论(0编辑  收藏  举报