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
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 }