Revert Portable/Renesas formatting (#876)

* Revert the formatting on Renesas ports
This commit is contained in:
Soren Ptak 2023-11-28 13:56:15 -05:00 committed by GitHub
parent a2a4485ed3
commit 147f34ab5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 932 additions and 963 deletions

View file

@ -27,8 +27,8 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the RX100 port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the RX100 port.
*----------------------------------------------------------*/
/* Standard C includes. */
#include "limits.h"
@ -46,35 +46,35 @@
/*-----------------------------------------------------------*/
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore
* PSW is set with U and I set, and PM and IPL clear. */
#define portINITIAL_PSW ( ( StackType_t ) 0x00030000 )
PSW is set with U and I set, and PM and IPL clear. */
#define portINITIAL_PSW ( ( StackType_t ) 0x00030000 )
/* The peripheral clock is divided by this value before being supplying the
* CMT. */
CMT. */
#if ( configUSE_TICKLESS_IDLE == 0 )
/* If tickless idle is not used then the divisor can be fixed. */
#define portCLOCK_DIVISOR 8UL
#define portCLOCK_DIVISOR 8UL
#elif ( configPERIPHERAL_CLOCK_HZ >= 12000000 )
#define portCLOCK_DIVISOR 512UL
#define portCLOCK_DIVISOR 512UL
#elif ( configPERIPHERAL_CLOCK_HZ >= 6000000 )
#define portCLOCK_DIVISOR 128UL
#define portCLOCK_DIVISOR 128UL
#elif ( configPERIPHERAL_CLOCK_HZ >= 1000000 )
#define portCLOCK_DIVISOR 32UL
#define portCLOCK_DIVISOR 32UL
#else
#define portCLOCK_DIVISOR 8UL
#define portCLOCK_DIVISOR 8UL
#endif
/* Keys required to lock and unlock access to certain system registers
* respectively. */
#define portUNLOCK_KEY 0xA50B
#define portLOCK_KEY 0xA500
respectively. */
#define portUNLOCK_KEY 0xA50B
#define portLOCK_KEY 0xA500
/*-----------------------------------------------------------*/
/* The following lines are to ensure vSoftwareInterruptEntry can be referenced,
* and therefore installed in the vector table, when the FreeRTOS code is built
* as a library. */
and therefore installed in the vector table, when the FreeRTOS code is built
as a library. */
extern BaseType_t vSoftwareInterruptEntry;
const BaseType_t * p_vSoftwareInterruptEntry = &vSoftwareInterruptEntry;
@ -109,10 +109,9 @@ void vSoftwareInterruptISR( void );
*/
static void prvSetupTimerInterrupt( void );
#ifndef configSETUP_TICK_INTERRUPT
/* The user has not provided their own tick interrupt configuration so use
* the definition in this file (which uses the interval timer). */
#define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt()
/* The user has not provided their own tick interrupt configuration so use
the definition in this file (which uses the interval timer). */
#define configSETUP_TICK_INTERRUPT() prvSetupTimerInterrupt()
#endif /* configSETUP_TICK_INTERRUPT */
/*
@ -127,7 +126,7 @@ static void prvSetupTimerInterrupt( void );
/*-----------------------------------------------------------*/
/* These is accessed by the inline assembler functions. */
extern void * pxCurrentTCB;
extern void *pxCurrentTCB;
extern void vTaskSwitchContext( void );
/*-----------------------------------------------------------*/
@ -137,35 +136,33 @@ static const uint32_t ulMatchValueForOneTick = ( ( configPERIPHERAL_CLOCK_HZ / p
#if configUSE_TICKLESS_IDLE == 1
/* Holds the maximum number of ticks that can be suppressed - which is
* basically how far into the future an interrupt can be generated. Set
* during initialisation. This is the maximum possible value that the
* compare match register can hold divided by ulMatchValueForOneTick. */
/* Holds the maximum number of ticks that can be suppressed - which is
basically how far into the future an interrupt can be generated. Set
during initialisation. This is the maximum possible value that the
compare match register can hold divided by ulMatchValueForOneTick. */
static const TickType_t xMaximumPossibleSuppressedTicks = USHRT_MAX / ( ( configPERIPHERAL_CLOCK_HZ / portCLOCK_DIVISOR ) / configTICK_RATE_HZ );
/* Flag set from the tick interrupt to allow the sleep processing to know if
* sleep mode was exited because of a tick interrupt, or an interrupt
* generated by something else. */
/* Flag set from the tick interrupt to allow the sleep processing to know if
sleep mode was exited because of a tick interrupt, or an interrupt
generated by something else. */
static volatile uint32_t ulTickFlag = pdFALSE;
/* The CMT counter is stopped temporarily each time it is re-programmed.
* The following constant offsets the CMT counter match value by the number of
* CMT counts that would typically be missed while the counter was stopped to
* compensate for the lost time. The large difference between the divided CMT
* clock and the CPU clock means it is likely ulStoppedTimerCompensation will
* equal zero - and be optimised away. */
/* The CMT counter is stopped temporarily each time it is re-programmed.
The following constant offsets the CMT counter match value by the number of
CMT counts that would typically be missed while the counter was stopped to
compensate for the lost time. The large difference between the divided CMT
clock and the CPU clock means it is likely ulStoppedTimerCompensation will
equal zero - and be optimised away. */
static const uint32_t ulStoppedTimerCompensation = 100UL / ( configCPU_CLOCK_HZ / ( configPERIPHERAL_CLOCK_HZ / portCLOCK_DIVISOR ) );
#endif /* if configUSE_TICKLESS_IDLE == 1 */
#endif
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
/* Offset to end up on 8 byte boundary. */
pxTopOfStack--;
@ -180,8 +177,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) pxCode;
/* When debugging it can be useful if every register is set to a known
* value. Otherwise code space can be saved by just setting the registers
* that need to be set. */
value. Otherwise code space can be saved by just setting the registers
that need to be set. */
#ifdef USE_FULL_REGISTER_INITIALISATION
{
pxTopOfStack--;
@ -214,19 +211,19 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = 0x22222222;
pxTopOfStack--;
}
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */
#else
{
/* Leave space for the registers that will get popped from the stack
* when the task first starts executing. */
when the task first starts executing. */
pxTopOfStack -= 15;
}
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */
#endif
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */
pxTopOfStack--;
*pxTopOfStack = 0x12345678; /* Accumulator. */
*pxTopOfStack = 0x12345678; /* Accumulator. */
pxTopOfStack--;
*pxTopOfStack = 0x87654321; /* Accumulator. */
*pxTopOfStack = 0x87654321; /* Accumulator. */
return pxTopOfStack;
}
@ -238,10 +235,10 @@ BaseType_t xPortStartScheduler( void )
if( pxCurrentTCB != NULL )
{
/* Call an application function to set up the timer that will generate
* the tick interrupt. This way the application can decide which
* peripheral to use. If tickless mode is used then the default
* implementation defined in this file (which uses CMT0) should not be
* overridden. */
the tick interrupt. This way the application can decide which
peripheral to use. If tickless mode is used then the default
implementation defined in this file (which uses CMT0) should not be
overridden. */
configSETUP_TICK_INTERRUPT();
/* Enable the software interrupt. */
@ -258,11 +255,11 @@ BaseType_t xPortStartScheduler( void )
}
/* Execution should not reach here as the tasks are now running!
* prvSetupTimerInterrupt() is called here to prevent the compiler outputting
* a warning about a statically declared function not being referenced in the
* case that the application writer has provided their own tick interrupt
* configuration routine (and defined configSETUP_TICK_INTERRUPT() such that
* their own routine will be called in place of prvSetupTimerInterrupt()). */
prvSetupTimerInterrupt() is called here to prevent the compiler outputting
a warning about a statically declared function not being referenced in the
case that the application writer has provided their own tick interrupt
configuration routine (and defined configSETUP_TICK_INTERRUPT() such that
their own routine will be called in place of prvSetupTimerInterrupt()). */
prvSetupTimerInterrupt();
/* Just to make sure the function is not optimised away. */
@ -277,26 +274,26 @@ BaseType_t xPortStartScheduler( void )
static void prvStartFirstTask( void )
{
/* When starting the scheduler there is nothing that needs moving to the
* interrupt stack because the function is not called from an interrupt.
* Just ensure the current stack is the user stack. */
SETPSW U
interrupt stack because the function is not called from an interrupt.
Just ensure the current stack is the user stack. */
SETPSW U
/* Obtain the location of the stack associated with which ever task
* pxCurrentTCB is currently pointing to. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L[ R15 ], R0
pxCurrentTCB is currently pointing to. */
MOV.L #_pxCurrentTCB, R15
MOV.L [R15], R15
MOV.L [R15], R0
/* Restore the registers from the stack of the task pointed to by
* pxCurrentTCB. */
POP R15
MVTACLO R15 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15 /* Accumulator high 32 bits. */
POPM R1 - R15 /* R1 to R15 - R0 is not included as it is the SP. */
RTE /* This pops the remaining registers. */
pxCurrentTCB. */
POP R15
MVTACLO R15 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15 /* Accumulator high 32 bits. */
POPM R1-R15 /* R1 to R15 - R0 is not included as it is the SP. */
RTE /* This pops the remaining registers. */
NOP
NOP
NOP
}
/*-----------------------------------------------------------*/
@ -304,7 +301,7 @@ static void prvStartFirstTask( void )
void prvTickISR( void )
{
/* Increment the tick, and perform any processing the new tick value
* necessitates. */
necessitates. */
set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY );
{
if( xTaskIncrementTick() != pdFALSE )
@ -312,7 +309,6 @@ void prvTickISR( void )
taskYIELD();
}
}
set_ipl( configKERNEL_INTERRUPT_PRIORITY );
#if configUSE_TICKLESS_IDLE == 1
@ -321,7 +317,7 @@ void prvTickISR( void )
ulTickFlag = pdTRUE;
/* If this is the first tick since exiting tickless mode then the CMT
* compare match value needs resetting. */
compare match value needs resetting. */
CMT0.CMCOR = ( uint16_t ) ulMatchValueForOneTick;
}
#endif
@ -338,87 +334,81 @@ void vSoftwareInterruptISR( void )
static void prvYieldHandler( void )
{
/* Re-enable interrupts. */
SETPSW I
SETPSW I
/* Move the data that was automatically pushed onto the interrupt stack
* when the interrupt occurred from the interrupt stack to the user stack.
*
* R15 is saved before it is clobbered. */
PUSH.L R15
when the interrupt occurred from the interrupt stack to the user stack.
R15 is saved before it is clobbered. */
PUSH.L R15
/* Read the user stack pointer. */
MVFC USP, R15
MVFC USP, R15
/* Move the address down to the data being moved. */
SUB # 12, R15
MVTC R15, USP
SUB #12, R15
MVTC R15, USP
/* Copy the data across. */
MOV.L[ R0 ], [ R15 ];
R15
MOV.L 4[ R0 ], 4[ R15 ];
PC
MOV.L 8[ R0 ], 8[ R15 ];
PSW
MOV.L [ R0 ], [ R15 ] ; R15
MOV.L 4[ R0 ], 4[ R15 ] ; PC
MOV.L 8[ R0 ], 8[ R15 ] ; PSW
/* Move the interrupt stack pointer to its new correct position. */
ADD # 12, R0
ADD #12, R0
/* All the rest of the registers are saved directly to the user stack. */
SETPSW U
SETPSW U
/* Save the rest of the general registers (R15 has been saved already). */
PUSHM R1 - R14
PUSHM R1-R14
/* Save the accumulator. */
MVFACHI R15
PUSH.L R15
MVFACMI R15;
Middle order word.
SHLL # 16, R15;
Shifted left as it is restored to the low order word.
PUSH.L R15
PUSH.L R15
MVFACMI R15 ; Middle order word.
SHLL #16, R15 ; Shifted left as it is restored to the low order word.
PUSH.L R15
/* Save the stack pointer to the TCB. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L R0, [ R15 ]
MOV.L #_pxCurrentTCB, R15
MOV.L [ R15 ], R15
MOV.L R0, [ R15 ]
/* Ensure the interrupt mask is set to the syscall priority while the
* kernel structures are being accessed. */
MVTIPL # configMAX_SYSCALL_INTERRUPT_PRIORITY
kernel structures are being accessed. */
MVTIPL #configMAX_SYSCALL_INTERRUPT_PRIORITY
/* Select the next task to run. */
BSR.A _vTaskSwitchContext
BSR.A _vTaskSwitchContext
/* Reset the interrupt mask as no more data structure access is
* required. */
MVTIPL # configKERNEL_INTERRUPT_PRIORITY
required. */
MVTIPL #configKERNEL_INTERRUPT_PRIORITY
/* Load the stack pointer of the task that is now selected as the Running
* state task from its TCB. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L[ R15 ], R0
state task from its TCB. */
MOV.L #_pxCurrentTCB,R15
MOV.L [ R15 ], R15
MOV.L [ R15 ], R0
/* Restore the context of the new task. The PSW (Program Status Word) and
* PC will be popped by the RTE instruction. */
POP R15
PC will be popped by the RTE instruction. */
POP R15
MVTACLO R15
POP R15
POP R15
MVTACHI R15
POPM R1 - R15
POPM R1-R15
RTE
NOP
NOP
NOP
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */
Artificially force an assert. */
configASSERT( pxCurrentTCB == NULL );
/* The following line is just to prevent the symbol getting optimised away. */
@ -460,11 +450,11 @@ static void prvSetupTimerInterrupt( void )
{
CMT0.CMCR.BIT.CKS = 0;
}
#else /* if portCLOCK_DIVISOR == 512 */
#else
{
#error Invalid portCLOCK_DIVISOR setting
}
#endif /* if portCLOCK_DIVISOR == 512 */
#endif
/* Enable the interrupt... */
@ -486,8 +476,8 @@ static void prvSetupTimerInterrupt( void )
configPRE_SLEEP_PROCESSING( xExpectedIdleTime );
/* xExpectedIdleTime being set to 0 by configPRE_SLEEP_PROCESSING()
* means the application defined code has already executed the WAIT
* instruction. */
means the application defined code has already executed the WAIT
instruction. */
if( xExpectedIdleTime > 0 )
{
wait();
@ -504,8 +494,8 @@ static void prvSetupTimerInterrupt( void )
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
{
uint32_t ulMatchValue, ulCompleteTickPeriods, ulCurrentCount;
eSleepModeStatus eSleepAction;
uint32_t ulMatchValue, ulCompleteTickPeriods, ulCurrentCount;
eSleepModeStatus eSleepAction;
/* THIS FUNCTION IS CALLED WITH THE SCHEDULER SUSPENDED. */
@ -516,41 +506,38 @@ static void prvSetupTimerInterrupt( void )
}
/* Calculate the reload value required to wait xExpectedIdleTime tick
* periods. */
periods. */
ulMatchValue = ulMatchValueForOneTick * xExpectedIdleTime;
if( ulMatchValue > ulStoppedTimerCompensation )
{
/* Compensate for the fact that the CMT is going to be stopped
* momentarily. */
momentarily. */
ulMatchValue -= ulStoppedTimerCompensation;
}
/* Stop the CMT momentarily. The time the CMT is stopped for is
* accounted for as best it can be, but using the tickless mode will
* inevitably result in some tiny drift of the time maintained by the
* kernel with respect to calendar time. */
accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */
CMT.CMSTR0.BIT.STR0 = 0;
while( CMT.CMSTR0.BIT.STR0 == 1 )
{
/* Nothing to do here. */
}
/* Critical section using the global interrupt bit as the i bit is
* automatically reset by the WAIT instruction. */
automatically reset by the WAIT instruction. */
clrpsw_i();
/* The tick flag is set to false before sleeping. If it is true when
* sleep mode is exited then sleep mode was probably exited because the
* tick was suppressed for the entire xExpectedIdleTime period. */
sleep mode is exited then sleep mode was probably exited because the
tick was suppressed for the entire xExpectedIdleTime period. */
ulTickFlag = pdFALSE;
/* If a context switch is pending then abandon the low power entry as
* the context switch might have been pended by an external interrupt that
* requires processing. */
the context switch might have been pended by an external interrupt that
requires processing. */
eSleepAction = eTaskConfirmSleepModeStatus();
if( eSleepAction == eAbortSleep )
{
/* Restart tick. */
@ -569,7 +556,7 @@ static void prvSetupTimerInterrupt( void )
SYSTEM.PRCR.WORD = portLOCK_KEY;
/* Sleep until something happens. Calling prvSleep() will
* automatically reset the i bit in the PSW. */
automatically reset the i bit in the PSW. */
prvSleep( xExpectedIdleTime );
/* Restart the CMT. */
@ -589,7 +576,7 @@ static void prvSetupTimerInterrupt( void )
SYSTEM.PRCR.WORD = portLOCK_KEY;
/* Adjust the match value to take into account that the current
* time slice is already partially complete. */
time slice is already partially complete. */
ulMatchValue -= ( uint32_t ) CMT0.CMCNT;
CMT0.CMCOR = ( uint16_t ) ulMatchValue;
@ -598,15 +585,14 @@ static void prvSetupTimerInterrupt( void )
CMT.CMSTR0.BIT.STR0 = 1;
/* Sleep until something happens. Calling prvSleep() will
* automatically reset the i bit in the PSW. */
automatically reset the i bit in the PSW. */
prvSleep( xExpectedIdleTime );
/* Stop CMT. Again, the time the SysTick is stopped for is
* accounted for as best it can be, but using the tickless mode will
* inevitably result in some tiny drift of the time maintained by the
* kernel with respect to calendar time. */
accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */
CMT.CMSTR0.BIT.STR0 = 0;
while( CMT.CMSTR0.BIT.STR0 == 1 )
{
/* Nothing to do here. */
@ -617,42 +603,42 @@ static void prvSetupTimerInterrupt( void )
if( ulTickFlag != pdFALSE )
{
/* The tick interrupt has already executed, although because
* this function is called with the scheduler suspended the actual
* tick processing will not occur until after this function has
* exited. Reset the match value with whatever remains of this
* tick period. */
this function is called with the scheduler suspended the actual
tick processing will not occur until after this function has
exited. Reset the match value with whatever remains of this
tick period. */
ulMatchValue = ulMatchValueForOneTick - ulCurrentCount;
CMT0.CMCOR = ( uint16_t ) ulMatchValue;
/* The tick interrupt handler will already have pended the tick
* processing in the kernel. As the pending tick will be
* processed as soon as this function exits, the tick value
* maintained by the tick is stepped forward by one less than the
* time spent sleeping. The actual stepping of the tick appears
* later in this function. */
processing in the kernel. As the pending tick will be
processed as soon as this function exits, the tick value
maintained by the tick is stepped forward by one less than the
time spent sleeping. The actual stepping of the tick appears
later in this function. */
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
}
else
{
/* Something other than the tick interrupt ended the sleep.
* How many complete tick periods passed while the processor was
* sleeping? */
How many complete tick periods passed while the processor was
sleeping? */
ulCompleteTickPeriods = ulCurrentCount / ulMatchValueForOneTick;
/* The match value is set to whatever fraction of a single tick
* period remains. */
period remains. */
ulMatchValue = ulCurrentCount - ( ulCompleteTickPeriods * ulMatchValueForOneTick );
CMT0.CMCOR = ( uint16_t ) ulMatchValue;
}
/* Restart the CMT so it runs up to the match value. The match value
* will get set to the value required to generate exactly one tick period
* the next time the CMT interrupt executes. */
will get set to the value required to generate exactly one tick period
the next time the CMT interrupt executes. */
CMT0.CMCNT = 0;
CMT.CMSTR0.BIT.STR0 = 1;
/* Wind the tick forward by the number of tick periods that the CPU
* remained in a low power state. */
remained in a low power state. */
vTaskStepTick( ulCompleteTickPeriods );
}
}

View file

@ -50,87 +50,87 @@
*/
/* Type definitions - these are a bit legacy and not really used now, other
* than portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
than portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop()
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop()
#pragma inline_asm vPortYield
static void vPortYield( void )
{
/* Save clobbered register - may not actually be necessary if inline asm
* functions are considered to use the same rules as function calls by the
* compiler. */
functions are considered to use the same rules as function calls by the
compiler. */
PUSH.L R5
/* Set ITU SWINTR. */
MOV.L # 872E0H, R5
MOV.B # 1, [ R5 ]
MOV.L #872E0H, R5
MOV.B #1, [R5]
/* Read back to ensure the value is taken before proceeding. */
MOV.L[ R5 ], R5
MOV.L [R5], R5
/* Restore clobbered register to its previous value. */
POP R5
}
#define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) { portYIELD(); } } while( 0 )
#define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) { portYIELD(); } } while( 0 )
/* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
* performed if configASSERT() is defined to ensure an assertion handler does not
* inadvertently attempt to lower the IPL when the call to assert was triggered
* because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
* when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
* functions are those that end in FromISR. FreeRTOS maintains a separate
* interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
performed if configASSERT() is defined to ensure an assertion handler does not
inadvertently attempt to lower the IPL when the call to assert was triggered
because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
functions are those that end in FromISR. FreeRTOS maintains a separate
interrupt API to ensure API function and interrupt entry is as fast and as
simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
#ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif
/* Critical nesting counts are stored in the TCB. */
#define portCRITICAL_NESTING_IN_TCB ( 1 )
#define portCRITICAL_NESTING_IN_TCB ( 1 )
/* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */
#define portSET_INTERRUPT_MASK_FROM_ISR() ( UBaseType_t ) get_ipl(); set_ipl( ( signed long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( signed long ) uxSavedInterruptStatus )
#define portSET_INTERRUPT_MASK_FROM_ISR() ( UBaseType_t ) get_ipl(); set_ipl( ( signed long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( signed long ) uxSavedInterruptStatus )
/*-----------------------------------------------------------*/
@ -138,15 +138,15 @@ extern void vTaskExitCritical( void );
#if configUSE_TICKLESS_IDLE == 1
#ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif
#endif
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/* *INDENT-OFF* */
#ifdef __cplusplus

View file

@ -27,8 +27,8 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the RX200 port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the RX200 port.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
@ -43,14 +43,14 @@
/*-----------------------------------------------------------*/
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore
* PSW is set with U and I set, and PM and IPL clear. */
#define portINITIAL_PSW ( ( StackType_t ) 0x00030000 )
PSW is set with U and I set, and PM and IPL clear. */
#define portINITIAL_PSW ( ( StackType_t ) 0x00030000 )
/*-----------------------------------------------------------*/
/* The following lines are to ensure vSoftwareInterruptEntry can be referenced,
* and therefore installed in the vector table, when the FreeRTOS code is built
* as a library. */
and therefore installed in the vector table, when the FreeRTOS code is built
as a library. */
extern BaseType_t vSoftwareInterruptEntry;
const BaseType_t * p_vSoftwareInterruptEntry = &vSoftwareInterruptEntry;
@ -80,8 +80,8 @@ void vSoftwareInterruptISR( void );
/*-----------------------------------------------------------*/
/* This is accessed by the inline assembler functions so is file scope for
* convenience. */
extern void * pxCurrentTCB;
convenience. */
extern void *pxCurrentTCB;
extern void vTaskSwitchContext( void );
/*-----------------------------------------------------------*/
@ -89,9 +89,7 @@ extern void vTaskSwitchContext( void );
/*
* See header file for description.
*/
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
/* Offset to end up on 8 byte boundary. */
pxTopOfStack--;
@ -106,8 +104,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) pxCode;
/* When debugging it can be useful if every register is set to a known
* value. Otherwise code space can be saved by just setting the registers
* that need to be set. */
value. Otherwise code space can be saved by just setting the registers
that need to be set. */
#ifdef USE_FULL_REGISTER_INITIALISATION
{
pxTopOfStack--;
@ -140,17 +138,17 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = 0x22222222;
pxTopOfStack--;
}
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */
#else
{
pxTopOfStack -= 15;
}
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */
#endif
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */
pxTopOfStack--;
*pxTopOfStack = 0x12345678; /* Accumulator. */
*pxTopOfStack = 0x12345678; /* Accumulator. */
pxTopOfStack--;
*pxTopOfStack = 0x87654321; /* Accumulator. */
*pxTopOfStack = 0x87654321; /* Accumulator. */
return pxTopOfStack;
}
@ -158,14 +156,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
extern void vApplicationSetupTimerInterrupt( void );
extern void vApplicationSetupTimerInterrupt( void );
/* Use pxCurrentTCB just so it does not get optimised away. */
if( pxCurrentTCB != NULL )
{
/* Call an application function to set up the timer that will generate the
* tick interrupt. This way the application can decide which peripheral to
* use. A demo application is provided to show a suitable example. */
tick interrupt. This way the application can decide which peripheral to
use. A demo application is provided to show a suitable example. */
vApplicationSetupTimerInterrupt();
/* Enable the software interrupt. */
@ -193,26 +191,26 @@ BaseType_t xPortStartScheduler( void )
static void prvStartFirstTask( void )
{
/* When starting the scheduler there is nothing that needs moving to the
* interrupt stack because the function is not called from an interrupt.
* Just ensure the current stack is the user stack. */
SETPSW U
interrupt stack because the function is not called from an interrupt.
Just ensure the current stack is the user stack. */
SETPSW U
/* Obtain the location of the stack associated with which ever task
* pxCurrentTCB is currently pointing to. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L[ R15 ], R0
pxCurrentTCB is currently pointing to. */
MOV.L #_pxCurrentTCB, R15
MOV.L [R15], R15
MOV.L [R15], R0
/* Restore the registers from the stack of the task pointed to by
* pxCurrentTCB. */
POP R15
MVTACLO R15 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15 /* Accumulator high 32 bits. */
POPM R1 - R15 /* R1 to R15 - R0 is not included as it is the SP. */
RTE /* This pops the remaining registers. */
pxCurrentTCB. */
POP R15
MVTACLO R15 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15 /* Accumulator high 32 bits. */
POPM R1-R15 /* R1 to R15 - R0 is not included as it is the SP. */
RTE /* This pops the remaining registers. */
NOP
NOP
NOP
}
/*-----------------------------------------------------------*/
@ -220,7 +218,7 @@ static void prvStartFirstTask( void )
void vTickISR( void )
{
/* Increment the tick, and perform any processing the new tick value
* necessitates. */
necessitates. */
set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY );
{
if( xTaskIncrementTick() != pdFALSE )
@ -228,7 +226,6 @@ void vTickISR( void )
taskYIELD();
}
}
set_ipl( configKERNEL_INTERRUPT_PRIORITY );
}
/*-----------------------------------------------------------*/
@ -243,86 +240,80 @@ void vSoftwareInterruptISR( void )
static void prvYieldHandler( void )
{
/* Re-enable interrupts. */
SETPSW I
SETPSW I
/* Move the data that was automatically pushed onto the interrupt stack when
* the interrupt occurred from the interrupt stack to the user stack.
*
* R15 is saved before it is clobbered. */
PUSH.L R15
the interrupt occurred from the interrupt stack to the user stack.
R15 is saved before it is clobbered. */
PUSH.L R15
/* Read the user stack pointer. */
MVFC USP, R15
MVFC USP, R15
/* Move the address down to the data being moved. */
SUB # 12, R15
MVTC R15, USP
SUB #12, R15
MVTC R15, USP
/* Copy the data across. */
MOV.L[ R0 ], [ R15 ];
R15
MOV.L 4[ R0 ], 4[ R15 ];
PC
MOV.L 8[ R0 ], 8[ R15 ];
PSW
MOV.L [ R0 ], [ R15 ] ; R15
MOV.L 4[ R0 ], 4[ R15 ] ; PC
MOV.L 8[ R0 ], 8[ R15 ] ; PSW
/* Move the interrupt stack pointer to its new correct position. */
ADD # 12, R0
ADD #12, R0
/* All the rest of the registers are saved directly to the user stack. */
SETPSW U
SETPSW U
/* Save the rest of the general registers (R15 has been saved already). */
PUSHM R1 - R14
PUSHM R1-R14
/* Save the accumulator. */
MVFACHI R15
PUSH.L R15
MVFACMI R15;
Middle order word.
SHLL # 16, R15;
Shifted left as it is restored to the low order word.
PUSH.L R15
PUSH.L R15
MVFACMI R15 ; Middle order word.
SHLL #16, R15 ; Shifted left as it is restored to the low order word.
PUSH.L R15
/* Save the stack pointer to the TCB. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L R0, [ R15 ]
MOV.L #_pxCurrentTCB, R15
MOV.L [ R15 ], R15
MOV.L R0, [ R15 ]
/* Ensure the interrupt mask is set to the syscall priority while the kernel
* structures are being accessed. */
MVTIPL # configMAX_SYSCALL_INTERRUPT_PRIORITY
structures are being accessed. */
MVTIPL #configMAX_SYSCALL_INTERRUPT_PRIORITY
/* Select the next task to run. */
BSR.A _vTaskSwitchContext
BSR.A _vTaskSwitchContext
/* Reset the interrupt mask as no more data structure access is required. */
MVTIPL # configKERNEL_INTERRUPT_PRIORITY
MVTIPL #configKERNEL_INTERRUPT_PRIORITY
/* Load the stack pointer of the task that is now selected as the Running
* state task from its TCB. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L[ R15 ], R0
state task from its TCB. */
MOV.L #_pxCurrentTCB,R15
MOV.L [ R15 ], R15
MOV.L [ R15 ], R0
/* Restore the context of the new task. The PSW (Program Status Word) and
* PC will be popped by the RTE instruction. */
POP R15
PC will be popped by the RTE instruction. */
POP R15
MVTACLO R15
POP R15
POP R15
MVTACHI R15
POPM R1 - R15
POPM R1-R15
RTE
NOP
NOP
NOP
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */
Artificially force an assert. */
configASSERT( pxCurrentTCB == NULL );
/* The following line is just to prevent the symbol getting optimised away. */

View file

@ -50,93 +50,93 @@
*/
/* Type definitions - these are a bit legacy and not really used now, other than
* portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop()
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop()
#pragma inline_asm vPortYield
static void vPortYield( void )
{
/* Save clobbered register - may not actually be necessary if inline asm
* functions are considered to use the same rules as function calls by the
* compiler. */
functions are considered to use the same rules as function calls by the
compiler. */
PUSH.L R5
/* Set ITU SWINTR. */
MOV.L # 553696, R5
MOV.B # 1, [ R5 ]
MOV.L #553696, R5
MOV.B #1, [R5]
/* Read back to ensure the value is taken before proceeding. */
MOV.L[ R5 ], R5
MOV.L [R5], R5
/* Restore clobbered register to its previous value. */
POP R5
}
#define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) portYIELD( ); } while( 0 )
#define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) portYIELD(); } while( 0 )
/* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
* performed if configASSERT() is defined to ensure an assertion handler does not
* inadvertently attempt to lower the IPL when the call to assert was triggered
* because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
* when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
* functions are those that end in FromISR. FreeRTOS maintains a separate
* interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
performed if configASSERT() is defined to ensure an assertion handler does not
inadvertently attempt to lower the IPL when the call to assert was triggered
because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
functions are those that end in FromISR. FreeRTOS maintains a separate
interrupt API to ensure API function and interrupt entry is as fast and as
simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
#ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif
/* Critical nesting counts are stored in the TCB. */
#define portCRITICAL_NESTING_IN_TCB ( 1 )
#define portCRITICAL_NESTING_IN_TCB ( 1 )
/* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */
#define portSET_INTERRUPT_MASK_FROM_ISR() get_ipl(); set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( long ) uxSavedInterruptStatus )
#define portSET_INTERRUPT_MASK_FROM_ISR() get_ipl(); set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( long ) uxSavedInterruptStatus )
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/* *INDENT-OFF* */
#ifdef __cplusplus

View file

@ -27,8 +27,8 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the RX600 port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the RX600 port.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
@ -43,15 +43,15 @@
/*-----------------------------------------------------------*/
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore
* PSW is set with U and I set, and PM and IPL clear. */
PSW is set with U and I set, and PM and IPL clear. */
#define portINITIAL_PSW ( ( StackType_t ) 0x00030000 )
#define portINITIAL_FPSW ( ( StackType_t ) 0x00000100 )
/*-----------------------------------------------------------*/
/* The following lines are to ensure vSoftwareInterruptEntry can be referenced,
* and therefore installed in the vector table, when the FreeRTOS code is built
* as a library. */
and therefore installed in the vector table, when the FreeRTOS code is built
as a library. */
extern BaseType_t vSoftwareInterruptEntry;
const BaseType_t * p_vSoftwareInterruptEntry = &vSoftwareInterruptEntry;
@ -81,8 +81,8 @@ void vSoftwareInterruptISR( void );
/*-----------------------------------------------------------*/
/* This is accessed by the inline assembler functions so is file scope for
* convenience. */
extern void * pxCurrentTCB;
convenience. */
extern void *pxCurrentTCB;
extern void vTaskSwitchContext( void );
/*-----------------------------------------------------------*/
@ -90,9 +90,7 @@ extern void vTaskSwitchContext( void );
/*
* See header file for description.
*/
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
/* R0 is not included as it is the stack pointer. */
@ -103,8 +101,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) pxCode;
/* When debugging it can be useful if every register is set to a known
* value. Otherwise code space can be saved by just setting the registers
* that need to be set. */
value. Otherwise code space can be saved by just setting the registers
that need to be set. */
#ifdef USE_FULL_REGISTER_INITIALISATION
{
pxTopOfStack--;
@ -137,11 +135,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = 0x22222222;
pxTopOfStack--;
}
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */
#else
{
pxTopOfStack -= 15;
}
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */
#endif
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */
pxTopOfStack--;
@ -157,14 +155,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
extern void vApplicationSetupTimerInterrupt( void );
extern void vApplicationSetupTimerInterrupt( void );
/* Use pxCurrentTCB just so it does not get optimised away. */
if( pxCurrentTCB != NULL )
{
/* Call an application function to set up the timer that will generate the
* tick interrupt. This way the application can decide which peripheral to
* use. A demo application is provided to show a suitable example. */
tick interrupt. This way the application can decide which peripheral to
use. A demo application is provided to show a suitable example. */
vApplicationSetupTimerInterrupt();
/* Enable the software interrupt. */
@ -192,28 +190,28 @@ BaseType_t xPortStartScheduler( void )
static void prvStartFirstTask( void )
{
/* When starting the scheduler there is nothing that needs moving to the
* interrupt stack because the function is not called from an interrupt.
* Just ensure the current stack is the user stack. */
SETPSW U
interrupt stack because the function is not called from an interrupt.
Just ensure the current stack is the user stack. */
SETPSW U
/* Obtain the location of the stack associated with which ever task
* pxCurrentTCB is currently pointing to. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L[ R15 ], R0
pxCurrentTCB is currently pointing to. */
MOV.L #_pxCurrentTCB, R15
MOV.L [R15], R15
MOV.L [R15], R0
/* Restore the registers from the stack of the task pointed to by
* pxCurrentTCB. */
POP R15
MVTACLO R15 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15 /* Accumulator high 32 bits. */
POP R15
MVTC R15, FPSW /* Floating point status word. */
POPM R1 - R15 /* R1 to R15 - R0 is not included as it is the SP. */
RTE /* This pops the remaining registers. */
pxCurrentTCB. */
POP R15
MVTACLO R15 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15 /* Accumulator high 32 bits. */
POP R15
MVTC R15,FPSW /* Floating point status word. */
POPM R1-R15 /* R1 to R15 - R0 is not included as it is the SP. */
RTE /* This pops the remaining registers. */
NOP
NOP
NOP
}
/*-----------------------------------------------------------*/
@ -221,7 +219,7 @@ static void prvStartFirstTask( void )
void vTickISR( void )
{
/* Increment the tick, and perform any processing the new tick value
* necessitates. */
necessitates. */
set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY );
{
if( xTaskIncrementTick() != pdFALSE )
@ -229,7 +227,6 @@ void vTickISR( void )
taskYIELD();
}
}
set_ipl( configKERNEL_INTERRUPT_PRIORITY );
}
/*-----------------------------------------------------------*/
@ -244,90 +241,84 @@ void vSoftwareInterruptISR( void )
static void prvYieldHandler( void )
{
/* Re-enable interrupts. */
SETPSW I
SETPSW I
/* Move the data that was automatically pushed onto the interrupt stack when
* the interrupt occurred from the interrupt stack to the user stack.
*
* R15 is saved before it is clobbered. */
PUSH.L R15
the interrupt occurred from the interrupt stack to the user stack.
R15 is saved before it is clobbered. */
PUSH.L R15
/* Read the user stack pointer. */
MVFC USP, R15
MVFC USP, R15
/* Move the address down to the data being moved. */
SUB # 12, R15
MVTC R15, USP
SUB #12, R15
MVTC R15, USP
/* Copy the data across. */
MOV.L[ R0 ], [ R15 ];
R15
MOV.L 4[ R0 ], 4[ R15 ];
PC
MOV.L 8[ R0 ], 8[ R15 ];
PSW
MOV.L [ R0 ], [ R15 ] ; R15
MOV.L 4[ R0 ], 4[ R15 ] ; PC
MOV.L 8[ R0 ], 8[ R15 ] ; PSW
/* Move the interrupt stack pointer to its new correct position. */
ADD # 12, R0
ADD #12, R0
/* All the rest of the registers are saved directly to the user stack. */
SETPSW U
SETPSW U
/* Save the rest of the general registers (R15 has been saved already). */
PUSHM R1 - R14
PUSHM R1-R14
/* Save the FPSW and accumulator. */
MVFC FPSW, R15
PUSH.L R15
MVFC FPSW, R15
PUSH.L R15
MVFACHI R15
PUSH.L R15
MVFACMI R15;
Middle order word.
SHLL # 16, R15;
Shifted left as it is restored to the low order word.
PUSH.L R15
PUSH.L R15
MVFACMI R15 ; Middle order word.
SHLL #16, R15 ; Shifted left as it is restored to the low order word.
PUSH.L R15
/* Save the stack pointer to the TCB. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L R0, [ R15 ]
MOV.L #_pxCurrentTCB, R15
MOV.L [ R15 ], R15
MOV.L R0, [ R15 ]
/* Ensure the interrupt mask is set to the syscall priority while the kernel
* structures are being accessed. */
MVTIPL # configMAX_SYSCALL_INTERRUPT_PRIORITY
structures are being accessed. */
MVTIPL #configMAX_SYSCALL_INTERRUPT_PRIORITY
/* Select the next task to run. */
BSR.A _vTaskSwitchContext
BSR.A _vTaskSwitchContext
/* Reset the interrupt mask as no more data structure access is required. */
MVTIPL # configKERNEL_INTERRUPT_PRIORITY
MVTIPL #configKERNEL_INTERRUPT_PRIORITY
/* Load the stack pointer of the task that is now selected as the Running
* state task from its TCB. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L[ R15 ], R0
state task from its TCB. */
MOV.L #_pxCurrentTCB,R15
MOV.L [ R15 ], R15
MOV.L [ R15 ], R0
/* Restore the context of the new task. The PSW (Program Status Word) and
* PC will be popped by the RTE instruction. */
POP R15
PC will be popped by the RTE instruction. */
POP R15
MVTACLO R15
POP R15
POP R15
MVTACHI R15
POP R15
MVTC R15, FPSW
POPM R1 - R15
POP R15
MVTC R15,FPSW
POPM R1-R15
RTE
NOP
NOP
NOP
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */
Artificially force an assert. */
configASSERT( pxCurrentTCB == NULL );
/* The following line is just to prevent the symbol getting optimised away. */

View file

@ -50,94 +50,94 @@
*/
/* Type definitions - these are a bit legacy and not really used now, other than
* portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop()
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop()
#pragma inline_asm vPortYield
static void vPortYield( void )
{
/* Save clobbered register - may not actually be necessary if inline asm
* functions are considered to use the same rules as function calls by the
* compiler. */
functions are considered to use the same rules as function calls by the
compiler. */
PUSH.L R5
/* Set ITU SWINTR. */
MOV.L # 553696, R5
MOV.B # 1, [ R5 ]
MOV.L #553696, R5
MOV.B #1, [R5]
/* Read back to ensure the value is taken before proceeding. */
MOV.L[ R5 ], R5
MOV.L [R5], R5
/* Restore clobbered register to its previous value. */
POP R5
}
#define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) portYIELD( ); } while( 0 )
#define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) portYIELD(); } while( 0 )
/* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
* performed if configASSERT() is defined to ensure an assertion handler does not
* inadvertently attempt to lower the IPL when the call to assert was triggered
* because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
* when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
* functions are those that end in FromISR. FreeRTOS maintains a separate
* interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
performed if configASSERT() is defined to ensure an assertion handler does not
inadvertently attempt to lower the IPL when the call to assert was triggered
because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
functions are those that end in FromISR. FreeRTOS maintains a separate
interrupt API to ensure API function and interrupt entry is as fast and as
simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
#ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif
/* Critical nesting counts are stored in the TCB. */
#define portCRITICAL_NESTING_IN_TCB ( 1 )
#define portCRITICAL_NESTING_IN_TCB ( 1 )
/* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */
#define portSET_INTERRUPT_MASK_FROM_ISR() get_ipl(); set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( long ) uxSavedInterruptStatus )
#define portSET_INTERRUPT_MASK_FROM_ISR() get_ipl(); set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( long ) uxSavedInterruptStatus )
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/* *INDENT-OFF* */
#ifdef __cplusplus

View file

@ -27,8 +27,8 @@
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the RX600 port.
*----------------------------------------------------------*/
* Implementation of functions defined in portable.h for the RX600 port.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
@ -47,15 +47,15 @@
/*-----------------------------------------------------------*/
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore
* PSW is set with U and I set, and PM and IPL clear. */
PSW is set with U and I set, and PM and IPL clear. */
#define portINITIAL_PSW ( ( StackType_t ) 0x00030000 )
#define portINITIAL_FPSW ( ( StackType_t ) 0x00000100 )
/*-----------------------------------------------------------*/
/* The following lines are to ensure vSoftwareInterruptEntry can be referenced,
* and therefore installed in the vector table, when the FreeRTOS code is built
* as a library. */
and therefore installed in the vector table, when the FreeRTOS code is built
as a library. */
extern BaseType_t vSoftwareInterruptEntry;
const BaseType_t * p_vSoftwareInterruptEntry = &vSoftwareInterruptEntry;
@ -85,8 +85,8 @@ void vSoftwareInterruptISR( void );
/*-----------------------------------------------------------*/
/* This is accessed by the inline assembler functions so is file scope for
* convenience. */
extern void * pxCurrentTCB;
convenience. */
extern void *pxCurrentTCB;
extern void vTaskSwitchContext( void );
/*-----------------------------------------------------------*/
@ -94,9 +94,7 @@ extern void vTaskSwitchContext( void );
/*
* See header file for description.
*/
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
/* R0 is not included as it is the stack pointer. */
@ -107,8 +105,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) pxCode;
/* When debugging it can be useful if every register is set to a known
* value. Otherwise code space can be saved by just setting the registers
* that need to be set. */
value. Otherwise code space can be saved by just setting the registers
that need to be set. */
#ifdef USE_FULL_REGISTER_INITIALISATION
{
pxTopOfStack--;
@ -141,11 +139,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = 0x22222222;
pxTopOfStack--;
}
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */
#else
{
pxTopOfStack -= 15;
}
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */
#endif
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */
pxTopOfStack--;
@ -169,14 +167,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void )
{
extern void vApplicationSetupTimerInterrupt( void );
extern void vApplicationSetupTimerInterrupt( void );
/* Use pxCurrentTCB just so it does not get optimised away. */
if( pxCurrentTCB != NULL )
{
/* Call an application function to set up the timer that will generate the
* tick interrupt. This way the application can decide which peripheral to
* use. A demo application is provided to show a suitable example. */
tick interrupt. This way the application can decide which peripheral to
use. A demo application is provided to show a suitable example. */
vApplicationSetupTimerInterrupt();
/* Enable the software interrupt. */
@ -204,36 +202,36 @@ BaseType_t xPortStartScheduler( void )
static void prvStartFirstTask( void )
{
/* When starting the scheduler there is nothing that needs moving to the
* interrupt stack because the function is not called from an interrupt.
* Just ensure the current stack is the user stack. */
SETPSW U
interrupt stack because the function is not called from an interrupt.
Just ensure the current stack is the user stack. */
SETPSW U
/* Obtain the location of the stack associated with which ever task
* pxCurrentTCB is currently pointing to. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L[ R15 ], R0
pxCurrentTCB is currently pointing to. */
MOV.L #_pxCurrentTCB, R15
MOV.L [R15], R15
MOV.L [R15], R0
/* Restore the registers from the stack of the task pointed to by
* pxCurrentTCB. */
POP R15
MVTACLO R15, A0 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15, A0 /* Accumulator high 32 bits. */
POP R15
MVTACGU R15, A0 /* Accumulator guard. */
POP R15
MVTACLO R15, A1 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15, A1 /* Accumulator high 32 bits. */
POP R15
MVTACGU R15, A1 /* Accumulator guard. */
POP R15
MVTC R15, FPSW /* Floating point status word. */
POPM R1 - R15 /* R1 to R15 - R0 is not included as it is the SP. */
RTE /* This pops the remaining registers. */
pxCurrentTCB. */
POP R15
MVTACLO R15, A0 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15, A0 /* Accumulator high 32 bits. */
POP R15
MVTACGU R15, A0 /* Accumulator guard. */
POP R15
MVTACLO R15, A1 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15, A1 /* Accumulator high 32 bits. */
POP R15
MVTACGU R15, A1 /* Accumulator guard. */
POP R15
MVTC R15,FPSW /* Floating point status word. */
POPM R1-R15 /* R1 to R15 - R0 is not included as it is the SP. */
RTE /* This pops the remaining registers. */
NOP
NOP
NOP
}
/*-----------------------------------------------------------*/
@ -241,7 +239,7 @@ static void prvStartFirstTask( void )
void vTickISR( void )
{
/* Increment the tick, and perform any processing the new tick value
* necessitates. */
necessitates. */
set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY );
{
if( xTaskIncrementTick() != pdFALSE )
@ -249,7 +247,6 @@ void vTickISR( void )
taskYIELD();
}
}
set_ipl( configKERNEL_INTERRUPT_PRIORITY );
}
/*-----------------------------------------------------------*/
@ -264,105 +261,99 @@ void vSoftwareInterruptISR( void )
static void prvYieldHandler( void )
{
/* Re-enable interrupts. */
SETPSW I
SETPSW I
/* Move the data that was automatically pushed onto the interrupt stack when
* the interrupt occurred from the interrupt stack to the user stack.
*
* R15 is saved before it is clobbered. */
PUSH.L R15
the interrupt occurred from the interrupt stack to the user stack.
R15 is saved before it is clobbered. */
PUSH.L R15
/* Read the user stack pointer. */
MVFC USP, R15
MVFC USP, R15
/* Move the address down to the data being moved. */
SUB # 12, R15
MVTC R15, USP
SUB #12, R15
MVTC R15, USP
/* Copy the data across. */
MOV.L[ R0 ], [ R15 ];
R15
MOV.L 4[ R0 ], 4[ R15 ];
PC
MOV.L 8[ R0 ], 8[ R15 ];
PSW
MOV.L [ R0 ], [ R15 ] ; R15
MOV.L 4[ R0 ], 4[ R15 ] ; PC
MOV.L 8[ R0 ], 8[ R15 ] ; PSW
/* Move the interrupt stack pointer to its new correct position. */
ADD # 12, R0
ADD #12, R0
/* All the rest of the registers are saved directly to the user stack. */
SETPSW U
SETPSW U
/* Save the rest of the general registers (R15 has been saved already). */
PUSHM R1 - R14
PUSHM R1-R14
/* Save the FPSW and accumulators. */
MVFC FPSW, R15
PUSH.L R15
MVFACGU # 0, A1, R15
PUSH.L R15
MVFACHI # 0, A1, R15
PUSH.L R15
MVFACLO # 0, A1, R15;
Low order word.
PUSH.L R15
MVFACGU # 0, A0, R15
PUSH.L R15
MVFACHI # 0, A0, R15
PUSH.L R15
MVFACLO # 0, A0, R15;
Low order word.
PUSH.L R15
MVFC FPSW, R15
PUSH.L R15
MVFACGU #0, A1, R15
PUSH.L R15
MVFACHI #0, A1, R15
PUSH.L R15
MVFACLO #0, A1, R15 ; Low order word.
PUSH.L R15
MVFACGU #0, A0, R15
PUSH.L R15
MVFACHI #0, A0, R15
PUSH.L R15
MVFACLO #0, A0, R15 ; Low order word.
PUSH.L R15
/* Save the stack pointer to the TCB. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L R0, [ R15 ]
MOV.L #_pxCurrentTCB, R15
MOV.L [ R15 ], R15
MOV.L R0, [ R15 ]
/* Ensure the interrupt mask is set to the syscall priority while the kernel
* structures are being accessed. */
MVTIPL # configMAX_SYSCALL_INTERRUPT_PRIORITY
structures are being accessed. */
MVTIPL #configMAX_SYSCALL_INTERRUPT_PRIORITY
/* Select the next task to run. */
BSR.A _vTaskSwitchContext
BSR.A _vTaskSwitchContext
/* Reset the interrupt mask as no more data structure access is required. */
MVTIPL # configKERNEL_INTERRUPT_PRIORITY
MVTIPL #configKERNEL_INTERRUPT_PRIORITY
/* Load the stack pointer of the task that is now selected as the Running
* state task from its TCB. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L[ R15 ], R0
state task from its TCB. */
MOV.L #_pxCurrentTCB,R15
MOV.L [ R15 ], R15
MOV.L [ R15 ], R0
/* Restore the context of the new task. The PSW (Program Status Word) and
* PC will be popped by the RTE instruction. */
POP R15
MVTACLO R15, A0 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15, A0 /* Accumulator high 32 bits. */
POP R15
MVTACGU R15, A0 /* Accumulator guard. */
POP R15
MVTACLO R15, A1 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15, A1 /* Accumulator high 32 bits. */
POP R15
MVTACGU R15, A1 /* Accumulator guard. */
POP R15
MVTC R15, FPSW
POPM R1 - R15
PC will be popped by the RTE instruction. */
POP R15
MVTACLO R15, A0 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15, A0 /* Accumulator high 32 bits. */
POP R15
MVTACGU R15, A0 /* Accumulator guard. */
POP R15
MVTACLO R15, A1 /* Accumulator low 32 bits. */
POP R15
MVTACHI R15, A1 /* Accumulator high 32 bits. */
POP R15
MVTACGU R15, A1 /* Accumulator guard. */
POP R15
MVTC R15,FPSW
POPM R1-R15
RTE
NOP
NOP
NOP
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */
Artificially force an assert. */
configASSERT( pxCurrentTCB == NULL );
/* The following line is just to prevent the symbol getting optimised away. */

View file

@ -50,94 +50,94 @@
*/
/* Type definitions - these are a bit legacy and not really used now, other than
* portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop()
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop()
#pragma inline_asm vPortYield
static void vPortYield( void )
{
/* Save clobbered register - may not actually be necessary if inline asm
* functions are considered to use the same rules as function calls by the
* compiler. */
functions are considered to use the same rules as function calls by the
compiler. */
PUSH.L R5
/* Set ITU SWINTR. */
MOV.L # 553696, R5
MOV.B # 1, [ R5 ]
MOV.L #553696, R5
MOV.B #1, [R5]
/* Read back to ensure the value is taken before proceeding. */
MOV.L[ R5 ], R5
MOV.L [R5], R5
/* Restore clobbered register to its previous value. */
POP R5
}
#define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) portYIELD( ); } while( 0 )
#define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) portYIELD(); } while( 0 )
/* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
* performed if configASSERT() is defined to ensure an assertion handler does not
* inadvertently attempt to lower the IPL when the call to assert was triggered
* because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
* when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
* functions are those that end in FromISR. FreeRTOS maintains a separate
* interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
performed if configASSERT() is defined to ensure an assertion handler does not
inadvertently attempt to lower the IPL when the call to assert was triggered
because the IPL value was found to be above configMAX_SYSCALL_INTERRUPT_PRIORITY
when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
functions are those that end in FromISR. FreeRTOS maintains a separate
interrupt API to ensure API function and interrupt entry is as fast and as
simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
#ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif
/* Critical nesting counts are stored in the TCB. */
#define portCRITICAL_NESTING_IN_TCB ( 1 )
#define portCRITICAL_NESTING_IN_TCB ( 1 )
/* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */
#define portSET_INTERRUPT_MASK_FROM_ISR() ( UBaseType_t ) get_ipl(); set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( long ) uxSavedInterruptStatus )
#define portSET_INTERRUPT_MASK_FROM_ISR() ( UBaseType_t ) get_ipl(); set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( long ) uxSavedInterruptStatus )
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/* *INDENT-OFF* */
#ifdef __cplusplus

View file

@ -54,22 +54,22 @@
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore
* PSW is set with U and I set, and PM and IPL clear. */
#define portINITIAL_PSW ( ( StackType_t ) 0x00030000 )
#define portINITIAL_FPSW ( ( StackType_t ) 0x00000100 )
#define portINITIAL_DPSW ( ( StackType_t ) 0x00000100 )
#define portINITIAL_DCMR ( ( StackType_t ) 0x00000000 )
#define portINITIAL_DECNT ( ( StackType_t ) 0x00000001 )
#define portINITIAL_PSW ( ( StackType_t ) 0x00030000 )
#define portINITIAL_FPSW ( ( StackType_t ) 0x00000100 )
#define portINITIAL_DPSW ( ( StackType_t ) 0x00000100 )
#define portINITIAL_DCMR ( ( StackType_t ) 0x00000000 )
#define portINITIAL_DECNT ( ( StackType_t ) 0x00000001 )
/* Tasks are not created with a DPFPU context, but can be given a DPFPU context
* after they have been created. A variable is stored as part of the tasks context
* that holds portNO_DPFPU_CONTEXT if the task does not have a DPFPU context, or
* any other value if the task does have a DPFPU context. */
#define portNO_DPFPU_CONTEXT ( ( StackType_t ) 0 )
#define portHAS_DPFPU_CONTEXT ( ( StackType_t ) 1 )
#define portNO_DPFPU_CONTEXT ( ( StackType_t ) 0 )
#define portHAS_DPFPU_CONTEXT ( ( StackType_t ) 1 )
/* The space on the stack required to hold the DPFPU data registers. This is 16
* 64-bit registers. */
#define portDPFPU_DATA_REGISTER_WORDS ( 16 * 2 )
#define portDPFPU_DATA_REGISTER_WORDS ( 16 * 2 )
/*-----------------------------------------------------------*/
@ -144,41 +144,41 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
* value. Otherwise code space can be saved by just setting the registers
* that need to be set. */
#ifdef USE_FULL_REGISTER_INITIALISATION
{
pxTopOfStack--;
*pxTopOfStack = 0xffffffff; /* r15. */
pxTopOfStack--;
*pxTopOfStack = 0xeeeeeeee;
pxTopOfStack--;
*pxTopOfStack = 0xdddddddd;
pxTopOfStack--;
*pxTopOfStack = 0xcccccccc;
pxTopOfStack--;
*pxTopOfStack = 0xbbbbbbbb;
pxTopOfStack--;
*pxTopOfStack = 0xaaaaaaaa;
pxTopOfStack--;
*pxTopOfStack = 0x99999999;
pxTopOfStack--;
*pxTopOfStack = 0x88888888;
pxTopOfStack--;
*pxTopOfStack = 0x77777777;
pxTopOfStack--;
*pxTopOfStack = 0x66666666;
pxTopOfStack--;
*pxTopOfStack = 0x55555555;
pxTopOfStack--;
*pxTopOfStack = 0x44444444;
pxTopOfStack--;
*pxTopOfStack = 0x33333333;
pxTopOfStack--;
*pxTopOfStack = 0x22222222;
pxTopOfStack--;
}
{
pxTopOfStack--;
*pxTopOfStack = 0xffffffff; /* r15. */
pxTopOfStack--;
*pxTopOfStack = 0xeeeeeeee;
pxTopOfStack--;
*pxTopOfStack = 0xdddddddd;
pxTopOfStack--;
*pxTopOfStack = 0xcccccccc;
pxTopOfStack--;
*pxTopOfStack = 0xbbbbbbbb;
pxTopOfStack--;
*pxTopOfStack = 0xaaaaaaaa;
pxTopOfStack--;
*pxTopOfStack = 0x99999999;
pxTopOfStack--;
*pxTopOfStack = 0x88888888;
pxTopOfStack--;
*pxTopOfStack = 0x77777777;
pxTopOfStack--;
*pxTopOfStack = 0x66666666;
pxTopOfStack--;
*pxTopOfStack = 0x55555555;
pxTopOfStack--;
*pxTopOfStack = 0x44444444;
pxTopOfStack--;
*pxTopOfStack = 0x33333333;
pxTopOfStack--;
*pxTopOfStack = 0x22222222;
pxTopOfStack--;
}
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */
{
pxTopOfStack -= 15;
}
{
pxTopOfStack -= 15;
}
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */
@ -198,73 +198,73 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = 0x66666666; /* Accumulator 0. */
#if ( configUSE_TASK_DPFPU_SUPPORT == 1 )
{
/* The task will start without a DPFPU context. A task that
* uses the DPFPU hardware must call vPortTaskUsesDPFPU() before
* executing any floating point instructions. */
pxTopOfStack--;
*pxTopOfStack = portNO_DPFPU_CONTEXT;
}
{
/* The task will start without a DPFPU context. A task that
* uses the DPFPU hardware must call vPortTaskUsesDPFPU() before
* executing any floating point instructions. */
pxTopOfStack--;
*pxTopOfStack = portNO_DPFPU_CONTEXT;
}
#elif ( configUSE_TASK_DPFPU_SUPPORT == 2 )
{
/* The task will start with a DPFPU context. Leave enough
* space for the registers - and ensure they are initialised if desired. */
#ifdef USE_FULL_REGISTER_INITIALISATION
{
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 1515.1515; /* DR15. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 1414.1414; /* DR14. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 1313.1313; /* DR13. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 1212.1212; /* DR12. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 1111.1111; /* DR11. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 1010.1010; /* DR10. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 909.0909; /* DR9. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 808.0808; /* DR8. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 707.0707; /* DR7. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 606.0606; /* DR6. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 505.0505; /* DR5. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 404.0404; /* DR4. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 303.0303; /* DR3. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 202.0202; /* DR2. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 101.0101; /* DR1. */
pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 9876.54321; /* DR0. */
/* The task will start with a DPFPU context. Leave enough
* space for the registers - and ensure they are initialised if desired. */
#ifdef USE_FULL_REGISTER_INITIALISATION
{
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 1515.1515; /* DR15. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 1414.1414; /* DR14. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 1313.1313; /* DR13. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 1212.1212; /* DR12. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 1111.1111; /* DR11. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 1010.1010; /* DR10. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 909.0909; /* DR9. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 808.0808; /* DR8. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 707.0707; /* DR7. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 606.0606; /* DR6. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 505.0505; /* DR5. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 404.0404; /* DR4. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 303.0303; /* DR3. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 202.0202; /* DR2. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 101.0101; /* DR1. */
pxTopOfStack -= 2;
*(double *)pxTopOfStack = 9876.54321;/* DR0. */
}
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */
{
pxTopOfStack -= portDPFPU_DATA_REGISTER_WORDS;
memset( pxTopOfStack, 0x00, portDPFPU_DATA_REGISTER_WORDS * sizeof( StackType_t ) );
}
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */
pxTopOfStack--;
*pxTopOfStack = portINITIAL_DECNT; /* DECNT. */
pxTopOfStack--;
*pxTopOfStack = portINITIAL_DCMR; /* DCMR. */
pxTopOfStack--;
*pxTopOfStack = portINITIAL_DPSW; /* DPSW. */
}
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */
{
pxTopOfStack -= portDPFPU_DATA_REGISTER_WORDS;
memset( pxTopOfStack, 0x00, portDPFPU_DATA_REGISTER_WORDS * sizeof( StackType_t ) );
}
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */
pxTopOfStack--;
*pxTopOfStack = portINITIAL_DECNT; /* DECNT. */
pxTopOfStack--;
*pxTopOfStack = portINITIAL_DCMR; /* DCMR. */
pxTopOfStack--;
*pxTopOfStack = portINITIAL_DPSW; /* DPSW. */
}
#elif ( configUSE_TASK_DPFPU_SUPPORT == 0 )
{
/* Omit DPFPU support. */
}
{
/* Omit DPFPU support. */
}
#else /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */
{
#error Invalid configUSE_TASK_DPFPU_SUPPORT setting - configUSE_TASK_DPFPU_SUPPORT must be set to 0, 1, 2, or left undefined.
}
{
#error Invalid configUSE_TASK_DPFPU_SUPPORT setting - configUSE_TASK_DPFPU_SUPPORT must be set to 0, 1, 2, or left undefined.
}
#endif /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */
return pxTopOfStack;
@ -330,74 +330,78 @@ void vPortEndScheduler( void )
#pragma inline_asm prvStartFirstTask
static void prvStartFirstTask( void )
{
#ifndef __CDT_PARSER__
#ifndef __CDT_PARSER__
/* When starting the scheduler there is nothing that needs moving to the
* interrupt stack because the function is not called from an interrupt.
* Just ensure the current stack is the user stack. */
SETPSW U
/* When starting the scheduler there is nothing that needs moving to the
* interrupt stack because the function is not called from an interrupt.
* Just ensure the current stack is the user stack. */
SETPSW U
/* Obtain the location of the stack associated with which ever task
* pxCurrentTCB is currently pointing to. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L[ R15 ], R0
/* Obtain the location of the stack associated with which ever task
* pxCurrentTCB is currently pointing to. */
MOV.L # _pxCurrentTCB, R15
MOV.L [ R15 ], R15
MOV.L [ R15 ], R0
/* Restore the registers from the stack of the task pointed to by
* pxCurrentTCB. */
/* Restore the registers from the stack of the task pointed to by
* pxCurrentTCB. */
#if ( configUSE_TASK_DPFPU_SUPPORT == 1 )
/* The restored ulPortTaskHasDPFPUContext is to be zero here.
* So, it is never necessary to restore the DPFPU context here. */
POP R15
MOV.L # _ulPortTaskHasDPFPUContext, R14
MOV.L R15, [ R14 ]
#elif ( configUSE_TASK_DPFPU_SUPPORT == 2 )
/* Restore the DPFPU context. */
DPOPM.L DPSW - DECNT
DPOPM.D DR0 - DR15
#endif /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */
#if ( configUSE_TASK_DPFPU_SUPPORT == 1 )
/* The restored ulPortTaskHasDPFPUContext is to be zero here.
* So, it is never necessary to restore the DPFPU context here. */
POP R15
MOV.L # _ulPortTaskHasDPFPUContext, R14
MOV.L R15, [ R14 ]
/* Accumulator low 32 bits. */
MVTACLO R15, A0
POP R15
#elif ( configUSE_TASK_DPFPU_SUPPORT == 2 )
/* Accumulator high 32 bits. */
MVTACHI R15, A0
POP R15
/* Restore the DPFPU context. */
DPOPM.L DPSW-DECNT
DPOPM.D DR0-DR15
/* Accumulator guard. */
MVTACGU R15, A0
POP R15
#endif /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */
/* Accumulator low 32 bits. */
MVTACLO R15, A1
POP R15
POP R15
/* Accumulator high 32 bits. */
MVTACHI R15, A1
POP R15
/* Accumulator low 32 bits. */
MVTACLO R15, A0
POP R15
/* Accumulator guard. */
MVTACGU R15, A1
POP R15
/* Accumulator high 32 bits. */
MVTACHI R15, A0
POP R15
/* Floating point status word. */
MVTC R15, FPSW
/* Accumulator guard. */
MVTACGU R15, A0
POP R15
/* R1 to R15 - R0 is not included as it is the SP. */
POPM R1 - R15
/* Accumulator low 32 bits. */
MVTACLO R15, A1
POP R15
/* This pops the remaining registers. */
RTE
NOP
NOP
#endif /* ifndef __CDT_PARSER__ */
/* Accumulator high 32 bits. */
MVTACHI R15, A1
POP R15
/* Accumulator guard. */
MVTACGU R15, A1
POP R15
/* Floating point status word. */
MVTC R15, FPSW
/* R1 to R15 - R0 is not included as it is the SP. */
POPM R1-R15
/* This pops the remaining registers. */
RTE
NOP
NOP
#endif /* ifndef __CDT_PARSER__ */
}
/*-----------------------------------------------------------*/
@ -410,155 +414,163 @@ void vSoftwareInterruptISR( void )
#pragma inline_asm prvYieldHandler
static void prvYieldHandler( void )
{
#ifndef __CDT_PARSER__
/* Re-enable interrupts. */
SETPSW I
#ifndef __CDT_PARSER__
/* Re-enable interrupts. */
SETPSW I
/* Move the data that was automatically pushed onto the interrupt stack when
* the interrupt occurred from the interrupt stack to the user stack.
*
* R15 is saved before it is clobbered. */
/* Move the data that was automatically pushed onto the interrupt stack when
* the interrupt occurred from the interrupt stack to the user stack.
*
* R15 is saved before it is clobbered. */
PUSH.L R15
/* Read the user stack pointer. */
MVFC USP, R15
/* Move the address down to the data being moved. */
SUB # 12, R15
MVTC R15, USP
/* Copy the data across, R15, then PC, then PSW. */
MOV.L [ R0 ], [ R15 ]
MOV.L 4[ R0 ], 4[ R15 ]
MOV.L 8[ R0 ], 8[ R15 ]
/* Move the interrupt stack pointer to its new correct position. */
ADD # 12, R0
/* All the rest of the registers are saved directly to the user stack. */
SETPSW U
/* Save the rest of the general registers (R15 has been saved already). */
PUSHM R1-R14
/* Save the FPSW and accumulators. */
MVFC FPSW, R15
PUSH.L R15
MVFACGU # 0, A1, R15
PUSH.L R15
MVFACHI # 0, A1, R15
PUSH.L R15
MVFACLO # 0, A1, R15 /* Low order word. */
PUSH.L R15
MVFACGU # 0, A0, R15
PUSH.L R15
MVFACHI # 0, A0, R15
PUSH.L R15
MVFACLO # 0, A0, R15 /* Low order word. */
PUSH.L R15
#if ( configUSE_TASK_DPFPU_SUPPORT == 1 )
/* Does the task have a DPFPU context that needs saving? If
* ulPortTaskHasDPFPUContext is 0 then no. */
MOV.L # _ulPortTaskHasDPFPUContext, R15
MOV.L [ R15 ], R15
CMP # 0, R15
/* Save the DPFPU context, if any. */
BEQ.B ?+
DPUSHM.D DR0-DR15
DPUSHM.L DPSW-DECNT
?:
/* Save ulPortTaskHasDPFPUContext itself. */
PUSH.L R15
/* Read the user stack pointer. */
MVFC USP, R15
#elif ( configUSE_TASK_DPFPU_SUPPORT == 2 )
/* Move the address down to the data being moved. */
SUB # 12, R15
MVTC R15, USP
/* Save the DPFPU context, always. */
DPUSHM.D DR0-DR15
DPUSHM.L DPSW-DECNT
/* Copy the data across, R15, then PC, then PSW. */
MOV.L[ R0 ], [ R15 ]
MOV.L 4[ R0 ], 4[ R15 ]
MOV.L 8[ R0 ], 8[ R15 ]
/* Move the interrupt stack pointer to its new correct position. */
ADD # 12, R0
/* All the rest of the registers are saved directly to the user stack. */
SETPSW U
/* Save the rest of the general registers (R15 has been saved already). */
PUSHM R1 - R14
/* Save the FPSW and accumulators. */
MVFC FPSW, R15
PUSH.L R15
MVFACGU # 0, A1, R15
PUSH.L R15
MVFACHI # 0, A1, R15
PUSH.L R15
MVFACLO # 0, A1, R15 /* Low order word. */
PUSH.L R15
MVFACGU # 0, A0, R15
PUSH.L R15
MVFACHI # 0, A0, R15
PUSH.L R15
MVFACLO # 0, A0, R15 /* Low order word. */
PUSH.L R15
#if ( configUSE_TASK_DPFPU_SUPPORT == 1 )
/* Does the task have a DPFPU context that needs saving? If
* ulPortTaskHasDPFPUContext is 0 then no. */
MOV.L # _ulPortTaskHasDPFPUContext, R15
MOV.L[ R15 ], R15
CMP # 0, R15
/* Save the DPFPU context, if any. */
BEQ.B ? +
DPUSHM.D DR0 - DR15
DPUSHM.L DPSW - DECNT
? :
/* Save ulPortTaskHasDPFPUContext itself. */
PUSH.L R15
#elif ( configUSE_TASK_DPFPU_SUPPORT == 2 )
/* Save the DPFPU context, always. */
DPUSHM.D DR0 - DR15
DPUSHM.L DPSW - DECNT
#endif /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */
#endif /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */
/* Save the stack pointer to the TCB. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L R0, [ R15 ]
/* Save the stack pointer to the TCB. */
MOV.L # _pxCurrentTCB, R15
MOV.L [ R15 ], R15
MOV.L R0, [ R15 ]
/* Ensure the interrupt mask is set to the syscall priority while the kernel
* structures are being accessed. */
MVTIPL # configMAX_SYSCALL_INTERRUPT_PRIORITY
/* Ensure the interrupt mask is set to the syscall priority while the kernel
* structures are being accessed. */
MVTIPL # configMAX_SYSCALL_INTERRUPT_PRIORITY
/* Select the next task to run. */
BSR.A _vTaskSwitchContext
/* Select the next task to run. */
BSR.A _vTaskSwitchContext
/* Reset the interrupt mask as no more data structure access is required. */
MVTIPL # configKERNEL_INTERRUPT_PRIORITY
/* Reset the interrupt mask as no more data structure access is required. */
MVTIPL # configKERNEL_INTERRUPT_PRIORITY
/* Load the stack pointer of the task that is now selected as the Running
* state task from its TCB. */
MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15
MOV.L[ R15 ], R0
/* Load the stack pointer of the task that is now selected as the Running
* state task from its TCB. */
MOV.L # _pxCurrentTCB, R15
MOV.L [ R15 ], R15
MOV.L [ R15 ], R0
/* Restore the context of the new task. The PSW (Program Status Word) and
* PC will be popped by the RTE instruction. */
/* Restore the context of the new task. The PSW (Program Status Word) and
* PC will be popped by the RTE instruction. */
#if ( configUSE_TASK_DPFPU_SUPPORT == 1 )
/* Is there a DPFPU context to restore? If the restored
* ulPortTaskHasDPFPUContext is zero then no. */
POP R15
MOV.L # _ulPortTaskHasDPFPUContext, R14
MOV.L R15, [ R14 ]
CMP # 0, R15
/* Restore the DPFPU context, if any. */
BEQ.B ? +
DPOPM.L DPSW - DECNT
DPOPM.D DR0 - DR15
? :
#elif ( configUSE_TASK_DPFPU_SUPPORT == 2 )
/* Restore the DPFPU context, always. */
DPOPM.L DPSW - DECNT
DPOPM.D DR0 - DR15
#endif /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */
#if ( configUSE_TASK_DPFPU_SUPPORT == 1 )
/* Is there a DPFPU context to restore? If the restored
* ulPortTaskHasDPFPUContext is zero then no. */
POP R15
MOV.L # _ulPortTaskHasDPFPUContext, R14
MOV.L R15, [ R14 ]
CMP # 0, R15
/* Accumulator low 32 bits. */
MVTACLO R15, A0
POP R15
/* Restore the DPFPU context, if any. */
BEQ.B ?+
DPOPM.L DPSW-DECNT
DPOPM.D DR0-DR15
?:
/* Accumulator high 32 bits. */
MVTACHI R15, A0
POP R15
#elif ( configUSE_TASK_DPFPU_SUPPORT == 2 )
/* Accumulator guard. */
MVTACGU R15, A0
POP R15
/* Restore the DPFPU context, always. */
DPOPM.L DPSW-DECNT
DPOPM.D DR0-DR15
/* Accumulator low 32 bits. */
MVTACLO R15, A1
POP R15
#endif /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */
/* Accumulator high 32 bits. */
MVTACHI R15, A1
POP R15
POP R15
/* Accumulator guard. */
MVTACGU R15, A1
POP R15
MVTC R15, FPSW
POPM R1 - R15
RTE
NOP
NOP
#endif /* ifndef __CDT_PARSER__ */
/* Accumulator low 32 bits. */
MVTACLO R15, A0
POP R15
/* Accumulator high 32 bits. */
MVTACHI R15, A0
POP R15
/* Accumulator guard. */
MVTACGU R15, A0
POP R15
/* Accumulator low 32 bits. */
MVTACLO R15, A1
POP R15
/* Accumulator high 32 bits. */
MVTACHI R15, A1
POP R15
/* Accumulator guard. */
MVTACGU R15, A1
POP R15
MVTC R15, FPSW
POPM R1-R15
RTE
NOP
NOP
#endif /* ifndef __CDT_PARSER__ */
}
/*-----------------------------------------------------------*/

View file

@ -28,7 +28,7 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#define PORTMACRO_H
/* *INDENT-OFF* */
#ifdef __cplusplus
@ -37,7 +37,7 @@
/* *INDENT-ON* */
/* Hardware specifics. */
#include <machine.h>
#include <machine.h>
/*-----------------------------------------------------------
* Port specific definitions.
@ -51,9 +51,9 @@
/* When the FIT configurator or the Smart Configurator is used, platform.h has to be
* used. */
#ifndef configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H
#define configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H 0
#endif
#ifndef configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H
#define configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H 0
#endif
/* If configUSE_TASK_DPFPU_SUPPORT is set to 1 (or undefined) then each task will
* be created without a DPFPU context, and a task must call vTaskUsesDPFPU() before
@ -61,73 +61,72 @@
* tasks are created with a DPFPU context by default, and calling vTaskUsesDPFPU() has
* no effect. If configUSE_TASK_DPFPU_SUPPORT is set to 0 then tasks never take care
* of any DPFPU context (even if DPFPU registers are used). */
#ifndef configUSE_TASK_DPFPU_SUPPORT
#define configUSE_TASK_DPFPU_SUPPORT 1
#endif
#ifndef configUSE_TASK_DPFPU_SUPPORT
#define configUSE_TASK_DPFPU_SUPPORT 1
#endif
/*-----------------------------------------------------------*/
/* Type definitions - these are a bit legacy and not really used now, other than
* portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
* not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif
#define portTICK_TYPE_IS_ATOMIC 1
#else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif
/*-----------------------------------------------------------*/
/* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop()
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop()
/* Yield equivalent to "*portITU_SWINTR = 0x01; ( void ) *portITU_SWINTR;"
* where portITU_SWINTR is the location of the software interrupt register
* (0x000872E0). Don't rely on the assembler to select a register, so instead
* save and restore clobbered registers manually. */
#pragma inline_asm vPortYield
static void vPortYield( void )
{
#pragma inline_asm vPortYield
static void vPortYield( void )
{
#ifndef __CDT_PARSER__
/* Save clobbered register - may not actually be necessary if inline asm
* functions are considered to use the same rules as function calls by the
* compiler. */
PUSH.L R5
/* Set ITU SWINTR. */
MOV.L # 000 872E0H, R5
MOV.B # 1, [ R5 ]
MOV.L # 000872E0H, R5
MOV.B # 1, [ R5 ]
/* Read back to ensure the value is taken before proceeding. */
CMP[ R5 ].UB, R5
CMP [ R5 ].UB, R5
/* Restore clobbered register to its previous value. */
POP R5
#endif /* ifndef __CDT_PARSER__ */
}
#endif
}
#define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( ( x ) != pdFALSE ) portYIELD( ); } while( 0 )
#define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( ( x ) != pdFALSE ) portYIELD(); } while( 0 )
/* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
@ -138,32 +137,32 @@ static void vPortYield( void )
* functions are those that end in FromISR. FreeRTOS maintains a separate
* interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
#ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
#ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
#define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif
/* Critical nesting counts are stored in the TCB. */
#define portCRITICAL_NESTING_IN_TCB ( 1 )
#define portCRITICAL_NESTING_IN_TCB ( 1 )
/* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */
#define portSET_INTERRUPT_MASK_FROM_ISR() ( UBaseType_t ) get_ipl(); set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( long ) uxSavedInterruptStatus )
#define portSET_INTERRUPT_MASK_FROM_ISR() ( UBaseType_t ) get_ipl(); set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( long ) uxSavedInterruptStatus )
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/
@ -172,18 +171,17 @@ extern void vTaskExitCritical( void );
* themselves a DPFPU context before using any DPFPU instructions. If
* configUSE_TASK_DPFPU_SUPPORT is set to 2 then all tasks will have a DPFPU context
* by default. */
#if ( configUSE_TASK_DPFPU_SUPPORT == 1 )
void vPortTaskUsesDPFPU( void );
#else
#if( configUSE_TASK_DPFPU_SUPPORT == 1 )
void vPortTaskUsesDPFPU( void );
#else
/* Each task has a DPFPU context already, so define this function away to
* nothing to prevent it being called accidentally. */
#define vPortTaskUsesDPFPU()
#endif
#define portTASK_USES_DPFPU() vPortTaskUsesDPFPU()
#define vPortTaskUsesDPFPU()
#endif
#define portTASK_USES_DPFPU() vPortTaskUsesDPFPU()
/* Definition to allow compatibility with existing FreeRTOS Demo using flop.c. */
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesDPFPU()
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesDPFPU()
/* *INDENT-OFF* */
#ifdef __cplusplus