0 PrefaceThis article describes how to control the easyarm gpio port through the file IO sysfs. Control gpio through sysfs, first access the/sys/class/gpio directory, write the gpio number to the export file, so that the operation interface of this gpio is exposed from the kernel space to the user space, gpio operation interfaces include ction and value. Direction controls the gpio direction, while value controls the gpio output or obtains the gpio input. For Linux learning, you can start from the application. First, you don't have to worry about writing the Linux driver. First, you can get started with Linux.
[Related blog] [easyarm I. mx28 Study Notes-install and use TFTP] [Raspberry Pi Study Notes-shell script operation gpio] [Linux Study Notes-Example: makefile index blog]
[Code repository] The code repository is located in Bitbucket -- easyarm-gpio-sysfs. Use Hg to clone or directly download the zip package. Do not use any version of Internet Explorer to access the link, unless you know that the Internet Explorer you are using complies with the HTML5 standard. Google or Firefox browser is recommended for access. If the domestic dual-core browser is used, switch to the speed mode.
1. Expose the gpio operation interface
static int gpio_export(int pin){ char buffer[BUFFER_MAX]; int len; int fd; fd = open("/sys/class/gpio/export", O_WRONLY); if (fd < 0) { fprintf(stderr, "Failed to open export for writing!\n"); return(-1); } len = snprintf(buffer, BUFFER_MAX, "%d", pin); if (write(fd, buffer, len) < 0) { fprintf(stderr, "Fail to export gpio!"); return -1; } close(fd); return 0;}
2. Hide the gpio operation interface
static int gpio_unexport(int pin){ char buffer[BUFFER_MAX]; int len; int fd; fd = open("/sys/class/gpio/unexport", O_WRONLY); if (fd < 0) { fprintf(stderr, "Failed to open unexport for writing!\n"); return -1; } len = snprintf(buffer, BUFFER_MAX, "%d", pin); if (write(fd, buffer, len) < 0) { fprintf(stderr, "Fail to unexport gpio!"); return -1; } close(fd); return 0;}
3. Configure the gpio direction
static int gpio_direction(int pin, int dir){ static const char dir_str[] = "in\0out"; char path[DIRECTION_MAX]; int fd; snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin); fd = open(path, O_WRONLY); if (fd < 0) { fprintf(stderr, "failed to open gpio direction for writing!\n"); return -1; } if (write(fd, &dir_str[dir == IN ? 0 : 3], dir == IN ? 2 : 3) < 0) { fprintf(stderr, "failed to set direction!\n"); return -1; } close(fd); return 0;}
[Simple description] [1] dir_str [dir = in? 0: 3], Dir = in? 2: 3 if the input is a constant macro in, take dir_str [0] = "in"; if the input constant macro is out, take dir_str [0] = "out ". Here, the "\ 0" in the array is cleverly used ".
4. Control gpio output
static int gpio_write(int pin, int value){ static const char values_str[] = "01"; char path[DIRECTION_MAX]; int fd; snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/value", pin); fd = open(path, O_WRONLY); if (fd < 0) { fprintf(stderr, "failed to open gpio value for writing!\n"); return -1; } if (write(fd, &values_str[value == LOW ? 0 : 1], 1) < 0) { fprintf(stderr, "failed to write value!\n"); return -1; } close(fd); return 0;}
5. Obtain gpio Input
static int gpio_read(int pin){ char path[DIRECTION_MAX]; char value_str[3]; int fd; snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/value", pin); fd = open(path, O_RDONLY); if (fd < 0) { fprintf(stderr, "failed to open gpio value for reading!\n"); return -1; } if (read(fd, value_str, 3) < 0) { fprintf(stderr, "failed to read value!\n"); return -1; } close(fd); return (atoi(value_str));}
6. gpio flip operation[Main function]
Int main (INT argc, char * argv []) {int I = 0; gpio_export (p24); gpio_direction (p24, out ); // gpio is in the output state for (I = 0; I <10; I ++) {printf ("led blink \ n"); gpio_write (p24, I % 2 ); usleep (500*1000);} gpio_write (p24, 0); // restore the output low-level gpio_unexport (p24); Return 0 ;}
[Makefile] -- the code tab here may display problems. Use the code repository as the main component.
# Executable File target = test # source file SRCS = gpio-sysfs.c # target file objs =$ (SRCS :. C =. o) # command compiler and options cross = arm-FSL-Linux-gnueabi-CC =$ (Cross) gccstrip =$ (Cross) stripcflags =-wall-STD = gnu99-O2 $ (target): $ (objs) $ (CC)-O [email protected] $ ^ $ (strip) [email protected] Clean: Rm-RF $ (target) $ (objs) # continuous action, clear and compile the Link first, and copy it to tftpboot install: clean $ (target) @ echo copy to the tftpboot directory CP $ (target )~ /Tftpboot @ echo copy end # The compilation rule [email protected] indicates the target file $ <indicates the first dependent file %. o: %. C $ (CC) $ (cflags)-O [email protected]-C $ <
[Cross-compile and copy to the tftp root directory] Make then copies the executable file test to the tftp root directory. For details about how to use makefile, see [Linux study notes -- Example: makefile index blog]
To facilitate the operation, create a script named run-test.sh in the target board and modify the execution permission. For more information about how to use TFTP, see easyarm I. mx28 Study Notes-install and use TFTP]
#!/bin/sh tftp -g -r test 192.168.1.106 chmod a+x test echo "start to run test." ./test
Execute the script to run test./run-test.sh
Figure 1 Final Result
7. Conclusion[1] file I/O operations on gpio, four functions are used: open close read write. [2] Write a specific gpio number to the export to expose the control interface from the kernel space to the user space. [3] using file I/O to operate Linux peripherals is universal. Raspberry Pi can also use this method.