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
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_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.
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_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
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_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
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_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
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_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_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_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
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
Post a Comment