From f6abf70e60051c8dc271e329eeef65028ba3126b Mon Sep 17 00:00:00 2001 From: RichardBarry Date: Tue, 22 Jan 2008 18:43:03 +0000 Subject: [PATCH] Prepare for V4.7.1 release. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@130 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Source/include/FreeRTOS.h | 4 + Source/include/queue.h | 7 ++ Source/include/semphr.h | 12 ++- Source/portable/IAR/ARM_CM3/port.c | 2 +- Source/portable/IAR/ARM_CM3/portasm.s | 3 +- Source/portable/IAR/AtmelSAM7S64/port.c | 1 - Source/portable/IAR/AtmelSAM7S64/portmacro.h | 2 - Source/portable/IAR/LPC2000/port.c | 6 +- Source/portable/IAR/LPC2000/portmacro.h | 2 +- Source/portable/IAR/STR71x/portmacro.h | 2 +- Source/portable/IAR/STR75x/portmacro.h | 2 +- Source/portable/IAR/STR91x/portmacro.h | 2 +- Source/queue.c | 83 +++++++++++++++++++- Source/tasks.c | 8 +- 14 files changed, 117 insertions(+), 19 deletions(-) diff --git a/Source/include/FreeRTOS.h b/Source/include/FreeRTOS.h index 61061b467..0799d522f 100644 --- a/Source/include/FreeRTOS.h +++ b/Source/include/FreeRTOS.h @@ -112,6 +112,10 @@ #error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #endif +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 0 +#endif + #ifndef configUSE_MUTEXES #define configUSE_MUTEXES 0 #endif diff --git a/Source/include/queue.h b/Source/include/queue.h index bafb56619..9b1867e8e 100644 --- a/Source/include/queue.h +++ b/Source/include/queue.h @@ -1201,6 +1201,13 @@ signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, port xQueueHandle xQueueCreateMutex( void ); xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ); +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ); +portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ); + #ifdef __cplusplus } #endif diff --git a/Source/include/semphr.h b/Source/include/semphr.h index 029333130..b5c61e04c 100644 --- a/Source/include/semphr.h +++ b/Source/include/semphr.h @@ -304,17 +304,19 @@ typedef xQueueHandle xSemaphoreHandle; void vTimerISR( void * pvParameters ) { static unsigned portCHAR ucLocalTickCount = 0; + static portBASE_TYPE xTaskWoken; // A timer tick has occurred. // ... Do other time functions. // Is it time for vATask () to run? + xTaskWoken = pdFALSE; ucLocalTickCount++; if( ucLocalTickCount >= TICKS_TO_WAIT ) { // Unblock the task by releasing the semaphore. - xSemaphoreGive( xSemaphore ); + xSemaphoreGiveFromISR( xSemaphore, xTaskWoken ); // Reset the count so we release the semaphore again in 10 ticks time. ucLocalTickCount = 0; @@ -368,10 +370,11 @@ typedef xQueueHandle xSemaphoreHandle; * \ingroup Semaphores */ #define xSemaphoreCreateMutex() xQueueCreateMutex() +#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex() /** * semphr. h - *
xSemaphoreHandle xSemaphoreCreateCounting( uxCountValue, uxInitialCount )
+ *
xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )
* * Macro that creates a counting semaphore by using the existing * queue mechanism. @@ -430,7 +433,10 @@ typedef xQueueHandle xSemaphoreHandle; * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting * \ingroup Semaphores */ -#define xSemaphoreCreateCounting( uxCountValue, uxInitialCount ) xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ) +#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount ) + +#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( xMutex, xBlockTime ) +#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( xMutex ) #endif /* SEMAPHORE_H */ diff --git a/Source/portable/IAR/ARM_CM3/port.c b/Source/portable/IAR/ARM_CM3/port.c index f580a6302..f4039f145 100644 --- a/Source/portable/IAR/ARM_CM3/port.c +++ b/Source/portable/IAR/ARM_CM3/port.c @@ -69,7 +69,7 @@ defined. The value 255 should also ensure backward compatibility. FreeRTOS.org versions prior to V4.3.0 did not include this definition. */ #ifndef configKERNEL_INTERRUPT_PRIORITY - #define configKERNEL_INTERRUPT_PRIORITY 255 + #define configKERNEL_INTERRUPT_PRIORITY 0 #endif /* Each task maintains its own interrupt status in the critical nesting diff --git a/Source/portable/IAR/ARM_CM3/portasm.s b/Source/portable/IAR/ARM_CM3/portasm.s index f6231d93f..c4280c0a6 100644 --- a/Source/portable/IAR/ARM_CM3/portasm.s +++ b/Source/portable/IAR/ARM_CM3/portasm.s @@ -51,7 +51,8 @@ FreeRTOS.org versions prior to V4.3.0 did not include this definition. */ #endif - RSEG ICODE:CODE + RSEG CODE:CODE(2) + thumb EXTERN vPortYieldFromISR EXTERN vPortSwitchContext diff --git a/Source/portable/IAR/AtmelSAM7S64/port.c b/Source/portable/IAR/AtmelSAM7S64/port.c index de31f23cc..4be1b6160 100644 --- a/Source/portable/IAR/AtmelSAM7S64/port.c +++ b/Source/portable/IAR/AtmelSAM7S64/port.c @@ -41,7 +41,6 @@ /* Standard includes. */ #include -#include /* Scheduler includes. */ #include "FreeRTOS.h" diff --git a/Source/portable/IAR/AtmelSAM7S64/portmacro.h b/Source/portable/IAR/AtmelSAM7S64/portmacro.h index 10372f01e..8147233c0 100644 --- a/Source/portable/IAR/AtmelSAM7S64/portmacro.h +++ b/Source/portable/IAR/AtmelSAM7S64/portmacro.h @@ -38,8 +38,6 @@ #ifndef PORTMACRO_H #define PORTMACRO_H -#include - #ifdef __cplusplus extern "C" { #endif diff --git a/Source/portable/IAR/LPC2000/port.c b/Source/portable/IAR/LPC2000/port.c index 69036f56c..b3ea9ae1a 100644 --- a/Source/portable/IAR/LPC2000/port.c +++ b/Source/portable/IAR/LPC2000/port.c @@ -41,14 +41,14 @@ /* Changes from V3.2.2 - + Bug fix - The prescale value for the timer setup is now written to T0PR - instead of T0PC. This bug would have had no effect unless a prescale + + Bug fix - The prescale value for the timer setup is now written to T0PR + instead of T0PC. This bug would have had no effect unless a prescale value was actually used. */ /* Standard includes. */ #include -#include +#include /* Scheduler includes. */ #include "FreeRTOS.h" diff --git a/Source/portable/IAR/LPC2000/portmacro.h b/Source/portable/IAR/LPC2000/portmacro.h index 10372f01e..2776ede70 100644 --- a/Source/portable/IAR/LPC2000/portmacro.h +++ b/Source/portable/IAR/LPC2000/portmacro.h @@ -38,7 +38,7 @@ #ifndef PORTMACRO_H #define PORTMACRO_H -#include +#include #ifdef __cplusplus extern "C" { diff --git a/Source/portable/IAR/STR71x/portmacro.h b/Source/portable/IAR/STR71x/portmacro.h index 2e48bec58..73b6b028b 100644 --- a/Source/portable/IAR/STR71x/portmacro.h +++ b/Source/portable/IAR/STR71x/portmacro.h @@ -48,7 +48,7 @@ *----------------------------------------------------------- */ -#include +#include #ifdef __cplusplus extern "C" { diff --git a/Source/portable/IAR/STR75x/portmacro.h b/Source/portable/IAR/STR75x/portmacro.h index 8b0827d12..e78ac0d82 100644 --- a/Source/portable/IAR/STR75x/portmacro.h +++ b/Source/portable/IAR/STR75x/portmacro.h @@ -48,7 +48,7 @@ *----------------------------------------------------------- */ -#include +#include #ifdef __cplusplus extern "C" { diff --git a/Source/portable/IAR/STR91x/portmacro.h b/Source/portable/IAR/STR91x/portmacro.h index 95ac0873e..f2c139225 100644 --- a/Source/portable/IAR/STR91x/portmacro.h +++ b/Source/portable/IAR/STR91x/portmacro.h @@ -48,7 +48,7 @@ *----------------------------------------------------------- */ -#include +#include #ifdef __cplusplus extern "C" { diff --git a/Source/queue.c b/Source/queue.c index 67e24e9c3..782408f27 100644 --- a/Source/queue.c +++ b/Source/queue.c @@ -55,13 +55,14 @@ /* Effectively make a union out of the xQUEUE structure. */ #define pxMutexHolder pcTail #define uxQueueType pcHead +#define uxRecursiveCallCount pcReadFrom #define queueQUEUE_IS_MUTEX NULL /* Semaphores do not actually store or copy data, so have an items size of zero. */ #define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( 0 ) #define queueDONT_BLOCK ( ( portTickType ) 0 ) - +#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0 ) /* * Definition of the queue used by the scheduler. * Items are queued by copy, not reference. @@ -107,6 +108,8 @@ signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, const void * co signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, const void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ); xQueueHandle xQueueCreateMutex( void ); xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ); +portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ); +portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ); signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ); signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ); @@ -261,9 +264,84 @@ size_t xQueueSizeInBytes; #endif /* configUSE_MUTEXES */ /*-----------------------------------------------------------*/ +#if configUSE_RECURSIVE_MUTEXES == 1 + + portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ) + { + portBASE_TYPE xReturn; + + /* If this is the task that holds the mutex then pxMutexHolder will not + change outside of this task. If this task does not hold the mutex then + pxMutexHolder can never coincidentally equal the tasks handle, and as + this is the only condition we are interested in it does not matter if + pxMutexHolder is accessed simultaneously by another task. Therefore no + mutual exclusion is required to test the pxMutexHolder variable. */ + if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() ) + { + /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to + the task handle, therefore no underflow check is required. Also, + uxRecursiveCallCount is only modified by the mutex holder, and as + there can only be one, no mutual exclusion is required to modify the + uxRecursiveCallCount member. */ + ( pxMutex->uxRecursiveCallCount )--; + + /* Have we unwound the call count? */ + if( pxMutex->uxRecursiveCallCount == 0 ) + { + /* Return the mutex. This will automatically unblock any other + task that might be waiting to access the mutex. */ + xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK ); + } + + xReturn = pdPASS; + } + else + { + /* We cannot give the mutex because we are not the holder. */ + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if configUSE_RECURSIVE_MUTEXES == 1 + + portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime ) + { + portBASE_TYPE xReturn; + + /* Comments regarding mutual exclusion as per those within + xQueueGiveMutexRecursive(). */ + + if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() ) + { + ( pxMutex->uxRecursiveCallCount )++; + xReturn = pdPASS; + } + else + { + xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE ); + + /* pdPASS will only be returned if we successfully obtained the mutex, + we may have blocked to reach here. */ + if( xReturn == pdPASS ) + { + ( pxMutex->uxRecursiveCallCount )++; + } + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + #if configUSE_COUNTING_SEMAPHORES == 1 - xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) + xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount, portBASE_TYPE xIsRecursive ) { xQueueHandle pxHandle; @@ -902,6 +980,7 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port { /* The mutex is no longer being held. */ vTaskPriorityDisinherit( ( void * const ) pxQueue->pxMutexHolder ); + pxQueue->pxMutexHolder = NULL; } } #endif diff --git a/Source/tasks.c b/Source/tasks.c index a605b99f2..3a4c8ce7a 100644 --- a/Source/tasks.c +++ b/Source/tasks.c @@ -1213,7 +1213,11 @@ signed portBASE_TYPE xAlreadyYielded = pdFALSE; /* As we have processed some ticks it is appropriate to yield to ensure the highest priority task that is ready to run is the task actually running. */ - xYieldRequired = pdTRUE; + #if configUSE_PREEMPTION == 1 + { + xYieldRequired = pdTRUE; + } + #endif } if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) ) @@ -1985,7 +1989,7 @@ tskTCB *pxNewTCB; /* Adjust the mutex holder state to account for its new priority. */ listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority ); - /* If the task being modified is in the read state it will need to + /* If the task being modified is in the ready state it will need to be moved in to a new list. */ if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) ) { -- 2.39.5