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

View file

@ -50,87 +50,87 @@
*/ */
/* Type definitions - these are a bit legacy and not really used now, other /* Type definitions - these are a bit legacy and not really used now, other
* than portSTACK_TYPE and portBASE_TYPE. */ than portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char #define portCHAR char
#define portFLOAT float #define portFLOAT float
#define portDOUBLE double #define portDOUBLE double
#define portLONG long #define portLONG long
#define portSHORT short #define portSHORT short
#define portSTACK_TYPE uint32_t #define portSTACK_TYPE uint32_t
#define portBASE_TYPE long #define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t; typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t; typedef long BaseType_t;
typedef unsigned long UBaseType_t; typedef unsigned long UBaseType_t;
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) #if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t; typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff #define portMAX_DELAY ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 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. */ not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#else #else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Hardware specifics. */ /* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */ #define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1 #define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop() #define portNOP() nop()
#pragma inline_asm vPortYield #pragma inline_asm vPortYield
static void vPortYield( void ) static void vPortYield( void )
{ {
/* Save clobbered register - may not actually be necessary if inline asm /* Save clobbered register - may not actually be necessary if inline asm
* functions are considered to use the same rules as function calls by the functions are considered to use the same rules as function calls by the
* compiler. */ compiler. */
PUSH.L R5 PUSH.L R5
/* Set ITU SWINTR. */ /* Set ITU SWINTR. */
MOV.L # 872E0H, R5 MOV.L #872E0H, R5
MOV.B # 1, [ R5 ] MOV.B #1, [R5]
/* Read back to ensure the value is taken before proceeding. */ /* 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. */ /* Restore clobbered register to its previous value. */
POP R5 POP R5
} }
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) { portYIELD(); } } while( 0 ) #define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) { portYIELD(); } } while( 0 )
/* These macros should not be called directly, but through the /* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
* performed if configASSERT() is defined to ensure an assertion handler does not 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 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 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 when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
* functions are those that end in FromISR. FreeRTOS maintains a separate 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 interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */ simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 ) #define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
#ifdef configASSERT #ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= 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 ) #define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else #else
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif #endif
/* Critical nesting counts are stored in the TCB. */ /* 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. */ /* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void ); extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void ); extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical() #define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical() #define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */ /* 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 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 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( signed long ) uxSavedInterruptStatus )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -138,15 +138,15 @@ extern void vTaskExitCritical( void );
#if configUSE_TICKLESS_IDLE == 1 #if configUSE_TICKLESS_IDLE == 1
#ifndef portSUPPRESS_TICKS_AND_SLEEP #ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif #endif
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */ /* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( 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 ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #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. */ /* Scheduler includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
@ -43,14 +43,14 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore /* 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_PSW ( ( StackType_t ) 0x00030000 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following lines are to ensure vSoftwareInterruptEntry can be referenced, /* The following lines are to ensure vSoftwareInterruptEntry can be referenced,
* and therefore installed in the vector table, when the FreeRTOS code is built and therefore installed in the vector table, when the FreeRTOS code is built
* as a library. */ as a library. */
extern BaseType_t vSoftwareInterruptEntry; extern BaseType_t vSoftwareInterruptEntry;
const BaseType_t * p_vSoftwareInterruptEntry = &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 /* This is accessed by the inline assembler functions so is file scope for
* convenience. */ convenience. */
extern void * pxCurrentTCB; extern void *pxCurrentTCB;
extern void vTaskSwitchContext( void ); extern void vTaskSwitchContext( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -89,9 +89,7 @@ extern void vTaskSwitchContext( void );
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
TaskFunction_t pxCode,
void * pvParameters )
{ {
/* Offset to end up on 8 byte boundary. */ /* Offset to end up on 8 byte boundary. */
pxTopOfStack--; pxTopOfStack--;
@ -106,8 +104,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) pxCode; *pxTopOfStack = ( StackType_t ) pxCode;
/* When debugging it can be useful if every register is set to a known /* 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 value. Otherwise code space can be saved by just setting the registers
* that need to be set. */ that need to be set. */
#ifdef USE_FULL_REGISTER_INITIALISATION #ifdef USE_FULL_REGISTER_INITIALISATION
{ {
pxTopOfStack--; pxTopOfStack--;
@ -140,17 +138,17 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = 0x22222222; *pxTopOfStack = 0x22222222;
pxTopOfStack--; pxTopOfStack--;
} }
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */ #else
{ {
pxTopOfStack -= 15; pxTopOfStack -= 15;
} }
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */ #endif
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x12345678; /* Accumulator. */ *pxTopOfStack = 0x12345678; /* Accumulator. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x87654321; /* Accumulator. */ *pxTopOfStack = 0x87654321; /* Accumulator. */
return pxTopOfStack; return pxTopOfStack;
} }
@ -158,14 +156,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
extern void vApplicationSetupTimerInterrupt( void ); extern void vApplicationSetupTimerInterrupt( void );
/* Use pxCurrentTCB just so it does not get optimised away. */ /* Use pxCurrentTCB just so it does not get optimised away. */
if( pxCurrentTCB != NULL ) if( pxCurrentTCB != NULL )
{ {
/* Call an application function to set up the timer that will generate the /* Call an application function to set up the timer that will generate the
* tick interrupt. This way the application can decide which peripheral to tick interrupt. This way the application can decide which peripheral to
* use. A demo application is provided to show a suitable example. */ use. A demo application is provided to show a suitable example. */
vApplicationSetupTimerInterrupt(); vApplicationSetupTimerInterrupt();
/* Enable the software interrupt. */ /* Enable the software interrupt. */
@ -193,26 +191,26 @@ BaseType_t xPortStartScheduler( void )
static void prvStartFirstTask( void ) static void prvStartFirstTask( void )
{ {
/* When starting the scheduler there is nothing that needs moving to the /* When starting the scheduler there is nothing that needs moving to the
* interrupt stack because the function is not called from an interrupt. interrupt stack because the function is not called from an interrupt.
* Just ensure the current stack is the user stack. */ Just ensure the current stack is the user stack. */
SETPSW U SETPSW U
/* Obtain the location of the stack associated with which ever task /* Obtain the location of the stack associated with which ever task
* pxCurrentTCB is currently pointing to. */ pxCurrentTCB is currently pointing to. */
MOV.L # _pxCurrentTCB, R15 MOV.L #_pxCurrentTCB, R15
MOV.L[ R15 ], R15 MOV.L [R15], R15
MOV.L[ R15 ], R0 MOV.L [R15], R0
/* Restore the registers from the stack of the task pointed to by /* Restore the registers from the stack of the task pointed to by
* pxCurrentTCB. */ pxCurrentTCB. */
POP R15 POP R15
MVTACLO R15 /* Accumulator low 32 bits. */ MVTACLO R15 /* Accumulator low 32 bits. */
POP R15 POP R15
MVTACHI R15 /* Accumulator high 32 bits. */ MVTACHI R15 /* Accumulator high 32 bits. */
POPM R1 - R15 /* R1 to R15 - R0 is not included as it is the SP. */ POPM R1-R15 /* R1 to R15 - R0 is not included as it is the SP. */
RTE /* This pops the remaining registers. */ RTE /* This pops the remaining registers. */
NOP
NOP NOP
NOP
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -220,7 +218,7 @@ static void prvStartFirstTask( void )
void vTickISR( void ) void vTickISR( void )
{ {
/* Increment the tick, and perform any processing the new tick value /* Increment the tick, and perform any processing the new tick value
* necessitates. */ necessitates. */
set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY ); set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY );
{ {
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
@ -228,7 +226,6 @@ void vTickISR( void )
taskYIELD(); taskYIELD();
} }
} }
set_ipl( configKERNEL_INTERRUPT_PRIORITY ); set_ipl( configKERNEL_INTERRUPT_PRIORITY );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -243,86 +240,80 @@ void vSoftwareInterruptISR( void )
static void prvYieldHandler( void ) static void prvYieldHandler( void )
{ {
/* Re-enable interrupts. */ /* Re-enable interrupts. */
SETPSW I SETPSW I
/* Move the data that was automatically pushed onto the interrupt stack when /* Move the data that was automatically pushed onto the interrupt stack when
* the interrupt occurred from the interrupt stack to the user stack. the interrupt occurred from the interrupt stack to the user stack.
*
* R15 is saved before it is clobbered. */ R15 is saved before it is clobbered. */
PUSH.L R15 PUSH.L R15
/* Read the user stack pointer. */ /* Read the user stack pointer. */
MVFC USP, R15 MVFC USP, R15
/* Move the address down to the data being moved. */ /* Move the address down to the data being moved. */
SUB # 12, R15 SUB #12, R15
MVTC R15, USP MVTC R15, USP
/* Copy the data across. */ /* Copy the data across. */
MOV.L[ R0 ], [ R15 ]; MOV.L [ R0 ], [ R15 ] ; R15
R15 MOV.L 4[ R0 ], 4[ R15 ] ; PC
MOV.L 8[ R0 ], 8[ R15 ] ; PSW
MOV.L 4[ R0 ], 4[ R15 ];
PC
MOV.L 8[ R0 ], 8[ R15 ];
PSW
/* Move the interrupt stack pointer to its new correct position. */ /* 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. */ /* 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). */ /* Save the rest of the general registers (R15 has been saved already). */
PUSHM R1 - R14 PUSHM R1-R14
/* Save the accumulator. */ /* Save the accumulator. */
MVFACHI R15 MVFACHI R15
PUSH.L R15 PUSH.L R15
MVFACMI R15; MVFACMI R15 ; Middle order word.
Middle order word. SHLL #16, R15 ; Shifted left as it is restored to the low order word.
SHLL # 16, R15; PUSH.L R15
Shifted left as it is restored to the low order word.
PUSH.L R15
/* Save the stack pointer to the TCB. */ /* Save the stack pointer to the TCB. */
MOV.L # _pxCurrentTCB, R15 MOV.L #_pxCurrentTCB, R15
MOV.L[ R15 ], R15 MOV.L [ R15 ], R15
MOV.L R0, [ R15 ] MOV.L R0, [ R15 ]
/* Ensure the interrupt mask is set to the syscall priority while the kernel /* Ensure the interrupt mask is set to the syscall priority while the kernel
* structures are being accessed. */ structures are being accessed. */
MVTIPL # configMAX_SYSCALL_INTERRUPT_PRIORITY MVTIPL #configMAX_SYSCALL_INTERRUPT_PRIORITY
/* Select the next task to run. */ /* Select the next task to run. */
BSR.A _vTaskSwitchContext BSR.A _vTaskSwitchContext
/* Reset the interrupt mask as no more data structure access is required. */ /* 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 /* Load the stack pointer of the task that is now selected as the Running
* state task from its TCB. */ state task from its TCB. */
MOV.L # _pxCurrentTCB, R15 MOV.L #_pxCurrentTCB,R15
MOV.L[ R15 ], R15 MOV.L [ R15 ], R15
MOV.L[ R15 ], R0 MOV.L [ R15 ], R0
/* Restore the context of the new task. The PSW (Program Status Word) and /* Restore the context of the new task. The PSW (Program Status Word) and
* PC will be popped by the RTE instruction. */ PC will be popped by the RTE instruction. */
POP R15 POP R15
MVTACLO R15 MVTACLO R15
POP R15 POP R15
MVTACHI R15 MVTACHI R15
POPM R1 - R15 POPM R1-R15
RTE RTE
NOP NOP
NOP NOP
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */ Artificially force an assert. */
configASSERT( pxCurrentTCB == NULL ); configASSERT( pxCurrentTCB == NULL );
/* The following line is just to prevent the symbol getting optimised away. */ /* 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 /* Type definitions - these are a bit legacy and not really used now, other than
* portSTACK_TYPE and portBASE_TYPE. */ portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char #define portCHAR char
#define portFLOAT float #define portFLOAT float
#define portDOUBLE double #define portDOUBLE double
#define portLONG long #define portLONG long
#define portSHORT short #define portSHORT short
#define portSTACK_TYPE uint32_t #define portSTACK_TYPE uint32_t
#define portBASE_TYPE long #define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t; typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t; typedef long BaseType_t;
typedef unsigned long UBaseType_t; typedef unsigned long UBaseType_t;
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) #if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t; typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff #define portMAX_DELAY ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 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. */ not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#else #else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Hardware specifics. */ /* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */ #define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1 #define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop() #define portNOP() nop()
#pragma inline_asm vPortYield #pragma inline_asm vPortYield
static void vPortYield( void ) static void vPortYield( void )
{ {
/* Save clobbered register - may not actually be necessary if inline asm /* Save clobbered register - may not actually be necessary if inline asm
* functions are considered to use the same rules as function calls by the functions are considered to use the same rules as function calls by the
* compiler. */ compiler. */
PUSH.L R5 PUSH.L R5
/* Set ITU SWINTR. */ /* Set ITU SWINTR. */
MOV.L # 553696, R5 MOV.L #553696, R5
MOV.B # 1, [ R5 ] MOV.B #1, [R5]
/* Read back to ensure the value is taken before proceeding. */ /* 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. */ /* Restore clobbered register to its previous value. */
POP R5 POP R5
} }
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) portYIELD( ); } while( 0 ) #define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) portYIELD(); } while( 0 )
/* These macros should not be called directly, but through the /* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
* performed if configASSERT() is defined to ensure an assertion handler does not 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 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 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 when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
* functions are those that end in FromISR. FreeRTOS maintains a separate 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 interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */ simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 ) #define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
#ifdef configASSERT #ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= 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 ) #define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else #else
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif #endif
/* Critical nesting counts are stored in the TCB. */ /* 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. */ /* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void ); extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void ); extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical() #define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical() #define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */ /* As this port allows interrupt nesting... */
#define portSET_INTERRUPT_MASK_FROM_ISR() get_ipl(); set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #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 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( long ) uxSavedInterruptStatus )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */ /* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( 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 ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #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. */ /* Scheduler includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
@ -43,15 +43,15 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore /* 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_PSW ( ( StackType_t ) 0x00030000 )
#define portINITIAL_FPSW ( ( StackType_t ) 0x00000100 ) #define portINITIAL_FPSW ( ( StackType_t ) 0x00000100 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following lines are to ensure vSoftwareInterruptEntry can be referenced, /* The following lines are to ensure vSoftwareInterruptEntry can be referenced,
* and therefore installed in the vector table, when the FreeRTOS code is built and therefore installed in the vector table, when the FreeRTOS code is built
* as a library. */ as a library. */
extern BaseType_t vSoftwareInterruptEntry; extern BaseType_t vSoftwareInterruptEntry;
const BaseType_t * p_vSoftwareInterruptEntry = &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 /* This is accessed by the inline assembler functions so is file scope for
* convenience. */ convenience. */
extern void * pxCurrentTCB; extern void *pxCurrentTCB;
extern void vTaskSwitchContext( void ); extern void vTaskSwitchContext( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -90,9 +90,7 @@ extern void vTaskSwitchContext( void );
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
TaskFunction_t pxCode,
void * pvParameters )
{ {
/* R0 is not included as it is the stack pointer. */ /* R0 is not included as it is the stack pointer. */
@ -103,8 +101,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) pxCode; *pxTopOfStack = ( StackType_t ) pxCode;
/* When debugging it can be useful if every register is set to a known /* 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 value. Otherwise code space can be saved by just setting the registers
* that need to be set. */ that need to be set. */
#ifdef USE_FULL_REGISTER_INITIALISATION #ifdef USE_FULL_REGISTER_INITIALISATION
{ {
pxTopOfStack--; pxTopOfStack--;
@ -137,11 +135,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = 0x22222222; *pxTopOfStack = 0x22222222;
pxTopOfStack--; pxTopOfStack--;
} }
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */ #else
{ {
pxTopOfStack -= 15; pxTopOfStack -= 15;
} }
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */ #endif
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */
pxTopOfStack--; pxTopOfStack--;
@ -157,14 +155,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
extern void vApplicationSetupTimerInterrupt( void ); extern void vApplicationSetupTimerInterrupt( void );
/* Use pxCurrentTCB just so it does not get optimised away. */ /* Use pxCurrentTCB just so it does not get optimised away. */
if( pxCurrentTCB != NULL ) if( pxCurrentTCB != NULL )
{ {
/* Call an application function to set up the timer that will generate the /* Call an application function to set up the timer that will generate the
* tick interrupt. This way the application can decide which peripheral to tick interrupt. This way the application can decide which peripheral to
* use. A demo application is provided to show a suitable example. */ use. A demo application is provided to show a suitable example. */
vApplicationSetupTimerInterrupt(); vApplicationSetupTimerInterrupt();
/* Enable the software interrupt. */ /* Enable the software interrupt. */
@ -192,28 +190,28 @@ BaseType_t xPortStartScheduler( void )
static void prvStartFirstTask( void ) static void prvStartFirstTask( void )
{ {
/* When starting the scheduler there is nothing that needs moving to the /* When starting the scheduler there is nothing that needs moving to the
* interrupt stack because the function is not called from an interrupt. interrupt stack because the function is not called from an interrupt.
* Just ensure the current stack is the user stack. */ Just ensure the current stack is the user stack. */
SETPSW U SETPSW U
/* Obtain the location of the stack associated with which ever task /* Obtain the location of the stack associated with which ever task
* pxCurrentTCB is currently pointing to. */ pxCurrentTCB is currently pointing to. */
MOV.L # _pxCurrentTCB, R15 MOV.L #_pxCurrentTCB, R15
MOV.L[ R15 ], R15 MOV.L [R15], R15
MOV.L[ R15 ], R0 MOV.L [R15], R0
/* Restore the registers from the stack of the task pointed to by /* Restore the registers from the stack of the task pointed to by
* pxCurrentTCB. */ pxCurrentTCB. */
POP R15 POP R15
MVTACLO R15 /* Accumulator low 32 bits. */ MVTACLO R15 /* Accumulator low 32 bits. */
POP R15 POP R15
MVTACHI R15 /* Accumulator high 32 bits. */ MVTACHI R15 /* Accumulator high 32 bits. */
POP R15 POP R15
MVTC R15, FPSW /* Floating point status word. */ MVTC R15,FPSW /* Floating point status word. */
POPM R1 - R15 /* R1 to R15 - R0 is not included as it is the SP. */ POPM R1-R15 /* R1 to R15 - R0 is not included as it is the SP. */
RTE /* This pops the remaining registers. */ RTE /* This pops the remaining registers. */
NOP
NOP NOP
NOP
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -221,7 +219,7 @@ static void prvStartFirstTask( void )
void vTickISR( void ) void vTickISR( void )
{ {
/* Increment the tick, and perform any processing the new tick value /* Increment the tick, and perform any processing the new tick value
* necessitates. */ necessitates. */
set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY ); set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY );
{ {
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
@ -229,7 +227,6 @@ void vTickISR( void )
taskYIELD(); taskYIELD();
} }
} }
set_ipl( configKERNEL_INTERRUPT_PRIORITY ); set_ipl( configKERNEL_INTERRUPT_PRIORITY );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -244,90 +241,84 @@ void vSoftwareInterruptISR( void )
static void prvYieldHandler( void ) static void prvYieldHandler( void )
{ {
/* Re-enable interrupts. */ /* Re-enable interrupts. */
SETPSW I SETPSW I
/* Move the data that was automatically pushed onto the interrupt stack when /* Move the data that was automatically pushed onto the interrupt stack when
* the interrupt occurred from the interrupt stack to the user stack. the interrupt occurred from the interrupt stack to the user stack.
*
* R15 is saved before it is clobbered. */ R15 is saved before it is clobbered. */
PUSH.L R15 PUSH.L R15
/* Read the user stack pointer. */ /* Read the user stack pointer. */
MVFC USP, R15 MVFC USP, R15
/* Move the address down to the data being moved. */ /* Move the address down to the data being moved. */
SUB # 12, R15 SUB #12, R15
MVTC R15, USP MVTC R15, USP
/* Copy the data across. */ /* Copy the data across. */
MOV.L[ R0 ], [ R15 ]; MOV.L [ R0 ], [ R15 ] ; R15
R15 MOV.L 4[ R0 ], 4[ R15 ] ; PC
MOV.L 8[ R0 ], 8[ R15 ] ; PSW
MOV.L 4[ R0 ], 4[ R15 ];
PC
MOV.L 8[ R0 ], 8[ R15 ];
PSW
/* Move the interrupt stack pointer to its new correct position. */ /* 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. */ /* 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). */ /* Save the rest of the general registers (R15 has been saved already). */
PUSHM R1 - R14 PUSHM R1-R14
/* Save the FPSW and accumulator. */ /* Save the FPSW and accumulator. */
MVFC FPSW, R15 MVFC FPSW, R15
PUSH.L R15 PUSH.L R15
MVFACHI R15 MVFACHI R15
PUSH.L R15 PUSH.L R15
MVFACMI R15; MVFACMI R15 ; Middle order word.
Middle order word. SHLL #16, R15 ; Shifted left as it is restored to the low order word.
SHLL # 16, R15; PUSH.L R15
Shifted left as it is restored to the low order word.
PUSH.L R15
/* Save the stack pointer to the TCB. */ /* Save the stack pointer to the TCB. */
MOV.L # _pxCurrentTCB, R15 MOV.L #_pxCurrentTCB, R15
MOV.L[ R15 ], R15 MOV.L [ R15 ], R15
MOV.L R0, [ R15 ] MOV.L R0, [ R15 ]
/* Ensure the interrupt mask is set to the syscall priority while the kernel /* Ensure the interrupt mask is set to the syscall priority while the kernel
* structures are being accessed. */ structures are being accessed. */
MVTIPL # configMAX_SYSCALL_INTERRUPT_PRIORITY MVTIPL #configMAX_SYSCALL_INTERRUPT_PRIORITY
/* Select the next task to run. */ /* Select the next task to run. */
BSR.A _vTaskSwitchContext BSR.A _vTaskSwitchContext
/* Reset the interrupt mask as no more data structure access is required. */ /* 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 /* Load the stack pointer of the task that is now selected as the Running
* state task from its TCB. */ state task from its TCB. */
MOV.L # _pxCurrentTCB, R15 MOV.L #_pxCurrentTCB,R15
MOV.L[ R15 ], R15 MOV.L [ R15 ], R15
MOV.L[ R15 ], R0 MOV.L [ R15 ], R0
/* Restore the context of the new task. The PSW (Program Status Word) and /* Restore the context of the new task. The PSW (Program Status Word) and
* PC will be popped by the RTE instruction. */ PC will be popped by the RTE instruction. */
POP R15 POP R15
MVTACLO R15 MVTACLO R15
POP R15 POP R15
MVTACHI R15 MVTACHI R15
POP R15 POP R15
MVTC R15, FPSW MVTC R15,FPSW
POPM R1 - R15 POPM R1-R15
RTE RTE
NOP NOP
NOP NOP
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */ Artificially force an assert. */
configASSERT( pxCurrentTCB == NULL ); configASSERT( pxCurrentTCB == NULL );
/* The following line is just to prevent the symbol getting optimised away. */ /* 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 /* Type definitions - these are a bit legacy and not really used now, other than
* portSTACK_TYPE and portBASE_TYPE. */ portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char #define portCHAR char
#define portFLOAT float #define portFLOAT float
#define portDOUBLE double #define portDOUBLE double
#define portLONG long #define portLONG long
#define portSHORT short #define portSHORT short
#define portSTACK_TYPE uint32_t #define portSTACK_TYPE uint32_t
#define portBASE_TYPE long #define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t; typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t; typedef long BaseType_t;
typedef unsigned long UBaseType_t; typedef unsigned long UBaseType_t;
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) #if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t; typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff #define portMAX_DELAY ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 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. */ not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#else #else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Hardware specifics. */ /* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */ #define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1 #define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop() #define portNOP() nop()
#pragma inline_asm vPortYield #pragma inline_asm vPortYield
static void vPortYield( void ) static void vPortYield( void )
{ {
/* Save clobbered register - may not actually be necessary if inline asm /* Save clobbered register - may not actually be necessary if inline asm
* functions are considered to use the same rules as function calls by the functions are considered to use the same rules as function calls by the
* compiler. */ compiler. */
PUSH.L R5 PUSH.L R5
/* Set ITU SWINTR. */ /* Set ITU SWINTR. */
MOV.L # 553696, R5 MOV.L #553696, R5
MOV.B # 1, [ R5 ] MOV.B #1, [R5]
/* Read back to ensure the value is taken before proceeding. */ /* 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. */ /* Restore clobbered register to its previous value. */
POP R5 POP R5
} }
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) portYIELD( ); } while( 0 ) #define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) portYIELD(); } while( 0 )
/* These macros should not be called directly, but through the /* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
* performed if configASSERT() is defined to ensure an assertion handler does not 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 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 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 when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
* functions are those that end in FromISR. FreeRTOS maintains a separate 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 interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */ simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 ) #define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
#ifdef configASSERT #ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= 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 ) #define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else #else
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif #endif
/* Critical nesting counts are stored in the TCB. */ /* 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. */ /* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void ); extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void ); extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical() #define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical() #define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */ /* As this port allows interrupt nesting... */
#define portSET_INTERRUPT_MASK_FROM_ISR() get_ipl(); set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #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 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( long ) uxSavedInterruptStatus )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */ /* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( 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 ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #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. */ /* Scheduler includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
@ -47,15 +47,15 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore /* 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_PSW ( ( StackType_t ) 0x00030000 )
#define portINITIAL_FPSW ( ( StackType_t ) 0x00000100 ) #define portINITIAL_FPSW ( ( StackType_t ) 0x00000100 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following lines are to ensure vSoftwareInterruptEntry can be referenced, /* The following lines are to ensure vSoftwareInterruptEntry can be referenced,
* and therefore installed in the vector table, when the FreeRTOS code is built and therefore installed in the vector table, when the FreeRTOS code is built
* as a library. */ as a library. */
extern BaseType_t vSoftwareInterruptEntry; extern BaseType_t vSoftwareInterruptEntry;
const BaseType_t * p_vSoftwareInterruptEntry = &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 /* This is accessed by the inline assembler functions so is file scope for
* convenience. */ convenience. */
extern void * pxCurrentTCB; extern void *pxCurrentTCB;
extern void vTaskSwitchContext( void ); extern void vTaskSwitchContext( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -94,9 +94,7 @@ extern void vTaskSwitchContext( void );
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
TaskFunction_t pxCode,
void * pvParameters )
{ {
/* R0 is not included as it is the stack pointer. */ /* R0 is not included as it is the stack pointer. */
@ -107,8 +105,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = ( StackType_t ) pxCode; *pxTopOfStack = ( StackType_t ) pxCode;
/* When debugging it can be useful if every register is set to a known /* 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 value. Otherwise code space can be saved by just setting the registers
* that need to be set. */ that need to be set. */
#ifdef USE_FULL_REGISTER_INITIALISATION #ifdef USE_FULL_REGISTER_INITIALISATION
{ {
pxTopOfStack--; pxTopOfStack--;
@ -141,11 +139,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = 0x22222222; *pxTopOfStack = 0x22222222;
pxTopOfStack--; pxTopOfStack--;
} }
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */ #else
{ {
pxTopOfStack -= 15; pxTopOfStack -= 15;
} }
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */ #endif
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */
pxTopOfStack--; pxTopOfStack--;
@ -169,14 +167,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
extern void vApplicationSetupTimerInterrupt( void ); extern void vApplicationSetupTimerInterrupt( void );
/* Use pxCurrentTCB just so it does not get optimised away. */ /* Use pxCurrentTCB just so it does not get optimised away. */
if( pxCurrentTCB != NULL ) if( pxCurrentTCB != NULL )
{ {
/* Call an application function to set up the timer that will generate the /* Call an application function to set up the timer that will generate the
* tick interrupt. This way the application can decide which peripheral to tick interrupt. This way the application can decide which peripheral to
* use. A demo application is provided to show a suitable example. */ use. A demo application is provided to show a suitable example. */
vApplicationSetupTimerInterrupt(); vApplicationSetupTimerInterrupt();
/* Enable the software interrupt. */ /* Enable the software interrupt. */
@ -204,36 +202,36 @@ BaseType_t xPortStartScheduler( void )
static void prvStartFirstTask( void ) static void prvStartFirstTask( void )
{ {
/* When starting the scheduler there is nothing that needs moving to the /* When starting the scheduler there is nothing that needs moving to the
* interrupt stack because the function is not called from an interrupt. interrupt stack because the function is not called from an interrupt.
* Just ensure the current stack is the user stack. */ Just ensure the current stack is the user stack. */
SETPSW U SETPSW U
/* Obtain the location of the stack associated with which ever task /* Obtain the location of the stack associated with which ever task
* pxCurrentTCB is currently pointing to. */ pxCurrentTCB is currently pointing to. */
MOV.L # _pxCurrentTCB, R15 MOV.L #_pxCurrentTCB, R15
MOV.L[ R15 ], R15 MOV.L [R15], R15
MOV.L[ R15 ], R0 MOV.L [R15], R0
/* Restore the registers from the stack of the task pointed to by /* Restore the registers from the stack of the task pointed to by
* pxCurrentTCB. */ pxCurrentTCB. */
POP R15 POP R15
MVTACLO R15, A0 /* Accumulator low 32 bits. */ MVTACLO R15, A0 /* Accumulator low 32 bits. */
POP R15 POP R15
MVTACHI R15, A0 /* Accumulator high 32 bits. */ MVTACHI R15, A0 /* Accumulator high 32 bits. */
POP R15 POP R15
MVTACGU R15, A0 /* Accumulator guard. */ MVTACGU R15, A0 /* Accumulator guard. */
POP R15 POP R15
MVTACLO R15, A1 /* Accumulator low 32 bits. */ MVTACLO R15, A1 /* Accumulator low 32 bits. */
POP R15 POP R15
MVTACHI R15, A1 /* Accumulator high 32 bits. */ MVTACHI R15, A1 /* Accumulator high 32 bits. */
POP R15 POP R15
MVTACGU R15, A1 /* Accumulator guard. */ MVTACGU R15, A1 /* Accumulator guard. */
POP R15 POP R15
MVTC R15, FPSW /* Floating point status word. */ MVTC R15,FPSW /* Floating point status word. */
POPM R1 - R15 /* R1 to R15 - R0 is not included as it is the SP. */ POPM R1-R15 /* R1 to R15 - R0 is not included as it is the SP. */
RTE /* This pops the remaining registers. */ RTE /* This pops the remaining registers. */
NOP
NOP NOP
NOP
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -241,7 +239,7 @@ static void prvStartFirstTask( void )
void vTickISR( void ) void vTickISR( void )
{ {
/* Increment the tick, and perform any processing the new tick value /* Increment the tick, and perform any processing the new tick value
* necessitates. */ necessitates. */
set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY ); set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY );
{ {
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
@ -249,7 +247,6 @@ void vTickISR( void )
taskYIELD(); taskYIELD();
} }
} }
set_ipl( configKERNEL_INTERRUPT_PRIORITY ); set_ipl( configKERNEL_INTERRUPT_PRIORITY );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -264,105 +261,99 @@ void vSoftwareInterruptISR( void )
static void prvYieldHandler( void ) static void prvYieldHandler( void )
{ {
/* Re-enable interrupts. */ /* Re-enable interrupts. */
SETPSW I SETPSW I
/* Move the data that was automatically pushed onto the interrupt stack when /* Move the data that was automatically pushed onto the interrupt stack when
* the interrupt occurred from the interrupt stack to the user stack. the interrupt occurred from the interrupt stack to the user stack.
*
* R15 is saved before it is clobbered. */ R15 is saved before it is clobbered. */
PUSH.L R15 PUSH.L R15
/* Read the user stack pointer. */ /* Read the user stack pointer. */
MVFC USP, R15 MVFC USP, R15
/* Move the address down to the data being moved. */ /* Move the address down to the data being moved. */
SUB # 12, R15 SUB #12, R15
MVTC R15, USP MVTC R15, USP
/* Copy the data across. */ /* Copy the data across. */
MOV.L[ R0 ], [ R15 ]; MOV.L [ R0 ], [ R15 ] ; R15
R15 MOV.L 4[ R0 ], 4[ R15 ] ; PC
MOV.L 8[ R0 ], 8[ R15 ] ; PSW
MOV.L 4[ R0 ], 4[ R15 ];
PC
MOV.L 8[ R0 ], 8[ R15 ];
PSW
/* Move the interrupt stack pointer to its new correct position. */ /* 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. */ /* 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). */ /* Save the rest of the general registers (R15 has been saved already). */
PUSHM R1 - R14 PUSHM R1-R14
/* Save the FPSW and accumulators. */ /* Save the FPSW and accumulators. */
MVFC FPSW, R15 MVFC FPSW, R15
PUSH.L R15 PUSH.L R15
MVFACGU # 0, A1, R15 MVFACGU #0, A1, R15
PUSH.L R15 PUSH.L R15
MVFACHI # 0, A1, R15 MVFACHI #0, A1, R15
PUSH.L R15 PUSH.L R15
MVFACLO # 0, A1, R15; MVFACLO #0, A1, R15 ; Low order word.
Low order word. PUSH.L R15
PUSH.L R15 MVFACGU #0, A0, R15
MVFACGU # 0, A0, R15 PUSH.L R15
PUSH.L R15 MVFACHI #0, A0, R15
MVFACHI # 0, A0, R15 PUSH.L R15
PUSH.L R15 MVFACLO #0, A0, R15 ; Low order word.
MVFACLO # 0, A0, R15; PUSH.L R15
Low order word.
PUSH.L R15
/* Save the stack pointer to the TCB. */ /* Save the stack pointer to the TCB. */
MOV.L # _pxCurrentTCB, R15 MOV.L #_pxCurrentTCB, R15
MOV.L[ R15 ], R15 MOV.L [ R15 ], R15
MOV.L R0, [ R15 ] MOV.L R0, [ R15 ]
/* Ensure the interrupt mask is set to the syscall priority while the kernel /* Ensure the interrupt mask is set to the syscall priority while the kernel
* structures are being accessed. */ structures are being accessed. */
MVTIPL # configMAX_SYSCALL_INTERRUPT_PRIORITY MVTIPL #configMAX_SYSCALL_INTERRUPT_PRIORITY
/* Select the next task to run. */ /* Select the next task to run. */
BSR.A _vTaskSwitchContext BSR.A _vTaskSwitchContext
/* Reset the interrupt mask as no more data structure access is required. */ /* 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 /* Load the stack pointer of the task that is now selected as the Running
* state task from its TCB. */ state task from its TCB. */
MOV.L # _pxCurrentTCB, R15 MOV.L #_pxCurrentTCB,R15
MOV.L[ R15 ], R15 MOV.L [ R15 ], R15
MOV.L[ R15 ], R0 MOV.L [ R15 ], R0
/* Restore the context of the new task. The PSW (Program Status Word) and /* Restore the context of the new task. The PSW (Program Status Word) and
* PC will be popped by the RTE instruction. */ PC will be popped by the RTE instruction. */
POP R15 POP R15
MVTACLO R15, A0 /* Accumulator low 32 bits. */ MVTACLO R15, A0 /* Accumulator low 32 bits. */
POP R15 POP R15
MVTACHI R15, A0 /* Accumulator high 32 bits. */ MVTACHI R15, A0 /* Accumulator high 32 bits. */
POP R15 POP R15
MVTACGU R15, A0 /* Accumulator guard. */ MVTACGU R15, A0 /* Accumulator guard. */
POP R15 POP R15
MVTACLO R15, A1 /* Accumulator low 32 bits. */ MVTACLO R15, A1 /* Accumulator low 32 bits. */
POP R15 POP R15
MVTACHI R15, A1 /* Accumulator high 32 bits. */ MVTACHI R15, A1 /* Accumulator high 32 bits. */
POP R15 POP R15
MVTACGU R15, A1 /* Accumulator guard. */ MVTACGU R15, A1 /* Accumulator guard. */
POP R15 POP R15
MVTC R15, FPSW MVTC R15,FPSW
POPM R1 - R15 POPM R1-R15
RTE RTE
NOP NOP
NOP NOP
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
* Artificially force an assert. */ Artificially force an assert. */
configASSERT( pxCurrentTCB == NULL ); configASSERT( pxCurrentTCB == NULL );
/* The following line is just to prevent the symbol getting optimised away. */ /* 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 /* Type definitions - these are a bit legacy and not really used now, other than
* portSTACK_TYPE and portBASE_TYPE. */ portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char #define portCHAR char
#define portFLOAT float #define portFLOAT float
#define portDOUBLE double #define portDOUBLE double
#define portLONG long #define portLONG long
#define portSHORT short #define portSHORT short
#define portSTACK_TYPE uint32_t #define portSTACK_TYPE uint32_t
#define portBASE_TYPE long #define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t; typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t; typedef long BaseType_t;
typedef unsigned long UBaseType_t; typedef unsigned long UBaseType_t;
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) #if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t; typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff #define portMAX_DELAY ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 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. */ not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#else #else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Hardware specifics. */ /* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */ #define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1 #define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop() #define portNOP() nop()
#pragma inline_asm vPortYield #pragma inline_asm vPortYield
static void vPortYield( void ) static void vPortYield( void )
{ {
/* Save clobbered register - may not actually be necessary if inline asm /* Save clobbered register - may not actually be necessary if inline asm
* functions are considered to use the same rules as function calls by the functions are considered to use the same rules as function calls by the
* compiler. */ compiler. */
PUSH.L R5 PUSH.L R5
/* Set ITU SWINTR. */ /* Set ITU SWINTR. */
MOV.L # 553696, R5 MOV.L #553696, R5
MOV.B # 1, [ R5 ] MOV.B #1, [R5]
/* Read back to ensure the value is taken before proceeding. */ /* 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. */ /* Restore clobbered register to its previous value. */
POP R5 POP R5
} }
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) portYIELD( ); } while( 0 ) #define portYIELD_FROM_ISR( x ) do { if( x != pdFALSE ) portYIELD(); } while( 0 )
/* These macros should not be called directly, but through the /* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is
* performed if configASSERT() is defined to ensure an assertion handler does not 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 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 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 when an ISR safe FreeRTOS API function was executed. ISR safe FreeRTOS API
* functions are those that end in FromISR. FreeRTOS maintains a separate 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 interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */ simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 ) #define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
#ifdef configASSERT #ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= 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 ) #define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else #else
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif #endif
/* Critical nesting counts are stored in the TCB. */ /* 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. */ /* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void ); extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void ); extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical() #define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical() #define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */ /* As this port allows interrupt nesting... */
#define portSET_INTERRUPT_MASK_FROM_ISR() ( UBaseType_t ) get_ipl(); set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #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 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( long ) uxSavedInterruptStatus )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */ /* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( 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 ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -54,22 +54,22 @@
/* Tasks should start with interrupts enabled and in Supervisor mode, therefore /* 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_PSW ( ( StackType_t ) 0x00030000 )
#define portINITIAL_FPSW ( ( StackType_t ) 0x00000100 ) #define portINITIAL_FPSW ( ( StackType_t ) 0x00000100 )
#define portINITIAL_DPSW ( ( StackType_t ) 0x00000100 ) #define portINITIAL_DPSW ( ( StackType_t ) 0x00000100 )
#define portINITIAL_DCMR ( ( StackType_t ) 0x00000000 ) #define portINITIAL_DCMR ( ( StackType_t ) 0x00000000 )
#define portINITIAL_DECNT ( ( StackType_t ) 0x00000001 ) #define portINITIAL_DECNT ( ( StackType_t ) 0x00000001 )
/* Tasks are not created with a DPFPU context, but can be given a DPFPU context /* 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 * 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 * 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. */ * any other value if the task does have a DPFPU context. */
#define portNO_DPFPU_CONTEXT ( ( StackType_t ) 0 ) #define portNO_DPFPU_CONTEXT ( ( StackType_t ) 0 )
#define portHAS_DPFPU_CONTEXT ( ( StackType_t ) 1 ) #define portHAS_DPFPU_CONTEXT ( ( StackType_t ) 1 )
/* The space on the stack required to hold the DPFPU data registers. This is 16 /* The space on the stack required to hold the DPFPU data registers. This is 16
* 64-bit registers. */ * 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 * value. Otherwise code space can be saved by just setting the registers
* that need to be set. */ * that need to be set. */
#ifdef USE_FULL_REGISTER_INITIALISATION #ifdef USE_FULL_REGISTER_INITIALISATION
{ {
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0xffffffff; /* r15. */ *pxTopOfStack = 0xffffffff; /* r15. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0xeeeeeeee; *pxTopOfStack = 0xeeeeeeee;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0xdddddddd; *pxTopOfStack = 0xdddddddd;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0xcccccccc; *pxTopOfStack = 0xcccccccc;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0xbbbbbbbb; *pxTopOfStack = 0xbbbbbbbb;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0xaaaaaaaa; *pxTopOfStack = 0xaaaaaaaa;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x99999999; *pxTopOfStack = 0x99999999;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x88888888; *pxTopOfStack = 0x88888888;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x77777777; *pxTopOfStack = 0x77777777;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x66666666; *pxTopOfStack = 0x66666666;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x55555555; *pxTopOfStack = 0x55555555;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x44444444; *pxTopOfStack = 0x44444444;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x33333333; *pxTopOfStack = 0x33333333;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x22222222; *pxTopOfStack = 0x22222222;
pxTopOfStack--; pxTopOfStack--;
} }
#else /* ifdef USE_FULL_REGISTER_INITIALISATION */ #else /* ifdef USE_FULL_REGISTER_INITIALISATION */
{ {
pxTopOfStack -= 15; pxTopOfStack -= 15;
} }
#endif /* ifdef USE_FULL_REGISTER_INITIALISATION */ #endif /* ifdef USE_FULL_REGISTER_INITIALISATION */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R1 */
@ -198,73 +198,73 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*pxTopOfStack = 0x66666666; /* Accumulator 0. */ *pxTopOfStack = 0x66666666; /* Accumulator 0. */
#if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) #if ( configUSE_TASK_DPFPU_SUPPORT == 1 )
{ {
/* The task will start without a DPFPU context. A task that /* The task will start without a DPFPU context. A task that
* uses the DPFPU hardware must call vPortTaskUsesDPFPU() before * uses the DPFPU hardware must call vPortTaskUsesDPFPU() before
* executing any floating point instructions. */ * executing any floating point instructions. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = portNO_DPFPU_CONTEXT; *pxTopOfStack = portNO_DPFPU_CONTEXT;
} }
#elif ( configUSE_TASK_DPFPU_SUPPORT == 2 ) #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; /* The task will start with a DPFPU context. Leave enough
*( double * ) pxTopOfStack = 1515.1515; /* DR15. */ * space for the registers - and ensure they are initialised if desired. */
pxTopOfStack -= 2; #ifdef USE_FULL_REGISTER_INITIALISATION
*( double * ) pxTopOfStack = 1414.1414; /* DR14. */ {
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 1313.1313; /* DR13. */ *(double *)pxTopOfStack = 1515.1515; /* DR15. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 1212.1212; /* DR12. */ *(double *)pxTopOfStack = 1414.1414; /* DR14. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 1111.1111; /* DR11. */ *(double *)pxTopOfStack = 1313.1313; /* DR13. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 1010.1010; /* DR10. */ *(double *)pxTopOfStack = 1212.1212; /* DR12. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 909.0909; /* DR9. */ *(double *)pxTopOfStack = 1111.1111; /* DR11. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 808.0808; /* DR8. */ *(double *)pxTopOfStack = 1010.1010; /* DR10. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 707.0707; /* DR7. */ *(double *)pxTopOfStack = 909.0909; /* DR9. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 606.0606; /* DR6. */ *(double *)pxTopOfStack = 808.0808; /* DR8. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 505.0505; /* DR5. */ *(double *)pxTopOfStack = 707.0707; /* DR7. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 404.0404; /* DR4. */ *(double *)pxTopOfStack = 606.0606; /* DR6. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 303.0303; /* DR3. */ *(double *)pxTopOfStack = 505.0505; /* DR5. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 202.0202; /* DR2. */ *(double *)pxTopOfStack = 404.0404; /* DR4. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 101.0101; /* DR1. */ *(double *)pxTopOfStack = 303.0303; /* DR3. */
pxTopOfStack -= 2; pxTopOfStack -= 2;
*( double * ) pxTopOfStack = 9876.54321; /* DR0. */ *(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 ) #elif ( configUSE_TASK_DPFPU_SUPPORT == 0 )
{ {
/* Omit DPFPU support. */ /* Omit DPFPU support. */
} }
#else /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */ #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 ) */ #endif /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */
return pxTopOfStack; return pxTopOfStack;
@ -330,74 +330,78 @@ void vPortEndScheduler( void )
#pragma inline_asm prvStartFirstTask #pragma inline_asm prvStartFirstTask
static void prvStartFirstTask( void ) static void prvStartFirstTask( void )
{ {
#ifndef __CDT_PARSER__ #ifndef __CDT_PARSER__
/* When starting the scheduler there is nothing that needs moving to the /* When starting the scheduler there is nothing that needs moving to the
* interrupt stack because the function is not called from an interrupt. * interrupt stack because the function is not called from an interrupt.
* Just ensure the current stack is the user stack. */ * Just ensure the current stack is the user stack. */
SETPSW U SETPSW U
/* Obtain the location of the stack associated with which ever task /* Obtain the location of the stack associated with which ever task
* pxCurrentTCB is currently pointing to. */ * pxCurrentTCB is currently pointing to. */
MOV.L # _pxCurrentTCB, R15 MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15 MOV.L [ R15 ], R15
MOV.L[ R15 ], R0 MOV.L [ R15 ], R0
/* Restore the registers from the stack of the task pointed to by /* Restore the registers from the stack of the task pointed to by
* pxCurrentTCB. */ * pxCurrentTCB. */
#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 ]
#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 ) */
/* The restored ulPortTaskHasDPFPUContext is to be zero here.
* So, it is never necessary to restore the DPFPU context here. */
POP R15 POP R15
MOV.L # _ulPortTaskHasDPFPUContext, R14
MOV.L R15, [ R14 ]
/* Accumulator low 32 bits. */ #elif ( configUSE_TASK_DPFPU_SUPPORT == 2 )
MVTACLO R15, A0
POP R15
/* Accumulator high 32 bits. */ /* Restore the DPFPU context. */
MVTACHI R15, A0 DPOPM.L DPSW-DECNT
POP R15 DPOPM.D DR0-DR15
/* Accumulator guard. */ #endif /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */
MVTACGU R15, A0
POP R15
/* Accumulator low 32 bits. */ POP R15
MVTACLO R15, A1
POP R15
/* Accumulator high 32 bits. */ /* Accumulator low 32 bits. */
MVTACHI R15, A1 MVTACLO R15, A0
POP R15 POP R15
/* Accumulator guard. */ /* Accumulator high 32 bits. */
MVTACGU R15, A1 MVTACHI R15, A0
POP R15 POP R15
/* Floating point status word. */ /* Accumulator guard. */
MVTC R15, FPSW MVTACGU R15, A0
POP R15
/* R1 to R15 - R0 is not included as it is the SP. */ /* Accumulator low 32 bits. */
POPM R1 - R15 MVTACLO R15, A1
POP R15
/* This pops the remaining registers. */ /* Accumulator high 32 bits. */
RTE MVTACHI R15, A1
NOP POP R15
NOP
#endif /* ifndef __CDT_PARSER__ */ /* 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 #pragma inline_asm prvYieldHandler
static void prvYieldHandler( void ) static void prvYieldHandler( void )
{ {
#ifndef __CDT_PARSER__ #ifndef __CDT_PARSER__
/* Re-enable interrupts. */
SETPSW I /* Re-enable interrupts. */
SETPSW I
/* Move the data that was automatically pushed onto the interrupt stack when /* Move the data that was automatically pushed onto the interrupt stack when
* the interrupt occurred from the interrupt stack to the user stack. * the interrupt occurred from the interrupt stack to the user stack.
* *
* R15 is saved before it is clobbered. */ * 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 PUSH.L R15
/* Read the user stack pointer. */ #elif ( configUSE_TASK_DPFPU_SUPPORT == 2 )
MVFC USP, R15
/* Move the address down to the data being moved. */ /* Save the DPFPU context, always. */
SUB # 12, R15 DPUSHM.D DR0-DR15
MVTC R15, USP DPUSHM.L DPSW-DECNT
/* Copy the data across, R15, then PC, then PSW. */ #endif /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */
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 ) */
/* Save the stack pointer to the TCB. */ /* Save the stack pointer to the TCB. */
MOV.L # _pxCurrentTCB, R15 MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15 MOV.L [ R15 ], R15
MOV.L R0, [ R15 ] MOV.L R0, [ R15 ]
/* Ensure the interrupt mask is set to the syscall priority while the kernel /* Ensure the interrupt mask is set to the syscall priority while the kernel
* structures are being accessed. */ * structures are being accessed. */
MVTIPL # configMAX_SYSCALL_INTERRUPT_PRIORITY MVTIPL # configMAX_SYSCALL_INTERRUPT_PRIORITY
/* Select the next task to run. */ /* Select the next task to run. */
BSR.A _vTaskSwitchContext BSR.A _vTaskSwitchContext
/* Reset the interrupt mask as no more data structure access is required. */ /* 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 /* Load the stack pointer of the task that is now selected as the Running
* state task from its TCB. */ * state task from its TCB. */
MOV.L # _pxCurrentTCB, R15 MOV.L # _pxCurrentTCB, R15
MOV.L[ R15 ], R15 MOV.L [ R15 ], R15
MOV.L[ R15 ], R0 MOV.L [ R15 ], R0
/* Restore the context of the new task. The PSW (Program Status Word) and /* Restore the context of the new task. The PSW (Program Status Word) and
* PC will be popped by the RTE instruction. */ * PC will be popped by the RTE instruction. */
#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
/* 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 ) */
/* Is there a DPFPU context to restore? If the restored
* ulPortTaskHasDPFPUContext is zero then no. */
POP R15 POP R15
MOV.L # _ulPortTaskHasDPFPUContext, R14
MOV.L R15, [ R14 ]
CMP # 0, R15
/* Accumulator low 32 bits. */ /* Restore the DPFPU context, if any. */
MVTACLO R15, A0 BEQ.B ?+
POP R15 DPOPM.L DPSW-DECNT
DPOPM.D DR0-DR15
?:
/* Accumulator high 32 bits. */ #elif ( configUSE_TASK_DPFPU_SUPPORT == 2 )
MVTACHI R15, A0
POP R15
/* Accumulator guard. */ /* Restore the DPFPU context, always. */
MVTACGU R15, A0 DPOPM.L DPSW-DECNT
POP R15 DPOPM.D DR0-DR15
/* Accumulator low 32 bits. */ #endif /* if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) */
MVTACLO R15, A1
POP R15
/* Accumulator high 32 bits. */ POP R15
MVTACHI R15, A1
POP R15
/* Accumulator guard. */ /* Accumulator low 32 bits. */
MVTACGU R15, A1 MVTACLO R15, A0
POP R15 POP R15
MVTC R15, FPSW
POPM R1 - R15 /* Accumulator high 32 bits. */
RTE MVTACHI R15, A0
NOP POP R15
NOP
#endif /* ifndef __CDT_PARSER__ */ /* 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 #ifndef PORTMACRO_H
#define PORTMACRO_H #define PORTMACRO_H
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
@ -37,7 +37,7 @@
/* *INDENT-ON* */ /* *INDENT-ON* */
/* Hardware specifics. */ /* Hardware specifics. */
#include <machine.h> #include <machine.h>
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Port specific definitions. * Port specific definitions.
@ -51,9 +51,9 @@
/* When the FIT configurator or the Smart Configurator is used, platform.h has to be /* When the FIT configurator or the Smart Configurator is used, platform.h has to be
* used. */ * used. */
#ifndef configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H #ifndef configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H
#define configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H 0 #define configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H 0
#endif #endif
/* If configUSE_TASK_DPFPU_SUPPORT is set to 1 (or undefined) then each task will /* 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 * 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 * 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 * 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). */ * of any DPFPU context (even if DPFPU registers are used). */
#ifndef configUSE_TASK_DPFPU_SUPPORT #ifndef configUSE_TASK_DPFPU_SUPPORT
#define configUSE_TASK_DPFPU_SUPPORT 1 #define configUSE_TASK_DPFPU_SUPPORT 1
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Type definitions - these are a bit legacy and not really used now, other than /* Type definitions - these are a bit legacy and not really used now, other than
* portSTACK_TYPE and portBASE_TYPE. */ * portSTACK_TYPE and portBASE_TYPE. */
#define portCHAR char #define portCHAR char
#define portFLOAT float #define portFLOAT float
#define portDOUBLE double #define portDOUBLE double
#define portLONG long #define portLONG long
#define portSHORT short #define portSHORT short
#define portSTACK_TYPE uint32_t #define portSTACK_TYPE uint32_t
#define portBASE_TYPE long #define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t; typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t; typedef long BaseType_t;
typedef unsigned long UBaseType_t; typedef unsigned long UBaseType_t;
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
typedef uint16_t TickType_t; typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff #define portMAX_DELAY ( TickType_t ) 0xffff
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 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. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#else #else
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Hardware specifics. */ /* Hardware specifics. */
#define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */ #define portBYTE_ALIGNMENT 8 /* Could make four, according to manual. */
#define portSTACK_GROWTH -1 #define portSTACK_GROWTH -1
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portNOP() nop() #define portNOP() nop()
/* Yield equivalent to "*portITU_SWINTR = 0x01; ( void ) *portITU_SWINTR;" /* Yield equivalent to "*portITU_SWINTR = 0x01; ( void ) *portITU_SWINTR;"
* where portITU_SWINTR is the location of the software interrupt register * where portITU_SWINTR is the location of the software interrupt register
* (0x000872E0). Don't rely on the assembler to select a register, so instead * (0x000872E0). Don't rely on the assembler to select a register, so instead
* save and restore clobbered registers manually. */ * save and restore clobbered registers manually. */
#pragma inline_asm vPortYield #pragma inline_asm vPortYield
static void vPortYield( void ) static void vPortYield( void )
{ {
#ifndef __CDT_PARSER__ #ifndef __CDT_PARSER__
/* Save clobbered register - may not actually be necessary if inline asm /* Save clobbered register - may not actually be necessary if inline asm
* functions are considered to use the same rules as function calls by the * functions are considered to use the same rules as function calls by the
* compiler. */ * compiler. */
PUSH.L R5 PUSH.L R5
/* Set ITU SWINTR. */ /* Set ITU SWINTR. */
MOV.L # 000 872E0H, R5 MOV.L # 000872E0H, R5
MOV.B # 1, [ R5 ] MOV.B # 1, [ R5 ]
/* Read back to ensure the value is taken before proceeding. */ /* 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. */ /* Restore clobbered register to its previous value. */
POP R5 POP R5
#endif /* ifndef __CDT_PARSER__ */ #endif
} }
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portYIELD_FROM_ISR( x ) do { if( ( x ) != pdFALSE ) portYIELD( ); } while( 0 ) #define portYIELD_FROM_ISR( x ) do { if( ( x ) != pdFALSE ) portYIELD(); } while( 0 )
/* These macros should not be called directly, but through the /* These macros should not be called directly, but through the
* taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros. An extra check is * 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 * 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 * interrupt API to ensure API function and interrupt entry is as fast and as
* simple as possible. */ * simple as possible. */
#define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 ) #define portENABLE_INTERRUPTS() set_ipl( ( long ) 0 )
#ifdef configASSERT #ifdef configASSERT
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( get_ipl() <= 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 ) #define portDISABLE_INTERRUPTS() if( get_ipl() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#else #else
#define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #define portDISABLE_INTERRUPTS() set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY )
#endif #endif
/* Critical nesting counts are stored in the TCB. */ /* 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. */ /* The critical nesting functions defined within tasks.c. */
extern void vTaskEnterCritical( void ); extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void ); extern void vTaskExitCritical( void );
#define portENTER_CRITICAL() vTaskEnterCritical() #define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical() #define portEXIT_CRITICAL() vTaskExitCritical()
/* As this port allows interrupt nesting... */ /* As this port allows interrupt nesting... */
#define portSET_INTERRUPT_MASK_FROM_ISR() ( UBaseType_t ) get_ipl(); set_ipl( ( long ) configMAX_SYSCALL_INTERRUPT_PRIORITY ) #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 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) set_ipl( ( long ) uxSavedInterruptStatus )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. */ /* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( 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 ) #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 * 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 * configUSE_TASK_DPFPU_SUPPORT is set to 2 then all tasks will have a DPFPU context
* by default. */ * by default. */
#if ( configUSE_TASK_DPFPU_SUPPORT == 1 ) #if( configUSE_TASK_DPFPU_SUPPORT == 1 )
void vPortTaskUsesDPFPU( void ); void vPortTaskUsesDPFPU( void );
#else #else
/* Each task has a DPFPU context already, so define this function away to /* Each task has a DPFPU context already, so define this function away to
* nothing to prevent it being called accidentally. */ * nothing to prevent it being called accidentally. */
#define vPortTaskUsesDPFPU() #define vPortTaskUsesDPFPU()
#endif #endif
#define portTASK_USES_DPFPU() vPortTaskUsesDPFPU() #define portTASK_USES_DPFPU() vPortTaskUsesDPFPU()
/* Definition to allow compatibility with existing FreeRTOS Demo using flop.c. */ /* 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* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus