mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Add flop support.
This commit is contained in:
parent
65b947b50f
commit
094945625d
|
@ -59,8 +59,16 @@
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#define portINITIAL_SR 0UL /* No interrupts masked. */
|
/* Library includes. */
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
#define portINITIAL_SR 0UL /* No interrupts masked. */
|
||||||
|
|
||||||
|
/* Allocate enough space for FPR0 to FPR15, FPUL and FPSCR, each of which is 4
|
||||||
|
bytes big. If this number is changed then the 72 in portasm.src also needs
|
||||||
|
changing. */
|
||||||
|
#define portFLOP_REGISTERS_TO_STORE ( 18 )
|
||||||
|
#define portFLOP_STORAGE_SIZE ( portFLOP_REGISTERS_TO_STORE * 4 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -196,7 +204,7 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
trapa( 32 );
|
trapa( portSTART_SCHEDULER_TRAP_NO );
|
||||||
|
|
||||||
/* Should not get here. */
|
/* Should not get here. */
|
||||||
return pdFAIL;
|
return pdFAIL;
|
||||||
|
@ -229,6 +237,58 @@ extern void vApplicationSetupTimerInterrupt( void );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortYield( void )
|
||||||
|
{
|
||||||
|
long lInterruptMask;
|
||||||
|
|
||||||
|
lInterruptMask = get_imask();
|
||||||
|
|
||||||
|
/* taskYIELD() can only be called from a task, not an interrupt, so the
|
||||||
|
current interrupt mask can only be 0 or portKERNEL_INTERRUPT_PRIORITY and
|
||||||
|
the mask can be set without risk of accidentally lowering the mask value. */
|
||||||
|
set_imask( portKERNEL_INTERRUPT_PRIORITY );
|
||||||
|
|
||||||
|
trapa( portYIELD_TRAP_NO );
|
||||||
|
|
||||||
|
set_imask( ( int ) lInterruptMask );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xPortUsesFloatingPoint( xTaskHandle xTask )
|
||||||
|
{
|
||||||
|
unsigned long *pulFlopBuffer;
|
||||||
|
portBASE_TYPE xReturn;
|
||||||
|
extern void * volatile pxCurrentTCB;
|
||||||
|
|
||||||
|
if( xTask == NULL )
|
||||||
|
{
|
||||||
|
xTask = pxCurrentTCB;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a buffer large enough to hold all the flop registers. */
|
||||||
|
pulFlopBuffer = ( unsigned long * ) pvPortMalloc( portFLOP_STORAGE_SIZE );
|
||||||
|
|
||||||
|
if( pulFlopBuffer != NULL )
|
||||||
|
{
|
||||||
|
memset( ( void * ) pulFlopBuffer, 0x00, portFLOP_STORAGE_SIZE );
|
||||||
|
|
||||||
|
*pulFlopBuffer = get_fpscr();
|
||||||
|
|
||||||
|
/* Use the task tag to point to the flop buffer. Pass pointer to just above
|
||||||
|
the buffer because the flop save routine uses a pre-decrement. */
|
||||||
|
vTaskSetApplicationTaskTag( xTask, ( void * ) ( pulFlopBuffer + portFLOP_REGISTERS_TO_STORE ) );
|
||||||
|
xReturn = pdPASS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -57,9 +57,11 @@
|
||||||
|
|
||||||
.export _vPortStartFirstTask
|
.export _vPortStartFirstTask
|
||||||
.export _ulPortGetGBR
|
.export _ulPortGetGBR
|
||||||
.export _vPortYield
|
.export _vPortYieldHandler
|
||||||
.export _vPortPreemptiveTick
|
.export _vPortPreemptiveTick
|
||||||
.export _vPortCooperativeTick
|
.export _vPortCooperativeTick
|
||||||
|
.export _vPortSaveFlopRegisters
|
||||||
|
.export _vPortRestoreFlopRegisters
|
||||||
|
|
||||||
.section P
|
.section P
|
||||||
|
|
||||||
|
@ -118,19 +120,7 @@ _vPortStartFirstTask:
|
||||||
|
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
|
|
||||||
_vPortYield:
|
_vPortYieldHandler:
|
||||||
|
|
||||||
; Push r0 so it can be used.
|
|
||||||
mov.l r0, @-r15
|
|
||||||
|
|
||||||
; Set the interrupt mask in the status register.
|
|
||||||
stc sr, r0
|
|
||||||
or #H'70, r0
|
|
||||||
ldc r0, sr
|
|
||||||
|
|
||||||
; Restore r0 so its original value can be saved by the movml.l instruction
|
|
||||||
; below, without ending up with two copies on the stack.
|
|
||||||
mov.l @r15+, r0
|
|
||||||
|
|
||||||
portSAVE_CONTEXT
|
portSAVE_CONTEXT
|
||||||
|
|
||||||
|
@ -176,5 +166,58 @@ _ulPortGetGBR:
|
||||||
rts
|
rts
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
|
||||||
|
_vPortSaveFlopRegisters:
|
||||||
|
|
||||||
|
fmov.s fr0, @-r4
|
||||||
|
fmov.s fr1, @-r4
|
||||||
|
fmov.s fr2, @-r4
|
||||||
|
fmov.s fr3, @-r4
|
||||||
|
fmov.s fr4, @-r4
|
||||||
|
fmov.s fr5, @-r4
|
||||||
|
fmov.s fr6, @-r4
|
||||||
|
fmov.s fr7, @-r4
|
||||||
|
fmov.s fr8, @-r4
|
||||||
|
fmov.s fr9, @-r4
|
||||||
|
fmov.s fr10, @-r4
|
||||||
|
fmov.s fr11, @-r4
|
||||||
|
fmov.s fr12, @-r4
|
||||||
|
fmov.s fr13, @-r4
|
||||||
|
fmov.s fr14, @-r4
|
||||||
|
fmov.s fr15, @-r4
|
||||||
|
sts.l fpul, @-r4
|
||||||
|
sts.l fpscr, @-r4
|
||||||
|
|
||||||
|
rts
|
||||||
|
nop
|
||||||
|
|
||||||
|
;-----------------------------------------------------------
|
||||||
|
|
||||||
|
_vPortRestoreFlopRegisters:
|
||||||
|
|
||||||
|
add.l #-72, r4
|
||||||
|
lds.l @r4+, fpscr
|
||||||
|
lds.l @r4+, fpul
|
||||||
|
fmov.s @r4+, fr15
|
||||||
|
fmov.s @r4+, fr14
|
||||||
|
fmov.s @r4+, fr13
|
||||||
|
fmov.s @r4+, fr12
|
||||||
|
fmov.s @r4+, fr11
|
||||||
|
fmov.s @r4+, fr10
|
||||||
|
fmov.s @r4+, fr9
|
||||||
|
fmov.s @r4+, fr8
|
||||||
|
fmov.s @r4+, fr7
|
||||||
|
fmov.s @r4+, fr6
|
||||||
|
fmov.s @r4+, fr5
|
||||||
|
fmov.s @r4+, fr4
|
||||||
|
fmov.s @r4+, fr3
|
||||||
|
fmov.s @r4+, fr2
|
||||||
|
fmov.s @r4+, fr1
|
||||||
|
fmov.s @r4+, fr0
|
||||||
|
|
||||||
|
rts
|
||||||
|
nop
|
||||||
|
|
||||||
.end
|
.end
|
||||||
|
|
||||||
|
|
|
@ -90,15 +90,27 @@ extern "C" {
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#define portSTACK_GROWTH -1
|
#define portSTACK_GROWTH -1
|
||||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portYIELD() trapa( 33 )
|
#define portNOP() nop()
|
||||||
#define portNOP() nop()
|
#define portSTART_SCHEDULER_TRAP_NO ( 32 )
|
||||||
|
#define portYIELD_TRAP_NO ( 33 )
|
||||||
|
#define portKERNEL_INTERRUPT_PRIORITY ( 1 )
|
||||||
|
|
||||||
|
void vPortYield( void );
|
||||||
|
#define portYIELD() vPortYield()
|
||||||
|
|
||||||
|
portBASE_TYPE xPortUsesFloatingPoint( void* xTask );
|
||||||
|
void vPortSaveFlopRegisters( void *pulBuffer );
|
||||||
|
void vPortRestoreFlopRegisters( void *pulBuffer );
|
||||||
|
#define traceTASK_SWITCHED_OUT() if( pxCurrentTCB->pxTaskTag != NULL ) vPortSaveFlopRegisters( pxCurrentTCB->pxTaskTag )
|
||||||
|
#define traceTASK_SWITCHED_IN() if( pxCurrentTCB->pxTaskTag != NULL ) vPortRestoreFlopRegisters( pxCurrentTCB->pxTaskTag )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() set_imask( 0x00 )
|
#define portENABLE_INTERRUPTS() set_imask( 0x00 )
|
||||||
#define portDISABLE_INTERRUPTS() set_imask( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portDISABLE_INTERRUPTS() set_imask( portKERNEL_INTERRUPT_PRIORITY )
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
#define portCRITICAL_NESTING_IN_TCB ( 1 )
|
#define portCRITICAL_NESTING_IN_TCB ( 1 )
|
||||||
|
|
Loading…
Reference in a new issue