Problems with vTaskDelayUntil on ATmega323

rapurvey wrote on Wednesday, February 23, 2005:

I have currently written a test application with just 2 tasks using preemptive scheduling.  Each task toggles a bit on a port and then delays using vTaskDelayUntil for a period of time.

The problem is that I am getting strange results as one task will run for say 100 iterations and then the other task will keep running not letting the first task get any processing time.  This all seems to work ok though if I use vTaskDelay instead.

Im running this in simulation mode in AVRStudio as I havnt got any hardware yet.

Does anybody have any ideas?

rtel wrote on Wednesday, February 23, 2005:

Hi,

Just to clarify - are you seeing that the application executes correctly with both tasks executing as expected until a certain time - after which the problem occurs?

I presume you are using WinAVR (or some other verison of GCC).  Could you send me your project so I can try it?  If so zip up the entire directory (including source and demo) and mail to the address from the Contacts page on the WEB site.  Can you also include a few lines on how the project is built if this is different from the standard buildcoff or buildhex batch files.

Regards,
Richard.

rapurvey wrote on Wednesday, February 23, 2005:

The application works as expected using vTaskDelay but using vTaskDelayUntil causes the application perform inconsistantly depending on the priority and delays of the tasks.

Im using WinAVR (the latest).  Ill send the project to you straight away.

rtel wrote on Wednesday, February 23, 2005:

Hi,

The first parameter to vTaskDelayUntil() is the last execution time - which gets updated by vTaskDelayUntil() so it is correct for the next call.

In the code you sent the variable mxLastWakeTime is global - but used by two different tasks.  This means that one task will corrupt the value used by the other.

Try placing mxLastWakeTime on the stack for each task (and remove the global variable), for example:

void vTask1( void * pv )
{
…// Declare it here
…portTickType mxLastWakeTime;

…// Init it here
…mxLastWakeTime = xTaskGetTickCount();

…while(1)
…{
…// Your code task 1 code …

…vTaskDelayUntil( &mxLastWakeTime, 5 );
…}
}

void vTask2( void * pv )
{
…// Declare it here
…portTickType mxLastWakeTime;

…// Init it here
…mxLastWakeTime = xTaskGetTickCount();

…while(1)
…{
…// Your task 2 code …

…vTaskDelayUntil( &mxLastWakeTime, 10 );
…}
}

This way each task has it’s own mxLastWakeTime value.

One other small thing.  mxLastWakeTime should not be initialised until the scheduler has been started.  This is because the tick count variable is not initialised until this time.  In this case this does not really matter as the tick count should be set to 0 by the C startup code anyway, and moving the variable to the stack means the scheduler must be started for the code to run.

rtel wrote on Wednesday, February 23, 2005:

Forgot to say - post again if this doesn’t solve the problem.

rapurvey wrote on Wednesday, February 23, 2005:

Thanks Richard, that works now. :slight_smile: