Hello,
I implemented FreeRTOS on KEAZ1284.
In my application I create 1 task and 2 timers. Of course also the Idle task is present.
I checked by using two debug pins:
PA2: toggle when the Idle task is executed,
PA3: toggle when the prvTimerTask is executed.
What I see is:
Idle Task is always running, starting a few ms from the POR.
-prvTimerTask sometime starts with a long delay (more than 50 ms).
/* create ADC task, priority is the second to last parameter */
(void)xTaskCreate(vADCTask, "ADC", configMINIMAL_STACK_SIZE, NULL_POINTER,
2u, ADC_getTaskHandlePtr());
/* create a 2 ms auto-reload timer, callback function is the last parameter */
x2msTimer = xTimerCreate("T2ms", pdMS_TO_TICKS(2u), pdTRUE, NULL_POINTER,
SWC_prv2msTimerCallback);
/* check the software timer was created */
if(x2msTimer != NULL_POINTER)
{
/* start the software timer, using a block time of 0, the scheduler has
* not been started yet so any block time specified here would be
* ignored anyway */
(void)xTimerStart(x2msTimer, 0u);
}
/* create a 10 ms auto-reload timer, callback function is the last parameter */
x10msTimer = xTimerCreate("T10ms", pdMS_TO_TICKS(10u), pdTRUE, NULL_POINTER,
SWC_prv10msTimerCallback);
/* check the software timer was created */
if(x10msTimer != NULL_POINTER)
{
/* start the software timer, using a block time of 0, the scheduler has
* not been started yet so any block time specified here would be
* ignored anyway */
(void)xTimerStart(x10msTimer, 0u);
}
/* start the created tasks running */
vTaskStartScheduler();
static portTASK_FUNCTION( prvTimerTask, pvParameters )
{
TickType_t xNextExpireTime;
BaseType_t xListWasEmpty;
/* Just to avoid compiler warnings. */
( void ) pvParameters;
#if( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 )
{
extern void vApplicationDaemonTaskStartupHook( void );
/* Allow the application writer to execute some code in the context of
this task at the point the task starts executing. This is useful if the
application includes initialisation code that would benefit from
executing after the scheduler has been started. */
vApplicationDaemonTaskStartupHook();
}
#endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */
for( ;; )
{
/* Query the timers list to see if it contains any timers, and if so,
obtain the time at which the next timer will expire. */
//EmPa >>>>>>>>>>>>>>TOGGLE A DEBUG LINE
static uint8_t x =0;
if (x==0)
{
GPIO_SET_IN(PTA,PTA2);
GPIO_ENABLE_PULLUP(PTA,PTA2);
x=1;
}else if(x==1)
{
GPIO_SET_OUT(PTA,PTA2);
GPIO_SET_LOW(PTA,PTA2);
x=0;
}
//<<<<<<<<<<<<<<<<<TOGGLE A DEBUG LINE -END
xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );
/* If a timer has expired, process it. Otherwise, block this task
until either a timer does expire, or a command is received. */
prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );
/* Empty the command queue. */
prvProcessReceivedCommands();
}
}
in prvIdleTask (module task.c) see below:
/*
* -----------------------------------------------------------
* The Idle task.
* ----------------------------------------------------------
*
* The portTASK_FUNCTION() macro is used to allow port/compiler specific
* language extensions. The equivalent prototype for this function is:
*
* void prvIdleTask( void *pvParameters );
*
*/
static portTASK_FUNCTION( prvIdleTask, pvParameters )
{
/* Stop warnings. */
( void ) pvParameters;
/** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE
SCHEDULER IS STARTED. **/
/* In case a task that has a secure context deletes itself, in which case
the idle task is responsible for deleting the task's secure context, if
any. */
portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE );
for( ;; )
{
/* See if any tasks have deleted themselves - if so then the idle task
is responsible for freeing the deleted task's TCB and stack. */
prvCheckTasksWaitingTermination();
#if ( configUSE_PREEMPTION == 0 )
{
/* If we are not using preemption we keep forcing a task switch to
see if any other task has become available. If we are using
preemption we don't need to do this as any task becoming available
will automatically get the processor anyway. */
taskYIELD();
}
#endif /* configUSE_PREEMPTION */
#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. */
//EmPa >>>>>>>>>>>>>>>>>>>>>>> TOGGLE A DEBUG LINE
static uint8_t x =0;
if (x==0)
{
GPIO_SET_IN(PTA,PTA3);
GPIO_ENABLE_PULLUP(PTA,PTA3);
x=1;
}else if(x==1)
{
GPIO_SET_OUT(PTA,PTA3);
GPIO_SET_LOW(PTA,PTA3);
x=0;
}
//<<<<<<<<<<<<<<<<<<<<<< TOGGLE A DEBUG LINE - END
if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 )
{
taskYIELD();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */
#if ( configUSE_IDLE_HOOK == 1 )
{
extern void vApplicationIdleHook( void );
/* Call the user defined function from within the idle task. This
allows the application designer to add background functionality
without the overhead of a separate task.
NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
CALL A FUNCTION THAT MIGHT BLOCK. */
vApplicationIdleHook();
}
#endif /* configUSE_IDLE_HOOK */
/* This conditional compilation should use inequality to 0, not equality
to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when
user defined low power mode implementations require
configUSE_TICKLESS_IDLE to be set to a value other than 1. */
#if ( configUSE_TICKLESS_IDLE != 0 )
{
TickType_t xExpectedIdleTime;
/* It is not desirable to suspend then resume the scheduler on
each iteration of the idle task. Therefore, a preliminary
test of the expected idle time is performed without the
scheduler suspended. The result here is not necessarily
valid. */
xExpectedIdleTime = prvGetExpectedIdleTime();
if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
{
vTaskSuspendAll();
{
/* Now the scheduler is suspended, the expected idle
time can be sampled again, and this time its value can
be used. */
configASSERT( xNextTaskUnblockTime >= xTickCount );
xExpectedIdleTime = prvGetExpectedIdleTime();
/* Define the following macro to set xExpectedIdleTime to 0
if the application does not want
portSUPPRESS_TICKS_AND_SLEEP() to be called. */
configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime );
if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
{
traceLOW_POWER_IDLE_BEGIN();
portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
traceLOW_POWER_IDLE_END();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
( void ) xTaskResumeAll();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* configUSE_TICKLESS_IDLE */
}
}
/*-----------------------------------------------------------*/