Recommended Posts

I've just started to have a play with Novo and would like to know what overheads/impacts of setting the system timer to smaller values? i.e. in the examples it is set to update the system timer once every mSec.

I take it the system timer function handles the scheduling and context switching, so will these occur every mSec if there is a higher priority task waiting? Unless my task yields and is not waiting on system timer or a semaphore, then I may have a mSec or more to wait until a lower task gets to run?

What is the smallest SystemTime that would be usable, without too much time being taken in context swaps and scheduling?

Are there any figures/times on the actual context switch? How long does it take to switch out the current task and switch in the next scheduled one? Especially for the pic16 running at 20Mhz.

Share this post

Link to post

Share on other sites

I take it the system timer function handles the scheduling and context switching, so will these occur every mSec if there is a higher priority task waiting? Unless my task yields and is not waiting on system timer or a semaphore, then I may have a mSec or more to wait until a lower task gets to run?

No. Novo is a co-operative multi-tasking OS. Context switching is done when a task yields. calling SysTimerUpdate() gets the system timer updated and checks if any sleeping tasks need moving to the run queue and flags this by moving the sleep update head pointer (actually an array index). The overhead of this routine is pretty small, the bigger part of the work is done on the next task yield.

Here is the code of that routine:

void SysTimerUpdate()
{
++scheduler.os_tickCnt;
// repeat until all timed out tasks processed
// normally only one times out at a time, but two or more
// could have exactly the same timeout time
while( 1 )
{
if( GetSleepUpdateHead() == SLEEP_QUEUE_HEAD ) // queue empty
break;
// Check for time reached - we only need to check first in queue as they
// are in timeout order
// Data accessed directly to avoid interrupt debug check as is this code that
// needs all other to access safely when its called from an ISR.
if( scheduler.os_tickCnt != scheduler.task_wakeupTime[ GetSleepUpdateHead() ] )
break;
SetSleepUpdateHead( GetNextTask( GetSleepUpdateHead() ) );
}
}

I have noticed that the comment here is a bit wrong:

// Check for time reached - we only need to check first in queue as they

// are in timeout order

Actually tasks wakeup times are checked until the one currently at the sleep queue head is not due to wakeup. This is because at for any given tick count more than one task maybe due to wake up.

How long does this code take to execute; well the worse case is dependant on how many tasks are sleeping and may wake up at the same time. The design objective was to minimise overhead in interrupt service routine.

If you compile the NovoLedFlash supplied sample code that uses an 8 bit tick counter, you end up with the following asm for SysTimerUpdate ():