Jump to content
Sign in to follow this  
madeinoz

Systemtimer Overheads

Recommended Posts

G'day one and all,

 

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.

 

 

Thanks,

 

Stephen...

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 ():

02A2		SysTimerUp_0001D
02A2	   ; { SysTimerUpdate; function begin
02A2  1283   BCF STATUS, RP0
02A3  1303   BCF STATUS, RP1
02A4  0AC1   INCF gbl_scheduler+D'33', F
02A5		label34
02A5  083D   MOVF gbl_scheduler+D'29', W
02A6  3A04   XORLW 0x04
02A7  1903   BTFSC STATUS,Z
02A8  3A00   XORLW 0x00
02A9  1903   BTFSC STATUS,Z
02AA  0008   RETURN
02AB  1383   BCF STATUS,IRP
02AC  3020   MOVLW LOW(gbl_scheduler+D'0')
02AD  0084   MOVWF FSR
02AE  301E   MOVLW 0x1E
02AF  0784   ADDWF FSR, F
02B0  083D   MOVF gbl_scheduler+D'29', W
02B1  0784   ADDWF FSR, F
02B2  0800   MOVF INDF, W
02B3  0641   XORWF gbl_scheduler+D'33', W
02B4  1D03   BTFSS STATUS,Z
02B5  0008   RETURN
02B6  1383   BCF STATUS,IRP
02B7  3020   MOVLW LOW(gbl_scheduler+D'0')
02B8  0084   MOVWF FSR
02B9  302B   MOVLW 0x2B
02BA  0784   ADDWF FSR, F
02BB  083D   MOVF gbl_scheduler+D'29', W
02BC  0784   ADDWF FSR, F
02BD  0800   MOVF INDF, W
02BE  00BD   MOVWF gbl_scheduler+D'29'
02BF  2AA5   GOTO label34
02C0	   ; } SysTimerUpdate function end

Really not to heavy, looks like I did an excellent job here B)

 

I would suggest you get hold of the Novo RTOS source code if you don't have it already, that will give you more of an idea of what is going on behind the scenes.

 

I hope that helps.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
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  

×
×
  • Create New...