Kernel changes:

Minor change to xQueueGenericReceive() to catch the extreme case of data being placed into a queue between a task timing out and leaving the xQueueGenericReceive() function.
Added xSemaphoreGetCount() macro.


Demo app changes:
Updated countsem.c to test the new xSemaphoreGetCount() macro.
This commit is contained in:
Richard Barry 2016-01-12 15:52:44 +00:00
parent f81575dcee
commit b832d5801f
5 changed files with 53 additions and 19 deletions

View File

@ -68,7 +68,7 @@
*/
/*
/*
* Simple demonstration of the usage of counting semaphore.
*/
@ -84,7 +84,7 @@
#define countMAX_COUNT_VALUE ( 200 )
/* Constants used to indicate whether or not the semaphore should have been
created with its maximum count value, or its minimum count value. These
created with its maximum count value, or its minimum count value. These
numbers are used to ensure that the pointers passed in as the task parameters
are valid. */
#define countSTART_AT_MAX_COUNT ( 0xaa )
@ -118,7 +118,7 @@ static void prvCountingSemaphoreTask( void *pvParameters );
static void prvIncrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter );
/*
* Utility function to decrement the semaphore count value up from
* Utility function to decrement the semaphore count value up from
* countMAX_COUNT_VALUE to zero.
*/
static void prvDecrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter );
@ -134,11 +134,11 @@ typedef struct COUNT_SEM_STRUCT
/* Set to countSTART_AT_MAX_COUNT if the semaphore should be created with
its count value set to its max count value, or countSTART_AT_ZERO if it
should have been created with its count value set to 0. */
UBaseType_t uxExpectedStartCount;
UBaseType_t uxExpectedStartCount;
/* Incremented on each cycle of the demo task. Used to detect a stalled
task. */
UBaseType_t uxLoopCounter;
UBaseType_t uxLoopCounter;
} xCountSemStruct;
/* Two structures are defined, one is passed to each test task. */
@ -160,10 +160,10 @@ void vStartCountingSemaphoreTasks( void )
xParameters[ 1 ].uxLoopCounter = 0;
/* vQueueAddToRegistry() adds the semaphore to the registry, if one is
in use. The registry is provided as a means for kernel aware
in use. The registry is provided as a means for kernel aware
debuggers to locate semaphores and has no purpose if a kernel aware debugger
is not being used. The call to vQueueAddToRegistry() will be removed
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
defined to be less than 1. */
vQueueAddToRegistry( ( QueueHandle_t ) xParameters[ 0 ].xSemaphore, "Counting_Sem_1" );
vQueueAddToRegistry( ( QueueHandle_t ) xParameters[ 1 ].xSemaphore, "Counting_Sem_2" );
@ -174,7 +174,7 @@ void vStartCountingSemaphoreTasks( void )
{
/* Create the demo tasks, passing in the semaphore to use as the parameter. */
xTaskCreate( prvCountingSemaphoreTask, "CNT1", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 0 ] ), tskIDLE_PRIORITY, NULL );
xTaskCreate( prvCountingSemaphoreTask, "CNT2", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 1 ] ), tskIDLE_PRIORITY, NULL );
xTaskCreate( prvCountingSemaphoreTask, "CNT2", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 1 ] ), tskIDLE_PRIORITY, NULL );
}
}
/*-----------------------------------------------------------*/
@ -193,6 +193,8 @@ UBaseType_t ux;
/* We should be able to 'take' the semaphore countMAX_COUNT_VALUE times. */
for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )
{
configASSERT( xSemaphoreGetCount( xSemaphore ) == ( countMAX_COUNT_VALUE - ux ) );
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) != pdPASS )
{
/* We expected to be able to take the semaphore. */
@ -206,8 +208,9 @@ UBaseType_t ux;
taskYIELD();
#endif
/* If the semaphore count is zero then we should not be able to 'take'
/* If the semaphore count is zero then we should not be able to 'take'
the semaphore. */
configASSERT( xSemaphoreGetCount( xSemaphore ) == 0 );
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS )
{
xErrorDetected = pdTRUE;
@ -219,7 +222,7 @@ static void prvIncrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_
{
UBaseType_t ux;
/* If the semaphore count is zero then we should not be able to 'take'
/* If the semaphore count is zero then we should not be able to 'take'
the semaphore. */
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS )
{
@ -229,6 +232,8 @@ UBaseType_t ux;
/* We should be able to 'give' the semaphore countMAX_COUNT_VALUE times. */
for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )
{
configASSERT( xSemaphoreGetCount( xSemaphore ) == ux );
if( xSemaphoreGive( xSemaphore ) != pdPASS )
{
/* We expected to be able to take the semaphore. */
@ -257,7 +262,7 @@ xCountSemStruct *pxParameter;
#ifdef USE_STDIO
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
const char * const pcTaskStartMsg = "Counting semaphore demo started.\r\n";
/* Queue a message for printing to say the task has started. */

View File

@ -776,6 +776,10 @@ extern "C" {
#define configSUPPORT_STATIC_ALLOCATION 0
#endif
#if( ( configUSE_RECURSIVE_MUTEXES == 1 ) && ( configUSE_MUTEXES != 1 ) )
#error configUSE_MUTEXES must be set to 1 to use recursive mutexes
#endif
#if( portTICK_TYPE_IS_ATOMIC == 0 )
/* Either variables of tick type cannot be read atomically, or
portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when

View File

@ -839,6 +839,18 @@ typedef QueueHandle_t SemaphoreHandle_t;
*/
#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )
/**
* semphr.h
* <pre>TaskHandle_t xSemaphoreGetCount( SemaphoreHandle_t xMutex );</pre>
*
* If the semaphore is a counting semaphore then xSemaphoreGetCount() returns
* its current count value. If the semaphore is a binary semaphore then
* xSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the
* semaphore is not available.
*
*/
#define xSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
#endif /* SEMAPHORE_H */

View File

@ -797,8 +797,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
prvUnlockQueue( pxQueue );
( void ) xTaskResumeAll();
/* Return to the original privilege level before exiting the
function. */
traceQUEUE_SEND_FAILED( pxQueue );
return errQUEUE_FULL;
}
@ -1385,7 +1383,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
taskENTER_CRITICAL();
{
/* Is there data in the queue now? To be running the calling task
must be the highest priority task wanting to access the queue. */
must be the highest priority task wanting to access the queue. */
if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 )
{
/* Remember the read position in case the queue is only being
@ -1541,8 +1539,16 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
{
prvUnlockQueue( pxQueue );
( void ) xTaskResumeAll();
traceQUEUE_RECEIVE_FAILED( pxQueue );
return errQUEUE_EMPTY;
if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
{
traceQUEUE_RECEIVE_FAILED( pxQueue );
return errQUEUE_EMPTY;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
}
}

View File

@ -1618,7 +1618,7 @@ uint16_t usIdleTaskStackSize = tskIDLE_STACK_SIZE;
configASSERT( xReturn );
}
/* Prevent compiler warnings if INCLUDE_xTaskGetIdleTaskHandle is set to 0,
/* Prevent compiler warnings if INCLUDE_xTaskGetIdleTaskHandle is set to 0,
meaning xIdleTaskHandle is not used anywhere else. */
( void ) xIdleTaskHandle;
}
@ -2732,9 +2732,13 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
/* Stop warnings. */
( void ) pvParameters;
/** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE
SCHEDULER IS STARTED. **/
for( ;; )
{
/* See if any tasks have been deleted. */
/* 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 )
@ -3029,7 +3033,7 @@ UBaseType_t x;
the calling task. */
pxTCB = prvGetTCBFromHandle( xTaskToModify );
vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 );
vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 );
}
#endif /* portUSING_MPU_WRAPPERS */
@ -3069,6 +3073,9 @@ UBaseType_t uxPriority;
static void prvCheckTasksWaitingTermination( void )
{
/** THIS FUNCTION IS CALLED FROM THE RTOS IDLE TASK **/
#if ( INCLUDE_vTaskDelete == 1 )
{
BaseType_t xListIsEmpty;