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 "task.h"
|
||||
|
||||
/* 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();
|
||||
|
||||
/* Start the first task. */
|
||||
trapa( 32 );
|
||||
trapa( portSTART_SCHEDULER_TRAP_NO );
|
||||
|
||||
/* Should not get here. */
|
||||
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 _ulPortGetGBR
|
||||
.export _vPortYield
|
||||
.export _vPortYieldHandler
|
||||
.export _vPortPreemptiveTick
|
||||
.export _vPortCooperativeTick
|
||||
.export _vPortSaveFlopRegisters
|
||||
.export _vPortRestoreFlopRegisters
|
||||
|
||||
.section P
|
||||
|
||||
|
@ -118,19 +120,7 @@ _vPortStartFirstTask:
|
|||
|
||||
;-----------------------------------------------------------
|
||||
|
||||
_vPortYield:
|
||||
|
||||
; 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
|
||||
_vPortYieldHandler:
|
||||
|
||||
portSAVE_CONTEXT
|
||||
|
||||
|
@ -176,5 +166,58 @@ _ulPortGetGBR:
|
|||
rts
|
||||
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
|
||||
|
||||
|
|
|
@ -93,12 +93,24 @@ extern "C" {
|
|||
#define portBYTE_ALIGNMENT 4
|
||||
#define portSTACK_GROWTH -1
|
||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||
#define portYIELD() trapa( 33 )
|
||||
#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 portDISABLE_INTERRUPTS() set_imask( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
#define portDISABLE_INTERRUPTS() set_imask( portKERNEL_INTERRUPT_PRIORITY )
|
||||
|
||||
/* Critical section handling. */
|
||||
#define portCRITICAL_NESTING_IN_TCB ( 1 )
|
||||
|
|
Loading…
Reference in a new issue