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] [November 2016 Threads] Timer task never gets unblockedPosted by j99yu on November 1, 2016 Platform: ATSAMG55J19
FreeRTOS version: 8.0.1 (most recent version available in Atmel Studio 7)
I'm trying to defer function processing by calling xTimerPendFunctionCallFromISR() in a USB handler ISR.
I followed the example from http://www.freertos.org/xTimerPendFunctionCallFromISR.html and have something like the following in my function UHP_Handler():
~~~
...
BaseTypet xHigherPriorityTaskWoken = pdFALSE;
xTimerPendFunctionCallFromISR(ohcibottomhalf,
&IntInfo,
NULL,
&xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
...
~~~
When the timer task runs, it gets blocked on portYIELDWITHINAPI() when there are no messages in the queue and then it never seems to unblock even after messages get queued.
I have the task priorities set up such that the timer task priority has highest priority (largest numeric value) and have the USB interrupt priority set up as 11 (which is lower priority than configLIBRARYMAXSYSCALLINTERRUPTPRIORITY) .
Other relevant code :
~~~
define configMAXPRIORITIES ( ( uint32t ) 5 )
define configPRIO_BITS 4
define configLIBRARYLOWESTINTERRUPT_PRIORITY 0x0f
define configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 10
define configKERNELINTERRUPTPRIORITY ( configLIBRARYLOWESTINTERRUPTPRIORITY << (8 - configPRIOBITS) )
define configMAXSYSCALLINTERRUPTPRIORITY ( configLIBRARYMAXSYSCALLINTERRUPTPRIORITY << (8 - configPRIOBITS) )
~~~
I have three tasks running: idle task (priority 0), timer task (priority 4), and an application task (priority 1).
Question:
Why isn't the timer task running after portYIELDFROMISR() gets called in the interrupt handler? The first time that the interrupt handler executes, xHigherPriorityTaskWoken does get set to pdTRUE, but in every subsequent execution, this variable equals pdFALSE.
Timer task never gets unblockedPosted by rtel on November 1, 2016 I cannot see anything obviously wrong in your code.
Why isn't the timer task running after portYIELDFROMISR() gets
called in the interrupt handler? The first time that the interrupt
handler executes, xHigherPriorityTaskWoken does get set to pdTRUE,
but in every subsequent execution, this variable equals pdFALSE.
This would seem to indicate that the first time it is called it
successfully unblocks the timer task, but in subsequent calls the timer
task was not found to be in the blocked state - maybe because it was:
1) Unblocked by the first ISR, but never executed. That could be due to
a memory corruption, perhaps. Do you have configASSERT() defined?
(Google it for the documentation page). Do you have
configCHECKFORSTACK_OVERFLOW set to 2?
2) The task was unblocked, and it executed, but the implementation of
the function that was executed caused the timer task to enter the
blocked state before the function had returned. What is the function
you are deferring to the timer task doing? Is it blocking on anything
else or does it just run to completion?
Timer task never gets unblockedPosted by j99yu on November 6, 2016 configASSERT is defined and I've changed configCHECKFORSTACK_OVERFLOW from 1 to 2.
No difference.
The behaviour seems to be case 1) you mentioned. No context switching is happening after portENDSWITCHINGISR(); execution simply resumes in the task that was running prior to the interrupt. I assume that the correct behaviour is that vTaskSwitchContext() gets run at some point after portENDSWITCHINGISR(). However, this is not happening.
What could be preventing a context switching from occuring? How does a context switch happen from within an ISR anyway?
Timer task never gets unblockedPosted by rtel on November 7, 2016
How does a
context switch happen from within an ISR anyway?
You are using an ARM Cortex-M, right? If so then the context switch
happens in the PendSV interrupt, and the interrupt that asks for the
context switch simply sets the PendSV interrupt pending. Once the
PendSV is set pending it will execute immediately that all other higher
priority interrupts have completed.
I assume you have the PendSV interrupt installed? Are you seeing other
context switches or is it always the same task that is running (perhaps
re-reading the thread the answer to that would be obvious, but I'm
replying via email).
I would recommend updating to the latest version of FreeRTOS as it will
contain many more configASSERT() calls that might highlight your issue..
You can do that by simply copying the latest source files (including
the port layer) over the top of the source files you are currently using.
Timer task never gets unblockedPosted by j99yu on November 8, 2016 I can see context switches happening up until the point that the USB interrupt is enabled. Could it be that these interrupts are occuring at too high a frequency (every ms) and keep preempting the PendSV interrupt, never allowing it to run?
Timer task never gets unblockedPosted by rtel on November 8, 2016 Interrupts at 1ms is not going to be a problem.
I can see context switches happening up until the point that the USB
interrupt is enabled.
That is a big clue. Have you posted the code of the USB ISR? Is the
USB working in an application that is not using FreeRTOS?
Timer task never gets unblockedPosted by j99yu on November 10, 2016 This is the code for the USB ISR:
~~~
void UHP_Handler()
{
uint32_t int_status;
uint32_t rh_status;
uint32_t rh_port_status;
struct interruptInfo IntInfo;
rh_status = OHCI->HcRhStatus;
rh_port_status = OHCI->HcRhPortStatus;
/**
* Read interrupt status (and flush pending writes). We ignore the
* optimization of checking the LSB of hcca->done_head; it doesn't
* work on all systems (edge triggering for OHCI can be a factor).
*/
int_status = OHCI->HcInterruptStatus;
/* We only care about interrupts that are enabled */
int_status &= OHCI->HcInterruptEnable;
IntInfo.int_status= int_status;
IntInfo.rh_port_status= rh_port_status;
IntInfo.rh_status= rh_status;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTimerPendFunctionCallFromISR(ohci_bottomhalf,
&IntInfo,
NULL,
&xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
~~~
After raising the PendSV interrupt priority to be above that of the USB ISR, it now gets invoked. Is there an issue, however, setting the PendSV priority to be one of the highest?
Timer task never gets unblockedPosted by davedoors on November 10, 2016 Are you clearing the interrupt? How often is the interrupt executing? When you answer the second question don't say how often you think it is executing, measure it, you might be surprised. Your post basically says only higher priority interrupt will execute after the USB interrupt which might mean the USB interrupt is executing all the time.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|