Preparing for new release...

Kernel changes:
- Remove an assert that was preventing xQueueSendFromISR() being used to give a mutex from an ISR (mutexes cannot be given using xSemaphoreGiveFromISR()).
- Introduce xTaskNotifyAndQueryFromISR() as the interrupt safe version of xTaskNotifyAndQuery().

Common demo task changes:
- Update IntSemTest.c to prove the theory that it is safe to give a mutex type semaphore from an interrupt using xQueueSendFromISR() instead of xSemaphoreGiveFromISR().
- Update TaskNotify.c to test the new xTaskNotifyAndQuery() from ISR fuction.
This commit is contained in:
Richard Barry 2015-08-01 07:03:32 +00:00
parent 25b911e0bd
commit 4c3722bd76
6 changed files with 129 additions and 62 deletions

View file

@ -163,7 +163,7 @@ static SemaphoreHandle_t xMasterSlaveMutex = NULL;
/* Flag that allows the master task to control when the interrupt gives or does
not give the mutex. There is no mutual exclusion on this variable, but this is
only test code and it should be fine in the 32=bit test environment. */
static BaseType_t xOkToGiveMutex = pdFALSE, xOkToGiveCountingSemaphore = pdFALSE;
static BaseType_t xOkToGiveMutex = pdFALSE, xOkToGiveCountingSemaphore = pdFALSE, xOkToGiveMasterSlaveMutex = pdFALSE;
/* Used to coordinate timing between tasks and the interrupt. */
const TickType_t xInterruptGivePeriod = pdMS_TO_TICKS( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS );
@ -217,6 +217,8 @@ static void vInterruptMutexMasterTask( void *pvParameters )
static void prvTakeAndGiveInTheSameOrder( void )
{
static BaseType_t xGiveFromTask = pdTRUE;
/* Ensure the slave is suspended, and that this task is running at the
lower priority as expected as the start conditions. */
#if( INCLUDE_eTaskGetState == 1 )
@ -293,10 +295,27 @@ static void prvTakeAndGiveInTheSameOrder( void )
/* Finally give back the shared mutex. This time the higher priority
task should run before this task runs again - so this task should have
disinherited the priority and the higher priority task should be in the
suspended state again. */
if( xSemaphoreGive( xMasterSlaveMutex ) != pdPASS )
suspended state again. Alternatve beetween giving the mutex from this task,
and giving it from the interrupt. */
if( xGiveFromTask == pdTRUE )
{
xErrorDetected = pdTRUE;
if( xSemaphoreGive( xMasterSlaveMutex ) != pdPASS )
{
xErrorDetected = pdTRUE;
}
/* Give the mutex from the interrupt on the next go around. */
xGiveFromTask = pdFALSE;
}
else
{
/* Wait for the mutex to be given from the interrupt. */
xOkToGiveMasterSlaveMutex = pdTRUE;
vTaskDelay( xInterruptGivePeriod + ( xInterruptGivePeriod >> 1 ) );
xOkToGiveMasterSlaveMutex = pdFALSE;
/* Give the mutex from the task on the next go around. */
xGiveFromTask = pdTRUE;
}
if( uxTaskPriorityGet( NULL ) != intsemMASTER_PRIORITY )
@ -514,15 +533,36 @@ TickType_t xTimeNow;
xTimeNow = xTaskGetTickCountFromISR();
if( ( ( TickType_t ) ( xTimeNow - xLastGiveTime ) ) >= pdMS_TO_TICKS( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS ) )
{
configASSERT( xISRMutex );
if( xOkToGiveMutex != pdFALSE )
{
configASSERT( xISRMutex );
/* Null is used as the second parameter in this give, and non-NULL
in the other gives for code coverage reasons. */
xSemaphoreGiveFromISR( xISRMutex, NULL );
in the other gives, for code coverage reasons. NOTE: This is a
Mutex, so xQueueGiveFromISR() should be used in place of
xSemaphoreGiveFromISR() in case there is a mutex holder that has
inherited a priority (although, in the case of xISRMutex, there
isn't). The "item to queue" parameter is set to NULL as no data is
copied into a mutex.*/
xQueueSendFromISR( ( QueueHandle_t ) xISRMutex, NULL, NULL );
/* Second give attempt should fail. */
configASSERT( xSemaphoreGiveFromISR( xISRMutex, &xHigherPriorityTaskWoken ) == pdFAIL );
configASSERT( xQueueSendFromISR( xISRMutex, NULL, &xHigherPriorityTaskWoken ) == pdFAIL );
}
if( xOkToGiveMasterSlaveMutex != pdFALSE )
{
configASSERT( xOkToGiveMasterSlaveMutex );
/* NOTE: This is a Mutex, so xQueueGiveFromISR() should be used in
place of xSemaphoreGiveFromISR() in case there is a mutex holder
that has inherited a priority (as indeed there is in this case).
The "item to queue" parameter is set to NULL as no data is copied
into a mutex. */
xQueueSendFromISR( ( QueueHandle_t ) xMasterSlaveMutex, NULL, NULL );
/* Second give attempt should fail. */
configASSERT( xQueueSendFromISR( xMasterSlaveMutex, NULL, &xHigherPriorityTaskWoken ) == pdFAIL );
}
if( xOkToGiveCountingSemaphore != pdFALSE )

View file

@ -472,8 +472,10 @@ TickType_t xPeriod;
void xNotifyTaskFromISR( void )
{
static BaseType_t xCallCount = 0;
static BaseType_t xCallCount = 0, xAPIToUse = 0;
const BaseType_t xCallInterval = pdMS_TO_TICKS( 50 );
uint32_t ulPreviousValue;
const uint32_t ulUnexpectedValue = 0xff;
/* The task performs some tests before starting the timer that gives the
notification from this interrupt. If the timer has not been created yet
@ -488,7 +490,28 @@ const BaseType_t xCallInterval = pdMS_TO_TICKS( 50 );
/* It is time to 'give' the notification again. */
xCallCount = 0;
vTaskNotifyGiveFromISR( xTaskToNotify, NULL );
/* Test using both vTaskNotifyGiveFromISR(), xTaskNotifyFromISR()
and xTaskNotifyAndQueryFromISR(). */
switch( xAPIToUse )
{
case 0: vTaskNotifyGiveFromISR( xTaskToNotify, NULL );
xAPIToUse++;
break;
case 1: xTaskNotifyFromISR( xTaskToNotify, 0, eIncrement, NULL );
xAPIToUse++;
break;
case 2: ulPreviousValue = ulUnexpectedValue;
xTaskNotifyAndQueryFromISR( xTaskToNotify, 0, eIncrement, &ulPreviousValue, NULL );
configASSERT( ulPreviousValue != ulUnexpectedValue );
xAPIToUse = 0;
break;
default:/* Should never get here!. */
break;
}
ulTimerNotificationsSent++;
}
}

View file

@ -302,6 +302,8 @@ volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
( void ) ulLine;
( void ) pcFileName;
printf( "ASSERT! Line %d, file %s\r\n", ulLine, pcFileName );
taskENTER_CRITICAL();
{
/* Stop the trace recording. */