mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-11 13:54:16 -04:00
Core kernel code:
- Re-introduce the ability to give a mutex from an ISR. Common demo code: - Add additional tests into the GenQTest files for priority inheritance and using a mutex from an ISR.
This commit is contained in:
parent
6507701fdf
commit
ff5d3512b3
13 changed files with 379 additions and 176 deletions
|
@ -73,7 +73,7 @@
|
|||
typedef void (*TaskFunction_t)( void * );
|
||||
|
||||
/* Converts a time in milliseconds to a time in ticks. */
|
||||
#define pdMS_TO_TICKS( xTimeInMs ) ( ( ( TickType_t ) xTimeInMs * configTICK_RATE_HZ ) / ( TickType_t ) 1000 )
|
||||
#define pdMS_TO_TICKS( xTimeInMs ) ( ( ( TickType_t ) ( xTimeInMs ) * configTICK_RATE_HZ ) / ( TickType_t ) 1000 )
|
||||
|
||||
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||
|
|
|
@ -1554,12 +1554,9 @@ eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION;
|
|||
|
||||
/*
|
||||
* For internal use only. Increment the mutex held count when a mutex is
|
||||
* taken and decrement the mutex held count when the mutex is given back
|
||||
* respectively. The mutex held count is used to know when it is safe to
|
||||
* disinherit a priority.
|
||||
* taken and return the handle of the task that has taken the mutex.
|
||||
*/
|
||||
void vTaskIncrementMutexHeldCount( void );
|
||||
void vTaskDecrementMutexHeldCount( void );
|
||||
void *pvTaskIncrementMutexHeldCount( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
|||
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
||||
2) Incorrect interrupt priority assignment, especially on Cortex-M3
|
||||
parts where numerically high priority values denote low actual
|
||||
interrupt priories, which can seem counter intuitive. See
|
||||
interrupt priorities, which can seem counter intuitive. See
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
|
||||
3) Calling an API function from within a critical section or when
|
||||
the scheduler is suspended, or calling an API function that does
|
||||
|
|
|
@ -421,10 +421,7 @@ QueueHandle_t xReturn = NULL;
|
|||
|
||||
traceCREATE_MUTEX( pxNewQueue );
|
||||
|
||||
/* Start with the semaphore in the expected state. Preload the
|
||||
mutex held count as calling xQueueGenericSend() will decrement the
|
||||
count back to 0. */
|
||||
vTaskIncrementMutexHeldCount();
|
||||
/* Start with the semaphore in the expected state. */
|
||||
( void ) xQueueGenericSend( pxNewQueue, NULL, ( TickType_t ) 0U, queueSEND_TO_BACK );
|
||||
}
|
||||
else
|
||||
|
@ -702,7 +699,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
the mutexes were given back in an order that is
|
||||
different to that in which they were taken. */
|
||||
queueYIELD_IF_USING_PREEMPTION();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
|
@ -1125,8 +1122,8 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
{
|
||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||
{
|
||||
/* The task waiting has a higher priority so record that a
|
||||
context switch is required. */
|
||||
/* The task waiting has a higher priority so
|
||||
record that a context switch is required. */
|
||||
if( pxHigherPriorityTaskWoken != NULL )
|
||||
{
|
||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||
|
@ -1243,7 +1240,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
{
|
||||
/* Record the information required to implement
|
||||
priority inheritance should it become necessary. */
|
||||
pxQueue->pxMutexHolder = ( int8_t * ) xTaskGetCurrentTaskHandle(); /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */
|
||||
pxQueue->pxMutexHolder = ( int8_t * ) pvTaskIncrementMutexHeldCount(); /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1633,7 +1630,6 @@ BaseType_t xReturn = pdFALSE;
|
|||
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
|
||||
{
|
||||
/* The mutex is no longer being held. */
|
||||
vTaskDecrementMutexHeldCount();
|
||||
xReturn = xTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );
|
||||
pxQueue->pxMutexHolder = NULL;
|
||||
}
|
||||
|
@ -1699,7 +1695,7 @@ BaseType_t xReturn = pdFALSE;
|
|||
|
||||
static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer )
|
||||
{
|
||||
if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )
|
||||
if( pxQueue->uxItemSize != 0 )
|
||||
{
|
||||
pxQueue->u.pcReadFrom += pxQueue->uxItemSize;
|
||||
if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */
|
||||
|
@ -1712,11 +1708,6 @@ static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer
|
|||
}
|
||||
( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A mutex was taken. */
|
||||
vTaskIncrementMutexHeldCount();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -553,14 +553,14 @@ TCB_t * pxNewTCB;
|
|||
pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) ); /*lint !e923 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. */
|
||||
|
||||
/* Check the alignment of the calculated top of stack is correct. */
|
||||
configASSERT( ( ( ( uint32_t ) pxTopOfStack & ( uint32_t ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
|
||||
configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
|
||||
}
|
||||
#else /* portSTACK_GROWTH */
|
||||
{
|
||||
pxTopOfStack = pxNewTCB->pxStack;
|
||||
|
||||
/* Check the alignment of the stack buffer is correct. */
|
||||
configASSERT( ( ( ( uint32_t ) pxNewTCB->pxStack & ( uint32_t ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
|
||||
configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
|
||||
|
||||
/* If we want to use stack checking on architectures that use
|
||||
a positive stack growth direction then we also need to store the
|
||||
|
@ -3246,6 +3246,9 @@ TCB_t *pxTCB;
|
|||
|
||||
if( pxMutexHolder != NULL )
|
||||
{
|
||||
configASSERT( pxTCB->uxMutexesHeld );
|
||||
( pxTCB->uxMutexesHeld )--;
|
||||
|
||||
if( pxTCB->uxPriority != pxTCB->uxBasePriority )
|
||||
{
|
||||
/* Only disinherit if no other mutexes are held. */
|
||||
|
@ -3584,7 +3587,7 @@ TickType_t uxReturn;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vTaskIncrementMutexHeldCount( void )
|
||||
void *pvTaskIncrementMutexHeldCount( void )
|
||||
{
|
||||
#if ( configUSE_MUTEXES == 1 )
|
||||
{
|
||||
|
@ -3594,26 +3597,13 @@ void vTaskIncrementMutexHeldCount( void )
|
|||
{
|
||||
( pxCurrentTCB->uxMutexesHeld )++;
|
||||
}
|
||||
|
||||
return pxCurrentTCB;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vTaskDecrementMutexHeldCount( void )
|
||||
{
|
||||
#if ( configUSE_MUTEXES == 1 )
|
||||
{
|
||||
/* If xSemaphoreCreateMutex() is called before any tasks have been created
|
||||
then pxCurrentTCB will be NULL. */
|
||||
if( pxCurrentTCB != NULL )
|
||||
{
|
||||
configASSERT( pxCurrentTCB->uxMutexesHeld );
|
||||
( pxCurrentTCB->uxMutexesHeld )--;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FREERTOS_MODULE_TEST
|
||||
#include "tasks_test_access_functions.h"
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue