Jump to content
Sign in to follow this  
cpetito

Task Priorities - Lower Is Higher?

Recommended Posts

Novo RTOS is great. I am using it with BoostC Version 6.96.

 

I just want to confirm that my understanding based on documentation and examples is correct: the lower the task priority number the higher priority for the task.

 

Which means that unless a task with lower number sleeps or waits for an event, it will block execution of tasks with higher numbers.

 

My experience seems to contradict.

 

I have three real time tasks (listed in decreasing real time importance):

  • Play Audio (22Khz PWM)
  • Update LCD display (every second)
  • Input IR codes

 

RTOS timer is updated every .1 msec.

Audio waits on a semaphore.

LCD waits on a semaphore generated by a timer interrupt every second.

IR waits on a semaphore generated by a port bit interrupt.

 

The audio PCM data is from a MMC card buffered in a circular queue.

 

With all the tasks set to priority = 2, I get occasional buffer underruns with the audio. The root solution is to improve the efficiency of the code, but I decided to play a bit with task priorities to see the results.

 

Initially I set the priorities as Audio = 0, LCD = 1, IR = 3.

 

The unexpected result was that the audio underruns were much worse.

 

I then set the priorities as Audio = 3, LCD = 1, IR = 0.

 

Now the audio plays perfectly, but because when running, the audio task yields, but never sleeps, the LCD is not updated until the audio task completes.

 

I may be over looking something obvious, but if lower numbers are higher priorities, I will look at / simulate the code in more detail to find why the results are contrary to expectations.

 

Thank you for any pointers or comments.

 

Carl Petito

Share this post


Link to post
Share on other sites
Novo RTOS is great. I am using it with BoostC Version 6.96.

Very glad you find it useful :-)

 

I just want to confirm that my understanding based on documentation and examples is correct: the lower the task priority number the higher priority for the task.

 

Which means that unless a task with lower number sleeps or waits for an event, it will block execution of tasks with higher numbers.

Yes that is correct.

You can confirm this by creating two tasks, one with a higher priority than the other.

In each task simply call Sys_Yield(); in an infinite loop.

Set a break point on both Sys_Yields(); function calls. You should find that only the high priority one gets call.

 

Please try this as when I tried something strange happened (sometimes the low priority Sys_Yield(); task got called), but I was using a new release candidate so all may have not been well, even so I was a little surprised.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Dave,

 

Thanks for the reply. Great minds must think alike! I just finished a test as you suggested.

 

Bottom line, I believe that smaller numbers yield a lower priority.

 

I used BoostC's wizard (Version 6.96) to create the following test.

 

Task0 simply toggles RB1 and Task1 toggles RB2.

 

Running this code in the simulator with the following priorities yielded the following results:

 

  • Task0 P:2, Task1 P:2 - RB1, RB2 blink, as expected
  • Task0 P:0, Task1 P:2 - only RB2 blinks, but expected RB1
  • Task0 P:2, Task1 P:0 - only RB1 blinks, but expected RB2

 

Perhaps I am misinterpreting something or have confused my brain along the way. :(

 

Thanks,

Carl Petito

 

#include <system.h>
#include <novocfg_pic16t3e5ts1.h>
#include <novo.h>


//Target PIC16F877 configuration word
#pragma DATA _CONFIG, _PWRTE_OFF & _BODEN_OFF & _WDT_OFF & _LVP_ON & _CPD_OFF & _DEBUG_OFF & _HS_OSC & _CP_OFF

//Set clock frequency
#pragma CLOCK_FREQ	20000000

#define hTask0 0
#define hTask1 1



void interrupt( void )
{
//Handle timer0 interrupt
if( intcon & (1<<T0IF) )
{
	SysTimerUpdate();

	clear_bit( intcon, T0IF ); //clear timer 0 interrupt bit
}

//Handle timer1 interrupt
if( pir1 & (1<<TMR1IF) )
{
	clear_bit( pir1, TMR1IF ); //clear timer 1 interrupt bit
}

//Handle timer2 interrupt
if( pir1 & (1<<TMR2IF) )
{
	clear_bit( pir1, TMR2IF ); //clear timer 2 interrupt bit
}

}

void Task0()
{
//This is a task place holder, replace with your own code
while( 1 )
{
	portb.1 = !portb.1;  //added this bit toggle
	Sys_Yield();
}
}

void Task1()
{
//This is a task place holder, replace with your own code
while( 1 )
{
	portb.2 = !portb.2;  //added this bit toggle
	Sys_Yield();
}
}



void main( void )
{
//Configure port A
trisa = 0x00;
//Configure port B
trisb = 0x00;
//Configure port C
trisc = 0x00;
//Configure port D
trisd = 0x00;
//Configure port E
trise = 0x00;

//Configure A/D pins
adcon1 = 0x06;


//Initialize port A
porta = 0x00;
//Initialize port B
portb = 0x00;
//Initialize port C
portc = 0x00;
//Initialize port D
portd = 0x00;
//Initialize port E
porte = 0x00;
//Set Timer0 mode
clear_bit( option_reg, T0CS ); //configure timer0 as a timer
//Set prescaler assignment
clear_bit( option_reg, PSA ); //prescaler is assigned to timer0
//Set prescaler rate
clear_bit( option_reg, PS2 ); //prescaler rate 1:2
clear_bit( option_reg, PS1 );
clear_bit( option_reg, PS0 );
//Set timer0 source edge selection
set_bit( option_reg, T0SE ); //increment on high-to-low transition on RA4/T0CKI pin

//Set timer 1 prescaler rate
clear_bit( t1con, T1CKPS1 ); //prescaler rate 1:1
clear_bit( t1con, T1CKPS0 );
//Set timer 1 mode
clear_bit( t1con, TMR1ON ); //disable timer 1

//Set timer 2 prescaler rate
clear_bit( t2con, T2CKPS1 ); //prescaler rate 1:1
clear_bit( t2con, T2CKPS0 );
//Set timer 2 postscaler rate
clear_bit( t2con, TOUTPS3 ); //postscaler rate 1:1
clear_bit( t2con, TOUTPS2 );
clear_bit( t2con, TOUTPS1 );
clear_bit( t2con, TOUTPS0 );
//Set timer 2 mode (enable or disable)
clear_bit( t2con, TMR2ON ); //enable timer 2


//Enable interrupts (Timer0)
intcon = 0xA0;


//Initialize Novo RTOS
SysInit();

//Create Novo tasks
SysCreateTask( hTask0, 2, Task0 ); //0 - expect RB1 to blink, but RB2 blinks
SysCreateTask( hTask1, 2, Task1 );

//Start Novo tasks
SysStartTask( hTask0 );
SysStartTask( hTask1 );


//Endless loop
while( 1 ) Sys_Yield();
}

Share this post


Link to post
Share on other sites

From Novo RTOS manual "The lower the task priority value, the higher the task priority. A task with a priority value of 0 (zero) has the highest priority. Only the highest priority tasks in the run queue are executed when another task yields." If that's not the case than either the document is wrong or there is a bug in Novo software.

 

Regards,

Pabel

Share this post


Link to post
Share on other sites
From Novo RTOS manual "The lower the task priority value, the higher the task priority. A task with a priority value of 0 (zero) has the highest priority. Only the highest priority tasks in the run queue are executed when another task yields." If that's not the case than either the document is wrong or there is a bug in Novo software.

 

Regards,

Pabel

 

Pavel,

 

Thank you for the reply.

 

Please see the sample that I added to this thread.

 

It is a very simple test created with the BoostC wizard and unless someone can point my mistake, it seems that the documentation does not agree with the behavior.

 

Regards,

Carl Petito

Share this post


Link to post
Share on other sites
It is a very simple test created with the BoostC wizard and unless someone can point my mistake, it seems that the documentation does not agree with the behavior.
Yes the documentation does appear to be wrong, I just done the same simple test. I will check some other test samples I have.

I'm just surprised that this is the first time anyone seems to have noticed this.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Thanks for the confirmation - my brain is now a little less confused :(

 

I am dealing with real time audio that is pushing the PIC's limits, so the effect was very obvious. Especially with some inefficient initial code.

 

You folks have great products and I am very impressed with the level of support and quick responses.

 

I am sure that whatever the issue, it will be resolved.

 

Regards,

Carl Petito

Share this post


Link to post
Share on other sites
Thanks for the confirmation - my brain is now a little less confused :unsure:

 

I am dealing with real time audio that is pushing the PIC's limits, so the effect was very obvious. Especially with some inefficient initial code.

 

You folks have great products and I am very impressed with the level of support and quick responses.

 

I am sure that whatever the issue, it will be resolved.

 

Regards,

Carl Petito

Has this issue been resolved one way or another yet?

 

Regards

 

davidb

Share this post


Link to post
Share on other sites
Has this issue been resolved one way or another yet?
Yes the Novo RTOS documentation has been updated.

 

Regards

Dave

Share this post


Link to post
Share on other sites
Yes the Novo RTOS documentation has been updated.

 

Regards

Dave

Thanks Dave.

 

Apart from having a quick play I haven't made the jump and used Novo on a real project yet so the following may seem like ridiculous questions.

 

With priorities enabled I assume that 15 levels are always available since there seems to be no way that you can choose the maximum number. Before the re-alignment of the documentation to the code it seemed obvious (at least to me) that you would always use 0 as the highest level and then as many levels as required with increasing numbers and decreasing priority (including equal priority).

 

Since 14 is now the highest priority what should you do if you only require say 3 levels? Does using 14, 13 and 12 have any impact on the code or memory compared to using 2, 1 and 0 in high to low order? Is there any problem in using say 14, 5, and 0? Is it simply the order that is important rather than the absolute values?

 

I think having a variable number for the highest priority rather than it always being 0 makes the code a little less easy to understand although maybe the levels could be redefined in some way to make it clearer.

 

Regards

 

davidb

Share this post


Link to post
Share on other sites
Yes the Novo RTOS documentation has been updated.

 

Regards

Dave

Thanks Dave.

 

Apart from having a quick play I haven't made the jump and used Novo on a real project yet so the following may seem like ridiculous questions.

 

With priorities enabled I assume that 15 levels are always available since there seems to be no way that you can choose the maximum number. Before the re-alignment of the documentation to the code it seemed obvious (at least to me) that you would always use 0 as the highest level and then as many levels as required with increasing numbers and decreasing priority (including equal priority).

 

Since 14 is now the highest priority what should you do if you only require say 3 levels? Does using 14, 13 and 12 have any impact on the code or memory compared to using 2, 1 and 0 in high to low order? Is there any problem in using say 14, 5, and 0? Is it simply the order that is important rather than the absolute values?

The actual value makes no difference, a task with higher value priority has precendence over a task with lower priority value.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Your content will need to be approved by a moderator

Guest
You are commenting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×