Jump to content
Sign in to follow this  
Bryan Gerold

Sys_yield

Recommended Posts

I'm using the the NOVO RTOS to develop an commercial application for a vending machine and so far am having great success.

 

I was having a problem with tasks waking up before there scheduled time and found this was due to me not calling Sys_Yield() before every Sys_Sleep() call.

 

I may be wrong but I believe I have found a potential problem.

On the off chance that an interrupt occurs and and the next task in the sleep queue reaches its scheduled wake up time after the last SysTimerIdleProcess() and before another task is being put to sleep, it would corrupt the the sleep queue and cause both tasks to be moved immediately into the run queue when the next SysTimerIdleProcess occurs.

 

Example:

 

void Task_0()

Share this post


Link to post
Share on other sites

Bryan,

 

I was having a problem with tasks waking up before there scheduled time and found this was due to me not calling Sys_Yield() before every Sys_Sleep() call.
This should not be necessary, Sys_Sleep() does the required yielding.

 

...

...

Example:

 

void Task_0()

It would be good to see your example.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Dave,

 

Thank you for the quick response.

 

In the following example Task_1 will occasional run before its scheduled time.

 

#pragma CLOCK_FREQ 20000000 

#include <boostc.h>
#include <system.h>

#include "novo\novoConfig.h"
#include "novo\novo.h"

void interruptStart();

void Task_0();
void Task_1();

#define HTASK0 0
#define HTASK1 1

void interruptStart()
{
//Enable Interrupts
intcon.GIE = 1; // Global Inerrupt enable.
intcon.PEIE = 1; //Peripheral Interrupt Enable.

//Set interrupt Prioritys.
rcon.IPEN = 1;// Enable low Priority.
intcon2.TMR0IP = 0; // Timer0 set to low.

//Enable interrupts.
intcon.TMR0IE = 1; //enable TMR0 overflow bit.
}

void Task_0()
{
while(1)
	{
		delay_ms(100);
		Sys_Sleep( 2000 );
	}	
}		

void Task_1()
{
while(1)
	{
		delay_s(2);
		Sys_Sleep( 12000 );
	}	
}	

void main()
{
SysInit();

t0con = 128;

interruptStart();

SysCreateTask( HTASK0 , 5 , Task_0 );
SysCreateTask( HTASK1 , 5 , Task_1 );

SysStartTask( HTASK0 );
SysStartTask( HTASK1 );


while( 1 )
	{
		Sys_Yield();
	}	

}

void interrupt_low(void)
{
SysTimerUpdate();

tmr0h = 0xF6;
tmr0l = 0x3B;

intcon.TMR0IF = 0;
}

 

What seems to be happening is while task_1 is running task_0 will reach its scheduled wake up time.

 

When Sys_Sleep is called from task_1 it will will erroneously be put into the sleep queue before task_0

 

			if( i != SLEEP_QUEUE_HEAD ) // start reached
			remainingSleep = GetTaskWakeUpTime( i ) - scheduler.os_tickCnt;
		else
			remainingSleep = 0;

		// When the time diff in less than 0, we know that the task to insert times out before this task,
		// so we insert before it in the queue
		if( sleepTime >= remainingSleep )

 

The calculated value for the remaning sleep time of next task in the queue will be wrong because it has already passed its scheduled wake up time.

 

because the os_sleepUpdateHead has already been moved

the next time SysTimerIdleProcess() is called it will move both task_0 and task_1 into the run queue.

 

I would appreciate any feedback you could give me on this.

 

Thanks, Bryan.

Share this post


Link to post
Share on other sites

Bryan,

Dave,

 

Thank you for the quick response.

 

In the following example Task_1 will occasional run before its scheduled time.

I'm off on vacation, so can't look at this issue until I return (1 week).

What you could do to help is come up with code that demonstrates the issue and can be run under the SourceBoost simulator/Debugger.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Dave,

 

I have attached the sample program you asked it for.

 

The program is built in BoostC V7.03

Novo is being built with the test program(seemed to run better in the debugger that way)

 

There are notes explaining the problem in the Task_1 Fx.

 

I hope you enjoy your vacation.

 

Thanks,

Bryan

NovoTest.zip

Share this post


Link to post
Share on other sites

Bryan,

Dave,

 

I have attached the sample program you asked it for.

 

The program is built in BoostC V7.03

Novo is being built with the test program(seemed to run better in the debugger that way)

 

There are notes explaining the problem in the Task_1 Fx.

This is indeed an issue, and your fix can still fail if a task wake up time occurs at just the wrong moment.

 

I have some modified Novo RTOS code that I want to send to you. Please send a mail to support@sourceboost.com and I will send you the code.

 

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 emoticons maximum 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  

×