Skip to content

Commit 80457ca

Browse files
committed
added multiple idle tasks
1 parent 83595e8 commit 80457ca

File tree

1 file changed

+96
-16
lines changed

1 file changed

+96
-16
lines changed

tasks.c

Lines changed: 96 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,9 @@ static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION;
467467
*
468468
*/
469469
static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ) PRIVILEGED_FUNCTION;
470+
#if ( configNUM_CORES > 1 )
471+
static portTASK_FUNCTION_PROTO( prvMinimalIdleTask, pvParameters ) PRIVILEGED_FUNCTION;
472+
#endif
470473

471474
/*
472475
* Utility to free all memory allocated by the scheduler to hold a TCB,
@@ -1545,7 +1548,11 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
15451548
pxNewTCB->xTaskRunState = taskTASK_NOT_RUNNING;
15461549

15471550
/* Is this an idle task? */
1551+
#if(configNUM_CORES > 1)
1552+
pxNewTCB->xIsIdle = ( pxTaskCode == prvIdleTask ) || (pxTaskCode == prvMinimalIdleTask);
1553+
#else
15481554
pxNewTCB->xIsIdle = ( pxTaskCode == prvIdleTask );
1555+
#endif
15491556

15501557
if( pxCreatedTask != NULL )
15511558
{
@@ -2663,22 +2670,40 @@ void vTaskStartScheduler( void )
26632670

26642671
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
26652672
{
2666-
#error User must specify an array of buffers for idle task TCBs and stacks
2667-
StaticTask_t * pxIdleTaskTCBBuffer = NULL;
2668-
StackType_t * pxIdleTaskStackBuffer = NULL;
2669-
uint32_t ulIdleTaskStackSize;
2670-
2671-
/* The Idle task is created using user provided RAM - obtain the
2672-
* address of the RAM then create the idle task. */
2673-
vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize );
2674-
xIdleTaskHandle[ xCoreID ] = xTaskCreateStatic( prvIdleTask,
2675-
cIdleName,
2676-
ulIdleTaskStackSize,
2677-
( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */
2678-
portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */
2679-
pxIdleTaskStackBuffer,
2680-
pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
2681-
2673+
if(xCoreID == 0)
2674+
{
2675+
StaticTask_t * pxIdleTaskTCBBuffer = NULL;
2676+
StackType_t * pxIdleTaskStackBuffer = NULL;
2677+
uint32_t ulIdleTaskStackSize;
2678+
2679+
/* The Idle task is created using user provided RAM - obtain the
2680+
* address of the RAM then create the idle task. */
2681+
vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize );
2682+
xIdleTaskHandle[ xCoreID ] = xTaskCreateStatic( prvIdleTask,
2683+
cIdleName,
2684+
ulIdleTaskStackSize,
2685+
( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */
2686+
portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */
2687+
pxIdleTaskStackBuffer,
2688+
pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
2689+
}
2690+
#if( configNUM_CORES > 1)
2691+
else
2692+
{
2693+
struct taskMemory{
2694+
StaticTask_t TCB;
2695+
StackType_t stack[configMINIMAL_STACK_SIZE];
2696+
};
2697+
static struct taskMemory idleMemory[configNUM_CORES];
2698+
xIdleTaskHandle[ xCoreID ] = xTaskCreateStatic( prvMinimalIdleTask,
2699+
cIdleName,
2700+
configMINIMAL_STACK_SIZE,
2701+
( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */
2702+
portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */
2703+
idleMemory[xCoreID].stack,
2704+
&idleMemory[xCoreID].TCB ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
2705+
}
2706+
#endif
26822707
if( xIdleTaskHandle[ xCoreID ] != NULL )
26832708
{
26842709
xReturn = pdPASS;
@@ -4146,6 +4171,61 @@ void vTaskMissedYield( void )
41464171

41474172
#endif /* configUSE_TRACE_FACILITY */
41484173

4174+
/*
4175+
* -----------------------------------------------------------
4176+
* The MinimalIdle task.
4177+
* ----------------------------------------------------------
4178+
*
4179+
* The portTASK_FUNCTION() macro is used to allow port/compiler specific
4180+
* language extensions. The equivalent prototype for this function is:
4181+
*
4182+
* void prvMinimalIdleTask( void *pvParameters );
4183+
*
4184+
* The minimal idle task is used for all the additional Cores in a SMP system.
4185+
* There must be only 1 idle task and the rest are minimal idle tasks.
4186+
*
4187+
* @todo additional conditional compiles to remove this function.
4188+
*/
4189+
#if (configNUM_CORES > 1)
4190+
static portTASK_FUNCTION( prvMinimalIdleTask, pvParameters )
4191+
{
4192+
for(;;)
4193+
{
4194+
#if ( configUSE_PREEMPTION == 0 )
4195+
{
4196+
/* If we are not using preemption we keep forcing a task switch to
4197+
* see if any other task has become available. If we are using
4198+
* preemption we don't need to do this as any task becoming available
4199+
* will automatically get the processor anyway. */
4200+
taskYIELD();
4201+
}
4202+
#endif /* configUSE_PREEMPTION */
4203+
4204+
#if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
4205+
{
4206+
/* When using preemption tasks of equal priority will be
4207+
* timesliced. If a task that is sharing the idle priority is ready
4208+
* to run then the idle task should yield before the end of the
4209+
* timeslice.
4210+
*
4211+
* A critical region is not required here as we are just reading from
4212+
* the list, and an occasional incorrect value will not matter. If
4213+
* the ready list at the idle priority contains one more task than the
4214+
* number of idle tasks, which is equal to the configured numbers of cores
4215+
* then a task other than the idle task is ready to execute. */
4216+
if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) configNUM_CORES )
4217+
{
4218+
taskYIELD();
4219+
}
4220+
else
4221+
{
4222+
mtCOVERAGE_TEST_MARKER();
4223+
}
4224+
}
4225+
#endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */
4226+
}
4227+
}
4228+
#endif
41494229
/*
41504230
* -----------------------------------------------------------
41514231
* The Idle task.

0 commit comments

Comments
 (0)