I’m Trying to handle external interrupt on pin PB2. I suspend the task using vTaskSuspend(NULL); and in ISR I use xTaskResumeFromISR( ); then portYIELD_FROM_ISR(); to Resume the suspended task. When I debug the code it gets stuck at this part in tasks.c
#if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
{
/* When using preemption tasks of equal priority will be
timesliced. If a task that is sharing the idle priority is ready
to run then the idle task should yield before the end of the
timeslice.
A critical region is not required here as we are just reading from
the list, and an occasional incorrect value will not matter. If
the ready list at the idle priority contains more than one task
then a task other than the idle task is ready to execute. */
if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 )
{
taskYIELD();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
First, using suspend/resume has the risk that if the resume comes before the suspend actually happens, it gets missed, which is one reason using a semaphore, or direct-to-task notificatons are generally better for that task.
Second, this sort of hang up is often due to bad interrupt priorities, you don’t say what processor you are using, but if it is an ARM family, these have an inverted from normal structure, (low numbers are higher priority) and often default to priority 0, which is the highest, and above the level nomrally allowed by FreeRTOS. There are asserts in the code that can be enabled by an appropriate definition for the configASSERT macro.
I would put that more strongly - as per the documentation do not use
suspend resume in this scenario - in fact I thought the ‘resume from
isr’ function had been removed for this reason.
Thank you so much for your reply
I tried to use vTaskNotifyGiveFromISR() in the ISR and ulTaskNotifyTake() in the Task but the code gets stuck in this part in tasks.c line 3376
static void prvCheckTasksWaitingTermination( void )
{
/** THIS FUNCTION IS CALLED FROM THE RTOS IDLE TASK **/
#if ( INCLUDE_vTaskDelete == 1 )
{
BaseType_t xListIsEmpty;
/* ucTasksDeleted is used to prevent vTaskSuspendAll() being called
too often in the idle task. */
while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )