GOLDEN RULES FOR RTOS PROGRAMMING

Programming is not about typing, It's about thinking

Author of this page : Jaydeep Shah

Email : radhey04ec@gmail.com

https://os.mbed.com/media/uploads/radhey04ec/istock-817577680.jpg

-RTOS (Real Time OS) and thread concepts are always useful when you want to achieve deadline ,and also you can use your CPU core more efficiently. As we know when we want to handle multiple task or events at a same time parallel execution and thread concepts are very useful to handle this situation.

But things become messy and hard to debug if you miss some rule while coding . Your CPU is single core that means your CPU can only execute one instruction at a time. With help of pipe-lining ,catch memory and different types of architecture related performance enhancement concepts helps to speed up the processing speed . Because of this limitation ideally your CPU handle one task at a time, but to handle multiple tasks you need splits time slots for different processes. Here your thread priority , scheduler , KERNEL and RTOS itself play important roles .

so lets get started.....

RULE #1

"Thread Function always return void "

In general case Threads never terminate , and that cause we always use while(true) statement inside thread functions. After creating thread object if you will try to connect it with functions which is returning some data then there will be a chance of compile time error or OS-CRASH message after uploading code on your board. If you are using any other IDE / Platform then it is hard to debug this problems . So always keep in minds "Functions which are related with thread never return anything".

Here is the one example , beginners (and sometimes hard coder) does these mistakes.

Thread with return type functions

#include "mbed.h"
#include "rtos.h"

Thread T1;

float measure_data(void); //Function declaration only

//Above function return float type value

int main()
{

T1.start(measure_data);  //Never connect this type of functions with thread

while(true)
{

}

}

So now we are ready to learn second rule.

Quote:

Computers are good at following instructions ,but not at reading your mind.

RULE #2

Use right way to set priority of Thread

This is most important when you use MBED platform, because you will not get any compile time error.

There are way to identify error ,first is connect your board with serial terminal where you can see OS-CRASH message and error code , second one is on board user led blinking . (Here is another point : Never use on board led , there is chance of miss guide your interpretation). Oops!!!! ERROR : 0x80010132 Check below image, if you are getting this type of message on your serial terminal then probably you did some Thread parameters related message :

https://os.mbed.com/media/uploads/radhey04ec/error.jpg

This is because we used wrong method to set Thread priority. We used dot method to call class function set_priority() .

Example

Wrong method to set thread priority

#include "mbed.h"
#include "rtos.h"'

Thread T1;

int main()
{

T1.set_priority(osPriorityLow1);  //Wrong way.....

}

Never use this method... otherwise you end up with OS crash.......................

https://os.mbed.com/media/uploads/radhey04ec/o-woman-at-computer-facebook.jpg

I have not checked thread related library , but this is may be class member function set_priority() try to modify access protected or private data . Anyway simple way is use Constructor I mean assign priority when creating Thread object , or another way is manual turning on /off using SEMAPHORE or SIGNAL mechanism.

Solution for Thread priority

#include "rtos.h"
#include "mbed.h"

Thread T1(osPriorityLow);  //SET PRIORITY AT  DECLARATION TIME --- C++ CONSTRUCTOR CONCEPT
Thread T2;

//Function declaration
void do_this(void);

int main()
{

T1.start(do_this);  //right way ...

}

Quote:

Your code represents your Thinking Level !!!

RULE #3

Never Use long code in ISR - INTERRUPT SERVICE ROUTINE

This is most and important rules doesn't matter you are using which programming technique or platform. Micro controller suspend all other Threads and process when Interrupt generated . If you are using multitask environment (Number of threads and parallel process) then this type of Interrupt cause microcontroller suspend all other important task.

Let's see one example :

LED blinking using thread concept


//CONCEPTUAL CODE ONLY  -need proper object and declaration if you want to use it on MBED

Thread T1;

void led_blink()
{

led ! =led;
wait(1); // 1 second delay

}

int main()
{
T1.start(led_blink);
wait(1);
}

You can see Led blink almost on 1 second interval. Simple and straight forward process. But letss see what happen if ISR is too long.

LONG ISR with Threads

InterruptIn Push_button(PA_1) ;  // Push button base interrupt object

Thread T1;

void led_blink()
{
led != led;  // led state changing

}

void ISR_FUNCTION()
{
.........................
..........LONG CODE & WAIT() METHOD...............
..........................

}
int main()

{
T1.start(led_blink);
push_button.rise(&ISR_FUNCTION);  //Interrupt on rising edge

}

https://os.mbed.com/media/uploads/radhey04ec/mv5bowm1nzaym2itmtnlmc00nzrmltk5owmtmmqzntfiode0ngqxxkeyxkfqcgdeqxvynjmxnzq2ntq-._v1_sx600_cr0-0-600-337_al_.jpg

Yes, your board pause all other parallel processes and that cause Failure and serious damage. It is important when deadline in RTOS is very critical specially for medical or defense base applications.

Simple solution is never use LONG CODE & DELAY inside ISR. As a programmer you need to serve ISR as soon as quick so CPU can concentrate on other parallel processes & threads.

- Use some types of Flag variable and monitor that flag in main or other Thread. Do the task according Flag condition changes.

- Use Semaphore or SIGNAL type mechanism , when Interrupt occur , ISR will run and change Semaphore variable or set/reset signal and other thread continually monitor that signal to do things accordingly.

-Never use long Code inside ISR.

-Avoid to use any type of delay and function call inside ISR.

Quote:

Sometimes it's better to leave something alone, to pause, and that's very true of programming

RULE #4

Inside ISR - Think twice before using any Functions

If you are inside ISR block, seriously this is very dangerous place specially multi process environment

Yes, that is true because of MUTEX GUARD . If possible do not use any functions inside ISR routine.

https://os.mbed.com/media/uploads/radhey04ec/lady_security_guard_services.jpg

MUTEX protect many library (many class member functions) , basically it allow to access one process at a time to avoid some critical situation / condition. So if you refer many API refrence /Handbook you will see many functions are not callable from ISR.

I have attached below one image regarding this subject ,so always refer related documentation and library before using in ISR. One simple example in MBED is Serial class. If you create Serial object and attached interrupt with that object to know timing of Transmitting /Receiving new data. But if you try to call printf() ,getc(), puts() type functions inside ISR than you will get error or chance of damaging OS code.

To avoid complexity many programmers use RawSerial instead of Serial. RawSerial have no any MUTEX Guard protection.

https://os.mbed.com/media/uploads/radhey04ec/untitled.jpg

Here I attached one example of RawSerial class:

Import program19_RAWSERIAL_UART_RECEIVE

UART INTERRUPT FOR READING SERIAL DATA HERE I USED RawSerial class to read data from Slave device on UART PORT. MODULE IS TESTED WITH TERMINAL. JAYDEEP SHAH --radhey04ec@gmail.com

Specially whenever you deal with stdio.h library related functions that time more concentration require. Entire library is protected with Mutex guard.

I have discussed some important rules here, there are many other parameters which are also important for programming , but I do not want to discuss here in details.

  1. 1 : CLEAR UART BUFFER BEFORE STORING AND READING DATA (Specially when data comparison require)
  1. 2: Always declare all functions on TOP before creating threads / object / ISR - This is because compiler can not find these if thread declare first.
  1. 3: Avoid to write same code again and again. Use function call or proper method.
  1. 4: Make sure are you going with POP (Process Oriented) or OOPS (Object oriented) way.

Author information :

JAYDEEP SHAH - Research & Development Engineer ELECTRONICS & COMMUNICATION

Email : radhey04ec@gmail.com


Please log in to post comments.