diff --git a/portable/GCC/ARM_CRx_No_GIC/port.c b/portable/GCC/ARM_CRx_No_GIC/port.c index 029e4f251..a34524d76 100644 --- a/portable/GCC/ARM_CRx_No_GIC/port.c +++ b/portable/GCC/ARM_CRx_No_GIC/port.c @@ -28,6 +28,7 @@ /* Standard includes. */ #include +#include /* Scheduler includes. */ #include "FreeRTOS.h" @@ -80,10 +81,16 @@ #define portTASK_RETURN_ADDRESS prvTaskExitError #endif +/* The space on the stack required to hold the FPU registers. */ +#if ( configFPU_D32 == 1 ) + #define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 ) /* D0-D31 and FPSCR. */ +#else + #define portFPU_REGISTER_WORDS ( ( 16 * 2 ) + 1 ) /* D0-D15 and FPSCR. */ +#endif /*-----------------------------------------------------------*/ /* - * These functions are necessarily written in assembly code, so are implemented + * These functions are necessarily written in assembly code, so are implemented * in portASM.S. */ extern void vPortRestoreTaskContext( void ); @@ -186,12 +193,33 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, /* The task will start with a critical nesting count of 0 as interrupts are * enabled. */ *pxTopOfStack = portNO_CRITICAL_NESTING; - pxTopOfStack--; - /* The task will start without a floating point context. A task that uses - * the floating point hardware must call vPortTaskUsesFPU() before executing - * any floating point instructions. */ - *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + #if ( configUSE_TASK_FPU_SUPPORT == 1 ) + { + /* The task will start without a floating point context. A task that uses + * the floating point hardware must call vPortTaskUsesFPU() before executing + * any floating point instructions. */ + pxTopOfStack--; + *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + } + #elif ( configUSE_TASK_FPU_SUPPORT == 2 ) + { + /* The task will start with a floating point context. Leave enough + * space for the registers - and ensure they are initialised to 0. */ + pxTopOfStack -= portFPU_REGISTER_WORDS; + memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) ); + + /* Initialise the slot containing ulPortTaskHasFPUContext to true as + * the task starts with a floating point context. */ + pxTopOfStack--; + *pxTopOfStack = pdTRUE; + ulPortTaskHasFPUContext = pdTRUE; + } + #else + { + #error "Invalid configUSE_TASK_FPU_SUPPORT value - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined." + } + #endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */ return pxTopOfStack; } @@ -312,13 +340,17 @@ void FreeRTOS_Tick_Handler( void ) } /*-----------------------------------------------------------*/ -void vPortTaskUsesFPU( void ) -{ - /* A task is registering the fact that it needs an FPU context. Set the - * FPU flag (which is saved as part of the task context). */ - ulPortTaskHasFPUContext = pdTRUE; +#if ( configUSE_TASK_FPU_SUPPORT != 2 ) - /* Initialise the floating point status register. */ - vPortInitialiseFPSCR(); -} + void vPortTaskUsesFPU( void ) + { + /* A task is registering the fact that it needs an FPU context. Set the + * FPU flag (which is saved as part of the task context). */ + ulPortTaskHasFPUContext = pdTRUE; + + /* Initialise the floating point status register. */ + vPortInitialiseFPSCR(); + } + +#endif /* configUSE_TASK_FPU_SUPPORT */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CRx_No_GIC/portmacro.h b/portable/GCC/ARM_CRx_No_GIC/portmacro.h index 93fec019e..83a2c92bf 100644 --- a/portable/GCC/ARM_CRx_No_GIC/portmacro.h +++ b/portable/GCC/ARM_CRx_No_GIC/portmacro.h @@ -105,9 +105,6 @@ extern void vPortEnableInterrupts( void ); extern void vPortDisableInterrupts( void ); extern uint32_t ulPortSetInterruptMaskFromISR( void ); -/* The I bit within the CPSR. */ -#define portINTERRUPT_ENABLE_BIT ( 1 << 7 ) - /* In the absence of a priority mask register, these functions and macros * globally enable and disable interrupts. */ #define portENTER_CRITICAL() vPortEnterCritical(); @@ -135,9 +132,18 @@ extern uint32_t ulPortSetInterruptMaskFromISR( void ); * handler for whichever peripheral is used to generate the RTOS tick. */ void FreeRTOS_Tick_Handler( void ); -/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() - * before any floating point instructions are executed. */ -void vPortTaskUsesFPU( void ); +/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are + * created without an FPU context and must call vPortTaskUsesFPU() to give + * themselves an FPU context before using any FPU instructions. If + * configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU + * context by default. */ +#if ( configUSE_TASK_FPU_SUPPORT != 2 ) + void vPortTaskUsesFPU( void ); +#else + /* Each task has an FPU context already, so define this function away to + * nothing to prevent it from being called accidentally. */ + #define vPortTaskUsesFPU() +#endif #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )