From f4e2057a121de724d80bd9f3c5416f2de9abd742 Mon Sep 17 00:00:00 2001 From: rtel Date: Fri, 4 Jul 2014 13:17:21 +0000 Subject: [PATCH] Make the parameters to vPortDefineHeapRegions() const. Add additional asserts to the Keil CM3 and CM4F ports (other CM3/4 ports already updated). Add the additional yield necessitated by the mutex held count to the case when configUSE_QUEUE_SETS is 0. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2271 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- FreeRTOS/Source/include/portable.h | 2 +- FreeRTOS/Source/portable/MemMang/heap_5.c | 4 ++-- FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c | 15 +++++++++++++++ FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c | 15 +++++++++++++++ FreeRTOS/Source/queue.c | 14 +++++++++++--- 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/FreeRTOS/Source/include/portable.h b/FreeRTOS/Source/include/portable.h index b602d8aa5..619daf9a7 100644 --- a/FreeRTOS/Source/include/portable.h +++ b/FreeRTOS/Source/include/portable.h @@ -381,7 +381,7 @@ typedef struct HeapRegion * terminated by a HeapRegions_t structure that has a size of 0. The region * with the lowest start address must appear first in the array. */ -void vPortDefineHeapRegions( HeapRegion_t *pxHeapRegions ); +void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ); /* diff --git a/FreeRTOS/Source/portable/MemMang/heap_5.c b/FreeRTOS/Source/portable/MemMang/heap_5.c index 813e29f40..9a15ac182 100644 --- a/FreeRTOS/Source/portable/MemMang/heap_5.c +++ b/FreeRTOS/Source/portable/MemMang/heap_5.c @@ -424,14 +424,14 @@ uint8_t *puc; } /*-----------------------------------------------------------*/ -void vPortDefineHeapRegions( HeapRegion_t *pxHeapRegions ) +void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) { BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock; uint8_t *pucAlignedHeap; size_t xTotalRegionSize, xTotalHeapSize = 0; BaseType_t xDefinedRegions = 0; uint32_t ulAddress; -HeapRegion_t *pxHeapRegion; +const HeapRegion_t *pxHeapRegion; /* Can only call once! */ configASSERT( pxEnd == NULL ); diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c index d813c5b06..cfefb2cef 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c @@ -110,6 +110,9 @@ is defined. */ #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0x1FUL ) + #define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) #define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) @@ -268,11 +271,13 @@ __asm void prvStartFirstTask( void ) msr msp, r0 /* Globally enable interrupts. */ cpsie i + cpsie f dsb isb /* Call SVC to start the first task. */ svc 0 nop + nop } /*-----------------------------------------------------------*/ @@ -370,6 +375,16 @@ void vPortEnterCritical( void ) uxCriticalNesting++; __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c index 7215ce788..6e47b3713 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c @@ -123,6 +123,9 @@ is defined. */ #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) #define portPRIGROUP_SHIFT ( 8UL ) +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0x1FUL ) + /* Constants required to manipulate the VFP. */ #define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ #define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) @@ -290,11 +293,13 @@ __asm void prvStartFirstTask( void ) msr msp, r0 /* Globally enable interrupts. */ cpsie i + cpsie f dsb isb /* Call SVC to start the first task. */ svc 0 nop + nop } /*-----------------------------------------------------------*/ @@ -414,6 +419,16 @@ void vPortEnterCritical( void ) uxCriticalNesting++; __dsb( portSY_FULL_READ_WRITE ); __isb( portSY_FULL_READ_WRITE ); + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Source/queue.c b/FreeRTOS/Source/queue.c index 48e05fd41..278178fe0 100644 --- a/FreeRTOS/Source/queue.c +++ b/FreeRTOS/Source/queue.c @@ -511,7 +511,7 @@ QueueHandle_t xReturn = NULL; } else { - /* The mutex cannot be given because the calling task is not the + /* The mutex cannot be given because the calling task is not the holder. */ xReturn = pdFAIL; @@ -547,7 +547,7 @@ QueueHandle_t xReturn = NULL; { xReturn = xQueueGenericReceive( pxMutex, NULL, xTicksToWait, pdFALSE ); - /* pdPASS will only be returned if the mutex was successfully + /* pdPASS will only be returned if the mutex was successfully obtained. The calling task may have entered the Blocked state before reaching here. */ if( xReturn == pdPASS ) @@ -695,6 +695,14 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue; mtCOVERAGE_TEST_MARKER(); } } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + executed if the task was holding multiple mutexes and + 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(); @@ -1627,7 +1635,7 @@ BaseType_t xReturn = pdFALSE; /* The mutex is no longer being held. */ vTaskDecrementMutexHeldCount(); xReturn = xTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder ); - pxQueue->pxMutexHolder = NULL; + pxQueue->pxMutexHolder = NULL; } else { -- 2.39.5