Page 1 of 1

ucos task priority question

Posted: Wed Jun 26, 2013 7:49 am
by fd9750
Hi,

I have been experimenting with introducing an extra ucos task and I have noticed something strange.

In essence I have taken the simple UDP read/write example from the examples I have got for the MOD54415 module. an it works really well.

Then I have introduced the following line of code:

Code: Select all

OSSimpleTaskCreate(ProcessLineData, MAIN_PRIO - 2 );
The actual task is:

Code: Select all

void ProcessLineData(void * pd)
{
while (1)
	{
	if (g_bDataCaptured)
		{
		LED3.set(LED_ON);
		memcpy(g_ulPixelData, g_ulRawPixelData, sizeof(g_ulPixelData));
		LED1.set(LED_OFF);
		LED2.set(LED_OFF);
		LED3.set(LED_OFF);
		g_bDataCaptured = OFF;
		}
	}
}
Note: the flag "g_bDataCaptured" is never ON (TRUE) so all it does is check the condition of that flag.

When I compile and flash the code the serial port does not work any more. I can't send UDP packages I have typed.
If I change the task's priority to, for example, MAIN_PRIO + 1 the serial port works again but for some reason the new task appears not to be called.

Any ideas anyone as to what I am overlooking ?

Re: ucos task priority question

Posted: Wed Jun 26, 2013 7:54 am
by versamodule
When using tasks you should place a "OSTimeDly( x );" inside the while loop to allow other tasks to fire.

Code: Select all

void ProcessLineData(void * pd)
{
   while (1)
   {
      if (g_bDataCaptured)
      {
         LED3.set(LED_ON);
         memcpy(g_ulPixelData, g_ulRawPixelData, sizeof(g_ulPixelData));
         LED1.set(LED_OFF);
         LED2.set(LED_OFF);
         LED3.set(LED_OFF);
        g_bDataCaptured = OFF;
      }

      OSTimeDly( 1 );     /Delay every 5ms
   }
}

Re: ucos task priority question

Posted: Wed Jun 26, 2013 8:49 am
by pbreed
Task 1 has the highest priority task 63 the lowest....


So MAIN_PRIO-2 is two higher than the main task....

There is nothing in your task that blocks, so it runs and the main task never does...

OSTimeDly would cause it to block...

so would waiting on I/O pending on a semaphore waiting for tcp or udp data......etc.....

The system is strict priority based, not round robin... so unles a task stops and waits for soething its going to block all tasks below it...

For instance say you want a task to wake up and dosomething when another task had data ready or foudn an error etc...



use a an OS_SEM the waiting task pends on the OS_SEM and task that wakes it up would post to the OS_SEM

The programmers guide covers all of this....

Re: ucos task priority question

Posted: Wed Jun 26, 2013 9:10 am
by rnixon
There is a section in the rtos manual that describes blocking and identifies which os functions block.

Re: ucos task priority question

Posted: Wed Jun 26, 2013 7:15 pm
by roland.ames
fd9750 wrote:Hi,

I have been experimenting with introducing an extra ucos task and I have noticed something strange.

In essence I have taken the simple UDP read/write example from the examples I have got for the MOD54415 module. an it works really well.

Then I have introduced the following line of code:

Code: Select all

OSSimpleTaskCreate(ProcessLineData, MAIN_PRIO - 2 );
The actual task is:

Code: Select all

void ProcessLineData(void * pd)
{
while (1)
	{
	if (g_bDataCaptured)
		{
		LED3.set(LED_ON);
		memcpy(g_ulPixelData, g_ulRawPixelData, sizeof(g_ulPixelData));
		LED1.set(LED_OFF);
		LED2.set(LED_OFF);
		LED3.set(LED_OFF);
		g_bDataCaptured = OFF;
		}
	}
}
Note: the flag "g_bDataCaptured" is never ON (TRUE) so all it does is check the condition of that flag.

When I compile and flash the code the serial port does not work any more. I can't send UDP packages I have typed.
If I change the task's priority to, for example, MAIN_PRIO + 1 the serial port works again but for some reason the new task appears not to be called.

Any ideas anyone as to what I am overlooking ?

try something like this

Code: Select all

OS_FLAGS YourFlags;
#define DataCapturedMASK  1
OSFlagCreate(&YourFlags);
OSSimpleTaskCreate(ProcessLineData, MAIN_PRIO - 2 );

void ProcessLineData(void * pd)
{
while (1)
	{
	OSFlagPend ( &YourFlags, DataCapturedMASK );
	LED3.set(LED_ON);
	memcpy(g_ulPixelData, g_ulRawPixelData, sizeof(g_ulPixelData));
	LED1.set(LED_OFF);
	LED2.set(LED_OFF);
	LED3.set(LED_OFF);
	OSFlagClear ( &YourFlags, DataCapturedMASK );
	}
}

some code somewhere will have to

Code: Select all

OSFlagSet(&YourFlags, DataCapturedMASK  );

Re: ucos task priority question

Posted: Wed Jun 26, 2013 11:16 pm
by fd9750
Hi Everyone,

10 minutes after posting I figured out I needed to do something to make the higher priority task wait for something to happen or it would block all lower priority tasks.

I did not know yet there are so many possible ways though so thanks for all the info.

No doubt I will be able to use one of the methods, with a bit of luck I will have something up and running by noon.

Re: ucos task priority question

Posted: Thu Jun 27, 2013 12:55 am
by fd9750
Hi All,

Thanks for the help, because of it it did not take till noon.

I used the method suggested by roland.ames and it works a treat.
Just a few extra bits of info though: I am using version 2.6.2 so are there a few subtle differences to what roland suggested.

1) The function to use to wait for a flag is "OSFlagPendAll" instead of "OSFlagPend". The latter probably comes from an earlier version.
2) The documentation of "OsFlagPendAll" mentions that you need to provide a timeout value. What it does not mention is that if you specify 0 for the timeout it means "wait for ever". I deduced that from another function description in the documentation where you have to specify a timeout. There it specifically says that 0 means "wait for ever". I assumed it was the same and apparently it is. A similar call to "OSFlagPend can also be found in one of the examples.

One extra question: what is the fastest task switch time I can expect to get when the specified task flag is changed by an interrupt (assuming there are no higher priority things going on) ?

Re: ucos task priority question

Posted: Thu Jun 27, 2013 9:10 am
by pbreed
Fastest task switch will depend on what processor your running this on..and if the task stacks are in SRAM or DRAM...

The general expectations are that interrupts -> task switch will be of the order of 2-10 usec....

If there is a lot of full frame ethernet traffic going on it could be longer.... up to maybe 20 usec

The quickest possible could be less than 1usec on some processors...