From Variscite Wiki

Manipulating a single GPIO via /sys/class/gpio

Using a command line or a script

GPIOs in i.MX are grouped in groups of 32 pins.
For example, GPIO0_3 belongs to the first group, pin 3. Its absolute number will be 3.
GPIO4_21 will be 4*32+21=149.
Assuming this GPIO is defined in your device tree, the following is an example of how to use it from userspace.

To export the GPIO for userspace use:

# echo 149 > /sys/class/gpio/export

To configure as output:

# echo out > /sys/class/gpio/gpio149/direction

Set GPIO high:

# echo 1 > /sys/class/gpio/gpio149/value

Set GPIO low:

# echo 0 > /sys/class/gpio/gpio149/value

To configure as input:

# echo in > /sys/class/gpio/gpio149/direction

Read the current value:

# cat /sys/class/gpio/gpio149/value

To free the GPIO after you're done using it:

# echo 149 > /sys/class/gpio/unexport

Using a C application

All of the command line operations above can be translated to C code:
Reserve (export) the GPIO:

#define IMX_GPIO_NR(port, index)    ((port)*32)+((index)&31))

int fd;
char buf[MAX_BUF]; 
int gpio = IMX_GPIO_NR(4, 21); /* Just an example */

fd = open("/sys/class/gpio/export", O_WRONLY);

sprintf(buf, "%d", gpio); 

write(fd, buf, strlen(buf));


Set the GPIO direction:

sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);

fd = open(buf, O_WRONLY);

/* Set out direction */
write(fd, "out", 3); 
/* Set in direction */
write(fd, "in", 2); 


In case of out direction set the GPIO value:

sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);

fd = open(buf, O_WRONLY);

/* Set GPIO high status */
write(fd, "1", 1); 
/* Set GPIO low status */
write(fd, "0", 1); 


In case of in direction get the current GPIO value:

char value;

sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);

fd = open(buf, O_RDONLY);

read(fd, &value, 1);

if (value == '0') { 
     /* Current GPIO status low */
} else {
     /* Current GPIO status high */


Once finished, free (unexport) the GPIO:

fd = open("/sys/class/gpio/unexport", O_WRONLY);

sprintf(buf, "%d", gpio);

write(fd, buf, strlen(buf));


Important notes:

  • Remember that after the first read operation, the file pointer will move to the next position in the file, so to get a correct value for each read operation you simply have to set the file pointer at the beginning of the file before reading by using the following command:
lseek(fd, 0, SEEK_SET);
  • This is only a short example. If you want to use it in your code, remember to add error handling to it.