一.通過過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 }