Tasks w/ same Priority Interrupt even with time slice off

I’ve configured FRTOS V8.2.0 with time slice off. I have a main task. The main task creates another task with the same priority. Here’s my psuedo code. ~~~~ void vTask1(taskparamt pvParameters) { printf(“TASK1nr”); for(;;); } void vMainTask( taskparamt pvParameters ) { TaskCreate(TASK1); printf(“MAIN TASKnr”); for(;;); } int main(void) { TaskCreate(MAIN_TASK); vTaskStartScheduler(); loop(); return 0; } ~~~~ The output is:
MAIN TASK TASK1
I do not expect this to happen. These two tasks have the same priority, and with configUSETIMESLICING set to 0, vTask1() shouldn’t run (to my knowledge) without vMainTask blocking for some reason – which it doesnt.

Tasks w/ same Priority Interrupt even with time slice off

I just tried this, albeit with FreeRTOS V8.2.3, and found that only “MAIN TASK” was printed out. What other tasks and/or interrupts do you have in your system? You will get a switch between the two equal priority tasks if a task that has a higher priority runs in the mean time, or if a context switch occurs in an interrupt. For example, if vMainTask and vTask1 have priority 1, and vMainTask is running when a priority 2 task (lets call it task X) enters the Ready state, then the scheduler will start running task X as it has the highest priority. Then, when task X re-enters the Blocked state, the scheduler will select vTask1. So the execution sequence would be vMainTask -> X -> vTask1. When I tried this, and found it behaved as expected, I didn’t have any other tasks or interrupt running. Regards.

Tasks w/ same Priority Interrupt even with time slice off

My sys tick interrupt occurs and it switches to task1 afterwards. Is there a configuration to set so that the same task runs before and after a context switch even if there are other tasks with the same priority? Also, if I change my tasks to print ‘1’ or ‘2’ respectively in the task loop, it prints ‘1’s until the systick interrupt, then ‘2’s, as you have said would happen. However, it never switches back to ‘1’s on the next systick interrupt. Why does it only switch tasks on the first occurence of the interrupt?

Tasks w/ same Priority Interrupt even with time slice off

If you have two tasks that have the same priority, and no other tasks in the Ready state, then: With configUSETIMESLICING set to 1 a context switch will occur on each tick interrupt. This context switching on the tick interrupt is the time slicing, and the behaviour that setting configUSETIMESLICING should suppress. Therefore… With configUSETIMESLICING set to 0 a context switch should not occur on a tick interrupt, but only when a higher priority task enters the Ready state, or when an interrupt other than the tick interrupt requests a context switch. ….if you are getting a context switch on each tick interrupt even when configUSETIMESLICING is 0, and when there are no other tasks an no other interrupts (as I think you are reporting) then something is wrong. I have just tried this again, this time on a Cortex-M, with the simple code:
volatile uint32_t t1 = 0, t2 = 0;

void task1( void * pv )
{
     for( ;; )
     {
         t1++;
     }
}

void task2( void * pv )
{
     for( ;; )
     {
         t2++;
     }
}

int main( void )
{
     prvSetupHardware();
     xTaskCreate( task1, "t1", configMINIMAL_STACK_SIZE, NULL, 1, NULL );
     xTaskCreate( task2, "t2", configMINIMAL_STACK_SIZE, NULL, 1, NULL );
     vTaskStartScheduler();
}
With configUSETIMESLICING set to 1, both t1 and t2 incremented. With configUSETIMESLICING set to 0, only t1 incremented and t2 remained at zero. Questions: – Which port are you using? – Do you have a tick hook defined that could be requesting a context switch? Regards.

Tasks w/ same Priority Interrupt even with time slice off

Something must be wrong then. I tested similar code as you have above, and my t1 counter increments to 47842, systick interrupts, then t2 increments indefinitely. (This is with configUSETIMESLICING set to 0). I’m using Freescale’s KSDK v1.3.0 that includes freeRTOS (freescale.com/ksdk) The port.c file included reports: /———————————————————– * FreeRTOS for 56800EX port by Richy Ye in Jan. 2013. *———————————————————-/ I’m using the TWR-K60D100M development board from Freescale. I haven’t created a tick hook.

Tasks w/ same Priority Interrupt even with time slice off

Is this GCC? If so, could you please email me the tasks.c, port.c and portmarco.h file so I can diff them. If it is not GCC there may also be a portasm assembler file. You can send them to r dot barry -AT- freertos.org.

Tasks w/ same Priority Interrupt even with time slice off

Sent.

Tasks w/ same Priority Interrupt even with time slice off

Hmm, so are you using a Cortex-M device? TWK-K60D100M would seem to indicate yes, but 56800EX would seem to indicate no – unless the 56800EX comment in the file is just for that port, as the port.c seems to cover a lot of different usage scenarios. Although the tasks.c file does contain some minor edits, there are none that would effect the time slicing behaviour. Unfortunately the port.c file is, as mentioned above, very specifc to Freescale, and so cannot be diffed with anything in the FreeRTOS distrobution with the same version number (it contains code for multiple chips and multiple compilers, for example). A quick look at the Cortex-M code in that file doesn’t immediately highlight anything that could change this behaviour though.

Tasks w/ same Priority Interrupt even with time slice off

Yes, the TWR-K60D100M uses a cortex m4. Is there anything else that I could try to help debug this problem?

Tasks w/ same Priority Interrupt even with time slice off

First a couple of questions: 1) It looks like you are only getting one yield. Therefore, there is a strong possibility the yield is already pending before the scheduler is started. Maybe that could be the issue? Although if that were the case I would still expect only one of the variables to increment – it would just be the other variable. 2) Is there any library code, or code generated by the processor expert stuff, that is executing before main() is called? Maybe that is doing something? On to your question: If you tried my very simple example, that just creates two tasks that do nothing other than increment a variable, and still had the problem – then that proves the yield is not coming from the application code (no drivers or IO functions are being called). Therefore the yield must be coming directly or indirectly from an interrupt. Again, if you are using my very simple example, then the only interrupt that should be running is the tick interrupt, so somehow it must be coming from there. I would therefore suggest putting a break point in the tick interrupt handler (which is in the port.c file you sent me) and step through that code. You are looking for something calling taskYIELD(), portYIELD(), or otherwise setting the PendSV bit in the NVIC INT CTRL register. Make double sure tick hook and idle hook functions are not defined, then manually delete all object files (rather than relying on a clean build doing this for you) before re-building from scratch.

Tasks w/ same Priority Interrupt even with time slice off

Digging a little deeper, I see the following: In the vPortTickHandler/SysTickHandler, it calls xTaskIncrementTick() which returns TRUE. It looks like the return value for xTaskIncrementTick() is whether or not a switch is required. It looks at the delayed list, and is seems as though there’s a task with the name “Tmr Svc” that it switches to. This task is created in xTimerCreateTimerTask() if configUSETIMERS is set to 1. Since the timer priority is greater than the task, it takes control. This must cause the task to be put on the back of the ready queue, and allow the other task to run. Does that make sense?

Tasks w/ same Priority Interrupt even with time slice off

Makes sense although if the priority of the timer task is above the priority of your tasks I would expect it to run first, then not again, unless a software timer is actually being created. Will look at this. My tests were also configured to have a timer task.

Tasks w/ same Priority Interrupt even with time slice off

I checked, and it does run first, then again at the first sys tick, then never again.

Tasks w/ same Priority Interrupt even with time slice off

Any updates with this? I have added definitions for the trace macros, and here is the output: start frtosmain //creating a test queue traceQUEUECREATE //creating producer task traceTASKCREATE PRODUCER traceMOVEDTASKTOREADYSTATE PRODUCER //creating consumer task traceTASKCREATE CONSUMER traceMOVEDTASKTOREADYSTATE CONSUMER //vTaskStartScheduler traceTASKCREATE IDLE traceMOVEDTASKTOREADYSTATE IDLE traceQUEUECREATE traceTASKCREATE Tmr Svc traceMOVEDTASKTOREADY_STATE Tmr Svc start prvTimerTask traceTASKDELAYUNTIL traceTASKSWITCHEDOUT Tmr Svc traceTASKSWITCHEDIN PRODUCER start producerTask //just an infinite loop traceTASKINCREMENTTICK 0 traceMOVEDTASKTOREADYSTATE Tmr Svc traceTASKSWITCHEDOUT PRODUCER traceTASKSWITCHEDIN Tmr Svc traceQUEUERECEIVEFAILED 536841760 traceTASKDELAYUNTIL traceTASKSWITCHEDOUT Tmr Svc traceTASKSWITCHEDIN CONSUMER start consumerTask traceTIMER_CREATE is defined, but it is never observed. Is there any other reason the Tmr Svc task would run on the first tick if no timer has been created?

Tasks w/ same Priority Interrupt even with time slice off

When I execute the code previously posted, the timer task only runs once, so I’m afraid I don’t know why it runs twice in your project. I suggest placing a break point in vTaskSwitchContext() within tasks.c, and inspect the pxCurrentTCB->pcTaskName variable when the break point is hit. When you see it it the timer service task for the second time, step out of the function using the debugger to end up in the timer task and see what it is doing (and why).

Tasks w/ same Priority Interrupt even with time slice off

On the first run of prvProcessTimerOrBlockTask() in the timer service task, I get: xTimeNow = 0. xNextExpireTime = 0. xListWasEmpty = 1. Then it executes vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime – xTimeNow ) ); vQueueWaitForMessageRestricted( VALID_PTR, 0 – 0 ); xTaskResumeAll() = FALSE, so then we call portYIELDWITHINAPI() On the second call, we come back from the vPortYieldFromISR() function. We then run prvProcessReceivedCommands(). Reading from the queue fails (queue is empty) and we exit this function. Upon reentry to the prvProcessTimerOrBlockTask() function, the only logic difference I see is vQueueWaitForMessageRestricted( VALID_PTR, ( 0 – 1 ) ); Since the parameters for this function are: ( QueueHandlet xQueue, TickTypet xTicksToWait ) It seems that xTicksToWait = 0 for the first occurence, and thus happens “immediately” and the second occurence has an xTicksToWait = 0xFFFFFFFF, or “infinite” wait. This seems to be the inherent problem. When you test this, what are your values for xTicksToWait?

Tasks w/ same Priority Interrupt even with time slice off

On the first run of prvProcessTimerOrBlockTask() in the timer service task, I get: xTimeNow = 0. xNextExpireTime = 0. xListWasEmpty = 1.
So far the same.
Then it executes vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime – xTimeNow ) ); vQueueWaitForMessageRestricted( VALID_PTR, 0 – 0 );
This is where our code bases differ. In V8.2.3 there is a third parameter which is “wait indefinitely”, which in my case is set to pdTRUE, hence it blocks indefinitely to wait for a command to arrive. The change to the code was made to allow timers to be supported better in lower power tickless applications.

Tasks w/ same Priority Interrupt even with time slice off

Do you know if this was an issue with 8.2.0? Just trying to make sure there isn’t anything else wrong with the way the code is executing.

Tasks w/ same Priority Interrupt even with time slice off

I’m not aware of any issues – I think the timers work just fine in the version you have – you are just seeing the very fine detail of the start up sequence. The changes in the latest version were made specifically for low power systems, to enable a tickless low power application to enter a very deep and extended sleep even when software timers are used – hence the new ‘block indefinitely’ parameter.