Menu

Real Time Systems

0 Comment


Introduction

Here I would like to write about the simple fitness device project I had been working on. It is based on the course Real time Bluetooth Networks  in Edx.

Objective

To build  a fitness device which runs on a Real Time Operating System.

  • Understanding of the types of schedulers and its implementation
  • Creation of threads
  • Implement blocking and sleeping semaphores

The RTOS makes use of 2 event threads and 6 main threads. A Round Robin scheduler is implemented with FIFO queues, blocking and sleeping features. The 2 hardware components used are MK-II Booster Pack and TM4C123GXL microcontroller.
The MK-II Booster Pack has all the necessary sensors embedded on it. It has an LCD display, 2 switches, a joystick, accelerometer, microphone, buzzer light and temperature sensors, while the TM4C123GXL is the microcontroller in which the algorithms are written.
The user code takes inputs from light, microphone, accelerometer, sound sensors and switches. It performs simple measurements of light intensity, sound, calculations for number of steps walked, temperature and it displays these values in a LCD display.
The 2 event threads are run using hardware timer interrupts and the 6 main threads are switched using the SysTick timer. The threads are as follows.
Thread0 : Event thread, samples microphone input at 1000 MHz
Thread1 : Event thread, samples accelerometer input as 10 Hz
Thread2 : Main thread, to detect steps, it runs about 10 Hz
Thread3 : Main thread, take input from buttons and outputs to buzzer or LED.
Thread4 : Main thread, measures temperature. Runs at 1 Hz.
Thread5 : Main thread, output numerical data to LCD, runs at 1 Hz.
Thread6 : Main thread, measures light, runs 1.25 Hz
Thread7 : Main thread, it does not sleep or block, hence keeps the OS running even when all the threads are sleeping or blocking.

Theory 

 What is an RTOS?

A software which manages resources in a computer system such as memory, I/O data, processors, schedules and switches tasks accordingly within the expected timing constraints is called a Real Time Operating System (RTOS).

Working of the RTOS

To build an RTOS, it is essential to understand the SysTick timer, semaphores, FIFO queues, creation of threads, thread switching and launching the OS. The RTOS has the following structures and functions.

  • Struct tcb{}
  • OS_Init(void)
  • void SetInitialStack(int i)
  • int OS_AddThreads()
  • int OS_AddPeriodicEventThread()
  • void static runperiodicevents()
  • void OS_Launch()
  • void Scheduler(void)
  • void OS_Sleep(uint32_t sleepTime)
  • void OS_InitSemaphore()
  • void OS_Wait()
  • void OS_Signal()
  • void OS_FIFO_Init()
  • int OS_FIFO_Put()
  • uint32_t OS_FIFO_Get()

SysTick Timer

A timer has to be present for the switching of the threads to happen. Hence, there is a core device in the Cortex M architecture called SysTick timer which is commonly used to generate periodic interrupts. These interrupts can be used to measure the time and run the threads accordingly. It is a 24 -bit down counter that runs at the bus clock frequency. It has 3 registers.
SysTick Control and Status Register (STCTRL)

SysTick Reload Value Register (STRELOAD)

SysTick Current Value Register (STCURRENT)

To configure the SysTick timer to generate periodic interrupts, the following steps have to be followed.

  1. Clear the ENABLE bit in STCTRL register
  2. Set values into STRELOAD Register.
  3. Write any desired value to STCURRENT Register.
  4. Set clock source as System clock in STCTRL.
  5. Enable the interrupts INTEN in STCTRL.
  6. Estabblish the priority for Systick interrupts using the SYSPRI3 Register.

Once the value in the STCURRENT register decrements to 0, the COUNT bit in the STCTRL register is set and STCURRENT is again reloaded with the value present in the STRELOAD register. Later the COUNT but is cleared. This way, periodic interrupts are generated with SysTick Timer to run the scheduler.The SysTick ISR works on the bus frequency, hence the frequency of interrupt is fbus/n+1.

Where ‘fbus is the bus frequency and ‘n’ is the reload value in STRELOAD register.

Threads

The smallest processing unit in an operating system is called a thread. They are the dynamic execution of a program.
A thread consists of a thread control block, stack and a program.

Thread Control Block (TCB) :

It is a structure that holds the attributes of the thread. It has one stack pointer which points to the stack for this thread, a link to see that the task control block forms a linked list and other attributes such as sleep and block.

Program:
It is the image of each thread and contains the set of codes which is to be executed.
Stack :
It is an array of contiguously allocated data which has details of respective threads. It shows where the program execution is starting etc. The stack is created using the SetInitialStack() function. The TC’s stack pointer points to the starting of the stack and the program counter (second last register) points to the program associated with the respective thread.

Thread Addition :
The OS_AddThreads() function is used to connect the threads with each other i.e connect programs associated with each thread with the TCB and initial stack.

Launching the OS and switching between the threads :

The OSLaunch() function is used to launch the OS. First configure the SysTick timer is done. Initially, the interrupts are disabled, the STCURRENT value is set to 0 and the SysTick is given the lowest priority. This is so that the event threads are given higher priority and do not switch out before the main thread switches. Set the reload value and enable the clock . The periodic events are also initialized in the OS_Launch. Finally, the Start_OS() function is used to set the stack pointer of the CPU with that of the first thread.

The StartOS function is written in assembly so that it is easy to manipulate the registers of the stack. It sets the first thread to the CPU stack pointer.
Once the thread is initialized and the OS is launched and the first thread is successfully running, after a given time slice mentioned by the SysTick timer, the thread must be switched so that other tasks can run. Hence, once the SysTick timer goes off after the time slice, the SysTick Handler is called to switch the threads.

First we disable the interrupts, push all the stack registers and processor stack pointer of the old thread back to the respective thread’s stack and TCB. Next an OS function is responsible for the sequential execution of the threads. It gives the threads the notion of concurrent processing. The threads do not run simultaneously, but run one at a time, switching between threads. This function is called a scheduler. The scheduler points to the next thread which has to run. (i.e the RunPtr now points to the next thread’s stack pointer). The scheduler skips the blocked or sleeping thread. Later pop the registers and enable the interrupts.

Note : 16 stack registers and the stack pointer in TCB are involved during the thread initialization and switching.
This thread switching is done every time the SysTick goes off. In order to improve the speed of switching, the OS_Suspend function is introduced. If the thread finishes running before the time slice, then it calls the OS_Suspend. This function simply triggers the SysTick interrupt again and the thread is switched in the SysTick handler. The STCURRENT is reset to zero in order to give full time slice to the next thread.

Event Threads :
They occur when there is changes in the hardware status eg, I/O triggering or ADC sampling. They are functions which don’t have any parameters or return values and the time to execute an event thread are short and bounded.

Semaphores :
After the successful OS launching and running of threads, we need a synchronize all the threads and run in order to build an real time processing embedded device. Hence, we use the concept of semaphores to synchronize and communicate between the threads.
A semaphore is basically a flag or counter that is used to communicate between the threads. It had 3 functions namely, OS_InitSemaphore, OS_Wait, and OS_Signal
OS_InitSemaphore

This function is used to initialize and store the semaphore value.
OS_Wait
If the OS_wait function is called with the semaphore value less than 0, then the thread will be blocked so that the scheduler skips this thread while switching. This is called blocking semaphore.

OS_Signal
This function will just increment the counter and if any thread is blocking on this semaphore, then it will be released.

First In First Out (FIFO) Queue :
This queue is used for creating a buffer interface between threads to store and transfer data. The data produced by threads is stored in this buffer and other threads can process this data as long as the buffer is not empty.
The below snippet is a 1 semaphore implementation where OS_FIFO_Init() function initializes variables and semaphore for the FIFO. The OS_FIFO_Put function stores data from the threads into the buffer and the OS_FIFO_Get() function returns the data from buffer to other threads.
 

 The links for the Codes and Video are as follows :

Reference

https://www.edx.org/course/real-time-bluetooth-networks-shape-the-world
https://www.cse.iitb.ac.in/~erts/html_pages/Resources/Tiva/tm4c123gh6pm-Datasheet.pdf
 

Get Email Updates
Free subscription to updates
We respect your privacy.

Tags: , , , , , , , , , , ,
Guest Blogging

Write for us - with benefits!

error: Copyright Content. Please refer to content policy,
%d bloggers like this: