mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-26 04:58:36 -04:00
Demo tasks only, with the aim of improving test coverage:
+ Split out the code that uses a mutex from an interrupt from GenQTest.c and add to new common demo task IntSemTest.c.
This commit is contained in:
parent
d55e7e77a2
commit
b6e4854f26
4 changed files with 488 additions and 101 deletions
|
@ -86,14 +86,13 @@
|
|||
#include "GenQTest.h"
|
||||
|
||||
#define genqQUEUE_LENGTH ( 5 )
|
||||
#define genqNO_BLOCK ( 0 )
|
||||
#define intsemNO_BLOCK ( 0 )
|
||||
|
||||
#define genqMUTEX_LOW_PRIORITY ( tskIDLE_PRIORITY )
|
||||
#define genqMUTEX_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||
#define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||
#define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 )
|
||||
|
||||
#define genqINTERRUPT_MUTEX_GIVE_PERIOD_MS ( 100 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
@ -122,28 +121,6 @@ static void prvLowPriorityMutexTask( void *pvParameters );
|
|||
static void prvMediumPriorityMutexTask( void *pvParameters );
|
||||
static void prvHighPriorityMutexTask( void *pvParameters );
|
||||
|
||||
/*
|
||||
* Exercises the priority inheritance when a task takes two mutexes, returning
|
||||
* them in a different order to which they were taken.
|
||||
*/
|
||||
static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex );
|
||||
|
||||
/*
|
||||
* Exercises the priority inheritance when a task takes two mutexes, returning
|
||||
* them in the same order in which they were taken.
|
||||
*/
|
||||
static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex );
|
||||
|
||||
/*
|
||||
* Task that receives an a mutex that is given from an interrupt - although
|
||||
* generally mutexes should not be used given in interrupts (and definitely
|
||||
* never taken in an interrupt) there are some circumstances when it may be
|
||||
* desirable. NOTE: This function is not declared static to prevent compiler
|
||||
* warnings being generated in demos where the function is declared but not
|
||||
* used.
|
||||
*/
|
||||
void vInterruptMutexTask( void *pvParameters );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Flag that will be latched to pdTRUE should any unexpected behaviour be
|
||||
|
@ -162,11 +139,6 @@ static volatile uint32_t ulGuardedVariable = 0;
|
|||
priority mutex test tasks. */
|
||||
static TaskHandle_t xHighPriorityMutexTask, xMediumPriorityMutexTask;
|
||||
|
||||
/* A mutex which is given from an interrupt - although generally mutexes should
|
||||
not be used given in interrupts (and definitely never taken in an interrupt)
|
||||
there are some circumstances when it may be desirable. */
|
||||
static SemaphoreHandle_t xISRMutex = NULL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vStartGenericQueueTasks( UBaseType_t uxPriority )
|
||||
|
@ -174,8 +146,6 @@ void vStartGenericQueueTasks( UBaseType_t uxPriority )
|
|||
QueueHandle_t xQueue;
|
||||
SemaphoreHandle_t xMutex;
|
||||
|
||||
xISRMutex = xSemaphoreCreateMutex();
|
||||
configASSERT( xISRMutex );
|
||||
|
||||
/* Create the queue that we are going to use for the
|
||||
prvSendFrontAndBackTest demo. */
|
||||
|
@ -211,14 +181,6 @@ SemaphoreHandle_t xMutex;
|
|||
xTaskCreate( prvLowPriorityMutexTask, "MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );
|
||||
xTaskCreate( prvMediumPriorityMutexTask, "MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );
|
||||
xTaskCreate( prvHighPriorityMutexTask, "MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );
|
||||
|
||||
/* Only when the windows simulator is being used - create the task that
|
||||
receives a mutex from an interrupt. */
|
||||
#ifdef _WINDOWS_
|
||||
{
|
||||
xTaskCreate( vInterruptMutexTask, "IntMu", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, NULL );
|
||||
}
|
||||
#endif /* __WINDOWS__ */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -244,14 +206,14 @@ QueueHandle_t xQueue;
|
|||
should have the same efect as sending it to the front of the queue.
|
||||
|
||||
First send to the front and check everything is as expected. */
|
||||
xQueueSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );
|
||||
xQueueSendToFront( xQueue, ( void * ) &ulLoopCounter, intsemNO_BLOCK );
|
||||
|
||||
if( uxQueueMessagesWaiting( xQueue ) != 1 )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
|
||||
if( xQueueReceive( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -270,14 +232,14 @@ QueueHandle_t xQueue;
|
|||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );
|
||||
xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, intsemNO_BLOCK );
|
||||
|
||||
if( uxQueueMessagesWaiting( xQueue ) != 1 )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
|
||||
if( xQueueReceive( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -303,7 +265,7 @@ QueueHandle_t xQueue;
|
|||
/* Place 2, 3, 4 into the queue, adding items to the back of the queue. */
|
||||
for( ulData = 2; ulData < 5; ulData++ )
|
||||
{
|
||||
xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK );
|
||||
xQueueSendToBack( xQueue, ( void * ) &ulData, intsemNO_BLOCK );
|
||||
}
|
||||
|
||||
/* Now the order in the queue should be 2, 3, 4, with 2 being the first
|
||||
|
@ -313,9 +275,9 @@ QueueHandle_t xQueue;
|
|||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
ulData = 1;
|
||||
xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );
|
||||
xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK );
|
||||
ulData = 0;
|
||||
xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );
|
||||
xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK );
|
||||
|
||||
/* Now the queue should be full, and when we read the data out we
|
||||
should receive 0, 1, 2, 3, 4. */
|
||||
|
@ -324,12 +286,12 @@ QueueHandle_t xQueue;
|
|||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
|
||||
if( xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
|
||||
if( xQueueSendToBack( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -342,7 +304,7 @@ QueueHandle_t xQueue;
|
|||
for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ )
|
||||
{
|
||||
/* Try peeking the data first. */
|
||||
if( xQueuePeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
|
||||
if( xQueuePeek( xQueue, &ulData2, intsemNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -356,7 +318,7 @@ QueueHandle_t xQueue;
|
|||
/* Now try receiving the data for real. The value should be the
|
||||
same. Clobber the value first so we know we really received it. */
|
||||
ulData2 = ~ulData2;
|
||||
if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
|
||||
if( xQueueReceive( xQueue, &ulData2, intsemNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -380,12 +342,12 @@ QueueHandle_t xQueue;
|
|||
|
||||
/* Our queue is empty once more, add 10, 11 to the back. */
|
||||
ulData = 10;
|
||||
if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )
|
||||
if( xQueueSend( xQueue, &ulData, intsemNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
ulData = 11;
|
||||
if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )
|
||||
if( xQueueSend( xQueue, &ulData, intsemNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -399,7 +361,7 @@ QueueHandle_t xQueue;
|
|||
front. */
|
||||
for( ulData = 9; ulData >= 7; ulData-- )
|
||||
{
|
||||
if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
|
||||
if( xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -412,12 +374,12 @@ QueueHandle_t xQueue;
|
|||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
|
||||
if( xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
|
||||
if( xQueueSendToBack( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -429,7 +391,7 @@ QueueHandle_t xQueue;
|
|||
/* Check the data we read out is in the expected order. */
|
||||
for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ )
|
||||
{
|
||||
if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
|
||||
if( xQueueReceive( xQueue, &ulData2, intsemNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -453,7 +415,7 @@ QueueHandle_t xQueue;
|
|||
static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex )
|
||||
{
|
||||
/* Take the mutex. It should be available now. */
|
||||
if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS )
|
||||
if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -513,7 +475,7 @@ static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, S
|
|||
}
|
||||
|
||||
/* Take the local mutex too, so two mutexes are now held. */
|
||||
if( xSemaphoreTake( xLocalMutex, genqNO_BLOCK ) != pdPASS )
|
||||
if( xSemaphoreTake( xLocalMutex, intsemNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -583,7 +545,7 @@ static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, S
|
|||
static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex )
|
||||
{
|
||||
/* Take the mutex. It should be available now. */
|
||||
if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS )
|
||||
if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -634,7 +596,7 @@ static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, Semaph
|
|||
}
|
||||
|
||||
/* Take the local mutex too, so two mutexes are now held. */
|
||||
if( xSemaphoreTake( xLocalMutex, genqNO_BLOCK ) != pdPASS )
|
||||
if( xSemaphoreTake( xLocalMutex, intsemNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
@ -787,46 +749,6 @@ SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* NOTE: This function is not declared static to prevent compiler warnings in
|
||||
demos where the function is declared but not used. */
|
||||
void vInterruptMutexTask( void *pvParameters )
|
||||
{
|
||||
const TickType_t xInterruptGivePeriod = pdMS_TO_TICKS( genqINTERRUPT_MUTEX_GIVE_PERIOD_MS );
|
||||
volatile uint32_t ulLoops = 0;
|
||||
|
||||
/* Just to avoid compiler warnings. */
|
||||
( void ) pvParameters;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Has to wait longer than the time between gives to make sure it
|
||||
should definitely have received the mutex. */
|
||||
if( xSemaphoreTake( xISRMutex, ( xInterruptGivePeriod * 2 ) ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulLoops++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vMutexISRInteractionTest( void )
|
||||
{
|
||||
static TickType_t xLastGiveTime = 0;
|
||||
TickType_t xTimeNow;
|
||||
|
||||
xTimeNow = xTaskGetTickCountFromISR();
|
||||
if( ( xTimeNow - xLastGiveTime ) >= pdMS_TO_TICKS( genqINTERRUPT_MUTEX_GIVE_PERIOD_MS ) )
|
||||
{
|
||||
configASSERT( xISRMutex );
|
||||
xSemaphoreGiveFromISR( xISRMutex, NULL );
|
||||
xLastGiveTime = xTimeNow;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* This is called to check that all the created tasks are still running. */
|
||||
BaseType_t xAreGenericQueueTasksStillRunning( void )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue