mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 17:48:33 -04:00
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:
parent
25b911e0bd
commit
4c3722bd76
6 changed files with 129 additions and 62 deletions
|
@ -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 )
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue