BLOG 2 RTOS

 

RTOS



What is an RTOS?


An RTOS is a piece pof code, or a system that controls other pieces of code. 

PIC Microcontroller Demonstration 

Demo_1 

Run

Demo 01 code below was ran: 

#task(rate=1000ms,max=100ms)
// the function can be called anything that a standard function can be called
void The_first_rtos_task ( )
{
   printf("1\n\r");
}

#task(rate=200ms,max=100ms)
void The_second_rtos_task ( )
{
   printf("\t2!\n\r");

Record
 
The code's output is recoded in Putty. 
#
Demo_01 inital




Review

The code runs each of the tasks at interval, at a given speed rate of 100ms, 200ms, 100ms.

Revise

For an iteration I added more tasks, and reduced the speed for each tasks operation. 

#task(rate=100ms,max=100ms)
void The_third_rtos_task ( )
{
   printf("\t\t3\n\r");
}

#task(rate=100ms,max=100ms)
void The_fourth_rtos_task ( )
{
   printf("\t\t4\n\n\r");
}


Demo_01 modified


Demo_2 

Run
Demo 2 is all about terminating a task, after it runs for a certain amout of time. 
The code below is ran: 

int8 counter;

#task(rate=1000ms,max=100ms)
void The_first_rtos_task ( )
{
   printf("1\n\r");
   // if the counter has reached the desired value, the rtos will terminate
   if(++counter==10)
      rtos_terminate ( );
}

#task(rate=500ms,max=100ms)
void The_second_rtos_task ( )
{
   printf("\t2!\n\r");
}


Record
The code's output is recoded in Putty. 

Demo_02 inital



Review

This code terminates all task when each task ran for 10 counts.

Revise

I included more tasks to be terminated, but it sted of the tasks being terminated we restarted the task using the function rtos_run

#task(rate=100ms,max=100ms)
void The_third_rtos_task ( )
{
   printf("\t\t3\n\r");
}


#task(rate=100ms,max=100ms)
void The_fourth_rtos_task ( )
{
   printf("\t\t5\n\r");
}


void main ( )
{
   // main is the best place to initialize resources the the rtos is dependent
   // upon
   
   while(1)
   {
   counter = 0;
   rtos_run ( );
   printf("RTOS restarting");
   }

Demo_02 modified



Demo_3

Run
Demo 3 is all about enabling and disabling a task, after it runs for a certain amout of time. 
The code below is ran: 

void The_first_rtos_task ( ) {
   printf("1\n\r");
   if(counter==3)
   {
      // to disable a task, simply pass the task name
      // into the rtos_disable function
      rtos_disable(The_third_rtos_task);
   }
}

void The_second_rtos_task ( ) {
   printf("\t2!\n\r");
   if(++counter==10) {
      counter=0;
      // enabling tasks is similar to disabling them
      rtos_enable(The_third_rtos_task);
   }
}


Record
Demo_03 inital


Review

Task 1 disables task 3, after it has completed it's task after  3 counts
Task 2 enables task 3 after  it has completed it's task after 10 count. 

Revise

Task 3 enables task 4, after it has completed it's task after  10 counts
Task 4 disables itself after  it has completed it's task after 5 count. 

void The_third_rtos_task ( ) {
   printf("\t\t3\n\r");
   if(++counter==10) {
   counter=0;
   //enable forurth task
   rtos_enable(The_fourth_rtos_task);
  }
}

void The_fourth_rtos_task ( ) {
   printf("\t\t18!\n\r");
   if(++counter==5) {
   counter=0;
   //enable forurth task
   rtos_disable(The_fourth_rtos_task);
  }
Demo_03 modified


Demo_4 

Run
Demo 4 is all about receiving and sending messages to each task, ( The tasks communicate with each other). 
The code below is ran: 

void The_first_rtos_task ( ) {
   // the function rtos_msg_poll will return the number of messages in the
   // current tasks queue
   // always make sure to check that their is a message or else the read
   // function will hang
   if(rtos_msg_poll ( )>0){
      // the function rtos_msg_read, reads the first value in the queue
      printf("messages recieved by task1 : %i\n\r",rtos_msg_read ( ));
      // the funciton rtos_msg_send, sends the value given as the
      // second parameter to the function given as the first
      rtos_msg_send(The_second_rtos_task,count);
      count++;
   }
}

void The_second_rtos_task ( ) {
   rtos_msg_send(The_first_rtos_task,count);
   if(rtos_msg_poll ( )>0){
      printf("messages recieved by task2 : %i\n\r",rtos_msg_read ( ));
      rtos_msg_send(The_third_rtos_task,count);
      count++;
   }
}

Record

Demo_04 inital



Review

rtos_msg_poll in the first task waits to see if any messages are coming in from task 2, if it does recieve the message it would output a print out that the message has been recieved from task 1. and it rerad's the message using rtos_msg_read. rtos_msg_send then sends the message to task 2, 

Revise

I added and extra task that would be able to read the message sent from task 2. 

void The_third_rtos_task ( ) {
   rtos_msg_send(The_second_rtos_task,count);
   if(rtos_msg_poll ( )>0){
      printf("messages recieved by task3 : %i\n\r",rtos_msg_read ( ));
      count++;
   }
}

Demo_04 modified


Demo_5 

Run
Demo 5 is all about yeilding. 

The code below is ran: 

void The_first_rtos_task ( ) {
   int count=0;
   // rtos_yield allows the user to break out of a task at a given point
   // and return to the same ponit when the task comes back into context
   while(TRUE){
      count++;
      rtos_msg_send(The_second_rtos_task,count);
      rtos_yield ( );
   }
}

void The_second_rtos_task ( ) {
   if(rtos_msg_poll( ))
   {
      printf("count is : %i\n\r",rtos_msg_read ( ));
   }
}

Record
Demo_05 inital



Review

When task 1 runs and sends a message to task 2, rtos_yield,  allows the user to exit out of that task 1 at a certain point of the task, and then  return back to that point when the task comes back into context. task 2 then reads the message. 

Revise

I added a similar task to taks 3 and task 4 

void The_third_rtos_task ( ) {
int count=0;
   // rtos_yield allows the user to break out of a task at a given point
   // and return to the same ponit when the task comes back into context
   while(TRUE){
      count--;
      rtos_msg_send(The_fourth_rtos_task,count);
      rtos_yield ( );
   }
}

void The_fourth_rtos_task ( ) {
   if(rtos_msg_poll( ))
   {
      printf("monitor is : %i\n\r",rtos_msg_read ( ));
   }
}
Demo_05 modified



Demo_6 

Run
Demo 6 is all about semaphores. 

void The_first_rtos_task ( ) {
   int i;

   // this will decrement the semaphore variable to zero which signals
   // that no more user may use the resource
   rtos_wait(sem);
   for(i=0;i<5;i++){
      
      //output_low(RED); delay_ms(1000); output_high(RED); delay_ms(1000);
      
      lcd_gotoxy( 1,1);
      printf(lcd_putc,"task1 red on  ");
      //clear lcd display 
      delay_ms(1000);
      //lcd_putc('\f');
      
      lcd_gotoxy( 1,1);
      printf(lcd_putc,"task1 red off");
      //clear lcd display 
      delay_ms(1000);
      //lcd_putc('\f');
      
      
      rtos_yield ( );
   }
   // this will inrement the semaphore variable to zero which then signals
   // that the resource is available for use
   rtos_signal(sem);
}


Review
Task 1 and task 2 are tasked to turn of an on an led and this is to be displayed in the LCD display.  the rtos_wait(sem)  decrement's to zero, the signals that is no longer used by the user. And the rtos_signal(sem) then  increments it to zero, the signal that are available for use.  

Revise

A similar task is written for task 3 to turn on and off an LED, when task 2 turn of it's LED the rtos_wait (sem), will wait for the available led, and then used it for 500ms, then it turns of after 500ms, this is displayed in the LCD as " Red on", "Red off"
Demo_06 modified 







Demo_7 

Run
Demo 6 is all about await. 

void The_first_rtos_task ( ) {
   // rtos_await simply waits for the given expression to be true
   // if it is not true, it acts like an rtos_yield and passes the system
   // to the next task
   rtos_await(count==10);
   //output_low(GREEN); delay_ms(200); output_high(GREEN); delay_ms(200);
         
      lcd_gotoxy( 1,1);
      printf(lcd_putc,"task1 red on  ");
      //clear lcd display 
      delay_ms(500);
      //lcd_putc('\f');
      
      lcd_gotoxy( 1,1);
      printf(lcd_putc,"task1 red off");
      //clear lcd display 
      delay_ms(500);
      //lcd_putc('\f');
   count=0;
}


Review
The first task awaits for 10 counts for a condition to be true, but the condition is not true so rtos_yield passes the system to task 2, task 2 passes the condition  and it is true and so the LED comes on for 500ms and the turns of, wiats for 500ms, and moves to the next task. 

Revise

A similar process is done in task 3. 
Demo_07 modification







Demo_8 

Run
This code, runs and Displays the task that are being used. 

void The_first_rtos_task ( ) {
   struct rtos_stats stats;
   rtos_stats(The_second_rtos_task,&stats);
   printf ( "\n\r" );
   printf ( "task_total_ticks : %Lius\n\r" ,
            (int32)(stats.task_total_ticks)*stats.hns_per_tick );
   printf ( "task_min_ticks   : %Lius\n\r" ,
            (int32)(stats.task_min_ticks)*stats.hns_per_tick );
   printf ( "task_max_ticks   : %Lius\n\r" ,
            (int32)(stats.task_max_ticks)*stats.hns_per_tick );
   printf ("\n\r");
}

Record

Demo_08 inital


Review
Task 1 prints out a structure of the rtos_stats, it prints out the total, max and min about of task done. hns_per_tick is used to multiply each stat, converting it to would the printed information would be in time, ie. seconds.  then task 2 over runs if it is true.  


Revise
I modified this first task by asking for the first number of ticks used. 

printf ( "task_first_ticks   : %Lius\n\r" ,
            (int32)(stats.task_first_ticks)*stats.hns_per_tick );



Demo_9 

Run
based on the diffrent commads each tasked is enabled and disabled. 

void The_kernal ( ) {
   while ( TRUE ) {
      printf ( "INPUT:> " );
      while(!input_ready)
         rtos_yield ( );

      printf ( "%S\n\r%S\n\r", input , en1 );

      if ( !strcmp( input , en1 ) )
         rtos_enable ( The_first_rtos_task );
      else if ( !strcmp( input , en2 ) )
         rtos_enable ( The_second_rtos_task );
      else if ( !strcmp( input , dis1 ) )
         rtos_disable ( The_first_rtos_task );
      else if ( !strcmp ( input , dis2 ) )
         rtos_disable ( The_second_rtos_task );
      else
         printf ( "Error: unknown command\n\r" );

      input_ready=FALSE;
      index=0;
   }
}


Review

Base on the en1 and dis1 that enables and disables the task1 and task 2, which is to turn on and off and led, these task can be seen on the led screen. 

Revise

I modified it by adding another task 

void The_third_rtos_task ( ) {
   //output_low(GREEN); delay_ms(20); output_high(GREEN);
           lcd_gotoxy( 1,1);
      printf(lcd_putc,"task3 red on  ");
      //clear lcd display 
      delay_ms(200);
      //lcd_putc('\f');
      
      lcd_gotoxy( 1,1);
      printf(lcd_putc,"task3 red off");
      //clear lcd display 
      delay_ms(200);
      //lcd_putc('\f');
}

Comments

Popular posts from this blog

Blog 1 - Igor Kapusniak