216_Fig_1A lot of development boards with different distributions of Linux are available in the embedded market. These boards come with different processors and therefore require different methods/libraries to handle their GPIOs (general-purpose input/output). To simplify this, one can use SYS file system (SYSfs) interface on any Linux-based board. This article focusses on SYSfs interface and sheds some light on shell scripting and application program to access GPIOs using this interface.

Linux is playing a significant role in the constantly-changing embedded electronics market. Day by day, the use of embedded Linux in modern embedded product development is becoming popular. Also, hardware platform plays an important role whilst implementing embedded Linux system. There are a lot of Linux-based development boards available in the market such as Raspberry Pi, BeagleBoard family, Panda board, Wand board and the others. These boards support various distributions of Linux such as Debian, Ubuntu, Angstrom, ArchLinux, Fedora and Android. The major problem in using GPIO pins in a Linux board is that the method to access them depends on the processor used and library support. Since there are a large variety of processors being used in embedded Linux boards, it becomes difficult to learn all the processors and then use the GPIOs. Linux, however, simplifies this by using what is called a ‘file system.’

Fig. 2: Device models in class
Fig. 2: Device models in class
Fig. 3: Accessing the GPIO pin
Fig. 3: Accessing the GPIO pin

File system, in simple language, can be explained as an interface (or rule) to store and access files on a storage device. Usually, in small embedded systems, file system is not used. Instead, the data is accessed directly using memory address through user program. This works fine when the amount of data is small. But as the system grows, it becomes very difficult to manage huge data in this way. This problem is overcome by the use of OS (operating system) and a file system. The OS can handle data from storage devices (memory card/HDD) efficiently with the use of file system.

Explore Circuits and Projects Explore Videos and Tutorials

Linux file system has a feature that simplifies GPIO access. In Linux, memory is separated into two spaces, i.e., kernel space and user space. Kernel space is part of memory occupied by the kernel modules, device drivers and everything that is under kernel’s control, whilst user space is the memory area which all user applications use. Linux treats all devices as if they are files. For instance, GPIOs are just files to the Linux. Thus, accessing GPIOs is like reading/writing of/to these files. Usually these GPIO pins are in kernel space (i.e., directly managed by kernel modules), but there is an easy way to manage these pins from user space.

Accessing GPIO using SYSfs interface
The process of accessing (setting or clearing) the GPIO pins of Raspberry Pi is given below:

READ
Network Storage with Raspberry Pi

Start the terminal of Raspberry Pi, type ‘cd /’ and press the Enter key from keyboard to change directory to root. Now type ‘ls’ and press the Enter key to see contents of directory. Now you are in root file structure of Linux with lots of subdirectories. One of the directories is ‘sys,’ which is nothing but SYSfs. SYSfs exports information about devices and drivers from the kernel space to user space. This mechanism is implemented as file system in ‘sys’ directory.

Now write the following and press Enter key after each command:

 

$ cd sys
$ cd class
$ ls

You will see devices supported by the development board as shown in Fig. 2.

A class gives a higher-level view (overview) of a device and hides implementation details (how internal logic is implemented). This class allows users to handle devices based on what they do, rather than how they work. In simple words, it is like a steering wheel of a car; driver just knows what it does and does not care how it is implemented inside the car.

Fig. 4: Raspberry pin configurations
Fig. 4: Raspberry pin configurations
Fig. 5: LED connection to GPIO04/PIN7
Fig. 5: LED connection to GPIO04/PIN7
Fig. 6: Steps for accessing the GPIO and enabling the LED to blink
Fig. 6: Steps for accessing the GPIO and enabling the LED to blink

Download Source Code: Click Here

Now write ‘cd gpio’ to enter the GPIO directory which contains two files, namely, export and unexport as shown in Fig. 3.

export. By writing GPIO number to this file, GPIO pin control is exported (or transferred) from kernel space to user space. This is equivalent to enabling the GPIO pin.

 

Example: $ echo 19 > export

This will create a ‘gpio19’ node (folder) for GPIO #19. This folder contains files which can be read/written to access GPIO 19 pin.

unexport. Reverses the effect of exporting.

 

Example: $ echo 19 > unexport

This will remove a ‘gpio19’ node (folder).

Now a user can access GPIO using its attributes. To see its attributes, type the below-mentioned commands. (Fig. 3 shows an example of gpio4.)

 

$ cd gpio19
$ ls

After the ‘ls’ command, you will see below-mentioned attributes:

direction. Reads as either ‘in’ or ‘out’ to declare pin as input or output.

value. Reads as either ‘0’ (low) or ‘1’ (high). If the GPIO is configured as an output, this value may be written; any non-zero value is treated as high.

edge. Reads as either ‘none,’ ‘rising,’ ‘falling’ or ‘both.’ Write these strings to select the signal edge(s).

active_low. Reads as either ‘0’ (false) or ‘1’ (true). Write any non-zero value to invert the value attribute both for reading and writing.

Now connect the LED as shown in Fig. 5 and follow the steps below to access the GPIO pins and enable the LED to blink (refer Fig. 6 for the steps). We will only use two attributes: direction and value.

READ
Arduino Projects: Fancy Lights Controller

1. Start the terminal window on Raspberry Pi and go to cd /sys/class/gpio/ directory.
2. Login as root (as we are accessing kernel space) by ‘su’ command and type the root password when prompted.
3. Export GPIO4 using ‘echo 4 > export’ command. By this statement you reserve GPIO for your application so other modules will not interfere.
4. New directory named ‘gpio4’ will be created.
5. Enter the directory by typing ‘cd gpio4’ to see and edit attributes of GPIO4.
6. Change attributes as: echo “out” > direction.
7. To switch the LED on use ‘echo 1 > value’ and to switch LED off use ‘echo 0 > value’
8. To see attribute’s value, use cat command: cat value or cat direction.
9. For disabling the GPIO, first write ‘cd ..’ to come one step back and then use ‘echo 4 > unexport’ command. The gpio4 folder will be deleted automatically.

By using these steps, you can enable the LED to blink manually. But what if you want it to blink automatically? For that you will use shell scripting.

Shell is a program that runs in background of a terminal. Terminal accepts command from keyboard and sends it to shell, which finds the meaning and executes the command. User enters commands one by one and they are executed in a similar manner. These commands can be stored as a sequence of commands to a file and shell can execute this file instead of entering the commands one by one in the future. This file is known as a shell script. Shell script is a series of commands written in plain text file. Shell script is just like the MS-DOS batch file.

Create a new file by typing ‘sudo nano firstscript’ in the terminal and enter the code given below in it:

 

#! /bin/bash

cd /sys/class/gpio
echo 4 > export
cd gpio4
echo “out” > direction

for i in {1..10}
do
echo 0 > value
sleep 1
echo 1 > value
sleep 1
done

cd ..
echo 4 > unexport

Now save the script by pressing ‘ctrl + o’ to save and ‘ctrl + x’ to exit.

To make the file executable, write the below-mentioned command in the terminal window:

 

$ chmod 777 firstscript
Now execute the script as follows
$ sudo ./firstscript

Accessing GPIO using SYSfs interface from application
The above steps are for controlling or accessing one GPIO but we can also handle more GPIOs at the same time by using an application. The application (‘c’ program) that we have discussed here also controls one GPIO, but the code can be easily modified to handle more GPIOs. Code accepts GPIO number from user and controls it.

READ
GPS- and GSM-Based Vehicle Tracking System

Create another file with command ‘sudo nano led.c’ for the code of the application program and copy below code in it.

 

————- led.c ————–
#include
#include
#include
#include
#include
#include

int gpio_export(unsigned int );
int gpio_unexport(unsigned int);
int gpio_set_dir(unsigned int ,
unsigned int );
int gpio_set_value(unsigned int ,
unsigned int );

#define SYSFS_GPIO_DIR “/sys/class/
gpio”
#define MAX_BUF 64

int main()
{
int x;
printf(“select the gpio “);
scanf(“%d”,&x); // accept GPIO number
from user

gpio_export(x); // export that gpio
to user space
gpio_set_dir(x,1); // set
direction of gpio as 1=output

while(1) //loop for blinking the led
{
gpio_set_value(x,1); // glowing led
connected to gpio x.
printf(“LED ON\n”);
sleep(1); // delay of 1 second
gpio_set_value(x,0); // led off
printf(“LED OFF”);
sleep(1);
}
// making GPIO free for other kernel
modules if loop is finite
gpio_unexport(x);
return 0;
}

/*********Export function*********/
int gpio_export(unsigned int gpio)
{
int fd, len;
char buf[MAX_BUF];

//opening EXPORT file as Write Only
fd = open(SYSFS_GPIO_DIR “/export”,
O_WRONLY);
if (fd < 0) // error in opening file
{
perror(“gpio/export”);
return fd;
}

len = snprintf(buf, sizeof(buf),
“%d”, gpio);
write(fd, buf, len);
close(fd);

return 0;
}

/********** gpio_unexport ********/
int gpio_unexport(unsigned int gpio)
{
int fd, len;
char buf[MAX_BUF];

fd = open(SYSFS_GPIO_DIR “/unexport”,
O_WRONLY);
if (fd < 0)
{
perror(“gpio/unexport”);
return fd;
}

len = snprintf(buf, sizeof(buf),
“%d”, gpio);
write(fd, buf, len);
close(fd);
return 0;
}

/******* gpio_set_direction *******/
int gpio_set_dir(unsigned int gpio,
unsigned int dir)
{
int fd,len;
char buf[MAX_BUF];

len=snprintf(buf, sizeof(buf), SYSFS_
GPIO_DIR “/gpio%d/direction”, gpio);

fd = open(buf, O_WRONLY);
if (fd < 0)
{
perror(“gpio/direction”);
return fd;
}

if (dir) // 1=output and 0=input
write(fd, “out”, 4);
else
write(fd, “in”, 3);

close(fd);
return 0;
}

/********* gpio_set_value *********/
int gpio_set_value(unsigned int gpio,
unsigned int val)
{
int fd;
char buf[MAX_BUF];

len=snprintf(buf, sizeof(buf),
SYSFS_GPIO_DIR “/gpio%d/value”,
gpio);

fd = open(buf, O_WRONLY);
if (fd < 0)
{
perror(“gpio/set-value”);
return fd;
}

if (val)
write(fd, “1”, 2);
else
write(fd, “0”, 2);

close(fd);
return 0;
}

After copying the code, use ‘ctrl+o’ to save and ‘ctrl+x’ to exit. To compile the code, use in-built gcc compiler in Linux and execute the code that will use SYSfs interface to get the LED blinking connected at a GPIO.

To compile the code:

 

$ gcc -o sysled led.c

To execute the code:

 

$ sudo ./sysled

where sysled is the output filename.


Onkar Ashok Mate is pursuing M.Tech in Electronics from Walchand College of Engineering, Sangli, Maharashtra and V.B. Dharmadhikari is an associate professor at Department of Electronics, Walchand College of Engineering, Sangli, Maharashtra

LEAVE A REPLY