An Operating System requires numerous tasks to be performed at the same time. The ‘Parallel Processing’ is the term which refers to the technique of executing many tasks at the same time. However actual parallel processing is not possible in commonly available computers, but they can simulate such an effect by high speed switching of small amount of CPU time to each of the process that need to be executed. In Operating Systems this process is called ‘Scheduling’ and it helps to achieve the multitasking in an Operating System.
The Raspberrypi is a microcontroller board which is powerful enough to run large operating systems like Linux, Mac and Windows. The Raspberrypi is a microcontroller board which runs on a SoC chip from the Broadcom with ARM11 processor at the core. The Board is a mini computer itself without any input or output devices but ports provided to connect them. The Raspberrypi is called a mini-computer because the SoC has the powerful ARM11 processor which runs on 700 MHz at its core and having the peripherals like timers, interrupt controller, GPIO, PCM / I2S, DMA controller, I2C, SPI slave, PWM, UART, USB, graphical processing unit (GPU) which includes VideoCore, MPEG-2 and MPEG-4 and a 512 MB SDRAM. There is an Ethernet port which can be used to connect the board to a computer network.
The Linux Operating Systems like Archlinux ARM, OpenELEC, Pidora, Raspbmc, RISC OS and the Raspbian and also Ubuntu versions are available for the Raspberrypi board. Linux operating systems especially Ubuntu is preferred for all kind of programming and development. The immediate advantage of having an Operating System like Ubuntu running on an embedded system device is multitasking. This article discusses how to perform single user multitasking in a Raspberrypi board by executing a single C code with multi-threading rather than executing different codes one after the another as background processes, or using a Shell script.
In this project the Raspberrypi board is loaded with Ubuntu and is remotely accessed using VNC. The Raspberrypi board is also connected to the internet. There are 26 connectors which can be taken out from the connector port of the Raspberrypi board. All the connector pins are taken out using 13*2 pin female connectors and at the other end of their wire 26 pin Burg stick male connectors are attached. The Burg stick male connectors allow each pin out from the Raspberrypi board to be plugged into the holes of a breadboard. To access the pins that coming out of the Broadcom controller of the Raspberrypi board using C language, a C library is available called “bcm2835” which has been downloaded and installed.
The term ‘Process’ refers to the code which is currently in execution and the term ‘thread’ refers to the small part of that code which the CPU will execute at a particular time. The fork () and execve () functions simply creates a new process from one particular process which then starts executing individually. However threading is a technique which makes different parts of the same process to execute in parallel. The following section discusses how to create a multi-threading code for blinking 8 LEDs for a Raspebrrypi board in such a way that they are being operated parallel.
There are eight general purpose IO pins on the 13*2 pin connectors of the Raspberrypi board and to each one of them a LED is connected through 1K resistor. Separate code can be written to blink the LEDs individually and made them into executable files named blink2, blink3, blink4, blink5, blink6, blink7 and blink8. The user can run any of the LED blinking programs from the command line. For example to execute the file ‘blink1’, the user can use the following command:
./blink1
The user can perform multi-tasking on them using the following commands one after the other:
./blink1 &
./blink2 &
./blink3 &
./blink4 &
./blink5 &
./blink6 &
./blink7 &
./blink8 &
The best method is to use create a thread for each of the above LED blinking code in a single C code and then execute it. The C code should have all the LED blinking codes as separate functions and then allow them to execute as threads when the entire code is executed. The threads can be created in a C code using the function ‘pthread_create ()’.
pthread_create ()
The function ‘pthread_create ()’ can start execute a function as a separate thread within the main process which calls the ‘pthread_create ()’. The prototype of the function ‘pthread_create ()’ is defined in the header file <pthread.h> as given below:
int pthread_create (
pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine) (void *),
void *arg
);
The third argument ‘start_routine’ in the above prototype is the pointer to a function which the ‘pthread_create ()’ can make the thread. A successful call to pthread_create() stores the ID of the new thread in the buffer pointed to by ‘thread’, which is the first argument.
The second argument ‘attr’ is the attributes that required to create the new thread and if the ‘NULL’ is used the default attributes will be used. The last argument ‘arg’ is the argument that need to be passed to the function which will start execute as a thread.
If the codes for ‘blink1’, ‘blink2’ etc. are written as separate functions in a single C file which are declared as the following:
void blink1 ( void );
void blink2 ( void );
void blink3 ( void );
void blink4 ( void );
void blink5 ( void );
void blink6 ( void );
void blink7 ( void );
void blink8 ( void );
The above functions can be executed as thread from the main code as given below:
int main()
{
pthread_t th1, th2, th3, th4, th5, th6, th7, th8;
pthread_create ( &th1, NULL, ( void* ) blink1, NULL );
pthread_create ( &th2, NULL, ( void* ) blink2, NULL );
pthread_create ( &th3, NULL, ( void* ) blink3, NULL );
pthread_create ( &th4, NULL, ( void* ) blink4, NULL );
pthread_create ( &th5, NULL, ( void* ) blink5, NULL );
pthread_create ( &th6, NULL, ( void* ) blink6, NULL );
pthread_create ( &th7, NULL, ( void* ) blink7, NULL );
pthread_create ( &th8, NULL, ( void* ) blink8, NULL );
while ( 1 );
return 0;
}
***Note that in this project the latest version of library “bcm2835” is used with an old version of Raspberrypi board. It is not possible to access the pin number 13 of the old board with the latest library version and hence in the code “blink3.c” the pin number 24 is used to blink the 3rd LED. The circuit diagram is also drawn accordingly. Those who have the latest version of the board can use the pin 13 without any trouble.
To find the ‘Revision’ and other important details about the Raspberrypi board, use the following command:
cat /proc/cpuinfo
Project Source Code
###
#include <bcm2835.h>#include <pthread.h>#include <unistd.h>#define PIN1 RPI_GPIO_P1_11#define PIN2 RPI_GPIO_P1_12#define PIN3 RPI_GPIO_P1_24#define PIN4 RPI_GPIO_P1_15#define PIN5 RPI_GPIO_P1_16#define PIN6 RPI_GPIO_P1_18#define PIN7 RPI_GPIO_P1_22#define PIN8 RPI_GPIO_P1_07void blink1 ( void );void blink2 ( void );void blink3 ( void );void blink4 ( void );void blink5 ( void );void blink6 ( void );void blink7 ( void );void blink8 ( void );int main(){pthread_t th1, th2, th3, th4, th5, th6, th7, th8;if (!bcm2835_init())return 1;pthread_create ( &th1, NULL, ( void* ) blink1, NULL );pthread_create ( &th2, NULL, ( void* ) blink2, NULL );pthread_create ( &th3, NULL, ( void* ) blink3, NULL );pthread_create ( &th4, NULL, ( void* ) blink4, NULL );pthread_create ( &th5, NULL, ( void* ) blink5, NULL );pthread_create ( &th6, NULL, ( void* ) blink6, NULL );pthread_create ( &th7, NULL, ( void* ) blink7, NULL );pthread_create ( &th8, NULL, ( void* ) blink8, NULL );while ( 1 );bcm2835_close();return 0;}void blink1 ( void ){// Set the pin to be an outputbcm2835_gpio_fsel(PIN1, BCM2835_GPIO_FSEL_OUTP);// Blinkwhile (1){// Turn it onbcm2835_gpio_write(PIN1, HIGH);// wait a bitbcm2835_delay(500);// turn it offbcm2835_gpio_write(PIN1, LOW);// wait a bitbcm2835_delay(500);}}void blink2 ( void ){// Set the pin to be an outputbcm2835_gpio_fsel(PIN2, BCM2835_GPIO_FSEL_OUTP);// Blinkwhile (1){// Turn it onbcm2835_gpio_write(PIN2, HIGH);// wait a bitbcm2835_delay(1000);// turn it offbcm2835_gpio_write(PIN2, LOW);// wait a bitbcm2835_delay(1000);}}void blink3 ( void ){// Set the pin to be an outputbcm2835_gpio_fsel(PIN3, BCM2835_GPIO_FSEL_OUTP);// Blinkwhile (1){// Turn it onbcm2835_gpio_write(PIN3, HIGH);// wait a bitbcm2835_delay(1500);// turn it offbcm2835_gpio_write(PIN3, LOW);// wait a bitbcm2835_delay(1500);}}void blink4 ( void ){// Set the pin to be an outputbcm2835_gpio_fsel(PIN4, BCM2835_GPIO_FSEL_OUTP);// Blinkwhile (1){// Turn it onbcm2835_gpio_write(PIN4, HIGH);// wait a bitbcm2835_delay(2000);// turn it offbcm2835_gpio_write(PIN4, LOW);// wait a bitbcm2835_delay(2000);}}void blink5 ( void ){// Set the pin to be an outputbcm2835_gpio_fsel(PIN5, BCM2835_GPIO_FSEL_OUTP);// Blinkwhile (1){// Turn it onbcm2835_gpio_write(PIN5, HIGH);// wait a bitbcm2835_delay(2500);// turn it offbcm2835_gpio_write(PIN5, LOW);// wait a bitbcm2835_delay(2500);}}void blink6 ( void ){// Set the pin to be an outputbcm2835_gpio_fsel(PIN6, BCM2835_GPIO_FSEL_OUTP);// Blinkwhile (1){// Turn it onbcm2835_gpio_write(PIN6, HIGH);// wait a bitbcm2835_delay(3000);// turn it offbcm2835_gpio_write(PIN6, LOW);// wait a bitbcm2835_delay(3000);}}void blink7 ( void ){// Set the pin to be an outputbcm2835_gpio_fsel(PIN7, BCM2835_GPIO_FSEL_OUTP);// Blinkwhile (1){// Turn it onbcm2835_gpio_write(PIN7, HIGH);// wait a bitbcm2835_delay(3500);// turn it offbcm2835_gpio_write(PIN7, LOW);// wait a bitbcm2835_delay(3500);}}void blink8 ( void ){// Set the pin to be an outputbcm2835_gpio_fsel(PIN8, BCM2835_GPIO_FSEL_OUTP);// Blinkwhile (1){// Turn it onbcm2835_gpio_write(PIN8, HIGH);// wait a bitbcm2835_delay(4000);// turn it offbcm2835_gpio_write(PIN8, LOW);// wait a bitbcm2835_delay(4000);}}###
Circuit Diagrams
Project Components
Project Video
Filed Under: Raspberry pi
Filed Under: Raspberry pi
Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.
Tell Us What You Think!!
You must be logged in to post a comment.