FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [May 2013 Threads] Pre-emptive mode starves task of exec timePosted by Tom Barclay on May 24, 2013 Hi, I am using FreeRTOS 7.3.0 on an Atmel SAM4 chip using the ASF library. I have a task that executes 4 calls in sequence then blocks. Each one is an interrupt driven state machine that issues an event from the ISR at the end. Each call waits for such an event before exiting. Each call invokes some SPI traffic which I can monitor on an external logic analyzer. What I observe is
Set the tick rate to 1ms and I see approx 1ms gaps between the calls. Set the tick rate to 5ms and I see approx 5ms gaps between the calls.
Set the config_USEPREEMPTIVE to 0
And I see very small gaps between the calls.
Clearly when 'preemtive', the RTOS is going off to do something else during these gaps.
In my code all tasks block, either on input Qs or output Q's or wait for events. The entire design is asynchronous and event driven. In my test setup I have no regular activity other than an LED flasher running at 100ms period. I start the test activity by a keypress.
I had presumed that at the RTOS tick the kernel would go around the other tasks, find they were all blocked and come back pretty sharpish to continue executing the test task ... but it appears not.
Anyone have any ideas ??? ...before I get down and dirty and start putting debug code into FreeRTOS itself.
Any help appreciated.
RE: Pre-emptive mode starves task of exec timePosted by Richard on May 24, 2013 Sorry, but I'm struggling to understand either the scenario or the problem you are describing. I think you have several event driven tasks that run through a state machine in response to events originating from interrupts, but I'm not sure what "that issues an event from the ISR at the end" as tasks can issue events *from* interrupts. Equally I don't understand "Each call waits for such an event before exiting".
Please post a little outline of the tasks, with a description of the behaviour you are seeing, and I may be able to explain why you are seeing that behaviour.
Regards.
RE: Pre-emptive mode starves task of exec timePosted by Tom Barclay on May 25, 2013 OK...hope it all makes more sense after reading this....
I have 14 tasks. Each task has the pattern
task start forever loop wait on event or message do something loop end task end
One of the tasks waits on a 200ms timer expiring (using vTaskDelay) which flashes an LED. All the other tasks block indefinitely.
In my test task, the do something part, there are 4 methods executing sequentially, call them A,B,C,D
Each method starts a sequence of SPI transactions that happens purely in the interrupt domain and then waits for the final interrupt to issue a xSemaphoreGiveFromISR. The sequence of actions in the interrupt domain is a state machine, each interrupt setting up the next SPI transfer and next state. The interrupts occur when an SPI transfer completes. The important point (I think) as its at the end of the interrupt sequence when an RTOS call is made.
So basically once the test task runs it executes as methodA entry start SPI transactions ------> SPI transfers in sequence of interrupts ---> send event from ISR wait for event from ISR methodA end
methodB entry ditto. etc etc etc
On the logic analyzer I observe the bursts of SPI data transfer (shown below)
....!!!!!..........................!!!!! ......................!!!!.............................!!!!!!!!!!!!!!!!.......
as each method executes.
The odd thing is that the gap between the bursts correlates (roughly) to the tick period. There is virtually no gap when I switch of the pre-emptive mode of RTOS operation.
Hope this helps ... Tom
RE: Pre-emptive mode starves task of exec timePosted by Dave on May 25, 2013 Seems clear. Are you context switching in the interrupt using portEND_SWITCHING_ISR or portYILD_FROM_ISR (depending on the port) when the event is sent to the task? If not then the switch will only happen on the next tick and the next task wont initiate its SPI transfer until that time.
RE: Pre-emptive mode starves task of exec timePosted by Tom Barclay on May 25, 2013 DaveDoors,
In the interrupt routine there is
1) ... higher_prio_task_woken = event_ISR_signal(* txfr_complete);// signal data ready
then on exit
2) ...portEND_SWITCHING_ISR(higher_prio_task_woken);
Just out of interest, in FreeRTOS 7.3.0 the 'higher_prio_task_woken' can be set to NULL.
What would be the impact ?
... Tom
RE: Pre-emptive mode starves task of exec timePosted by Tom Barclay on May 25, 2013 Thinking about the scheduling points... given that the only task available to run (ie not blocked) is the one task that was running, then would the call portEND_SWITCHING_ISR(pdTRUE) at the end of the interrupt force the same task to be re-scheduled ? Its not after all a higher priority !!!
or is the label of the variable "higher_prio_task_woken" misleading ? and a task of the same priority would also be scheduled ?
I'll try forcing the re-schedule and let you know what happens.
RE: Pre-emptive mode starves task of exec timePosted by Tom Barclay on May 25, 2013 OK ... looks like its a issue with value of "higher_prio_task_woken". I'll have to walk through and check all the code to make sure I haven't missed any execution steps or that the value of "higher_prio_task_woken" is not being overwritten somewhere but forcing the issue by using
portEND_SWITCHING_ISR(pdTRUE);
at the end of the interrupt fixes the problem.
Thanks for all your help,
RE: Pre-emptive mode starves task of exec timePosted by Richard on May 25, 2013 Also ensure configIDLE_SHOULD_YIELD is set to one in FreeRTOSConfig.h, otherwise if the idle task is running it will continue to run until the next tick interrupt occurs.
Regards.
RE: Pre-emptive mode starves task of exec timePosted by Richard on May 25, 2013 Forgot to say if you leave the xHigherPriorityTaskWoken parameter NULL then you have no way of knowing if calling the function caused a higher priority task to unblock or not. It is only meant as an optimisation that can be used when you know that a context switch is never needed.
Regards.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|