From 44fc666aef4934fc770463900e4c5a8c00dca88f Mon Sep 17 00:00:00 2001 From: rtel Date: Tue, 16 Aug 2016 11:38:58 +0000 Subject: [PATCH] Changes to core code and port layer: + Add configASSERT() into ARM Cortex-M ports to check the number of priority bit settings. + Clear the 'control' register before starting ARM Cortex-M4F ports in case the FPU is used before the scheduler is started. This just saves a few bytes on the main stack as it prevents space being left for a later save of FPU registers. + Added xSemaphoreGetMutexHolderFromISR(). + Corrected use of portNVIC_PENDSVSET to portNVIC_PENDSVSET_BIT in MPU ports. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2467 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../FreeRTOSConfig.h | 10 +- .../FreeRTOSConfig.h | 16 +- .../Demo/CORTEX_STM32F103_IAR/RTOSDemo.ewd | 957 ++++++++++++++---- .../Demo/CORTEX_STM32F103_IAR/RTOSDemo.ewp | 97 +- FreeRTOS/Demo/WIN32-MingW/.cproject | 25 +- FreeRTOS/Demo/WIN32-MingW/main.c | 1 - FreeRTOS/Source/event_groups.c | 6 +- FreeRTOS/Source/include/queue.h | 1 + FreeRTOS/Source/include/semphr.h | 11 + FreeRTOS/Source/include/task.h | 6 +- FreeRTOS/Source/portable/CCS/ARM_CM4F/port.c | 18 + .../Source/portable/CCS/ARM_CM4F/portasm.asm | 6 + FreeRTOS/Source/portable/GCC/ARM_CM3/port.c | 18 + .../portable/GCC/ARM_CM3_MPU/portmacro.h | 4 +- FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c | 24 + .../Source/portable/GCC/ARM_CM4_MPU/port.c | 25 +- .../portable/GCC/ARM_CM4_MPU/portmacro.h | 4 +- .../Source/portable/GCC/ARM_CM7/r0p1/port.c | 24 + FreeRTOS/Source/portable/IAR/ARM_CM3/port.c | 18 + FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c | 18 + .../Source/portable/IAR/ARM_CM4F/portasm.s | 6 + .../Source/portable/IAR/ARM_CM7/r0p1/port.c | 18 + .../portable/IAR/ARM_CM7/r0p1/portasm.s | 6 + FreeRTOS/Source/portable/MemMang/heap_1.c | 1 + .../Source/portable/MikroC/ARM_CM4F/port.c | 29 +- FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c | 18 + FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c | 24 + .../Source/portable/RVDS/ARM_CM4_MPU/port.c | 33 +- .../portable/RVDS/ARM_CM4_MPU/portmacro.h | 10 +- .../Source/portable/RVDS/ARM_CM7/r0p1/port.c | 24 + FreeRTOS/Source/queue.c | 26 + FreeRTOS/Source/tasks.c | 27 +- 32 files changed, 1246 insertions(+), 265 deletions(-) diff --git a/FreeRTOS/Demo/CORTEX_A2F200_IAR_and_Keil/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_A2F200_IAR_and_Keil/FreeRTOSConfig.h index dba557549..f004be2d4 100644 --- a/FreeRTOS/Demo/CORTEX_A2F200_IAR_and_Keil/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/CORTEX_A2F200_IAR_and_Keil/FreeRTOSConfig.h @@ -137,7 +137,7 @@ to exclude the API function. */ /* This demo makes use of one or more example stats formatting functions. These format the raw data provided by the uxTaskGetSystemState() function in to human -readable ASCII form. See the notes in the implementation of vTaskList() within +readable ASCII form. See the notes in the implementation of vTaskList() within FreeRTOS/Source/tasks.c for limitations. */ #define configUSE_STATS_FORMATTING_FUNCTIONS 1 @@ -148,7 +148,7 @@ FreeRTOS/Source/tasks.c for limitations. */ #ifdef __NVIC_PRIO_BITS #define configPRIO_BITS __NVIC_PRIO_BITS #else - #define configPRIO_BITS 5 /* 15 priority levels */ + #define configPRIO_BITS 5 /* 31 priority levels */ #endif #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x1f @@ -160,9 +160,9 @@ FreeRTOS/Source/tasks.c for limitations. */ /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) - -#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } - + +#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } + #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler #define vPortSVCHandler SVC_Handler diff --git a/FreeRTOS/Demo/CORTEX_A2F200_SoftConsole/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_A2F200_SoftConsole/FreeRTOSConfig.h index ae2e208b2..bb9a18e6d 100644 --- a/FreeRTOS/Demo/CORTEX_A2F200_SoftConsole/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/CORTEX_A2F200_SoftConsole/FreeRTOSConfig.h @@ -68,10 +68,10 @@ */ -/* +/* * The following #error directive is to remind users that a batch file must be - * executed prior to this project being built. The batch file *cannot* be - * executed from within the IDE! Once it has been executed, re-open or refresh + * executed prior to this project being built. The batch file *cannot* be + * executed from within the IDE! Once it has been executed, re-open or refresh * the Eclipse project and remove the #error line below. */ #error Ensure CreateProjectDirectoryStructure.bat has been executed before building. See comment immediately above. @@ -140,7 +140,7 @@ to exclude the API function. */ /* This demo makes use of one or more example stats formatting functions. These format the raw data provided by the uxTaskGetSystemState() function in to human -readable ASCII form. See the notes in the implementation of vTaskList() within +readable ASCII form. See the notes in the implementation of vTaskList() within FreeRTOS/Source/tasks.c for limitations. */ #define configUSE_STATS_FORMATTING_FUNCTIONS 1 @@ -153,7 +153,7 @@ unsigned long ulGetRunTimeCounterValue( void ); #ifdef __NVIC_PRIO_BITS #define configPRIO_BITS __NVIC_PRIO_BITS #else - #define configPRIO_BITS 5 /* 15 priority levels */ + #define configPRIO_BITS 5 /* 31 priority levels */ #endif #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x1f @@ -165,9 +165,9 @@ unsigned long ulGetRunTimeCounterValue( void ); /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) - -#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } - + +#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } + #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler #define vPortSVCHandler SVC_Handler diff --git a/FreeRTOS/Demo/CORTEX_STM32F103_IAR/RTOSDemo.ewd b/FreeRTOS/Demo/CORTEX_STM32F103_IAR/RTOSDemo.ewd index d04bd3e56..b78291201 100644 --- a/FreeRTOS/Demo/CORTEX_STM32F103_IAR/RTOSDemo.ewd +++ b/FreeRTOS/Demo/CORTEX_STM32F103_IAR/RTOSDemo.ewd @@ -12,7 +12,7 @@ C-SPY 2 - 23 + 28 1 1 - + + + + + + + + + + @@ -245,6 +281,181 @@ + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID 2 @@ -314,199 +525,425 @@ - JLINK_ID + IJET_ID 2 - 14 + 8 1 1 - + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -635,30 +1072,13 @@ PEMICRO_ID 2 - 0 + 3 1 1 - - - - - - - - - @@ -753,97 +1151,105 @@ - RDIJTAGJET_ID - 0 + STLINK_ID + 2 - 1 + 3 1 1 + + + + - - - - STLINK_ID - 2 - - 2 - 1 - 1 @@ -873,7 +1279,7 @@ - XDS100_ID + TIFET_ID 2 1 @@ -884,7 +1290,74 @@ 1 + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 5 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin 0 @@ -924,19 +1531,19 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\FreeRTOS\FreeRtosPlugin.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin 0 @@ -947,6 +1554,10 @@ $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 @@ -968,13 +1579,9 @@ 0 - $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 - - $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin - 1 - diff --git a/FreeRTOS/Demo/CORTEX_STM32F103_IAR/RTOSDemo.ewp b/FreeRTOS/Demo/CORTEX_STM32F103_IAR/RTOSDemo.ewp index 49da43607..95973e833 100644 --- a/FreeRTOS/Demo/CORTEX_STM32F103_IAR/RTOSDemo.ewp +++ b/FreeRTOS/Demo/CORTEX_STM32F103_IAR/RTOSDemo.ewp @@ -12,7 +12,7 @@ General 3 - 21 + 24 1 1 - - - + + + + + + + ICCARM 2 - 28 + 31 1 1 + + + + AARM 2 - 8 + 9 1 1 + @@ -563,7 +601,7 @@ 1 @@ -609,7 +648,7 @@ ILINK 0 - 15 + 17 1 1 + + diff --git a/FreeRTOS/Demo/WIN32-MingW/.cproject b/FreeRTOS/Demo/WIN32-MingW/.cproject index 825627bee..2d3483aa2 100644 --- a/FreeRTOS/Demo/WIN32-MingW/.cproject +++ b/FreeRTOS/Demo/WIN32-MingW/.cproject @@ -5,14 +5,14 @@ + - - + @@ -22,13 +22,13 @@ - - - @@ -50,6 +50,9 @@ diff --git a/FreeRTOS/Demo/WIN32-MingW/main.c b/FreeRTOS/Demo/WIN32-MingW/main.c index 8e0eccfda..e0ce75931 100644 --- a/FreeRTOS/Demo/WIN32-MingW/main.c +++ b/FreeRTOS/Demo/WIN32-MingW/main.c @@ -375,4 +375,3 @@ const HeapRegion_t xHeapRegions[] = vPortDefineHeapRegions( xHeapRegions ); } /*-----------------------------------------------------------*/ - diff --git a/FreeRTOS/Source/event_groups.c b/FreeRTOS/Source/event_groups.c index 15ffd644c..3780fe865 100644 --- a/FreeRTOS/Source/event_groups.c +++ b/FreeRTOS/Source/event_groups.c @@ -602,7 +602,7 @@ BaseType_t xMatchFound = pdFALSE; eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows that is was unblocked due to its required bits matching, rather than because it timed out. */ - ( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); + vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); } /* Move onto the next list item. Note pxListItem->pxNext is not @@ -634,8 +634,8 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); { /* Unblock the task, returning 0 as the event list is being deleted and cannot therefore have any bits set. */ - configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); - ( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); + configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); + vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); } #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) diff --git a/FreeRTOS/Source/include/queue.h b/FreeRTOS/Source/include/queue.h index b96ed5b38..5aaf709d8 100644 --- a/FreeRTOS/Source/include/queue.h +++ b/FreeRTOS/Source/include/queue.h @@ -1561,6 +1561,7 @@ QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; +void* xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; /* * For internal use only. Use xSemaphoreTakeMutexRecursive() or diff --git a/FreeRTOS/Source/include/semphr.h b/FreeRTOS/Source/include/semphr.h index f9867ae49..257cc9e90 100644 --- a/FreeRTOS/Source/include/semphr.h +++ b/FreeRTOS/Source/include/semphr.h @@ -1154,6 +1154,17 @@ typedef QueueHandle_t SemaphoreHandle_t; */ #define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) +/** + * semphr.h + *
TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex );
+ * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + */ +#define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) ) + /** * semphr.h *
UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
diff --git a/FreeRTOS/Source/include/task.h b/FreeRTOS/Source/include/task.h index 5e409c8dd..73b740b24 100644 --- a/FreeRTOS/Source/include/task.h +++ b/FreeRTOS/Source/include/task.h @@ -2141,14 +2141,14 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTi * Removes a task from both the specified event list and the list of blocked * tasks, and places it on a ready queue. * - * xTaskRemoveFromEventList()/xTaskRemoveFromUnorderedEventList() will be called + * xTaskRemoveFromEventList()/vTaskRemoveFromUnorderedEventList() will be called * if either an event occurs to unblock a task, or the block timeout period * expires. * * xTaskRemoveFromEventList() is used when the event list is in task priority * order. It removes the list item from the head of the event list as that will * have the highest priority owning task of all the tasks on the event list. - * xTaskRemoveFromUnorderedEventList() is used when the event list is not + * vTaskRemoveFromUnorderedEventList() is used when the event list is not * ordered and the event list items hold something other than the owning tasks * priority. In this case the event list item value is updated to the value * passed in the xItemValue parameter. @@ -2157,7 +2157,7 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTi * making the call, otherwise pdFALSE. */ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; -BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION; +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION; /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY diff --git a/FreeRTOS/Source/portable/CCS/ARM_CM4F/port.c b/FreeRTOS/Source/portable/CCS/ARM_CM4F/port.c index 65a2a5fad..8e92b6ac3 100644 --- a/FreeRTOS/Source/portable/CCS/ARM_CM4F/port.c +++ b/FreeRTOS/Source/portable/CCS/ARM_CM4F/port.c @@ -299,6 +299,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/FreeRTOS/Source/portable/CCS/ARM_CM4F/portasm.asm b/FreeRTOS/Source/portable/CCS/ARM_CM4F/portasm.asm index a392583b0..a111a0012 100644 --- a/FreeRTOS/Source/portable/CCS/ARM_CM4F/portasm.asm +++ b/FreeRTOS/Source/portable/CCS/ARM_CM4F/portasm.asm @@ -179,6 +179,12 @@ vPortStartFirstTask: .asmfunc ldr r0, [r0] ;/* Set the msp back to the start of the stack. */ msr msp, r0 + ;/* Clear the bit that indicates the FPU is in use in case the FPU was used + ;before the scheduler was started - which would otherwise result in the + ;unnecessary leaving of space in the SVC stack for lazy saving of FPU + ;registers. */ + mov r0, #0 + msr control, r0 ;/* Call SVC to start the first task. */ cpsie i cpsie f diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c index 960717a57..ff0abc740 100644 --- a/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c +++ b/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c @@ -324,6 +324,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/portmacro.h b/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/portmacro.h index 7b899661d..b44fe4c05 100644 --- a/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/portmacro.h +++ b/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/portmacro.h @@ -173,7 +173,7 @@ typedef struct MPU_SETTINGS #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) -#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ @@ -246,7 +246,7 @@ not necessary for to use this port. They are defined so the common demo files /* Set the privilege level to user mode if xRunningPrivileged is false. */ portFORCE_INLINE static void vPortResetPrivilege( BaseType_t xRunningPrivileged ) { - if( xRunningPrivileged != pdTRUE ) + if( xRunningPrivileged != pdTRUE ) { __asm volatile ( " mrs r0, control \n" \ " orr r0, #1 \n" \ diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c index 952c60b8b..0d673862d 100644 --- a/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c +++ b/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c @@ -291,11 +291,17 @@ void vPortSVCHandler( void ) static void prvPortStartFirstTask( void ) { + /* Start the first task. This also clears the bit that indicates the FPU is + in use in case the FPU was used before the scheduler was started - which + would otherwise result in the unnecessary leaving of space in the SVC stack + for lazy saving of FPU registers. */ __asm volatile( " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */ + " msr control, r0 \n" " cpsie i \n" /* Globally enable interrupts. */ " cpsie f \n" " dsb \n" @@ -354,6 +360,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/port.c index babea315f..06011f799 100644 --- a/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/port.c +++ b/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/port.c @@ -374,6 +374,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -407,12 +425,17 @@ BaseType_t xPortStartScheduler( void ) /* Lazy save always. */ *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; - /* Start the first task. */ + /* Start the first task. This also clears the bit that indicates the FPU is + in use in case the FPU was used before the scheduler was started - which + would otherwise result in the unnecessary leaving of space in the SVC stack + for lazy saving of FPU registers. */ __asm volatile( " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */ + " msr control, r0 \n" " cpsie i \n" /* Globally enable interrupts. */ " cpsie f \n" " dsb \n" diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/portmacro.h b/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/portmacro.h index 7b899661d..b44fe4c05 100644 --- a/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/portmacro.h +++ b/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/portmacro.h @@ -173,7 +173,7 @@ typedef struct MPU_SETTINGS #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) -#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ @@ -246,7 +246,7 @@ not necessary for to use this port. They are defined so the common demo files /* Set the privilege level to user mode if xRunningPrivileged is false. */ portFORCE_INLINE static void vPortResetPrivilege( BaseType_t xRunningPrivileged ) { - if( xRunningPrivileged != pdTRUE ) + if( xRunningPrivileged != pdTRUE ) { __asm volatile ( " mrs r0, control \n" \ " orr r0, #1 \n" \ diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/port.c index 86fb9cc6b..e0719c410 100644 --- a/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/port.c +++ b/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/port.c @@ -285,11 +285,17 @@ void vPortSVCHandler( void ) static void prvPortStartFirstTask( void ) { + /* Start the first task. This also clears the bit that indicates the FPU is + in use in case the FPU was used before the scheduler was started - which + would otherwise result in the unnecessary leaving of space in the SVC stack + for lazy saving of FPU registers. */ __asm volatile( " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */ + " msr control, r0 \n" " cpsie i \n" /* Globally enable interrupts. */ " cpsie f \n" " dsb \n" @@ -342,6 +348,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c b/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c index 595b49de8..2dadf0e49 100644 --- a/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c +++ b/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c @@ -279,6 +279,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c b/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c index 094965f88..57b7451f3 100644 --- a/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c +++ b/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c @@ -314,6 +314,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM4F/portasm.s b/FreeRTOS/Source/portable/IAR/ARM_CM4F/portasm.s index 758d6fa97..87d09697a 100644 --- a/FreeRTOS/Source/portable/IAR/ARM_CM4F/portasm.s +++ b/FreeRTOS/Source/portable/IAR/ARM_CM4F/portasm.s @@ -160,6 +160,12 @@ vPortStartFirstTask ldr r0, [r0] /* Set the msp back to the start of the stack. */ msr msp, r0 + /* Clear the bit that indicates the FPU is in use in case the FPU was used + before the scheduler was started - which would otherwise result in the + unnecessary leaving of space in the SVC stack for lazy saving of FPU + registers. */ + mov r0, #0 + msr control, r0 /* Call SVC to start the first task. */ cpsie i cpsie f diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/port.c b/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/port.c index 34a1b25a4..6ffc86f86 100644 --- a/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/port.c +++ b/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/port.c @@ -298,6 +298,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portasm.s b/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portasm.s index 2ab809a0e..e6414b8b7 100644 --- a/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portasm.s +++ b/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portasm.s @@ -162,6 +162,12 @@ vPortStartFirstTask ldr r0, [r0] /* Set the msp back to the start of the stack. */ msr msp, r0 + /* Clear the bit that indicates the FPU is in use in case the FPU was used + before the scheduler was started - which would otherwise result in the + unnecessary leaving of space in the SVC stack for lazy saving of FPU + registers. */ + mov r0, #0 + msr control, r0 /* Call SVC to start the first task. */ cpsie i cpsie f diff --git a/FreeRTOS/Source/portable/MemMang/heap_1.c b/FreeRTOS/Source/portable/MemMang/heap_1.c index 435c99d05..ea48ff63a 100644 --- a/FreeRTOS/Source/portable/MemMang/heap_1.c +++ b/FreeRTOS/Source/portable/MemMang/heap_1.c @@ -104,6 +104,7 @@ task.h is included from an application file. */ static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; #endif /* configAPPLICATION_ALLOCATED_HEAP */ +/* Index into the ucHeap array. */ static size_t xNextFreeByte = ( size_t ) 0; /*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Source/portable/MikroC/ARM_CM4F/port.c b/FreeRTOS/Source/portable/MikroC/ARM_CM4F/port.c index bb6993348..451518799 100644 --- a/FreeRTOS/Source/portable/MikroC/ARM_CM4F/port.c +++ b/FreeRTOS/Source/portable/MikroC/ARM_CM4F/port.c @@ -153,6 +153,7 @@ is defined. */ #define basepri 17 #define msp 8 #define ipsr 5 +#define control 20 /* From port.c. */ extern void *pxCurrentTCB; @@ -287,7 +288,7 @@ void vPortSVCHandler( void ) iv IVT_INT_SVCall ics ICS_OFF ldm r0!, (r4-r11, r14)/* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ msr psp, r0 /* Restore the task stack pointer. */ isb - mov r0, #0 + mov r0, #0 msr basepri, r0 bx r14 }; @@ -299,8 +300,14 @@ static void prvPortStartFirstTask( void ) __asm { ldr r0, =0xE000ED08 /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] - ldr r0, [r0] + ldr r0, [r0] msr msp, r0 /* Set the msp back to the start of the stack. */ + /* Clear the bit that indicates the FPU is in use in case the FPU was used + before the scheduler was started - which would otherwise result in the + unnecessary leaving of space in the SVC stack for lazy saving of FPU + registers. */ + mov r0, #0 + msr control, r0 cpsie i /* Globally enable interrupts. */ cpsie f dsb @@ -357,6 +364,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c index e15b91a16..53c39341e 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c @@ -325,6 +325,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c index 6902f9789..f1b6b29c1 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c @@ -302,6 +302,12 @@ __asm void prvStartFirstTask( void ) ldr r0, [r0] /* Set the msp back to the start of the stack. */ msr msp, r0 + /* Clear the bit that indicates the FPU is in use in case the FPU was used + before the scheduler was started - which would otherwise result in the + unnecessary leaving of space in the SVC stack for lazy saving of FPU + registers. */ + mov r0, #0 + msr control, r0 /* Globally enable interrupts. */ cpsie i cpsie f @@ -382,6 +388,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/port.c index 3cd924056..8c7e1ae30 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/port.c @@ -381,6 +381,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; @@ -426,11 +444,20 @@ __asm void prvStartFirstTask( void ) { PRESERVE8 - ldr r0, =0xE000ED08 /* Use the NVIC offset register to locate the stack. */ + /* Use the NVIC offset register to locate the stack. */ + ldr r0, =0xE000ED08 ldr r0, [r0] ldr r0, [r0] - msr msp, r0 /* Set the msp back to the start of the stack. */ - cpsie i /* Globally enable interrupts. */ + /* Set the msp back to the start of the stack. */ + msr msp, r0 + /* Clear the bit that indicates the FPU is in use in case the FPU was used + before the scheduler was started - which would otherwise result in the + unnecessary leaving of space in the SVC stack for lazy saving of FPU + registers. */ + mov r0, #0 + msr control, r0 + /* Globally enable interrupts. */ + cpsie i cpsie f dsb isb diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/portmacro.h b/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/portmacro.h index 8d441eef6..3555aa781 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/portmacro.h +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/portmacro.h @@ -179,7 +179,7 @@ typedef struct MPU_SETTINGS #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) -#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ @@ -273,7 +273,7 @@ static portFORCE_INLINE void vPortClearBASEPRIFromISR( void ) __asm { /* Set BASEPRI to 0 so no interrupts are masked. This function is only - used to lower the mask in an interrupt, so memory barriers are not + used to lower the mask in an interrupt, so memory barriers are not used. */ msr basepri, #0 } @@ -326,10 +326,10 @@ BaseType_t xReturn; portFORCE_INLINE static void vPortResetPrivilege( BaseType_t xRunningPrivileged ) { uint32_t ulReg; - - if( xRunningPrivileged != pdTRUE ) + + if( xRunningPrivileged != pdTRUE ) { - __asm + __asm { mrs ulReg, control orr ulReg, #1 diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c index 133f61ea8..ca37f577b 100644 --- a/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c +++ b/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c @@ -296,6 +296,12 @@ __asm void prvStartFirstTask( void ) ldr r0, [r0] /* Set the msp back to the start of the stack. */ msr msp, r0 + /* Clear the bit that indicates the FPU is in use in case the FPU was used + before the scheduler was started - which would otherwise result in the + unnecessary leaving of space in the SVC stack for lazy saving of FPU + registers. */ + mov r0, #0 + msr control, r0 /* Globally enable interrupts. */ cpsie i cpsie f @@ -366,6 +372,24 @@ BaseType_t xPortStartScheduler( void ) ucMaxPriorityValue <<= ( uint8_t ) 0x01; } + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; diff --git a/FreeRTOS/Source/queue.c b/FreeRTOS/Source/queue.c index 9884658eb..e8ae0d307 100644 --- a/FreeRTOS/Source/queue.c +++ b/FreeRTOS/Source/queue.c @@ -567,6 +567,32 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseT #endif /*-----------------------------------------------------------*/ +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + void* xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) + { + void *pxReturn; + + configASSERT( xSemaphore ); + + /* Mutexes cannot be used in interrupt service routines, so the mutex + holder should not change in an ISR, and therefore a critical section is + not required here. */ + if( ( ( Queue_t * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX ) + { + pxReturn = ( void * ) ( ( Queue_t * ) xSemaphore )->pxMutexHolder; + } + else + { + pxReturn = NULL; + } + + return pxReturn; + } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ + +#endif +/*-----------------------------------------------------------*/ + #if ( configUSE_RECURSIVE_MUTEXES == 1 ) BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) diff --git a/FreeRTOS/Source/tasks.c b/FreeRTOS/Source/tasks.c index d2d7b1159..f101e258e 100644 --- a/FreeRTOS/Source/tasks.c +++ b/FreeRTOS/Source/tasks.c @@ -2491,7 +2491,7 @@ implementations require configUSE_TICKLESS_IDLE to be set to a value other than mtCOVERAGE_TEST_MARKER(); } } - xTaskResumeAll(); + ( void ) xTaskResumeAll(); return xReturn; } @@ -2962,10 +2962,9 @@ BaseType_t xReturn; } /*-----------------------------------------------------------*/ -BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) { TCB_t *pxUnblockedTCB; -BaseType_t xReturn; /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by the event flags implementation. */ @@ -2988,22 +2987,12 @@ BaseType_t xReturn; if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) { - /* Return true if the task removed from the event list has - a higher priority than the calling task. This allows - the calling task to know if it should force a context - switch now. */ - xReturn = pdTRUE; - - /* Mark that a yield is pending in case the user is not using the - "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ + /* The unblocked task has a priority above that of the calling task, so + a context switch is required. This function is called with the + scheduler suspended so xYieldPending is set so the context switch + occurs immediately that the scheduler is resumed (unsuspended). */ xYieldPending = pdTRUE; } - else - { - xReturn = pdFALSE; - } - - return xReturn; } /*-----------------------------------------------------------*/ @@ -3438,7 +3427,7 @@ static void prvCheckTasksWaitingTermination( void ) pxTaskStatus->eCurrentState = eBlocked; } } - xTaskResumeAll(); + ( void ) xTaskResumeAll(); } } #endif /* INCLUDE_vTaskSuspend */ @@ -3502,7 +3491,7 @@ static void prvCheckTasksWaitingTermination( void ) static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) { - volatile TCB_t *pxNextTCB, *pxFirstTCB; + configLIST_VOLATILE TCB_t *pxNextTCB, *pxFirstTCB; UBaseType_t uxTask = 0; if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) -- 2.39.5