Skip to content

Commit 9e1b7c6

Browse files
committed
Add configurable FPU support
1 parent e4b924f commit 9e1b7c6

File tree

2 files changed

+58
-20
lines changed

2 files changed

+58
-20
lines changed

portable/GCC/ARM_CRx_No_GIC/port.c

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
/* Standard includes. */
3030
#include <stdlib.h>
31+
#include <string.h>
3132

3233
/* Scheduler includes. */
3334
#include "FreeRTOS.h"
@@ -80,10 +81,16 @@
8081
#define portTASK_RETURN_ADDRESS prvTaskExitError
8182
#endif
8283

84+
/* The space on the stack required to hold the FPU registers. */
85+
#if ( configFPU_D32 == 1 )
86+
#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 ) /* D0-D31 and FPSCR. */
87+
#else
88+
#define portFPU_REGISTER_WORDS ( ( 16 * 2 ) + 1 ) /* D0-D15 and FPSCR. */
89+
#endif
8390
/*-----------------------------------------------------------*/
8491

8592
/*
86-
* These functions are necessarily written in assembly code, so are implemented
93+
* These functions are necessarily written in assembly code, so are implemented
8794
* in portASM.S.
8895
*/
8996
extern void vPortRestoreTaskContext( void );
@@ -186,12 +193,33 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
186193
/* The task will start with a critical nesting count of 0 as interrupts are
187194
* enabled. */
188195
*pxTopOfStack = portNO_CRITICAL_NESTING;
189-
pxTopOfStack--;
190196

191-
/* The task will start without a floating point context. A task that uses
192-
* the floating point hardware must call vPortTaskUsesFPU() before executing
193-
* any floating point instructions. */
194-
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
197+
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
198+
{
199+
/* The task will start without a floating point context. A task that uses
200+
* the floating point hardware must call vPortTaskUsesFPU() before executing
201+
* any floating point instructions. */
202+
pxTopOfStack--;
203+
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
204+
}
205+
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
206+
{
207+
/* The task will start with a floating point context. Leave enough
208+
* space for the registers - and ensure they are initialised to 0. */
209+
pxTopOfStack -= portFPU_REGISTER_WORDS;
210+
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
211+
212+
/* Initialise the slot containing ulPortTaskHasFPUContext to true as
213+
* the task starts with a floating point context. */
214+
pxTopOfStack--;
215+
*pxTopOfStack = pdTRUE;
216+
ulPortTaskHasFPUContext = pdTRUE;
217+
}
218+
#else
219+
{
220+
#error "Invalid configUSE_TASK_FPU_SUPPORT value - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined."
221+
}
222+
#endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
195223

196224
return pxTopOfStack;
197225
}
@@ -312,13 +340,17 @@ void FreeRTOS_Tick_Handler( void )
312340
}
313341
/*-----------------------------------------------------------*/
314342

315-
void vPortTaskUsesFPU( void )
316-
{
317-
/* A task is registering the fact that it needs an FPU context. Set the
318-
* FPU flag (which is saved as part of the task context). */
319-
ulPortTaskHasFPUContext = pdTRUE;
343+
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
320344

321-
/* Initialise the floating point status register. */
322-
vPortInitialiseFPSCR();
323-
}
345+
void vPortTaskUsesFPU( void )
346+
{
347+
/* A task is registering the fact that it needs an FPU context. Set the
348+
* FPU flag (which is saved as part of the task context). */
349+
ulPortTaskHasFPUContext = pdTRUE;
350+
351+
/* Initialise the floating point status register. */
352+
vPortInitialiseFPSCR();
353+
}
354+
355+
#endif /* configUSE_TASK_FPU_SUPPORT */
324356
/*-----------------------------------------------------------*/

portable/GCC/ARM_CRx_No_GIC/portmacro.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,6 @@ extern void vPortEnableInterrupts( void );
105105
extern void vPortDisableInterrupts( void );
106106
extern uint32_t ulPortSetInterruptMaskFromISR( void );
107107

108-
/* The I bit within the CPSR. */
109-
#define portINTERRUPT_ENABLE_BIT ( 1 << 7 )
110-
111108
/* In the absence of a priority mask register, these functions and macros
112109
* globally enable and disable interrupts. */
113110
#define portENTER_CRITICAL() vPortEnterCritical();
@@ -135,9 +132,18 @@ extern uint32_t ulPortSetInterruptMaskFromISR( void );
135132
* handler for whichever peripheral is used to generate the RTOS tick. */
136133
void FreeRTOS_Tick_Handler( void );
137134

138-
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
139-
* before any floating point instructions are executed. */
140-
void vPortTaskUsesFPU( void );
135+
/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
136+
* created without an FPU context and must call vPortTaskUsesFPU() to give
137+
* themselves an FPU context before using any FPU instructions. If
138+
* configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU
139+
* context by default. */
140+
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
141+
void vPortTaskUsesFPU( void );
142+
#else
143+
/* Each task has an FPU context already, so define this function away to
144+
* nothing to prevent it from being called accidentally. */
145+
#define vPortTaskUsesFPU()
146+
#endif
141147
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
142148

143149
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )

0 commit comments

Comments
 (0)