|
28 | 28 |
|
29 | 29 | /* Standard includes. */
|
30 | 30 | #include <stdlib.h>
|
| 31 | +#include <string.h> |
31 | 32 |
|
32 | 33 | /* Scheduler includes. */
|
33 | 34 | #include "FreeRTOS.h"
|
|
80 | 81 | #define portTASK_RETURN_ADDRESS prvTaskExitError
|
81 | 82 | #endif
|
82 | 83 |
|
| 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 |
83 | 90 | /*-----------------------------------------------------------*/
|
84 | 91 |
|
85 | 92 | /*
|
86 |
| - * These functions are necessarily written in assembly code, so are implemented |
| 93 | + * These functions are necessarily written in assembly code, so are implemented |
87 | 94 | * in portASM.S.
|
88 | 95 | */
|
89 | 96 | extern void vPortRestoreTaskContext( void );
|
@@ -186,12 +193,33 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
186 | 193 | /* The task will start with a critical nesting count of 0 as interrupts are
|
187 | 194 | * enabled. */
|
188 | 195 | *pxTopOfStack = portNO_CRITICAL_NESTING;
|
189 |
| - pxTopOfStack--; |
190 | 196 |
|
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 ) */ |
195 | 223 |
|
196 | 224 | return pxTopOfStack;
|
197 | 225 | }
|
@@ -312,13 +340,17 @@ void FreeRTOS_Tick_Handler( void )
|
312 | 340 | }
|
313 | 341 | /*-----------------------------------------------------------*/
|
314 | 342 |
|
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 ) |
320 | 344 |
|
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 */ |
324 | 356 | /*-----------------------------------------------------------*/
|
0 commit comments