📄 dynamic.c
字号:
/* Raise our priority above the controller task to ensure a context
switch does not occur while we are accessing this variable. */
vTaskPrioritySet( NULL, ucOurPriority + 1 );
( *pulCounter )++;
vTaskPrioritySet( NULL, ucOurPriority );
}
}
/*-----------------------------------------------------------*/
/*
* Controller task as described above.
*/
static void vCounterControlTask( void * pvParameters )
{
unsigned portLONG ulLastCounter;
portSHORT sLoops;
portSHORT sError = pdFALSE;
const portCHAR * const pcTaskStartMsg = "Priority manipulation tasks started.\r\n";
const portCHAR * const pcTaskFailMsg = "Priority manipulation Task Failed\r\n";
/* Just to stop warning messages. */
( void ) pvParameters;
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
for( ;; )
{
/* Start with the counter at zero. */
ulCounter = ( unsigned portLONG ) 0;
/* First section : */
/* Check the continuous count task is running. */
for( sLoops = 0; sLoops < priLOOPS; sLoops++ )
{
/* Suspend the continuous count task so we can take a mirror of the
shared variable without risk of corruption. */
vTaskSuspend( xContinousIncrementHandle );
ulLastCounter = ulCounter;
vTaskResume( xContinousIncrementHandle );
/* Now delay to ensure the other task has processor time. */
vTaskDelay( priSLEEP_TIME );
/* Check the shared variable again. This time to ensure mutual
exclusion the whole scheduler will be locked. This is just for
demo purposes! */
vTaskSuspendAll();
{
if( ulLastCounter == ulCounter )
{
/* The shared variable has not changed. There is a problem
with the continuous count task so flag an error. */
sError = pdTRUE;
cTaskResumeAll();
vPrintDisplayMessage( &pcTaskFailMsg );
vTaskSuspendAll();
}
}
cTaskResumeAll();
}
/* Second section: */
/* Suspend the continuous counter task so it stops accessing the shared variable. */
vTaskSuspend( xContinousIncrementHandle );
/* Reset the variable. */
ulCounter = ( unsigned portLONG ) 0;
/* Resume the limited count task which has a higher priority than us.
We should therefore not return from this call until the limited count
task has suspended itself with a known value in the counter variable. */
vTaskResume( xLimitedIncrementHandle );
/* Does the counter variable have the expected value? */
if( ulCounter != priMAX_COUNT )
{
sError = pdTRUE;
vPrintDisplayMessage( &pcTaskFailMsg );
}
if( sError == pdFALSE )
{
/* If no errors have occurred then increment the check variable. */
portENTER_CRITICAL();
usCheckVariable++;
portEXIT_CRITICAL();
}
/* Resume the continuous count task and do it all again. */
vTaskResume( xContinousIncrementHandle );
}
}
/*-----------------------------------------------------------*/
static void vQueueSendWhenSuspendedTask( void *pvParameters )
{
static unsigned portLONG ulValueToSend = ( unsigned portLONG ) 0;
const portCHAR * const pcTaskStartMsg = "Queue send while suspended task started.\r\n";
const portCHAR * const pcTaskFailMsg = "Queue send while suspended failed.\r\n";
/* Just to stop warning messages. */
( void ) pvParameters;
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
for( ;; )
{
vTaskSuspendAll();
{
/* We must not block while the scheduler is suspended! */
if( cQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE )
{
if( cSuspendedQueueSendError == ( portCHAR ) pdFALSE )
{
cTaskResumeAll();
vPrintDisplayMessage( &pcTaskFailMsg );
vTaskSuspendAll();
}
cSuspendedQueueSendError = pdTRUE;
}
}
cTaskResumeAll();
vTaskDelay( priSLEEP_TIME );
++ulValueToSend;
}
}
/*-----------------------------------------------------------*/
static void vQueueReceiveWhenSuspendedTask( void *pvParameters )
{
static unsigned portLONG ulExpectedValue = ( unsigned portLONG ) 0, ulReceivedValue;
const portCHAR * const pcTaskStartMsg = "Queue receive while suspended task started.\r\n";
const portCHAR * const pcTaskFailMsg = "Queue receive while suspended failed.\r\n";
portCHAR cGotValue;
/* Just to stop warning messages. */
( void ) pvParameters;
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
for( ;; )
{
do
{
/* Suspending the scheduler here is fairly pointless and
undesirable for a normal application. It is done here purely
to test the scheduler. The inner cTaskResumeAll() should
never return pdTRUE as the scheduler is still locked by the
outer call. */
vTaskSuspendAll();
{
vTaskSuspendAll();
{
cGotValue = cQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK );
}
if( cTaskResumeAll() )
{
cSuspendedQueueReceiveError = ( portCHAR ) pdTRUE;
}
}
cTaskResumeAll();
} while( cGotValue == ( portCHAR ) pdFALSE );
if( ulReceivedValue != ulExpectedValue )
{
if( cSuspendedQueueReceiveError == ( portCHAR ) pdFALSE )
{
vPrintDisplayMessage( &pcTaskFailMsg );
}
cSuspendedQueueReceiveError = ( portCHAR ) pdTRUE;
}
++ulExpectedValue;
}
}
/*-----------------------------------------------------------*/
/* Called to check that all the created tasks are still running without error. */
portSHORT sAreDynamicPriorityTasksStillRunning( void )
{
/* Keep a history of the check variables so we know if it has been incremented
since the last call. */
static unsigned portSHORT usLastTaskCheck = ( unsigned portSHORT ) 0;
portSHORT sReturn = pdTRUE;
/* Check the tasks are still running by ensuring the check variable
is still incrementing. */
if( usCheckVariable == usLastTaskCheck )
{
/* The check has not incremented so an error exists. */
sReturn = pdFALSE;
}
if( cSuspendedQueueSendError == ( portCHAR ) pdTRUE )
{
sReturn = pdFALSE;
}
if( cSuspendedQueueReceiveError == ( portCHAR ) pdTRUE )
{
sReturn = pdFALSE;
}
usLastTaskCheck = usCheckVariable;
return sReturn;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -