mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-06-09 05:49:04 -04:00
Style: Revert uncrustify for portable directories (#122)
* Style: revert uncrustify portable directories * Style: Uncrustify Some Portable files Co-authored-by: Alfred Gedeon <gedeonag@amazon.com>
This commit is contained in:
parent
a6da1cd0ce
commit
86653e2a1f
|
@ -22,7 +22,6 @@
|
||||||
* http://www.FreeRTOS.org
|
* http://www.FreeRTOS.org
|
||||||
* http://aws.amazon.com/freertos
|
* http://aws.amazon.com/freertos
|
||||||
*
|
*
|
||||||
* 1 tab == 4 spaces!
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||||
|
@ -876,7 +875,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
/* *INDENT-OFF* */
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
StackType_t * pxEndOfStack,
|
StackType_t * pxEndOfStack,
|
||||||
|
@ -889,6 +888,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
TaskFunction_t pxCode,
|
TaskFunction_t pxCode,
|
||||||
void * pvParameters ) /* PRIVILEGED_FUNCTION */
|
void * pvParameters ) /* PRIVILEGED_FUNCTION */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
/* *INDENT-ON* */
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
* interrupt. */
|
* interrupt. */
|
||||||
|
@ -1051,7 +1051,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||||
int32_t lIndex = 0;
|
int32_t lIndex = 0;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* Declaration when these variable are defined in code instead of being
|
||||||
* exported from linker scripts. */
|
* exported from linker scripts. */
|
||||||
extern uint32_t * __privileged_sram_start__;
|
extern uint32_t * __privileged_sram_start__;
|
||||||
|
@ -1079,8 +1081,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* using a separate MPU region. This is needed because privileged
|
* using a separate MPU region. This is needed because privileged
|
||||||
* SRAM is already protected using an MPU region and ARMv8-M does
|
* SRAM is already protected using an MPU region and ARMv8-M does
|
||||||
* not allow overlapping MPU regions. */
|
* not allow overlapping MPU regions. */
|
||||||
if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&
|
if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) &&
|
||||||
ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )
|
( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) )
|
||||||
{
|
{
|
||||||
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;
|
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;
|
||||||
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;
|
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;
|
||||||
|
|
|
@ -26,22 +26,22 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes from V1.00:
|
Changes from V1.00:
|
||||||
*
|
|
||||||
+ Call to taskYIELD() from within tick ISR has been replaced by the more
|
+ Call to taskYIELD() from within tick ISR has been replaced by the more
|
||||||
+ efficient portSWITCH_CONTEXT().
|
efficient portSWITCH_CONTEXT().
|
||||||
+ ISR function definitions renamed to include the prv prefix.
|
+ ISR function definitions renamed to include the prv prefix.
|
||||||
+
|
|
||||||
+ Changes from V2.6.1
|
Changes from V2.6.1
|
||||||
+
|
|
||||||
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||||
+ macro to be consistent with the later ports.
|
macro to be consistent with the later ports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the Flashlite 186
|
* Implementation of functions defined in portable.h for the Flashlite 186
|
||||||
* port.
|
* port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -68,16 +68,14 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz );
|
||||||
static void prvExitFunction( void );
|
static void prvExitFunction( void );
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||||
* is being used. */
|
is being used. */
|
||||||
#if ( configUSE_PREEMPTION == 1 )
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
|
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
being used. */
|
||||||
* being used. */
|
|
||||||
static void __interrupt __far prvPreemptiveTick( void );
|
static void __interrupt __far prvPreemptiveTick( void );
|
||||||
#else
|
#else
|
||||||
|
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
being used. */
|
||||||
* being used. */
|
|
||||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -90,9 +88,9 @@ static void __interrupt __far prvYieldProcessor( void );
|
||||||
static BaseType_t xSchedulerRunning = pdFALSE;
|
static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
||||||
/* Points to the original routine installed on the vector we use for manual
|
/* Points to the original routine installed on the vector we use for manual
|
||||||
* context switches. This is then used to restore the original routine during
|
context switches. This is then used to restore the original routine during
|
||||||
* prvExitFunction(). */
|
prvExitFunction(). */
|
||||||
static void( __interrupt __far * pxOldSwitchISR )();
|
static void ( __interrupt __far *pxOldSwitchISR )();
|
||||||
|
|
||||||
/* Used to restore the original DOS context when the scheduler is ended. */
|
/* Used to restore the original DOS context when the scheduler is ended. */
|
||||||
static jmp_buf xJumpBuf;
|
static jmp_buf xJumpBuf;
|
||||||
|
@ -105,14 +103,14 @@ BaseType_t xPortStartScheduler( void )
|
||||||
/* This is called with interrupts already disabled. */
|
/* This is called with interrupts already disabled. */
|
||||||
|
|
||||||
/* Remember what was on the interrupts we are going to use
|
/* Remember what was on the interrupts we are going to use
|
||||||
* so we can put them back later if required. */
|
so we can put them back later if required. */
|
||||||
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
||||||
|
|
||||||
/* Put our manual switch (yield) function on a known
|
/* Put our manual switch (yield) function on a known
|
||||||
* vector. */
|
vector. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||||
|
|
||||||
#if ( configUSE_PREEMPTION == 1 )
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
{
|
{
|
||||||
/* Put our tick switch function on the timer interrupt. */
|
/* Put our tick switch function on the timer interrupt. */
|
||||||
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
||||||
|
@ -145,8 +143,8 @@ BaseType_t xPortStartScheduler( void )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||||
* is being used. */
|
is being used. */
|
||||||
#if ( configUSE_PREEMPTION == 1 )
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
static void __interrupt __far prvPreemptiveTick( void )
|
static void __interrupt __far prvPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Get the scheduler to update the task states following the tick. */
|
/* Get the scheduler to update the task states following the tick. */
|
||||||
|
@ -159,15 +157,15 @@ BaseType_t xPortStartScheduler( void )
|
||||||
/* Reset the PIC ready for the next time. */
|
/* Reset the PIC ready for the next time. */
|
||||||
portRESET_PIC();
|
portRESET_PIC();
|
||||||
}
|
}
|
||||||
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
#else
|
||||||
static void __interrupt __far prvNonPreemptiveTick( void )
|
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Same as preemptive tick, but the cooperative scheduler is being used
|
/* Same as preemptive tick, but the cooperative scheduler is being used
|
||||||
* so we don't have to switch in the context of the next task. */
|
so we don't have to switch in the context of the next task. */
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
portRESET_PIC();
|
portRESET_PIC();
|
||||||
}
|
}
|
||||||
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void __interrupt __far prvYieldProcessor( void )
|
static void __interrupt __far prvYieldProcessor( void )
|
||||||
|
@ -180,31 +178,30 @@ static void __interrupt __far prvYieldProcessor( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Jump back to the processor state prior to starting the
|
/* Jump back to the processor state prior to starting the
|
||||||
* scheduler. This means we are not going to be using a
|
scheduler. This means we are not going to be using a
|
||||||
* task stack frame so the task can be deleted. */
|
task stack frame so the task can be deleted. */
|
||||||
longjmp( xJumpBuf, 1 );
|
longjmp( xJumpBuf, 1 );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvExitFunction( void )
|
static void prvExitFunction( void )
|
||||||
{
|
{
|
||||||
const uint16_t usTimerDisable = 0x0000;
|
const uint16_t usTimerDisable = 0x0000;
|
||||||
uint16_t usTimer0Control;
|
uint16_t usTimer0Control;
|
||||||
|
|
||||||
/* Interrupts should be disabled here anyway - but no
|
/* Interrupts should be disabled here anyway - but no
|
||||||
* harm in making sure. */
|
harm in making sure. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( xSchedulerRunning == pdTRUE )
|
if( xSchedulerRunning == pdTRUE )
|
||||||
{
|
{
|
||||||
/* Put back the switch interrupt routines that was in place
|
/* Put back the switch interrupt routines that was in place
|
||||||
* before the scheduler started. */
|
before the scheduler started. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable the timer used for the tick to ensure the scheduler is
|
/* Disable the timer used for the tick to ensure the scheduler is
|
||||||
* not called before restoring interrupts. There was previously nothing
|
not called before restoring interrupts. There was previously nothing
|
||||||
* on this timer so there is no old ISR to restore. */
|
on this timer so there is no old ISR to restore. */
|
||||||
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable );
|
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable );
|
||||||
|
|
||||||
/* Restart the DOS tick. */
|
/* Restart the DOS tick. */
|
||||||
|
@ -219,18 +216,18 @@ static void prvExitFunction( void )
|
||||||
|
|
||||||
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
||||||
{
|
{
|
||||||
const uint16_t usMaxCountRegister = 0xff5a;
|
const uint16_t usMaxCountRegister = 0xff5a;
|
||||||
const uint16_t usTimerPriorityRegister = 0xff32;
|
const uint16_t usTimerPriorityRegister = 0xff32;
|
||||||
const uint16_t usTimerEnable = 0xC000;
|
const uint16_t usTimerEnable = 0xC000;
|
||||||
const uint16_t usRetrigger = 0x0001;
|
const uint16_t usRetrigger = 0x0001;
|
||||||
const uint16_t usTimerHighPriority = 0x0000;
|
const uint16_t usTimerHighPriority = 0x0000;
|
||||||
uint16_t usTimer0Control;
|
uint16_t usTimer0Control;
|
||||||
|
|
||||||
/* ( CPU frequency / 4 ) / clock 2 max count [inpw( 0xff62 ) = 7] */
|
/* ( CPU frequency / 4 ) / clock 2 max count [inpw( 0xff62 ) = 7] */
|
||||||
|
|
||||||
const uint32_t ulClockFrequency = ( uint32_t ) 0x7f31a0UL;
|
const uint32_t ulClockFrequency = ( uint32_t ) 0x7f31a0UL;
|
||||||
|
|
||||||
uint32_t ulTimerCount = ulClockFrequency / ulTickRateHz;
|
uint32_t ulTimerCount = ulClockFrequency / ulTickRateHz;
|
||||||
|
|
||||||
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerEnable | portTIMER_INTERRUPT_ENABLE | usRetrigger );
|
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerEnable | portTIMER_INTERRUPT_ENABLE | usRetrigger );
|
||||||
portOUTPUT_WORD( usMaxCountRegister, ( uint16_t ) ulTimerCount );
|
portOUTPUT_WORD( usMaxCountRegister, ( uint16_t ) ulTimerCount );
|
||||||
|
@ -244,3 +241,4 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
||||||
|
|
||||||
|
|
||||||
/*lint +e950 */
|
/*lint +e950 */
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef short BaseType_t;
|
typedef short BaseType_t;
|
||||||
typedef unsigned short UBaseType_t;
|
typedef unsigned short UBaseType_t;
|
||||||
|
|
||||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
|
@ -61,8 +61,7 @@ typedef unsigned short UBaseType_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() __asm{ pushf } \
|
||||||
__asm{ pushf } \
|
|
||||||
__asm{ cli } \
|
__asm{ cli } \
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() __asm{ popf }
|
#define portEXIT_CRITICAL() __asm{ popf }
|
||||||
|
@ -91,7 +90,8 @@ typedef unsigned short UBaseType_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
||||||
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,16 +26,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes from V2.6.1
|
Changes from V2.6.1
|
||||||
*
|
|
||||||
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||||
+ macro to be consistent with the later ports.
|
macro to be consistent with the later ports.
|
||||||
+
|
|
||||||
+ Changes from V4.0.1
|
Changes from V4.0.1
|
||||||
+
|
|
||||||
+ Add function prvSetTickFrequencyDefault() to set the DOS tick back to
|
+ Add function prvSetTickFrequencyDefault() to set the DOS tick back to
|
||||||
+ its proper value when the scheduler exits.
|
its proper value when the scheduler exits.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
|
@ -46,9 +46,9 @@
|
||||||
#include "portasm.h"
|
#include "portasm.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the industrial
|
* Implementation of functions defined in portable.h for the industrial
|
||||||
* PC port.
|
* PC port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
||||||
|
|
||||||
|
@ -61,21 +61,19 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz );
|
||||||
static void prvExitFunction( void );
|
static void prvExitFunction( void );
|
||||||
|
|
||||||
/* Either chain to the DOS tick (which itself clears the PIC) or clear the PIC
|
/* Either chain to the DOS tick (which itself clears the PIC) or clear the PIC
|
||||||
* directly. We chain to the DOS tick as close as possible to the standard DOS
|
directly. We chain to the DOS tick as close as possible to the standard DOS
|
||||||
* tick rate. */
|
tick rate. */
|
||||||
static void prvPortResetPIC( void );
|
static void prvPortResetPIC( void );
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative
|
/* The ISR used depends on whether the preemptive or cooperative
|
||||||
* scheduler is being used. */
|
scheduler is being used. */
|
||||||
#if ( configUSE_PREEMPTION == 1 )
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
|
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
being used. */
|
||||||
* being used. */
|
|
||||||
static void __interrupt __far prvPreemptiveTick( void );
|
static void __interrupt __far prvPreemptiveTick( void );
|
||||||
#else
|
#else
|
||||||
|
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
being used. */
|
||||||
* being used. */
|
|
||||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -83,7 +81,7 @@ static void prvPortResetPIC( void );
|
||||||
static void __interrupt __far prvYieldProcessor( void );
|
static void __interrupt __far prvYieldProcessor( void );
|
||||||
|
|
||||||
/* Set the tick frequency back so the floppy drive works correctly when the
|
/* Set the tick frequency back so the floppy drive works correctly when the
|
||||||
* scheduler exits. */
|
scheduler exits. */
|
||||||
static void prvSetTickFrequencyDefault( void );
|
static void prvSetTickFrequencyDefault( void );
|
||||||
|
|
||||||
/*lint -e956 File scopes necessary here. */
|
/*lint -e956 File scopes necessary here. */
|
||||||
|
@ -95,10 +93,10 @@ static int16_t sDOSTickCounter;
|
||||||
static BaseType_t xSchedulerRunning = pdFALSE;
|
static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
||||||
/* Points to the original routine installed on the vector we use for manual context switches. This is then used to restore the original routine during prvExitFunction(). */
|
/* Points to the original routine installed on the vector we use for manual context switches. This is then used to restore the original routine during prvExitFunction(). */
|
||||||
static void( __interrupt __far * pxOldSwitchISR )();
|
static void ( __interrupt __far *pxOldSwitchISR )();
|
||||||
|
|
||||||
/* Points to the original routine installed on the vector we use to chain to the DOS tick. This is then used to restore the original routine during prvExitFunction(). */
|
/* Points to the original routine installed on the vector we use to chain to the DOS tick. This is then used to restore the original routine during prvExitFunction(). */
|
||||||
static void( __interrupt __far * pxOldSwitchISRPlus1 )();
|
static void ( __interrupt __far *pxOldSwitchISRPlus1 )();
|
||||||
|
|
||||||
/* Used to restore the original DOS context when the scheduler is ended. */
|
/* Used to restore the original DOS context when the scheduler is ended. */
|
||||||
static jmp_buf xJumpBuf;
|
static jmp_buf xJumpBuf;
|
||||||
|
@ -108,12 +106,12 @@ static jmp_buf xJumpBuf;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
pxISR pxOriginalTickISR;
|
pxISR pxOriginalTickISR;
|
||||||
|
|
||||||
/* This is called with interrupts already disabled. */
|
/* This is called with interrupts already disabled. */
|
||||||
|
|
||||||
/* Remember what was on the interrupts we are going to use
|
/* Remember what was on the interrupts we are going to use
|
||||||
* so we can put them back later if required. */
|
so we can put them back later if required. */
|
||||||
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
||||||
pxOriginalTickISR = _dos_getvect( portTIMER_INT_NUMBER );
|
pxOriginalTickISR = _dos_getvect( portTIMER_INT_NUMBER );
|
||||||
pxOldSwitchISRPlus1 = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
|
pxOldSwitchISRPlus1 = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
|
||||||
|
@ -121,16 +119,16 @@ BaseType_t xPortStartScheduler( void )
|
||||||
prvSetTickFrequency( configTICK_RATE_HZ );
|
prvSetTickFrequency( configTICK_RATE_HZ );
|
||||||
|
|
||||||
/* Put our manual switch (yield) function on a known
|
/* Put our manual switch (yield) function on a known
|
||||||
* vector. */
|
vector. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||||
|
|
||||||
/* Put the old tick on a different interrupt number so we can
|
/* Put the old tick on a different interrupt number so we can
|
||||||
* call it when we want. */
|
call it when we want. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR );
|
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR );
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative
|
/* The ISR used depends on whether the preemptive or cooperative
|
||||||
* scheduler is being used. */
|
scheduler is being used. */
|
||||||
#if ( configUSE_PREEMPTION == 1 )
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
{
|
{
|
||||||
/* Put our tick switch function on the timer interrupt. */
|
/* Put our tick switch function on the timer interrupt. */
|
||||||
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
||||||
|
@ -143,8 +141,8 @@ BaseType_t xPortStartScheduler( void )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Setup a counter that is used to call the DOS interrupt as close
|
/* Setup a counter that is used to call the DOS interrupt as close
|
||||||
* to it's original frequency as can be achieved given our chosen tick
|
to it's original frequency as can be achieved given our chosen tick
|
||||||
* frequency. */
|
frequency. */
|
||||||
sDOSTickCounter = portTICKS_PER_DOS_TICK;
|
sDOSTickCounter = portTICKS_PER_DOS_TICK;
|
||||||
|
|
||||||
/* Clean up function if we want to return to DOS. */
|
/* Clean up function if we want to return to DOS. */
|
||||||
|
@ -166,8 +164,8 @@ BaseType_t xPortStartScheduler( void )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative
|
/* The ISR used depends on whether the preemptive or cooperative
|
||||||
* scheduler is being used. */
|
scheduler is being used. */
|
||||||
#if ( configUSE_PREEMPTION == 1 )
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
static void __interrupt __far prvPreemptiveTick( void )
|
static void __interrupt __far prvPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Get the scheduler to update the task states following the tick. */
|
/* Get the scheduler to update the task states following the tick. */
|
||||||
|
@ -180,15 +178,15 @@ BaseType_t xPortStartScheduler( void )
|
||||||
/* Reset the PIC ready for the next time. */
|
/* Reset the PIC ready for the next time. */
|
||||||
prvPortResetPIC();
|
prvPortResetPIC();
|
||||||
}
|
}
|
||||||
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
#else
|
||||||
static void __interrupt __far prvNonPreemptiveTick( void )
|
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Same as preemptive tick, but the cooperative scheduler is being used
|
/* Same as preemptive tick, but the cooperative scheduler is being used
|
||||||
* so we don't have to switch in the context of the next task. */
|
so we don't have to switch in the context of the next task. */
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
prvPortResetPIC();
|
prvPortResetPIC();
|
||||||
}
|
}
|
||||||
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void __interrupt __far prvYieldProcessor( void )
|
static void __interrupt __far prvYieldProcessor( void )
|
||||||
|
@ -201,22 +199,19 @@ static void __interrupt __far prvYieldProcessor( void )
|
||||||
static void prvPortResetPIC( void )
|
static void prvPortResetPIC( void )
|
||||||
{
|
{
|
||||||
/* We are going to call the DOS tick interrupt at as close a
|
/* We are going to call the DOS tick interrupt at as close a
|
||||||
* frequency to the normal DOS tick as possible. */
|
frequency to the normal DOS tick as possible. */
|
||||||
|
|
||||||
/* WE SHOULD NOT DO THIS IF YIELD WAS CALLED. */
|
/* WE SHOULD NOT DO THIS IF YIELD WAS CALLED. */
|
||||||
--sDOSTickCounter;
|
--sDOSTickCounter;
|
||||||
|
|
||||||
if( sDOSTickCounter <= 0 )
|
if( sDOSTickCounter <= 0 )
|
||||||
{
|
{
|
||||||
sDOSTickCounter = ( int16_t ) portTICKS_PER_DOS_TICK;
|
sDOSTickCounter = ( int16_t ) portTICKS_PER_DOS_TICK;
|
||||||
__asm {
|
__asm{ int portSWITCH_INT_NUMBER + 1 };
|
||||||
int portSWITCH_INT_NUMBER + 1
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Reset the PIC as the DOS tick is not being called to
|
/* Reset the PIC as the DOS tick is not being called to
|
||||||
* do it. */
|
do it. */
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
mov al, 20H
|
mov al, 20H
|
||||||
|
@ -229,20 +224,19 @@ static void prvPortResetPIC( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Jump back to the processor state prior to starting the
|
/* Jump back to the processor state prior to starting the
|
||||||
* scheduler. This means we are not going to be using a
|
scheduler. This means we are not going to be using a
|
||||||
* task stack frame so the task can be deleted. */
|
task stack frame so the task can be deleted. */
|
||||||
longjmp( xJumpBuf, 1 );
|
longjmp( xJumpBuf, 1 );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvExitFunction( void )
|
static void prvExitFunction( void )
|
||||||
{
|
{
|
||||||
void( __interrupt __far * pxOriginalTickISR )();
|
void ( __interrupt __far *pxOriginalTickISR )();
|
||||||
|
|
||||||
/* Interrupts should be disabled here anyway - but no
|
/* Interrupts should be disabled here anyway - but no
|
||||||
* harm in making sure. */
|
harm in making sure. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( xSchedulerRunning == pdTRUE )
|
if( xSchedulerRunning == pdTRUE )
|
||||||
{
|
{
|
||||||
/* Set the DOS tick back onto the timer ticker. */
|
/* Set the DOS tick back onto the timer ticker. */
|
||||||
|
@ -251,29 +245,28 @@ static void prvExitFunction( void )
|
||||||
prvSetTickFrequencyDefault();
|
prvSetTickFrequencyDefault();
|
||||||
|
|
||||||
/* Put back the switch interrupt routines that was in place
|
/* Put back the switch interrupt routines that was in place
|
||||||
* before the scheduler started. */
|
before the scheduler started. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 );
|
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The tick timer is back how DOS wants it. We can re-enable
|
/* The tick timer is back how DOS wants it. We can re-enable
|
||||||
* interrupts without the scheduler being called. */
|
interrupts without the scheduler being called. */
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
||||||
{
|
{
|
||||||
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
||||||
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
||||||
const uint32_t ulPIT_CONST = ( uint32_t ) 1193180UL;
|
const uint32_t ulPIT_CONST = ( uint32_t ) 1193180UL;
|
||||||
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||||
uint32_t ulOutput;
|
uint32_t ulOutput;
|
||||||
|
|
||||||
/* Setup the 8245 to tick at the wanted frequency. */
|
/* Setup the 8245 to tick at the wanted frequency. */
|
||||||
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
||||||
ulOutput = ulPIT_CONST / ulTickRateHz;
|
ulOutput = ulPIT_CONST / ulTickRateHz;
|
||||||
portOUTPUT_BYTE( usPIT0, ( uint16_t ) ( ulOutput & ( uint32_t ) 0xff ) );
|
portOUTPUT_BYTE( usPIT0, ( uint16_t )( ulOutput & ( uint32_t ) 0xff ) );
|
||||||
ulOutput >>= 8;
|
ulOutput >>= 8;
|
||||||
portOUTPUT_BYTE( usPIT0, ( uint16_t ) ( ulOutput & ( uint32_t ) 0xff ) );
|
portOUTPUT_BYTE( usPIT0, ( uint16_t ) ( ulOutput & ( uint32_t ) 0xff ) );
|
||||||
}
|
}
|
||||||
|
@ -281,14 +274,15 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
||||||
|
|
||||||
static void prvSetTickFrequencyDefault( void )
|
static void prvSetTickFrequencyDefault( void )
|
||||||
{
|
{
|
||||||
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
||||||
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
||||||
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||||
|
|
||||||
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
||||||
portOUTPUT_BYTE( usPIT0, 0 );
|
portOUTPUT_BYTE( usPIT0,0 );
|
||||||
portOUTPUT_BYTE( usPIT0, 0 );
|
portOUTPUT_BYTE( usPIT0,0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*lint +e950 */
|
/*lint +e950 */
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef short BaseType_t;
|
typedef short BaseType_t;
|
||||||
typedef unsigned short UBaseType_t;
|
typedef unsigned short UBaseType_t;
|
||||||
|
|
||||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
|
@ -61,8 +61,7 @@ typedef unsigned short UBaseType_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() __asm{ pushf } \
|
||||||
__asm{ pushf } \
|
|
||||||
__asm{ cli } \
|
__asm{ cli } \
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() __asm{ popf }
|
#define portEXIT_CRITICAL() __asm{ popf }
|
||||||
|
@ -91,7 +90,8 @@ typedef unsigned short UBaseType_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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( vTaskFunction, pvParameters ) void vTaskFunction( void * pvParameters )
|
#define portTASK_FUNCTION_PROTO( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
|
||||||
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void * pvParameters )
|
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -47,16 +47,16 @@ void portSWITCH_CONTEXT( void );
|
||||||
void portFIRST_CONTEXT( void );
|
void portFIRST_CONTEXT( void );
|
||||||
|
|
||||||
/* There are slightly different versions depending on whether you are building
|
/* There are slightly different versions depending on whether you are building
|
||||||
* to include debugger information. If debugger information is used then there
|
to include debugger information. If debugger information is used then there
|
||||||
* are a couple of extra bytes left of the ISR stack (presumably for use by the
|
are a couple of extra bytes left of the ISR stack (presumably for use by the
|
||||||
* debugger). The true stack pointer is then stored in the bp register. We add
|
debugger). The true stack pointer is then stored in the bp register. We add
|
||||||
* 2 to the stack pointer to remove the extra bytes before we restore our context. */
|
2 to the stack pointer to remove the extra bytes before we restore our context. */
|
||||||
|
|
||||||
#define portSWITCH_CONTEXT() \
|
#define portSWITCH_CONTEXT() \
|
||||||
asm { mov ax, seg pxCurrentTCB } \
|
asm { mov ax, seg pxCurrentTCB } \
|
||||||
asm { mov ds, ax } \
|
asm { mov ds, ax } \
|
||||||
asm { les bx, pxCurrentTCB } /* Save the stack pointer into the TCB. */ \
|
asm { les bx, pxCurrentTCB } /* Save the stack pointer into the TCB. */ \
|
||||||
asm { mov es : 0x2[ bx ], ss } \
|
asm { mov es:0x2[ bx ], ss } \
|
||||||
asm { mov es:[ bx ], sp } \
|
asm { mov es:[ bx ], sp } \
|
||||||
asm { call far ptr vTaskSwitchContext } /* Perform the switch. */ \
|
asm { call far ptr vTaskSwitchContext } /* Perform the switch. */ \
|
||||||
asm { mov ax, seg pxCurrentTCB } /* Restore the stack pointer from the TCB. */ \
|
asm { mov ax, seg pxCurrentTCB } /* Restore the stack pointer from the TCB. */ \
|
||||||
|
@ -83,4 +83,5 @@ void portFIRST_CONTEXT( void );
|
||||||
__asm { iret }
|
__asm { iret }
|
||||||
|
|
||||||
|
|
||||||
#endif /* ifndef PORT_ASM_H */
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -26,16 +26,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes from V1.00:
|
Changes from V1.00:
|
||||||
*
|
|
||||||
+ pxPortInitialiseStack() now initialises the stack of new tasks to the
|
+ pxPortInitialiseStack() now initialises the stack of new tasks to the
|
||||||
+ same format used by the compiler. This allows the compiler generated
|
same format used by the compiler. This allows the compiler generated
|
||||||
+ interrupt mechanism to be used for context switches.
|
interrupt mechanism to be used for context switches.
|
||||||
+
|
|
||||||
+ Changes from V2.6.1
|
Changes from V2.6.1
|
||||||
+
|
|
||||||
+ Move usPortCheckFreeStackSpace() to tasks.c.
|
+ Move usPortCheckFreeStackSpace() to tasks.c.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
|
@ -45,14 +45,12 @@
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
|
||||||
{
|
{
|
||||||
StackType_t DS_Reg = 0;
|
StackType_t DS_Reg = 0;
|
||||||
|
|
||||||
/* Place a few bytes of known values on the bottom of the stack.
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
* This is just useful for debugging. */
|
This is just useful for debugging. */
|
||||||
|
|
||||||
*pxTopOfStack = 0x1111;
|
*pxTopOfStack = 0x1111;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -69,8 +67,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||||
|
|
||||||
/* We are going to start the scheduler using a return from interrupt
|
/* We are going to start the scheduler using a return from interrupt
|
||||||
* instruction to load the program counter, so first there would be the
|
instruction to load the program counter, so first there would be the
|
||||||
* function call with parameters preamble. */
|
function call with parameters preamble. */
|
||||||
|
|
||||||
*pxTopOfStack = FP_SEG( pvParameters );
|
*pxTopOfStack = FP_SEG( pvParameters );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -90,8 +88,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The remaining registers would be pushed on the stack by our context
|
/* The remaining registers would be pushed on the stack by our context
|
||||||
* switch function. These are loaded with values simply to make debugging
|
switch function. These are loaded with values simply to make debugging
|
||||||
* easier. */
|
easier. */
|
||||||
*pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */
|
*pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */
|
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */
|
||||||
|
@ -104,9 +102,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* We need the true data segment. */
|
/* We need the true data segment. */
|
||||||
__asm {
|
__asm{ MOV DS_Reg, DS };
|
||||||
MOV DS_Reg, DS
|
|
||||||
};
|
|
||||||
|
|
||||||
*pxTopOfStack = DS_Reg; /* DS */
|
*pxTopOfStack = DS_Reg; /* DS */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -121,3 +117,4 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -37,17 +37,17 @@ uint32_t ulCriticalNesting = 9999;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Registers required to configure the RTI. */
|
/* Registers required to configure the RTI. */
|
||||||
#define portRTI_GCTRL_REG ( *( ( volatile uint32_t * ) 0xFFFFFC00 ) )
|
#define portRTI_GCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC00 ) )
|
||||||
#define portRTI_TBCTRL_REG ( *( ( volatile uint32_t * ) 0xFFFFFC04 ) )
|
#define portRTI_TBCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC04 ) )
|
||||||
#define portRTI_COMPCTRL_REG ( *( ( volatile uint32_t * ) 0xFFFFFC0C ) )
|
#define portRTI_COMPCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC0C ) )
|
||||||
#define portRTI_CNT0_FRC0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC10 ) )
|
#define portRTI_CNT0_FRC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC10 ) )
|
||||||
#define portRTI_CNT0_UC0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC14 ) )
|
#define portRTI_CNT0_UC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC14 ) )
|
||||||
#define portRTI_CNT0_CPUC0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC18 ) )
|
#define portRTI_CNT0_CPUC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC18 ) )
|
||||||
#define portRTI_CNT0_COMP0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC50 ) )
|
#define portRTI_CNT0_COMP0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC50 ) )
|
||||||
#define portRTI_CNT0_UDCP0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC54 ) )
|
#define portRTI_CNT0_UDCP0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC54 ) )
|
||||||
#define portRTI_SETINTENA_REG ( *( ( volatile uint32_t * ) 0xFFFFFC80 ) )
|
#define portRTI_SETINTENA_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC80 ) )
|
||||||
#define portRTI_CLEARINTENA_REG ( *( ( volatile uint32_t * ) 0xFFFFFC84 ) )
|
#define portRTI_CLEARINTENA_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC84 ) )
|
||||||
#define portRTI_INTFLAG_REG ( *( ( volatile uint32_t * ) 0xFFFFFC88 ) )
|
#define portRTI_INTFLAG_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC88 ) )
|
||||||
|
|
||||||
|
|
||||||
/* Constants required to set up the initial stack of each task. */
|
/* Constants required to set up the initial stack of each task. */
|
||||||
|
@ -57,7 +57,7 @@ uint32_t ulCriticalNesting = 9999;
|
||||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||||
|
|
||||||
/* The number of words on the stack frame between the saved Top Of Stack and
|
/* The number of words on the stack frame between the saved Top Of Stack and
|
||||||
* R0 (in which the parameters are passed. */
|
R0 (in which the parameters are passed. */
|
||||||
#define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 )
|
#define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -68,7 +68,7 @@ extern void vPortStartFirstTask( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Saved as part of the task context. Set to pdFALSE if the task does not
|
/* Saved as part of the task context. Set to pdFALSE if the task does not
|
||||||
* require an FPU context. */
|
require an FPU context. */
|
||||||
uint32_t ulTaskHasFPUContext = 0;
|
uint32_t ulTaskHasFPUContext = 0;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -77,11 +77,9 @@ uint32_t ulTaskHasFPUContext = 0;
|
||||||
/*
|
/*
|
||||||
* 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 )
|
|
||||||
{
|
{
|
||||||
StackType_t * pxOriginalTOS;
|
StackType_t *pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
|
@ -93,11 +91,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
* expected by the portRESTORE_CONTEXT() macro. */
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which is the start of the as
|
/* First on the stack is the return address - which is the start of the as
|
||||||
* the task has not executed yet. The offset is added to make the return
|
the task has not executed yet. The offset is added to make the return
|
||||||
* address appear as it would within an IRQ ISR. */
|
address appear as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
@ -133,11 +131,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
}
|
}
|
||||||
#else /* ifdef portPRELOAD_TASK_REGISTERS */
|
#else
|
||||||
{
|
{
|
||||||
pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS;
|
pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS;
|
||||||
}
|
}
|
||||||
#endif /* ifdef portPRELOAD_TASK_REGISTERS */
|
#endif
|
||||||
|
|
||||||
/* Function parameters are passed in R0. */
|
/* Function parameters are passed in R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
|
@ -157,8 +155,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing on the stack is the tasks ulUsingFPU value, which by
|
/* The last thing on the stack is the tasks ulUsingFPU value, which by
|
||||||
* default is set to indicate that the stack frame does not include FPU
|
default is set to indicate that the stack frame does not include FPU
|
||||||
* registers. */
|
registers. */
|
||||||
*pxTopOfStack = pdFALSE;
|
*pxTopOfStack = pdFALSE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -167,7 +165,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt(void)
|
||||||
{
|
{
|
||||||
/* Disable timer 0. */
|
/* Disable timer 0. */
|
||||||
portRTI_GCTRL_REG &= 0xFFFFFFFEUL;
|
portRTI_GCTRL_REG &= 0xFFFFFFFEUL;
|
||||||
|
@ -200,7 +198,7 @@ static void prvSetupTimerInterrupt( void )
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler(void)
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. */
|
/* Start the timer that generates the tick ISR. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
@ -209,7 +207,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
ulCriticalNesting = 0;
|
ulCriticalNesting = 0;
|
||||||
|
|
||||||
/* Start the first task. This is done from portASM.asm as ARM mode must be
|
/* Start the first task. This is done from portASM.asm as ARM mode must be
|
||||||
* used. */
|
used. */
|
||||||
vPortStartFirstTask();
|
vPortStartFirstTask();
|
||||||
|
|
||||||
/* Should not get here! */
|
/* Should not get here! */
|
||||||
|
@ -220,17 +218,17 @@ BaseType_t xPortStartScheduler( void )
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
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( ulCriticalNesting == 1000UL );
|
configASSERT( ulCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
* simply increment the system tick. */
|
* simply increment the system tick. */
|
||||||
__interrupt void vPortNonPreemptiveTick( void )
|
__interrupt void vPortNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
|
@ -238,13 +236,13 @@ void vPortEndScheduler( void )
|
||||||
portRTI_INTFLAG_REG = 0x00000001;
|
portRTI_INTFLAG_REG = 0x00000001;
|
||||||
|
|
||||||
/* Increment the tick count - this may make a delaying task ready
|
/* Increment the tick count - this may make a delaying task ready
|
||||||
* to run - but a context switch is not performed. */
|
to run - but a context switch is not performed. */
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* if configUSE_PREEMPTION == 0 */
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* The preemptive scheduler ISR is written in assembler and can be found
|
* The preemptive scheduler ISR is written in assembler and can be found
|
||||||
* in the portASM.asm file. This will only get used if portUSE_PREEMPTION
|
* in the portASM.asm file. This will only get used if portUSE_PREEMPTION
|
||||||
|
@ -253,7 +251,7 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
void vPortPreemptiveTick( void );
|
void vPortPreemptiveTick( void );
|
||||||
|
|
||||||
#endif /* if configUSE_PREEMPTION == 0 */
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -266,8 +264,8 @@ void vPortEnterCritical( void )
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
* portENTER_CRITICAL() has been called. */
|
portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -284,7 +282,7 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
* re-enabled. */
|
re-enabled. */
|
||||||
if( ulCriticalNesting == 0 )
|
if( ulCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portENABLE_INTERRUPTS(). */
|
/* Enable interrupts as per portENABLE_INTERRUPTS(). */
|
||||||
|
@ -301,7 +299,7 @@ void vPortExitCritical( void )
|
||||||
extern void vPortInitialiseFPSCR( void );
|
extern void vPortInitialiseFPSCR( void );
|
||||||
|
|
||||||
/* A task is registering the fact that it needs an FPU context. Set the
|
/* A task is registering the fact that it needs an FPU context. Set the
|
||||||
* FPU flag (saved as part of the task context. */
|
FPU flag (saved as part of the task context. */
|
||||||
ulTaskHasFPUContext = pdTRUE;
|
ulTaskHasFPUContext = pdTRUE;
|
||||||
|
|
||||||
/* Initialise the floating point status register. */
|
/* Initialise the floating point status register. */
|
||||||
|
@ -311,3 +309,4 @@ void vPortExitCritical( void )
|
||||||
#endif /* __TI_VFP_SUPPORT__ */
|
#endif /* __TI_VFP_SUPPORT__ */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -51,40 +51,40 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
#if (configUSE_16_BIT_TICKS == 1)
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xFFFF
|
#define portMAX_DELAY (TickType_t) 0xFFFF
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xFFFFFFFFF
|
#define portMAX_DELAY (TickType_t) 0xFFFFFFFFF
|
||||||
|
|
||||||
/* 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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical(void);
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical(void);
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
#define portDISABLE_INTERRUPTS() asm ( " CPSID I" )
|
#define portDISABLE_INTERRUPTS() asm( " CPSID I" )
|
||||||
#define portENABLE_INTERRUPTS() asm ( " CPSIE I" )
|
#define portENABLE_INTERRUPTS() asm( " CPSIE I" )
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
#pragma SWI_ALIAS( vPortYield, 0 )
|
#pragma SWI_ALIAS( vPortYield, 0 )
|
||||||
extern void vPortYield( void );
|
extern void vPortYield( void );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portSYS_SSIR1_REG ( *( ( volatile uint32_t * ) 0xFFFFFFB0 ) )
|
#define portSYS_SSIR1_REG ( * ( ( volatile uint32_t * ) 0xFFFFFFB0 ) )
|
||||||
#define portSYS_SSIR1_SSKEY ( 0x7500UL )
|
#define portSYS_SSIR1_SSKEY ( 0x7500UL )
|
||||||
#define portYIELD_WITHIN_API() { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; asm ( " DSB " ); asm ( " ISB " ); }
|
#define portYIELD_WITHIN_API() { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; asm( " DSB " ); asm( " ISB " ); }
|
||||||
#define portYIELD_FROM_ISR( x ) if( x != pdFALSE ) { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; ( void ) portSYS_SSIR1_REG; }
|
#define portYIELD_FROM_ISR( x ) if( x != pdFALSE ){ portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; ( void ) portSYS_SSIR1_REG; }
|
||||||
|
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
@ -93,16 +93,16 @@ extern void vPortYield( void );
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if ( configMAX_PRIORITIES > 32 )
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
@ -110,7 +110,8 @@ extern void vPortYield( void );
|
||||||
|
|
||||||
|
|
||||||
/* 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( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters)
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters)
|
||||||
|
|
||||||
#endif /* __PORTMACRO_H__ */
|
#endif /* __PORTMACRO_H__ */
|
||||||
|
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
; /*
|
;/*
|
||||||
* ; * FreeRTOS Kernel V10.3.1
|
; * FreeRTOS Kernel V10.3.1
|
||||||
* ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
* ; *
|
; *
|
||||||
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* ; * this software and associated documentation files (the "Software"), to deal in
|
; * this software and associated documentation files (the "Software"), to deal in
|
||||||
* ; * the Software without restriction, including without limitation the rights to
|
; * the Software without restriction, including without limitation the rights to
|
||||||
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
|
; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
* ; * subject to the following conditions:
|
; * subject to the following conditions:
|
||||||
* ; *
|
; *
|
||||||
* ; * The above copyright notice and this permission notice shall be included in all
|
; * The above copyright notice and this permission notice shall be included in all
|
||||||
* ; * copies or substantial portions of the Software.
|
; * copies or substantial portions of the Software.
|
||||||
* ; *
|
; *
|
||||||
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
* ; *
|
; *
|
||||||
* ; * http://www.FreeRTOS.org
|
; * http://www.FreeRTOS.org
|
||||||
* ; * http://aws.amazon.com/freertos
|
; * http://aws.amazon.com/freertos
|
||||||
* ; *
|
; *
|
||||||
* ; * 1 tab == 4 spaces!
|
; * 1 tab == 4 spaces!
|
||||||
* ; */
|
; */
|
||||||
|
|
||||||
.if $DEFINED( __LARGE_DATA_MODEL__ )
|
.if $DEFINED( __LARGE_DATA_MODEL__ )
|
||||||
.define "pushm.a", pushm_x
|
.define "pushm.a", pushm_x
|
||||||
.define "popm.a", popm_x
|
.define "popm.a", popm_x
|
||||||
.define "push.a", push_x
|
.define "push.a", push_x
|
||||||
|
@ -46,3 +46,8 @@
|
||||||
.define "call", call_x
|
.define "call", call_x
|
||||||
.define "ret", ret_x
|
.define "ret", ret_x
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,28 +30,28 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the MSP430X port.
|
* Implementation of functions defined in portable.h for the MSP430X port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
|
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
|
||||||
* not the MCLK. */
|
not the MCLK. */
|
||||||
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
|
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
|
||||||
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
|
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
|
||||||
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 )
|
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 )
|
||||||
|
|
||||||
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
||||||
* any details of its type. */
|
any details of its type. */
|
||||||
typedef void TCB_t;
|
typedef void TCB_t;
|
||||||
extern volatile TCB_t * volatile pxCurrentTCB;
|
extern volatile TCB_t * volatile pxCurrentTCB;
|
||||||
|
|
||||||
/* Each task maintains a count of the critical section nesting depth. Each
|
/* Each task maintains a count of the critical section nesting depth. Each
|
||||||
* time a critical section is entered the count is incremented. Each time a
|
time a critical section is entered the count is incremented. Each time a
|
||||||
* critical section is exited the count is decremented - with interrupts only
|
critical section is exited the count is decremented - with interrupts only
|
||||||
* being re-enabled if the count is zero.
|
being re-enabled if the count is zero.
|
||||||
*
|
|
||||||
* usCriticalNesting will get set to zero when the scheduler starts, but must
|
usCriticalNesting will get set to zero when the scheduler starts, but must
|
||||||
* not be initialised to zero as this will cause problems during the startup
|
not be initialised to zero as this will cause problems during the startup
|
||||||
* sequence. */
|
sequence. */
|
||||||
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -69,27 +69,25 @@ void vPortSetupTimerInterrupt( void );
|
||||||
*
|
*
|
||||||
* See the header file portable.h.
|
* See the header file portable.h.
|
||||||
*/
|
*/
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
TaskFunction_t pxCode,
|
|
||||||
void * pvParameters )
|
|
||||||
{
|
{
|
||||||
uint16_t * pusTopOfStack;
|
uint16_t *pusTopOfStack;
|
||||||
uint32_t * pulTopOfStack, ulTemp;
|
uint32_t *pulTopOfStack, ulTemp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Place a few bytes of known values on the bottom of the stack.
|
Place a few bytes of known values on the bottom of the stack.
|
||||||
* This is just useful for debugging and can be included if required.
|
This is just useful for debugging and can be included if required.
|
||||||
*
|
|
||||||
* pxTopOfStack = ( StackType_t ) 0x1111;
|
*pxTopOfStack = ( StackType_t ) 0x1111;
|
||||||
* pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
* pxTopOfStack = ( StackType_t ) 0x2222;
|
*pxTopOfStack = ( StackType_t ) 0x2222;
|
||||||
* pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
* pxTopOfStack = ( StackType_t ) 0x3333;
|
*pxTopOfStack = ( StackType_t ) 0x3333;
|
||||||
* pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Data types are need either 16 bits or 32 bits depending on the data
|
/* Data types are need either 16 bits or 32 bits depending on the data
|
||||||
* and code model used. */
|
and code model used. */
|
||||||
if( sizeof( pxCode ) == sizeof( uint16_t ) )
|
if( sizeof( pxCode ) == sizeof( uint16_t ) )
|
||||||
{
|
{
|
||||||
pusTopOfStack = ( uint16_t * ) pxTopOfStack;
|
pusTopOfStack = ( uint16_t * ) pxTopOfStack;
|
||||||
|
@ -138,19 +136,19 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x4444;
|
*pxTopOfStack = ( StackType_t ) 0x4444;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
#else /* ifdef PRELOAD_REGISTER_VALUES */
|
#else
|
||||||
pxTopOfStack -= 3;
|
pxTopOfStack -= 3;
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||||
pxTopOfStack -= 9;
|
pxTopOfStack -= 9;
|
||||||
#endif /* ifdef PRELOAD_REGISTER_VALUES */
|
#endif
|
||||||
|
|
||||||
/* A variable is used to keep track of the critical section nesting.
|
/* A variable is used to keep track of the critical section nesting.
|
||||||
* This variable has to be stored as part of the task context and is
|
This variable has to be stored as part of the task context and is
|
||||||
* initially set to zero. */
|
initially set to zero. */
|
||||||
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
/* Return a pointer to the top of the stack we have generated so this can
|
/* Return a pointer to the top of the stack we have generated so this can
|
||||||
* be stored in the task control block for the task. */
|
be stored in the task control block for the task. */
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -158,7 +156,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the MSP430 port will get stopped. If required simply
|
/* It is unlikely that the MSP430 port will get stopped. If required simply
|
||||||
* disable the tick interrupt here. */
|
disable the tick interrupt here. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -174,7 +172,7 @@ void vPortSetupTimerInterrupt( void )
|
||||||
#pragma vector=configTICK_VECTOR
|
#pragma vector=configTICK_VECTOR
|
||||||
interrupt void vTickISREntry( void )
|
interrupt void vTickISREntry( void )
|
||||||
{
|
{
|
||||||
extern void vPortTickISR( void );
|
extern void vPortTickISR( void );
|
||||||
|
|
||||||
__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
|
__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
|
||||||
#if configUSE_PREEMPTION == 1
|
#if configUSE_PREEMPTION == 1
|
||||||
|
@ -185,3 +183,5 @@ interrupt void vTickISREntry( void )
|
||||||
vPortCooperativeTickISR();
|
vPortCooperativeTickISR();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef short BaseType_t;
|
typedef short BaseType_t;
|
||||||
typedef unsigned short UBaseType_t;
|
typedef unsigned short UBaseType_t;
|
||||||
|
|
||||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
|
@ -80,8 +80,8 @@ typedef unsigned short UBaseType_t;
|
||||||
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
|
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
|
||||||
|
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint16_t usCriticalNesting; \
|
extern volatile uint16_t usCriticalNesting; \
|
||||||
\
|
\
|
||||||
portDISABLE_INTERRUPTS(); \
|
portDISABLE_INTERRUPTS(); \
|
||||||
\
|
\
|
||||||
|
@ -89,11 +89,11 @@ typedef unsigned short UBaseType_t;
|
||||||
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
||||||
/* times portENTER_CRITICAL() has been called. */ \
|
/* times portENTER_CRITICAL() has been called. */ \
|
||||||
usCriticalNesting++; \
|
usCriticalNesting++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint16_t usCriticalNesting; \
|
extern volatile uint16_t usCriticalNesting; \
|
||||||
\
|
\
|
||||||
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -107,7 +107,7 @@ typedef unsigned short UBaseType_t;
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
@ -127,8 +127,8 @@ extern void vPortYield( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
extern void vTaskSwitchContext( void );
|
extern void vTaskSwitchContext( void );
|
||||||
#define portYIELD_FROM_ISR( x ) if( x ) vPortYield()
|
#define portYIELD_FROM_ISR( x ) if( x ) vPortYield()
|
||||||
|
@ -136,7 +136,8 @@ extern void vTaskSwitchContext( void );
|
||||||
void vApplicationSetupTimerInterrupt( void );
|
void vApplicationSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/* sizeof( int ) != sizeof( long ) so a full printf() library is required if
|
/* sizeof( int ) != sizeof( long ) so a full printf() library is required if
|
||||||
* run time stats information is to be displayed. */
|
run time stats information is to be displayed. */
|
||||||
#define portLU_PRINTF_SPECIFIER_REQUIRED
|
#define portLU_PRINTF_SPECIFIER_REQUIRED
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
||||||
|
|
||||||
/* Supervisor mode set. */
|
/* Supervisor mode set. */
|
||||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000 )
|
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000)
|
||||||
|
|
||||||
/* The clock prescale into the timer peripheral. */
|
/* The clock prescale into the timer peripheral. */
|
||||||
#define portPRESCALE_VALUE ( ( uint8_t ) 10 )
|
#define portPRESCALE_VALUE ( ( uint8_t ) 10 )
|
||||||
|
@ -45,23 +45,20 @@ asm void interrupt VectorNumber_VL1swi vPortYieldISR( void );
|
||||||
static void prvSetupTimerInterrupt( void );
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
||||||
* will be set to 0 prior to the first task being started. */
|
will be set to 0 prior to the first task being started. */
|
||||||
static uint32_t ulCriticalNesting = 0x9999UL;
|
static uint32_t ulCriticalNesting = 0x9999UL;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
TaskFunction_t pxCode,
|
|
||||||
void * pvParameters )
|
|
||||||
{
|
{
|
||||||
uint32_t ulOriginalA5;
|
|
||||||
|
|
||||||
__asm {
|
uint32_t ulOriginalA5;
|
||||||
MOVE.L A5, ulOriginalA5
|
|
||||||
};
|
__asm{ MOVE.L A5, ulOriginalA5 };
|
||||||
|
|
||||||
|
|
||||||
*pxTopOfStack = ( StackType_t ) 0xDEADBEEF;
|
*pxTopOfStack = (StackType_t) 0xDEADBEEF;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Exception stack frame starts with the return address. */
|
/* Exception stack frame starts with the return address. */
|
||||||
|
@ -86,7 +83,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void vPortStartFirstTask( void );
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
ulCriticalNesting = 0UL;
|
ulCriticalNesting = 0UL;
|
||||||
|
|
||||||
|
@ -109,7 +106,7 @@ static void prvSetupTimerInterrupt( void )
|
||||||
RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ;
|
RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
/* Enable the RTC to generate interrupts - interrupts are already disabled
|
/* Enable the RTC to generate interrupts - interrupts are already disabled
|
||||||
* when this code executes. */
|
when this code executes. */
|
||||||
RTCSC_RTIE = 1;
|
RTCSC_RTIE = 1;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -125,20 +122,19 @@ void vPortEnterCritical( void )
|
||||||
if( ulCriticalNesting == 0UL )
|
if( ulCriticalNesting == 0UL )
|
||||||
{
|
{
|
||||||
/* Guard against context switches being pended simultaneously with a
|
/* Guard against context switches being pended simultaneously with a
|
||||||
* critical section being entered. */
|
critical section being entered. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( INTC_FRC == 0UL )
|
if( INTC_FRC == 0UL )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
} while( 1 );
|
} while( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -146,7 +142,6 @@ void vPortEnterCritical( void )
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
if( ulCriticalNesting == 0 )
|
if( ulCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
@ -156,7 +151,7 @@ void vPortExitCritical( void )
|
||||||
|
|
||||||
void vPortYieldHandler( void )
|
void vPortYieldHandler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulSavedInterruptMask;
|
uint32_t ulSavedInterruptMask;
|
||||||
|
|
||||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
|
@ -170,7 +165,7 @@ void vPortYieldHandler( void )
|
||||||
|
|
||||||
void interrupt VectorNumber_Vrtc vPortTickISR( void )
|
void interrupt VectorNumber_Vrtc vPortTickISR( void )
|
||||||
{
|
{
|
||||||
uint32_t ulSavedInterruptMask;
|
uint32_t ulSavedInterruptMask;
|
||||||
|
|
||||||
/* Clear the interrupt. */
|
/* Clear the interrupt. */
|
||||||
RTCSC |= RTCSC_RTIF_MASK;
|
RTCSC |= RTCSC_RTIF_MASK;
|
||||||
|
@ -185,3 +180,4 @@ void interrupt VectorNumber_Vrtc vPortTickISR( void )
|
||||||
}
|
}
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -43,73 +43,73 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#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 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
uint32_t ulPortSetIPL( uint32_t );
|
uint32_t ulPortSetIPL( uint32_t );
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
||||||
|
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
||||||
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
#define portNOP() asm volatile ( "nop" )
|
#define portNOP() asm volatile ( "nop" )
|
||||||
|
|
||||||
/* Context switches are requested using the force register. */
|
/* Context switches are requested using the force register. */
|
||||||
#define portYIELD() INTC_SFRC = 0x3E; portNOP(); portNOP(); portNOP(); portNOP(); portNOP()
|
#define portYIELD() INTC_SFRC = 0x3E; portNOP(); portNOP(); portNOP(); portNOP(); portNOP()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 ) __attribute__( ( noreturn ) )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \
|
||||||
if( xSwitchRequired != pdFALSE ) \
|
|
||||||
{ \
|
{ \
|
||||||
portYIELD(); \
|
portYIELD(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -33,38 +33,36 @@
|
||||||
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
||||||
|
|
||||||
/* Supervisor mode set. */
|
/* Supervisor mode set. */
|
||||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000 )
|
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000)
|
||||||
|
|
||||||
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
||||||
* will be set to 0 prior to the first task being started. */
|
will be set to 0 prior to the first task being started. */
|
||||||
static uint32_t ulCriticalNesting = 0x9999UL;
|
static uint32_t ulCriticalNesting = 0x9999UL;
|
||||||
|
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
lea.l( -60, % sp ), % sp; \
|
lea.l (-60, %sp), %sp; \
|
||||||
movem.l % d0 - % fp, ( % sp ); \
|
movem.l %d0-%fp, (%sp); \
|
||||||
move.l pxCurrentTCB, % a0; \
|
move.l pxCurrentTCB, %a0; \
|
||||||
move.l % sp, ( % a0 );
|
move.l %sp, (%a0);
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
move.l pxCurrentTCB, % a0; \
|
move.l pxCurrentTCB, %a0; \
|
||||||
move.l( % a0 ), % sp; \
|
move.l (%a0), %sp; \
|
||||||
movem.l( % sp ), % d0 - % fp; \
|
movem.l (%sp), %d0-%fp; \
|
||||||
lea.l % sp@( 60 ), % sp; \
|
lea.l %sp@(60), %sp; \
|
||||||
rte
|
rte
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
TaskFunction_t pxCode,
|
|
||||||
void * pvParameters )
|
|
||||||
{
|
{
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = ( StackType_t ) 0xDEADBEEF;
|
*pxTopOfStack = (StackType_t) 0xDEADBEEF;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Exception stack frame starts with the return address. */
|
/* Exception stack frame starts with the return address. */
|
||||||
|
@ -83,7 +81,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void vPortStartFirstTask( void );
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
ulCriticalNesting = 0UL;
|
ulCriticalNesting = 0UL;
|
||||||
|
|
||||||
|
@ -108,20 +106,19 @@ void vPortEnterCritical( void )
|
||||||
if( ulCriticalNesting == 0UL )
|
if( ulCriticalNesting == 0UL )
|
||||||
{
|
{
|
||||||
/* Guard against context switches being pended simultaneously with a
|
/* Guard against context switches being pended simultaneously with a
|
||||||
* critical section being entered. */
|
critical section being entered. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( MCF_INTC0_INTFRCH == 0UL )
|
if( MCF_INTC0_INTFRCH == 0UL )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
} while( 1 );
|
} while( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -129,7 +126,6 @@ void vPortEnterCritical( void )
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
if( ulCriticalNesting == 0 )
|
if( ulCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
@ -139,7 +135,7 @@ void vPortExitCritical( void )
|
||||||
|
|
||||||
void vPortYieldHandler( void )
|
void vPortYieldHandler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulSavedInterruptMask;
|
uint32_t ulSavedInterruptMask;
|
||||||
|
|
||||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
/* Note this will clear all forced interrupts - this is done for speed. */
|
/* Note this will clear all forced interrupts - this is done for speed. */
|
||||||
|
@ -148,3 +144,4 @@ void vPortYieldHandler( void )
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -43,72 +43,72 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#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 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
uint32_t ulPortSetIPL( uint32_t );
|
uint32_t ulPortSetIPL( uint32_t );
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
||||||
|
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
||||||
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
#define portNOP() asm volatile ( "nop" )
|
#define portNOP() asm volatile ( "nop" )
|
||||||
|
|
||||||
/* Note this will overwrite all other bits in the force register, it is done this way for speed. */
|
/* Note this will overwrite all other bits in the force register, it is done this way for speed. */
|
||||||
#define portYIELD() MCF_INTC0_INTFRCL = ( 1UL << configYIELD_INTERRUPT_VECTOR ); portNOP(); portNOP() /* -32 as we are using the high word of the 64bit mask. */
|
#define portYIELD() MCF_INTC0_INTFRCL = ( 1UL << configYIELD_INTERRUPT_VECTOR ); portNOP(); portNOP() /* -32 as we are using the high word of the 64bit mask. */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 ) __attribute__( ( noreturn ) )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \
|
||||||
if( xSwitchRequired != pdFALSE ) \
|
|
||||||
{ \
|
{ \
|
||||||
portYIELD(); \
|
portYIELD(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the HCS12 port.
|
* Implementation of functions defined in portable.h for the HCS12 port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -42,29 +42,29 @@
|
||||||
static void prvSetupTimerInterrupt( void );
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/* Interrupt service routines have to be in non-banked memory - as does the
|
/* Interrupt service routines have to be in non-banked memory - as does the
|
||||||
* scheduler startup function. */
|
scheduler startup function. */
|
||||||
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
||||||
|
|
||||||
/* Manual context switch function. This is the SWI ISR. */
|
/* Manual context switch function. This is the SWI ISR. */
|
||||||
void interrupt vPortYield( void );
|
void interrupt vPortYield( void );
|
||||||
|
|
||||||
/* Tick context switch function. This is the timer ISR. */
|
/* Tick context switch function. This is the timer ISR. */
|
||||||
void interrupt vPortTickInterrupt( void );
|
void interrupt vPortTickInterrupt( void );
|
||||||
|
|
||||||
/* Simply called by xPortStartScheduler(). xPortStartScheduler() does not
|
/* Simply called by xPortStartScheduler(). xPortStartScheduler() does not
|
||||||
* start the scheduler directly because the header file containing the
|
start the scheduler directly because the header file containing the
|
||||||
* xPortStartScheduler() prototype is part of the common kernel code, and
|
xPortStartScheduler() prototype is part of the common kernel code, and
|
||||||
* therefore cannot use the CODE_SEG pragma. */
|
therefore cannot use the CODE_SEG pragma. */
|
||||||
static BaseType_t xBankedStartScheduler( void );
|
static BaseType_t xBankedStartScheduler( void );
|
||||||
|
|
||||||
#pragma CODE_SEG DEFAULT
|
#pragma CODE_SEG DEFAULT
|
||||||
|
|
||||||
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
|
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
|
||||||
* critical section should not be left (i.e. interrupts should not be re-enabled)
|
critical section should not be left (i.e. interrupts should not be re-enabled)
|
||||||
* until the nesting depth reaches 0. This variable simply tracks the nesting
|
until the nesting depth reaches 0. This variable simply tracks the nesting
|
||||||
* depth. Each task maintains it's own critical nesting depth variable so
|
depth. Each task maintains it's own critical nesting depth variable so
|
||||||
* uxCriticalNesting is saved and restored from the task stack during a context
|
uxCriticalNesting is saved and restored from the task stack during a context
|
||||||
* switch. */
|
switch. */
|
||||||
volatile UBaseType_t uxCriticalNesting = 0xff;
|
volatile UBaseType_t uxCriticalNesting = 0xff;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -72,33 +72,31 @@ volatile UBaseType_t uxCriticalNesting = 0xff;
|
||||||
/*
|
/*
|
||||||
* 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 )
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Place a few bytes of known values on the bottom of the stack.
|
Place a few bytes of known values on the bottom of the stack.
|
||||||
* This can be uncommented to provide useful stack markers when debugging.
|
This can be uncommented to provide useful stack markers when debugging.
|
||||||
*
|
|
||||||
* pxTopOfStack = ( StackType_t ) 0x11;
|
*pxTopOfStack = ( StackType_t ) 0x11;
|
||||||
* pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
* pxTopOfStack = ( StackType_t ) 0x22;
|
*pxTopOfStack = ( StackType_t ) 0x22;
|
||||||
* pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
* pxTopOfStack = ( StackType_t ) 0x33;
|
*pxTopOfStack = ( StackType_t ) 0x33;
|
||||||
* pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
* expected by the portRESTORE_CONTEXT() macro. In this case the stack as
|
expected by the portRESTORE_CONTEXT() macro. In this case the stack as
|
||||||
* expected by the HCS12 RTI instruction. */
|
expected by the HCS12 RTI instruction. */
|
||||||
|
|
||||||
|
|
||||||
/* The address of the task function is placed in the stack byte at a time. */
|
/* The address of the task function is placed in the stack byte at a time. */
|
||||||
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pxCode ) ) + 1 );
|
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pxCode) ) + 1 );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pxCode ) ) + 0 );
|
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pxCode) ) + 0 );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Next are all the registers that form part of the task context. */
|
/* Next are all the registers that form part of the task context. */
|
||||||
|
@ -116,15 +114,15 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* A register contains parameter high byte. */
|
/* A register contains parameter high byte. */
|
||||||
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pvParameters ) ) + 0 );
|
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pvParameters) ) + 0 );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* B register contains parameter low byte. */
|
/* B register contains parameter low byte. */
|
||||||
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pvParameters ) ) + 1 );
|
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pvParameters) ) + 1 );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* CCR: Note that when the task starts interrupts will be enabled since
|
/* CCR: Note that when the task starts interrupts will be enabled since
|
||||||
* "I" bit of CCR is cleared */
|
"I" bit of CCR is cleared */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
@ -135,7 +133,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Finally the critical nesting depth is initialised with 0 (not within
|
/* Finally the critical nesting depth is initialised with 0 (not within
|
||||||
* a critical section). */
|
a critical section). */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -158,10 +156,10 @@ static void prvSetupTimerInterrupt( void )
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* xPortStartScheduler() does not start the scheduler directly because
|
/* xPortStartScheduler() does not start the scheduler directly because
|
||||||
* the header file containing the xPortStartScheduler() prototype is part
|
the header file containing the xPortStartScheduler() prototype is part
|
||||||
* of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
||||||
* Instead it simply calls the locally defined xBankedStartScheduler() -
|
Instead it simply calls the locally defined xBankedStartScheduler() -
|
||||||
* which does use the CODE_SEG pragma. */
|
which does use the CODE_SEG pragma. */
|
||||||
|
|
||||||
return xBankedStartScheduler();
|
return xBankedStartScheduler();
|
||||||
}
|
}
|
||||||
|
@ -172,7 +170,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
static BaseType_t xBankedStartScheduler( void )
|
static BaseType_t xBankedStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
||||||
* disabled when this function is called. */
|
disabled when this function is called. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Restore the context of the first task. */
|
/* Restore the context of the first task. */
|
||||||
|
@ -223,15 +221,17 @@ void interrupt vPortTickInterrupt( void )
|
||||||
TFLG1 = 1;
|
TFLG1 = 1;
|
||||||
|
|
||||||
/* Restore the context of a task - which may be a different task
|
/* Restore the context of a task - which may be a different task
|
||||||
* to that interrupted. */
|
to that interrupted. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
#else /* if configUSE_PREEMPTION == 1 */
|
#else
|
||||||
{
|
{
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
TFLG1 = 1;
|
TFLG1 = 1;
|
||||||
}
|
}
|
||||||
#endif /* if configUSE_PREEMPTION == 1 */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma CODE_SEG DEFAULT
|
#pragma CODE_SEG DEFAULT
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef signed char BaseType_t;
|
typedef signed char BaseType_t;
|
||||||
typedef unsigned char UBaseType_t;
|
typedef unsigned char UBaseType_t;
|
||||||
|
|
||||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
|
@ -80,12 +80,12 @@ typedef unsigned char UBaseType_t;
|
||||||
* directly. Each task maintains its own nesting count.
|
* directly. Each task maintains its own nesting count.
|
||||||
*/
|
*/
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
\
|
\
|
||||||
portDISABLE_INTERRUPTS(); \
|
portDISABLE_INTERRUPTS(); \
|
||||||
uxCriticalNesting++; \
|
uxCriticalNesting++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interrupts are disabled so we can access the nesting count directly. If the
|
* Interrupts are disabled so we can access the nesting count directly. If the
|
||||||
|
@ -93,7 +93,7 @@ typedef unsigned char UBaseType_t;
|
||||||
* section and interrupts can be re-enabled.
|
* section and interrupts can be re-enabled.
|
||||||
*/
|
*/
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
\
|
\
|
||||||
uxCriticalNesting--; \
|
uxCriticalNesting--; \
|
||||||
|
@ -101,7 +101,7 @@ typedef unsigned char UBaseType_t;
|
||||||
{ \
|
{ \
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
@ -117,8 +117,7 @@ typedef unsigned char UBaseType_t;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef BANKED_MODEL
|
#ifdef BANKED_MODEL
|
||||||
|
/*
|
||||||
/*
|
|
||||||
* Load the stack pointer for the task, then pull the critical nesting
|
* Load the stack pointer for the task, then pull the critical nesting
|
||||||
* count and PPAGE register from the stack. The remains of the
|
* count and PPAGE register from the stack. The remains of the
|
||||||
* context are restored by the RTI instruction.
|
* context are restored by the RTI instruction.
|
||||||
|
@ -136,7 +135,7 @@ typedef unsigned char UBaseType_t;
|
||||||
__asm( "staa 0x30" ); /* 0x30 = PPAGE */ \
|
__asm( "staa 0x30" ); /* 0x30 = PPAGE */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* By the time this macro is called the processor has already stacked the
|
* By the time this macro is called the processor has already stacked the
|
||||||
* registers. Simply stack the nesting count and PPAGE value, then save
|
* registers. Simply stack the nesting count and PPAGE value, then save
|
||||||
* the task stack pointer.
|
* the task stack pointer.
|
||||||
|
@ -153,9 +152,9 @@ typedef unsigned char UBaseType_t;
|
||||||
__asm( "ldx pxCurrentTCB" ); \
|
__asm( "ldx pxCurrentTCB" ); \
|
||||||
__asm( "sts 0, x" ); \
|
__asm( "sts 0, x" ); \
|
||||||
}
|
}
|
||||||
#else /* ifdef BANKED_MODEL */
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These macros are as per the BANKED versions above, but without saving
|
* These macros are as per the BANKED versions above, but without saving
|
||||||
* and restoring the PPAGE register.
|
* and restoring the PPAGE register.
|
||||||
*/
|
*/
|
||||||
|
@ -181,7 +180,7 @@ typedef unsigned char UBaseType_t;
|
||||||
__asm( "ldx pxCurrentTCB" ); \
|
__asm( "ldx pxCurrentTCB" ); \
|
||||||
__asm( "sts 0, x" ); \
|
__asm( "sts 0, x" ); \
|
||||||
}
|
}
|
||||||
#endif /* ifdef BANKED_MODEL */
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility macro to call macros above in correct order in order to perform a
|
* Utility macro to call macros above in correct order in order to perform a
|
||||||
|
@ -196,7 +195,8 @@ typedef unsigned char UBaseType_t;
|
||||||
|
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,13 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the Atmel AT91R40008
|
* Implementation of functions defined in portable.h for the Atmel AT91R40008
|
||||||
* port.
|
* port.
|
||||||
*
|
*
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in this file. The ISR routines, which can only be compiled
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
* to ARM mode are contained in portISR.c.
|
* to ARM mode are contained in portISR.c.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -73,24 +73,22 @@ extern void vPortISRStartFirstTask( 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 )
|
|
||||||
{
|
{
|
||||||
StackType_t * pxOriginalTOS;
|
StackType_t *pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
* is not really required. */
|
is not really required. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
* expected by the portRESTORE_CONTEXT() macro. */
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which in this case is the
|
/* First on the stack is the return address - which in this case is the
|
||||||
* start of the task. The offset is added to make the return address appear
|
start of the task. The offset is added to make the return address appear
|
||||||
* as it would within an IRQ ISR. */
|
as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
@ -124,12 +122,12 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
* R0. */
|
R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing onto the stack is the status register, which is set for
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
* system mode, with interrupts enabled. */
|
system mode, with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
@ -142,9 +140,9 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Some optimisation levels use the stack differently to others. This
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
* means the interrupt flags cannot always be stored on the stack and will
|
means the interrupt flags cannot always be stored on the stack and will
|
||||||
* instead be stored in a variable, which is then saved as part of the
|
instead be stored in a variable, which is then saved as part of the
|
||||||
* tasks context. */
|
tasks context. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -154,7 +152,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
* here already. */
|
here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
@ -168,7 +166,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the ARM port will require this function as there
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
* is nothing to return to. */
|
is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -177,7 +175,7 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulDummy;
|
volatile uint32_t ulDummy;
|
||||||
|
|
||||||
/* Enable clock to the tick timer... */
|
/* Enable clock to the tick timer... */
|
||||||
AT91C_BASE_PS->PS_PCER = portTIMER_CLK_ENABLE_BIT;
|
AT91C_BASE_PS->PS_PCER = portTIMER_CLK_ENABLE_BIT;
|
||||||
|
@ -192,17 +190,17 @@ static void prvSetupTimerInterrupt( void )
|
||||||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||||
|
|
||||||
/* Store interrupt handler function address in tick timer vector register...
|
/* Store interrupt handler function address in tick timer vector register...
|
||||||
* The ISR installed depends on whether the preemptive or cooperative
|
The ISR installed depends on whether the preemptive or cooperative
|
||||||
* scheduler is being used. */
|
scheduler is being used. */
|
||||||
#if configUSE_PREEMPTION == 1
|
#if configUSE_PREEMPTION == 1
|
||||||
{
|
{
|
||||||
extern void( vPreemptiveTick )( void );
|
extern void ( vPreemptiveTick )( void );
|
||||||
AT91C_BASE_AIC->AIC_SVR[ portTIMER_AIC_CHANNEL ] = ( uint32_t ) vPreemptiveTick;
|
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( uint32_t ) vPreemptiveTick;
|
||||||
}
|
}
|
||||||
#else // else use cooperative scheduler
|
#else // else use cooperative scheduler
|
||||||
{
|
{
|
||||||
extern void( vNonPreemptiveTick )( void );
|
extern void ( vNonPreemptiveTick )( void );
|
||||||
AT91C_BASE_AIC->AIC_SVR[ portTIMER_AIC_CHANNEL ] = ( uint32_t ) vNonPreemptiveTick;
|
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( uint32_t ) vNonPreemptiveTick;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -210,30 +208,31 @@ static void prvSetupTimerInterrupt( void )
|
||||||
AT91C_BASE_AIC->AIC_SMR[ portTIMER_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | portTICK_PRIORITY_6;
|
AT91C_BASE_AIC->AIC_SMR[ portTIMER_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | portTICK_PRIORITY_6;
|
||||||
|
|
||||||
/* Enable the tick timer interrupt...
|
/* Enable the tick timer interrupt...
|
||||||
*
|
|
||||||
* First at timer level */
|
First at timer level */
|
||||||
portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS;
|
portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS;
|
||||||
|
|
||||||
/* Then at the AIC level. */
|
/* Then at the AIC level. */
|
||||||
AT91C_BASE_AIC->AIC_IECR = ( 1 << portTIMER_AIC_CHANNEL );
|
AT91C_BASE_AIC->AIC_IECR = (1 << portTIMER_AIC_CHANNEL);
|
||||||
|
|
||||||
/* Calculate timer compare value to achieve the desired tick rate... */
|
/* Calculate timer compare value to achieve the desired tick rate... */
|
||||||
if( ( configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 2 ) ) <= 0xFFFF )
|
if( (configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2) ) <= 0xFFFF )
|
||||||
{
|
{
|
||||||
/* The tick rate is fast enough for us to use the faster timer input
|
/* The tick rate is fast enough for us to use the faster timer input
|
||||||
* clock (main clock / 2). */
|
clock (main clock / 2). */
|
||||||
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK2 | TC_BURST_NONE | TC_CPCTRG;
|
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK2 | TC_BURST_NONE | TC_CPCTRG;
|
||||||
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 2 );
|
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We must use a slower timer input clock (main clock / 8) because the
|
/* We must use a slower timer input clock (main clock / 8) because the
|
||||||
* tick rate is too slow for the faster input clock. */
|
tick rate is too slow for the faster input clock. */
|
||||||
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK8 | TC_BURST_NONE | TC_CPCTRG;
|
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK8 | TC_BURST_NONE | TC_CPCTRG;
|
||||||
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 8 );
|
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start tick timer... */
|
/* Start tick timer... */
|
||||||
portTIMER_REG_BASE_PTR->TC_CCR = TC_SWTRG | TC_CLKEN;
|
portTIMER_REG_BASE_PTR->TC_CCR = TC_SWTRG | TC_CLKEN;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -27,17 +27,17 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in port.c The ISR routines, which can only be compiled
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
* to ARM mode, are contained in this file.
|
* to ARM mode, are contained in this file.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes from V3.2.4
|
Changes from V3.2.4
|
||||||
*
|
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
+ than each line having its own asm block.
|
than each line having its own asm block.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
|
@ -54,7 +54,7 @@ volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
@ -66,7 +66,7 @@ void vPortISRStartFirstTask( void );
|
||||||
void vPortISRStartFirstTask( void )
|
void vPortISRStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* Simply start the scheduler. This is included here as it can only be
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
* called from ARM mode. */
|
called from ARM mode. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -82,9 +82,9 @@ void vPortISRStartFirstTask( void )
|
||||||
void vPortYieldProcessor( void )
|
void vPortYieldProcessor( void )
|
||||||
{
|
{
|
||||||
/* Within an IRQ ISR the link register has an offset from the true return
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
* address, but an SWI ISR does not. Add the offset manually so the same
|
address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
* ISR return code can be used in both cases. */
|
ISR return code can be used in both cases. */
|
||||||
asm volatile ( "ADD LR, LR, #4");
|
asm volatile ( "ADD LR, LR, #4" );
|
||||||
|
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
@ -104,9 +104,9 @@ void vPortYieldProcessor( void )
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
* simply increment the system tick. */
|
simply increment the system tick. */
|
||||||
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
||||||
void vNonPreemptiveTick( void )
|
void vNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
static volatile uint32_t ulDummy;
|
static volatile uint32_t ulDummy;
|
||||||
|
@ -122,23 +122,23 @@ void vPortYieldProcessor( void )
|
||||||
|
|
||||||
#else /* else preemption is turned on */
|
#else /* else preemption is turned on */
|
||||||
|
|
||||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||||
* saved on entry as part of the context switch. */
|
saved on entry as part of the context switch. */
|
||||||
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
void vPreemptiveTick( void ) __attribute__((naked));
|
||||||
void vPreemptiveTick( void )
|
void vPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* WARNING - Do not use local (stack) variables here. Use globals
|
/* WARNING - Do not use local (stack) variables here. Use globals
|
||||||
* if you must! */
|
if you must! */
|
||||||
static volatile uint32_t ulDummy;
|
static volatile uint32_t ulDummy;
|
||||||
|
|
||||||
/* Clear tick timer interrupt indication. */
|
/* Clear tick timer interrupt indication. */
|
||||||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||||
|
|
||||||
/* Increment the RTOS tick count, then look for the highest priority
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
* task that is ready to run. */
|
task that is ready to run. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
{
|
{
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
|
@ -151,7 +151,7 @@ void vPortYieldProcessor( void )
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* if configUSE_PREEMPTION == 0 */
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -162,50 +162,50 @@ void vPortYieldProcessor( void )
|
||||||
*/
|
*/
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void )
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14"); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEnableInterruptsFromThumb( void )
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14"); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
* different optimisation levels. The interrupt flags can therefore not always
|
different optimisation levels. The interrupt flags can therefore not always
|
||||||
* be saved to the stack. Instead the critical section nesting level is stored
|
be saved to the stack. Instead the critical section nesting level is stored
|
||||||
* in a variable, which is then saved as part of the stack context. */
|
in a variable, which is then saved as part of the stack context. */
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}"); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
* portENTER_CRITICAL() has been called. */
|
portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,16 +217,17 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
* re-enabled. */
|
re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}"); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,34 +26,34 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes from V3.2.3
|
Changes from V3.2.3
|
||||||
*
|
|
||||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||||
+
|
|
||||||
+ Changes from V3.2.4
|
Changes from V3.2.4
|
||||||
+
|
|
||||||
+ Removed the use of the %0 parameter within the assembler macros and
|
+ Removed the use of the %0 parameter within the assembler macros and
|
||||||
+ replaced them with hard coded registers. This will ensure the
|
replaced them with hard coded registers. This will ensure the
|
||||||
+ assembler does not select the link register as the temp register as
|
assembler does not select the link register as the temp register as
|
||||||
+ was occasionally happening previously.
|
was occasionally happening previously.
|
||||||
+
|
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
+ than each line having its own asm block.
|
than each line having its own asm block.
|
||||||
+
|
|
||||||
+ Changes from V4.5.0
|
Changes from V4.5.0
|
||||||
+
|
|
||||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||||
+ and replaced them with portYIELD_FROM_ISR() macro. Application code
|
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||||
+ should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||||
+ macros as per the V4.5.1 demo code.
|
macros as per the V4.5.1 demo code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -66,42 +66,42 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portYIELD() asm volatile ( "SWI 0" )
|
#define portYIELD() asm volatile ( "SWI 0" )
|
||||||
#define portNOP() asm volatile ( "NOP" )
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These define the timer to use for generating the tick interrupt.
|
* These define the timer to use for generating the tick interrupt.
|
||||||
* They are put in this file so they can be shared between "port.c"
|
* They are put in this file so they can be shared between "port.c"
|
||||||
* and "portisr.c".
|
* and "portisr.c".
|
||||||
*/
|
*/
|
||||||
#define portTIMER_REG_BASE_PTR AT91C_BASE_TC0
|
#define portTIMER_REG_BASE_PTR AT91C_BASE_TC0
|
||||||
#define portTIMER_CLK_ENABLE_BIT AT91C_PS_TC0
|
#define portTIMER_CLK_ENABLE_BIT AT91C_PS_TC0
|
||||||
#define portTIMER_AIC_CHANNEL ( ( uint32_t ) 4 )
|
#define portTIMER_AIC_CHANNEL ( ( uint32_t ) 4 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
@ -113,90 +113,90 @@
|
||||||
* THUMB mode code will result in a compile time error.
|
* THUMB mode code will result in a compile time error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Set the LR to the task stack. */ \
|
/* Set the LR to the task stack. */ \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"LDR R0, =pxCurrentTCB \n\t"\
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t"\
|
"LDR R0, [R0] \n\t" \
|
||||||
"LDR LR, [R0] \n\t"\
|
"LDR LR, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* The critical nesting depth is the first item on the stack. */ \
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
/* Load it into the ulCriticalNesting variable. */ \
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
"LDR R0, =ulCriticalNesting \n\t"\
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDMFD LR!, {R1} \n\t"\
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
"STR R1, [R0] \n\t"\
|
"STR R1, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* Get the SPSR from the stack. */ \
|
/* Get the SPSR from the stack. */ \
|
||||||
"LDMFD LR!, {R0} \n\t"\
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
"MSR SPSR, R0 \n\t"\
|
"MSR SPSR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore all system mode registers for the task. */ \
|
/* Restore all system mode registers for the task. */ \
|
||||||
"LDMFD LR, {R0-R14}^ \n\t"\
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
"NOP \n\t"\
|
"NOP \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore the return address. */ \
|
/* Restore the return address. */ \
|
||||||
"LDR LR, [LR, #+60] \n\t"\
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
\
|
\
|
||||||
/* And return - correcting the offset in the LR to obtain the */ \
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
/* correct address. */ \
|
/* correct address. */ \
|
||||||
"SUBS PC, LR, #4 \n\t"\
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Push R0 as we are going to use the register. */ \
|
/* Push R0 as we are going to use the register. */ \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t"\
|
"STMDB SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Set R0 to point to the task stack pointer. */ \
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
"STMDB SP,{SP}^ \n\t"\
|
"STMDB SP,{SP}^ \n\t" \
|
||||||
"NOP \n\t"\
|
"NOP \n\t" \
|
||||||
"SUB SP, SP, #4 \n\t"\
|
"SUB SP, SP, #4 \n\t" \
|
||||||
"LDMIA SP!,{R0} \n\t"\
|
"LDMIA SP!,{R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the return address onto the stack. */ \
|
/* Push the return address onto the stack. */ \
|
||||||
"STMDB R0!, {LR} \n\t"\
|
"STMDB R0!, {LR} \n\t" \
|
||||||
\
|
\
|
||||||
/* Now we have saved LR we can use it instead of R0. */ \
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
"MOV LR, R0 \n\t"\
|
"MOV LR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
"LDMIA SP!, {R0} \n\t"\
|
"LDMIA SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push all the system mode registers onto the task stack. */ \
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
"STMDB LR,{R0-LR}^ \n\t"\
|
"STMDB LR,{R0-LR}^ \n\t" \
|
||||||
"NOP \n\t"\
|
"NOP \n\t" \
|
||||||
"SUB LR, LR, #60 \n\t"\
|
"SUB LR, LR, #60 \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the SPSR onto the task stack. */ \
|
/* Push the SPSR onto the task stack. */ \
|
||||||
"MRS R0, SPSR \n\t"\
|
"MRS R0, SPSR \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t"\
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
"LDR R0, =ulCriticalNesting \n\t"\
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDR R0, [R0] \n\t"\
|
"LDR R0, [R0] \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t"\
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Store the new top of stack for the task. */ \
|
/* Store the new top of stack for the task. */ \
|
||||||
"LDR R0, =pxCurrentTCB \n\t"\
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t"\
|
"LDR R0, [R0] \n\t" \
|
||||||
"STR LR, [R0] \n\t"\
|
"STR LR, [R0] \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
|
|
||||||
|
@ -207,48 +207,49 @@
|
||||||
* defined then the utilities are defined as macros here - as per other ports.
|
* defined then the utilities are defined as macros here - as per other ports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */\
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */\
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */\
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */\
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} ") /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */\
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */\
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */\
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */\
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} ") /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,50 +1,51 @@
|
||||||
/** ---------------------------------------------------------------------------- */
|
//* ----------------------------------------------------------------------------
|
||||||
/** ATMEL Microcontroller Software Support - ROUSSET - */
|
//* ATMEL Microcontroller Software Support - ROUSSET -
|
||||||
/** ---------------------------------------------------------------------------- */
|
//* ----------------------------------------------------------------------------
|
||||||
/** DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */
|
//* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
/** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
|
//* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
/** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */
|
//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
/** DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */
|
//* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
/** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
|
//* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
/** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
|
//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
/** OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
|
//* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
/** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
|
//* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
/** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
|
//* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
/** EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
//* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/** ---------------------------------------------------------------------------- */
|
//* ----------------------------------------------------------------------------
|
||||||
/** File Name : lib_AT91SAM7X256.h */
|
//* File Name : lib_AT91SAM7X256.h
|
||||||
/** Object : AT91SAM7X256 inlined functions */
|
//* Object : AT91SAM7X256 inlined functions
|
||||||
/** Generated : AT91 SW Application Group 05/20/2005 (16:22:29) */
|
//* Generated : AT91 SW Application Group 05/20/2005 (16:22:29)
|
||||||
/** */
|
//*
|
||||||
/** CVS Reference : /lib_dbgu.h/1.1/Fri Jan 31 12:18:40 2003// */
|
//* CVS Reference : /lib_dbgu.h/1.1/Fri Jan 31 12:18:40 2003//
|
||||||
/** CVS Reference : /lib_pmc_SAM7X.h/1.1/Tue Feb 1 08:32:10 2005// */
|
//* CVS Reference : /lib_pmc_SAM7X.h/1.1/Tue Feb 1 08:32:10 2005//
|
||||||
/** CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005// */
|
//* CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005//
|
||||||
/** CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004// */
|
//* CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004//
|
||||||
/** CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003// */
|
//* CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003//
|
||||||
/** CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004// */
|
//* CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004//
|
||||||
/** CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002// */
|
//* CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002//
|
||||||
/** CVS Reference : /lib_spi2.h/1.1/Mon Aug 25 14:23:52 2003// */
|
//* CVS Reference : /lib_spi2.h/1.1/Mon Aug 25 14:23:52 2003//
|
||||||
/** CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004// */
|
//* CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004//
|
||||||
/** CVS Reference : /lib_aic_6075b.h/1.1/Fri May 20 14:01:19 2005// */
|
//* CVS Reference : /lib_aic_6075b.h/1.1/Fri May 20 14:01:19 2005//
|
||||||
/** CVS Reference : /lib_aes_6149a.h/1.1/Mon Jan 17 07:43:09 2005// */
|
//* CVS Reference : /lib_aes_6149a.h/1.1/Mon Jan 17 07:43:09 2005//
|
||||||
/** CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004// */
|
//* CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004//
|
||||||
/** CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003// */
|
//* CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003//
|
||||||
/** CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004// */
|
//* CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004//
|
||||||
/** CVS Reference : /lib_udp.h/1.4/Wed Feb 16 08:39:34 2005// */
|
//* CVS Reference : /lib_udp.h/1.4/Wed Feb 16 08:39:34 2005//
|
||||||
/** CVS Reference : /lib_des3_6150a.h/1.1/Mon Jan 17 09:19:19 2005// */
|
//* CVS Reference : /lib_des3_6150a.h/1.1/Mon Jan 17 09:19:19 2005//
|
||||||
/** CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003// */
|
//* CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003//
|
||||||
/** CVS Reference : /lib_MC_SAM7X.h/1.1/Thu Mar 25 15:19:14 2004// */
|
//* CVS Reference : /lib_MC_SAM7X.h/1.1/Thu Mar 25 15:19:14 2004//
|
||||||
/** CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003// */
|
//* CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003//
|
||||||
/** CVS Reference : /lib_can_AT91.h/1.4/Fri Oct 17 09:12:50 2003// */
|
//* CVS Reference : /lib_can_AT91.h/1.4/Fri Oct 17 09:12:50 2003//
|
||||||
/** CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004// */
|
//* CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004//
|
||||||
/** CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002// */
|
//* CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002//
|
||||||
/** ---------------------------------------------------------------------------- */
|
//* ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
#include "AT91SAM7X256.h"
|
#include "AT91SAM7X256.h"
|
||||||
|
|
||||||
|
|
||||||
/**---------------------------------------------------------------------------- */
|
//*----------------------------------------------------------------------------
|
||||||
/** \fn AT91F_AIC_ConfigureIt */
|
//* \fn AT91F_AIC_ConfigureIt
|
||||||
/** \brief Interrupt Handler Initialization */
|
//* \brief Interrupt Handler Initialization
|
||||||
/**---------------------------------------------------------------------------- */
|
//*----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,12 +27,12 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||||
*
|
*
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in this file. The ISR routines, which can only be compiled
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
* to ARM mode are contained in portISR.c.
|
* to ARM mode are contained in portISR.c.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -82,24 +82,22 @@ extern void vPortISRStartFirstTask( 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 )
|
|
||||||
{
|
{
|
||||||
StackType_t * pxOriginalTOS;
|
StackType_t *pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
* is not really required. */
|
is not really required. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
* expected by the portRESTORE_CONTEXT() macro. */
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which in this case is the
|
/* First on the stack is the return address - which in this case is the
|
||||||
* start of the task. The offset is added to make the return address appear
|
start of the task. The offset is added to make the return address appear
|
||||||
* as it would within an IRQ ISR. */
|
as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
@ -133,12 +131,12 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
* R0. */
|
R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing onto the stack is the status register, which is set for
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
* system mode, with interrupts enabled. */
|
system mode, with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
@ -151,9 +149,9 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Some optimisation levels use the stack differently to others. This
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
* means the interrupt flags cannot always be stored on the stack and will
|
means the interrupt flags cannot always be stored on the stack and will
|
||||||
* instead be stored in a variable, which is then saved as part of the
|
instead be stored in a variable, which is then saved as part of the
|
||||||
* tasks context. */
|
tasks context. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -163,7 +161,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
* here already. */
|
here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
@ -177,7 +175,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the ARM port will require this function as there
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
* is nothing to return to. */
|
is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -186,23 +184,30 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
|
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
|
||||||
|
|
||||||
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
|
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
|
||||||
* on whether the preemptive or cooperative scheduler is being used. */
|
on whether the preemptive or cooperative scheduler is being used. */
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
extern void( vNonPreemptiveTick ) ( void );
|
|
||||||
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vNonPreemptiveTick );
|
extern void ( vNonPreemptiveTick ) ( void );
|
||||||
|
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vNonPreemptiveTick );
|
||||||
|
|
||||||
#else
|
#else
|
||||||
extern void( vPreemptiveTick )( void );
|
|
||||||
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vPreemptiveTick );
|
extern void ( vPreemptiveTick )( void );
|
||||||
|
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPreemptiveTick );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configure the PIT period. */
|
/* Configure the PIT period. */
|
||||||
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
|
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
|
||||||
|
|
||||||
/* Enable the interrupt. Global interrupts are disables at this point so
|
/* Enable the interrupt. Global interrupts are disables at this point so
|
||||||
* this is safe. */
|
this is safe. */
|
||||||
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
|
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,17 +27,17 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in port.c The ISR routines, which can only be compiled
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
* to ARM mode, are contained in this file.
|
* to ARM mode, are contained in this file.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes from V3.2.4
|
Changes from V3.2.4
|
||||||
*
|
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
+ than each line having its own asm block.
|
than each line having its own asm block.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
@ -56,7 +56,7 @@ volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
@ -68,7 +68,7 @@ void vPortISRStartFirstTask( void );
|
||||||
void vPortISRStartFirstTask( void )
|
void vPortISRStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* Simply start the scheduler. This is included here as it can only be
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
* called from ARM mode. */
|
called from ARM mode. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -84,9 +84,9 @@ void vPortISRStartFirstTask( void )
|
||||||
void vPortYieldProcessor( void )
|
void vPortYieldProcessor( void )
|
||||||
{
|
{
|
||||||
/* Within an IRQ ISR the link register has an offset from the true return
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
* address, but an SWI ISR does not. Add the offset manually so the same
|
address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
* ISR return code can be used in both cases. */
|
ISR return code can be used in both cases. */
|
||||||
__asm volatile ( "ADD LR, LR, #4");
|
__asm volatile ( "ADD LR, LR, #4" );
|
||||||
|
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
@ -106,16 +106,16 @@ void vPortYieldProcessor( void )
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
* simply increment the system tick. */
|
simply increment the system tick. */
|
||||||
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
||||||
void vNonPreemptiveTick( void )
|
void vNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
uint32_t ulDummy;
|
uint32_t ulDummy;
|
||||||
|
|
||||||
/* Increment the tick count - which may wake some tasks but as the
|
/* Increment the tick count - which may wake some tasks but as the
|
||||||
* preemptive scheduler is not being used any woken task is not given
|
preemptive scheduler is not being used any woken task is not given
|
||||||
* processor time no matter what its priority. */
|
processor time no matter what its priority. */
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
|
|
||||||
/* Clear the PIT interrupt. */
|
/* Clear the PIT interrupt. */
|
||||||
|
@ -125,11 +125,11 @@ void vPortYieldProcessor( void )
|
||||||
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
|
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* if configUSE_PREEMPTION == 0 */
|
#else
|
||||||
|
|
||||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||||
* saved on entry as part of the context switch. */
|
saved on entry as part of the context switch. */
|
||||||
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
void vPreemptiveTick( void ) __attribute__((naked));
|
||||||
void vPreemptiveTick( void )
|
void vPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the current task. */
|
/* Save the context of the current task. */
|
||||||
|
@ -148,7 +148,7 @@ void vPortYieldProcessor( void )
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* if configUSE_PREEMPTION == 0 */
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -157,49 +157,49 @@ void vPortYieldProcessor( void )
|
||||||
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
|
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
|
||||||
* the utilities are defined as macros in portmacro.h - as per other ports.
|
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||||
*/
|
*/
|
||||||
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void )
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14"); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEnableInterruptsFromThumb( void )
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14"); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
* different optimisation levels. The interrupt flags can therefore not always
|
different optimisation levels. The interrupt flags can therefore not always
|
||||||
* be saved to the stack. Instead the critical section nesting level is stored
|
be saved to the stack. Instead the critical section nesting level is stored
|
||||||
* in a variable, which is then saved as part of the stack context. */
|
in a variable, which is then saved as part of the stack context. */
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}"); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
* portENTER_CRITICAL() has been called. */
|
portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,16 +211,17 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
* re-enabled. */
|
re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}"); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,34 +26,34 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes from V3.2.3
|
Changes from V3.2.3
|
||||||
*
|
|
||||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||||
+
|
|
||||||
+ Changes from V3.2.4
|
Changes from V3.2.4
|
||||||
+
|
|
||||||
+ Removed the use of the %0 parameter within the assembler macros and
|
+ Removed the use of the %0 parameter within the assembler macros and
|
||||||
+ replaced them with hard coded registers. This will ensure the
|
replaced them with hard coded registers. This will ensure the
|
||||||
+ assembler does not select the link register as the temp register as
|
assembler does not select the link register as the temp register as
|
||||||
+ was occasionally happening previously.
|
was occasionally happening previously.
|
||||||
+
|
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
+ than each line having its own asm block.
|
than each line having its own asm block.
|
||||||
+
|
|
||||||
+ Changes from V4.5.0
|
Changes from V4.5.0
|
||||||
+
|
|
||||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||||
+ and replaced them with portYIELD_FROM_ISR() macro. Application code
|
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||||
+ should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||||
+ macros as per the V4.5.1 demo code.
|
macros as per the V4.5.1 demo code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -66,32 +66,32 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 portLONG
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP() __asm volatile ( "NOP" );
|
#define portNOP() __asm volatile ( "NOP" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,92 +104,92 @@
|
||||||
* THUMB mode code will result in a compile time error.
|
* THUMB mode code will result in a compile time error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Set the LR to the task stack. */ \
|
/* Set the LR to the task stack. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"LDR R0, =pxCurrentTCB \n\t"\
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t"\
|
"LDR R0, [R0] \n\t" \
|
||||||
"LDR LR, [R0] \n\t"\
|
"LDR LR, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* The critical nesting depth is the first item on the stack. */ \
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
/* Load it into the ulCriticalNesting variable. */ \
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
"LDR R0, =ulCriticalNesting \n\t"\
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDMFD LR!, {R1} \n\t"\
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
"STR R1, [R0] \n\t"\
|
"STR R1, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* Get the SPSR from the stack. */ \
|
/* Get the SPSR from the stack. */ \
|
||||||
"LDMFD LR!, {R0} \n\t"\
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
"MSR SPSR, R0 \n\t"\
|
"MSR SPSR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore all system mode registers for the task. */ \
|
/* Restore all system mode registers for the task. */ \
|
||||||
"LDMFD LR, {R0-R14}^ \n\t"\
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
"NOP \n\t"\
|
"NOP \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore the return address. */ \
|
/* Restore the return address. */ \
|
||||||
"LDR LR, [LR, #+60] \n\t"\
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
\
|
\
|
||||||
/* And return - correcting the offset in the LR to obtain the */ \
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
/* correct address. */ \
|
/* correct address. */ \
|
||||||
"SUBS PC, LR, #4 \n\t"\
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Push R0 as we are going to use the register. */ \
|
/* Push R0 as we are going to use the register. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t"\
|
"STMDB SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Set R0 to point to the task stack pointer. */ \
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
"STMDB SP,{SP}^ \n\t"\
|
"STMDB SP,{SP}^ \n\t" \
|
||||||
"NOP \n\t"\
|
"NOP \n\t" \
|
||||||
"SUB SP, SP, #4 \n\t"\
|
"SUB SP, SP, #4 \n\t" \
|
||||||
"LDMIA SP!,{R0} \n\t"\
|
"LDMIA SP!,{R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the return address onto the stack. */ \
|
/* Push the return address onto the stack. */ \
|
||||||
"STMDB R0!, {LR} \n\t"\
|
"STMDB R0!, {LR} \n\t" \
|
||||||
\
|
\
|
||||||
/* Now we have saved LR we can use it instead of R0. */ \
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
"MOV LR, R0 \n\t"\
|
"MOV LR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
"LDMIA SP!, {R0} \n\t"\
|
"LDMIA SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push all the system mode registers onto the task stack. */ \
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
"STMDB LR,{R0-LR}^ \n\t"\
|
"STMDB LR,{R0-LR}^ \n\t" \
|
||||||
"NOP \n\t"\
|
"NOP \n\t" \
|
||||||
"SUB LR, LR, #60 \n\t"\
|
"SUB LR, LR, #60 \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the SPSR onto the task stack. */ \
|
/* Push the SPSR onto the task stack. */ \
|
||||||
"MRS R0, SPSR \n\t"\
|
"MRS R0, SPSR \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t"\
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
"LDR R0, =ulCriticalNesting \n\t"\
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDR R0, [R0] \n\t"\
|
"LDR R0, [R0] \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t"\
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Store the new top of stack for the task. */ \
|
/* Store the new top of stack for the task. */ \
|
||||||
"LDR R0, =pxCurrentTCB \n\t"\
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t"\
|
"LDR R0, [R0] \n\t" \
|
||||||
"STR LR, [R0] \n\t"\
|
"STR LR, [R0] \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -202,47 +202,48 @@
|
||||||
* defined then the utilities are defined as macros here - as per other ports.
|
* defined then the utilities are defined as macros here - as per other ports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */\
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */\
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */\
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */\
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} ") /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */\
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */\
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */\
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */\
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} ") /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,12 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||||
*
|
*
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in this file. The ISR routines, which can only be compiled
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
* to ARM mode are contained in portISR.c.
|
* to ARM mode are contained in portISR.c.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
|
@ -78,24 +78,22 @@ extern void vPortISRStartFirstTask( 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 )
|
|
||||||
{
|
{
|
||||||
StackType_t * pxOriginalTOS;
|
StackType_t *pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
* is not really required. */
|
is not really required. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
* expected by the portRESTORE_CONTEXT() macro. */
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which in this case is the
|
/* First on the stack is the return address - which in this case is the
|
||||||
* start of the task. The offset is added to make the return address appear
|
start of the task. The offset is added to make the return address appear
|
||||||
* as it would within an IRQ ISR. */
|
as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
@ -129,12 +127,12 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
* R0. */
|
R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing onto the stack is the status register, which is set for
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
* system mode, with interrupts enabled. */
|
system mode, with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||||
|
|
||||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||||
|
@ -146,9 +144,9 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Some optimisation levels use the stack differently to others. This
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
* means the interrupt flags cannot always be stored on the stack and will
|
means the interrupt flags cannot always be stored on the stack and will
|
||||||
* instead be stored in a variable, which is then saved as part of the
|
instead be stored in a variable, which is then saved as part of the
|
||||||
* tasks context. */
|
tasks context. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -158,7 +156,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
* here already. */
|
here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
@ -172,7 +170,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the ARM port will require this function as there
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
* is nothing to return to. */
|
is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -181,19 +179,18 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
uint32_t ulCompareMatch;
|
uint32_t ulCompareMatch;
|
||||||
|
extern void ( vTickISR )( void );
|
||||||
extern void( vTickISR )( void );
|
|
||||||
|
|
||||||
/* A 1ms tick does not require the use of the timer prescale. This is
|
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||||
* defaulted to zero but can be used if necessary. */
|
defaulted to zero but can be used if necessary. */
|
||||||
T0_PR = portPRESCALE_VALUE;
|
T0_PR = portPRESCALE_VALUE;
|
||||||
|
|
||||||
/* Calculate the match value required for our wanted tick rate. */
|
/* Calculate the match value required for our wanted tick rate. */
|
||||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
/* Protect against divide by zero. Using an if() statement still results
|
/* Protect against divide by zero. Using an if() statement still results
|
||||||
* in a warning - hence the #if. */
|
in a warning - hence the #if. */
|
||||||
#if portPRESCALE_VALUE != 0
|
#if portPRESCALE_VALUE != 0
|
||||||
{
|
{
|
||||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||||
|
@ -209,13 +206,16 @@ static void prvSetupTimerInterrupt( void )
|
||||||
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
|
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
|
||||||
|
|
||||||
/* The ISR installed depends on whether the preemptive or cooperative
|
/* The ISR installed depends on whether the preemptive or cooperative
|
||||||
* scheduler is being used. */
|
scheduler is being used. */
|
||||||
|
|
||||||
VICVectAddr0 = ( int32_t ) vTickISR;
|
VICVectAddr0 = ( int32_t ) vTickISR;
|
||||||
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
|
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
|
||||||
|
|
||||||
/* Start the timer - interrupts are disabled when this function is called
|
/* Start the timer - interrupts are disabled when this function is called
|
||||||
* so it is okay to do this here. */
|
so it is okay to do this here. */
|
||||||
T0_TCR = portENABLE_TIMER;
|
T0_TCR = portENABLE_TIMER;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,28 +27,28 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in port.c The ISR routines, which can only be compiled
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
* to ARM mode, are contained in this file.
|
* to ARM mode, are contained in this file.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes from V2.5.2
|
Changes from V2.5.2
|
||||||
*
|
|
||||||
+ The critical section management functions have been changed. These no
|
+ The critical section management functions have been changed. These no
|
||||||
+ longer modify the stack and are safe to use at all optimisation levels.
|
longer modify the stack and are safe to use at all optimisation levels.
|
||||||
+ The functions are now also the same for both ARM and THUMB modes.
|
The functions are now also the same for both ARM and THUMB modes.
|
||||||
+
|
|
||||||
+ Changes from V2.6.0
|
Changes from V2.6.0
|
||||||
+
|
|
||||||
+ Removed the 'static' from the definition of vNonPreemptiveTick() to
|
+ Removed the 'static' from the definition of vNonPreemptiveTick() to
|
||||||
+ allow the demo to link when using the cooperative scheduler.
|
allow the demo to link when using the cooperative scheduler.
|
||||||
+
|
|
||||||
+ Changes from V3.2.4
|
Changes from V3.2.4
|
||||||
+
|
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
+ than each line having its own asm block.
|
than each line having its own asm block.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
|
@ -65,7 +65,7 @@ volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
@ -77,7 +77,7 @@ void vPortISRStartFirstTask( void );
|
||||||
void vPortISRStartFirstTask( void )
|
void vPortISRStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* Simply start the scheduler. This is included here as it can only be
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
* called from ARM mode. */
|
called from ARM mode. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -93,9 +93,9 @@ void vPortISRStartFirstTask( void )
|
||||||
void vPortYieldProcessor( void )
|
void vPortYieldProcessor( void )
|
||||||
{
|
{
|
||||||
/* Within an IRQ ISR the link register has an offset from the true return
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
* address, but an SWI ISR does not. Add the offset manually so the same
|
address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
* ISR return code can be used in both cases. */
|
ISR return code can be used in both cases. */
|
||||||
__asm volatile ( "ADD LR, LR, #4");
|
__asm volatile ( "ADD LR, LR, #4" );
|
||||||
|
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
@ -111,20 +111,20 @@ void vPortYieldProcessor( void )
|
||||||
/*
|
/*
|
||||||
* The ISR used for the scheduler tick.
|
* The ISR used for the scheduler tick.
|
||||||
*/
|
*/
|
||||||
void vTickISR( void ) __attribute__( ( naked ) );
|
void vTickISR( void ) __attribute__((naked));
|
||||||
void vTickISR( void )
|
void vTickISR( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* Increment the RTOS tick count, then look for the highest priority
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
* task that is ready to run. */
|
task that is ready to run. */
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" bl xTaskIncrementTick \t\n"\
|
" bl xTaskIncrementTick \t\n" \
|
||||||
" cmp r0, #0 \t\n"\
|
" cmp r0, #0 \t\n" \
|
||||||
" beq SkipContextSwitch \t\n"\
|
" beq SkipContextSwitch \t\n" \
|
||||||
" bl vTaskSwitchContext \t\n"\
|
" bl vTaskSwitchContext \t\n" \
|
||||||
"SkipContextSwitch: \t\n"
|
"SkipContextSwitch: \t\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -145,50 +145,50 @@ void vTickISR( void )
|
||||||
*/
|
*/
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void )
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14"); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEnableInterruptsFromThumb( void )
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14"); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
* different optimisation levels. The interrupt flags can therefore not always
|
different optimisation levels. The interrupt flags can therefore not always
|
||||||
* be saved to the stack. Instead the critical section nesting level is stored
|
be saved to the stack. Instead the critical section nesting level is stored
|
||||||
* in a variable, which is then saved as part of the stack context. */
|
in a variable, which is then saved as part of the stack context. */
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}"); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
* portENTER_CRITICAL() has been called. */
|
portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,16 +200,16 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
* re-enabled. */
|
re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}"); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -43,32 +43,32 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 portLONG
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP() __asm volatile ( "NOP" );
|
#define portNOP() __asm volatile ( "NOP" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,92 +81,92 @@
|
||||||
* THUMB mode code will result in a compile time error.
|
* THUMB mode code will result in a compile time error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Set the LR to the task stack. */ \
|
/* Set the LR to the task stack. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"LDR R0, =pxCurrentTCB \n\t"\
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t"\
|
"LDR R0, [R0] \n\t" \
|
||||||
"LDR LR, [R0] \n\t"\
|
"LDR LR, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* The critical nesting depth is the first item on the stack. */ \
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
/* Load it into the ulCriticalNesting variable. */ \
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
"LDR R0, =ulCriticalNesting \n\t"\
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDMFD LR!, {R1} \n\t"\
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
"STR R1, [R0] \n\t"\
|
"STR R1, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* Get the SPSR from the stack. */ \
|
/* Get the SPSR from the stack. */ \
|
||||||
"LDMFD LR!, {R0} \n\t"\
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
"MSR SPSR, R0 \n\t"\
|
"MSR SPSR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore all system mode registers for the task. */ \
|
/* Restore all system mode registers for the task. */ \
|
||||||
"LDMFD LR, {R0-R14}^ \n\t"\
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
"NOP \n\t"\
|
"NOP \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore the return address. */ \
|
/* Restore the return address. */ \
|
||||||
"LDR LR, [LR, #+60] \n\t"\
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
\
|
\
|
||||||
/* And return - correcting the offset in the LR to obtain the */ \
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
/* correct address. */ \
|
/* correct address. */ \
|
||||||
"SUBS PC, LR, #4 \n\t"\
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Push R0 as we are going to use the register. */ \
|
/* Push R0 as we are going to use the register. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t"\
|
"STMDB SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Set R0 to point to the task stack pointer. */ \
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
"STMDB SP,{SP}^ \n\t"\
|
"STMDB SP,{SP}^ \n\t" \
|
||||||
"NOP \n\t"\
|
"NOP \n\t" \
|
||||||
"SUB SP, SP, #4 \n\t"\
|
"SUB SP, SP, #4 \n\t" \
|
||||||
"LDMIA SP!,{R0} \n\t"\
|
"LDMIA SP!,{R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the return address onto the stack. */ \
|
/* Push the return address onto the stack. */ \
|
||||||
"STMDB R0!, {LR} \n\t"\
|
"STMDB R0!, {LR} \n\t" \
|
||||||
\
|
\
|
||||||
/* Now we have saved LR we can use it instead of R0. */ \
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
"MOV LR, R0 \n\t"\
|
"MOV LR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
"LDMIA SP!, {R0} \n\t"\
|
"LDMIA SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push all the system mode registers onto the task stack. */ \
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
"STMDB LR,{R0-LR}^ \n\t"\
|
"STMDB LR,{R0-LR}^ \n\t" \
|
||||||
"NOP \n\t"\
|
"NOP \n\t" \
|
||||||
"SUB LR, LR, #60 \n\t"\
|
"SUB LR, LR, #60 \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the SPSR onto the task stack. */ \
|
/* Push the SPSR onto the task stack. */ \
|
||||||
"MRS R0, SPSR \n\t"\
|
"MRS R0, SPSR \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t"\
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
"LDR R0, =ulCriticalNesting \n\t"\
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDR R0, [R0] \n\t"\
|
"LDR R0, [R0] \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t"\
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Store the new top of stack for the task. */ \
|
/* Store the new top of stack for the task. */ \
|
||||||
"LDR R0, =pxCurrentTCB \n\t"\
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t"\
|
"LDR R0, [R0] \n\t" \
|
||||||
"STR LR, [R0] \n\t"\
|
"STR LR, [R0] \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void vTaskSwitchContext( void );
|
extern void vTaskSwitchContext( void );
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,47 +179,48 @@
|
||||||
* defined then the utilities are defined as macros here - as per other ports.
|
* defined then the utilities are defined as macros here - as per other ports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */\
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */\
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */\
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */\
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} ") /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */\
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */\
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */\
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */\
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} ") /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,12 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||||
*
|
*
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in this file. The ISR routines, which can only be compiled
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
* to ARM mode are contained in portISR.c.
|
* to ARM mode are contained in portISR.c.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
|
@ -78,24 +78,22 @@ extern void vPortISRStartFirstTask( 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 )
|
|
||||||
{
|
{
|
||||||
StackType_t * pxOriginalTOS;
|
StackType_t *pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
* is not really required. */
|
is not really required. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
* expected by the portRESTORE_CONTEXT() macro. */
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which in this case is the
|
/* First on the stack is the return address - which in this case is the
|
||||||
* start of the task. The offset is added to make the return address appear
|
start of the task. The offset is added to make the return address appear
|
||||||
* as it would within an IRQ ISR. */
|
as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
@ -129,12 +127,12 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
* R0. */
|
R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing onto the stack is the status register, which is set for
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
* system mode, with interrupts enabled. */
|
system mode, with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||||
|
|
||||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||||
|
@ -146,9 +144,9 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Some optimisation levels use the stack differently to others. This
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
* means the interrupt flags cannot always be stored on the stack and will
|
means the interrupt flags cannot always be stored on the stack and will
|
||||||
* instead be stored in a variable, which is then saved as part of the
|
instead be stored in a variable, which is then saved as part of the
|
||||||
* tasks context. */
|
tasks context. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -158,7 +156,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
* here already. */
|
here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
@ -172,7 +170,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the ARM port will require this function as there
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
* is nothing to return to. */
|
is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -181,21 +179,21 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
uint32_t ulCompareMatch;
|
uint32_t ulCompareMatch;
|
||||||
|
|
||||||
PCLKSEL0 = ( PCLKSEL0 & ( ~( 0x3 << 2 ) ) ) | ( 0x01 << 2 );
|
PCLKSEL0 = (PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
|
||||||
T0TCR = 2; /* Stop and reset the timer */
|
T0TCR = 2; /* Stop and reset the timer */
|
||||||
T0CTCR = 0; /* Timer mode */
|
T0CTCR = 0; /* Timer mode */
|
||||||
|
|
||||||
/* A 1ms tick does not require the use of the timer prescale. This is
|
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||||
* defaulted to zero but can be used if necessary. */
|
defaulted to zero but can be used if necessary. */
|
||||||
T0PR = portPRESCALE_VALUE;
|
T0PR = portPRESCALE_VALUE;
|
||||||
|
|
||||||
/* Calculate the match value required for our wanted tick rate. */
|
/* Calculate the match value required for our wanted tick rate. */
|
||||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
/* Protect against divide by zero. Using an if() statement still results
|
/* Protect against divide by zero. Using an if() statement still results
|
||||||
* in a warning - hence the #if. */
|
in a warning - hence the #if. */
|
||||||
#if portPRESCALE_VALUE != 0
|
#if portPRESCALE_VALUE != 0
|
||||||
{
|
{
|
||||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||||
|
@ -204,21 +202,21 @@ static void prvSetupTimerInterrupt( void )
|
||||||
T0MR1 = ulCompareMatch;
|
T0MR1 = ulCompareMatch;
|
||||||
|
|
||||||
/* Generate tick with timer 0 compare match. */
|
/* Generate tick with timer 0 compare match. */
|
||||||
T0MCR = ( 3 << 3 ); /* Reset timer on match and generate interrupt */
|
T0MCR = (3 << 3); /* Reset timer on match and generate interrupt */
|
||||||
|
|
||||||
/* Setup the VIC for the timer. */
|
/* Setup the VIC for the timer. */
|
||||||
VICIntEnable = 0x00000010;
|
VICIntEnable = 0x00000010;
|
||||||
|
|
||||||
/* The ISR installed depends on whether the preemptive or cooperative
|
/* The ISR installed depends on whether the preemptive or cooperative
|
||||||
* scheduler is being used. */
|
scheduler is being used. */
|
||||||
#if configUSE_PREEMPTION == 1
|
#if configUSE_PREEMPTION == 1
|
||||||
{
|
{
|
||||||
extern void( vPreemptiveTick )( void );
|
extern void ( vPreemptiveTick )( void );
|
||||||
VICVectAddr4 = ( int32_t ) vPreemptiveTick;
|
VICVectAddr4 = ( int32_t ) vPreemptiveTick;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
extern void( vNonPreemptiveTick )( void );
|
extern void ( vNonPreemptiveTick )( void );
|
||||||
VICVectAddr4 = ( int32_t ) vNonPreemptiveTick;
|
VICVectAddr4 = ( int32_t ) vNonPreemptiveTick;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -226,7 +224,10 @@ static void prvSetupTimerInterrupt( void )
|
||||||
VICVectCntl4 = 1;
|
VICVectCntl4 = 1;
|
||||||
|
|
||||||
/* Start the timer - interrupts are disabled when this function is called
|
/* Start the timer - interrupts are disabled when this function is called
|
||||||
* so it is okay to do this here. */
|
so it is okay to do this here. */
|
||||||
T0TCR = portENABLE_TIMER;
|
T0TCR = portENABLE_TIMER;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,10 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in port.c The ISR routines, which can only be compiled
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
* to ARM mode, are contained in this file.
|
* to ARM mode, are contained in this file.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
@ -47,7 +47,7 @@ volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
@ -59,7 +59,7 @@ void vPortISRStartFirstTask( void );
|
||||||
void vPortISRStartFirstTask( void )
|
void vPortISRStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* Simply start the scheduler. This is included here as it can only be
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
* called from ARM mode. */
|
called from ARM mode. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -75,15 +75,15 @@ void vPortISRStartFirstTask( void )
|
||||||
void vPortYieldProcessor( void )
|
void vPortYieldProcessor( void )
|
||||||
{
|
{
|
||||||
/* Within an IRQ ISR the link register has an offset from the true return
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
* address, but an SWI ISR does not. Add the offset manually so the same
|
address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
* ISR return code can be used in both cases. */
|
ISR return code can be used in both cases. */
|
||||||
__asm volatile ( "ADD LR, LR, #4");
|
__asm volatile ( "ADD LR, LR, #4" );
|
||||||
|
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* Find the highest priority task that is ready to run. */
|
/* Find the highest priority task that is ready to run. */
|
||||||
__asm volatile ( "bl vTaskSwitchContext");
|
__asm volatile( "bl vTaskSwitchContext" );
|
||||||
|
|
||||||
/* Restore the context of the new task. */
|
/* Restore the context of the new task. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
|
@ -98,9 +98,9 @@ void vPortYieldProcessor( void )
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
* simply increment the system tick. */
|
simply increment the system tick. */
|
||||||
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
||||||
void vNonPreemptiveTick( void )
|
void vNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
|
@ -108,24 +108,24 @@ void vPortYieldProcessor( void )
|
||||||
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* if configUSE_PREEMPTION == 0 */
|
#else
|
||||||
|
|
||||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||||
* saved on entry as part of the context switch. */
|
saved on entry as part of the context switch. */
|
||||||
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
void vPreemptiveTick( void ) __attribute__((naked));
|
||||||
void vPreemptiveTick( void )
|
void vPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* Increment the RTOS tick count, then look for the highest priority
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
* task that is ready to run. */
|
task that is ready to run. */
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" bl xTaskIncrementTick \t\n"\
|
" bl xTaskIncrementTick \t\n" \
|
||||||
" cmp r0, #0 \t\n"\
|
" cmp r0, #0 \t\n" \
|
||||||
" beq SkipContextSwitch \t\n"\
|
" beq SkipContextSwitch \t\n" \
|
||||||
" bl vTaskSwitchContext \t\n"\
|
" bl vTaskSwitchContext \t\n" \
|
||||||
"SkipContextSwitch: \t\n"
|
"SkipContextSwitch: \t\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ void vPortYieldProcessor( void )
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* if configUSE_PREEMPTION == 0 */
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -148,50 +148,50 @@ void vPortYieldProcessor( void )
|
||||||
*/
|
*/
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void )
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14"); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEnableInterruptsFromThumb( void )
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||||
"BX R14"); /* Return back to thumb. */
|
"BX R14" ); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
* different optimisation levels. The interrupt flags can therefore not always
|
different optimisation levels. The interrupt flags can therefore not always
|
||||||
* be saved to the stack. Instead the critical section nesting level is stored
|
be saved to the stack. Instead the critical section nesting level is stored
|
||||||
* in a variable, which is then saved as part of the stack context. */
|
in a variable, which is then saved as part of the stack context. */
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}"); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
* portENTER_CRITICAL() has been called. */
|
portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,16 +203,16 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
* re-enabled. */
|
re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}"); /* Pop R0. */
|
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,34 +26,34 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes from V3.2.3
|
Changes from V3.2.3
|
||||||
*
|
|
||||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||||
+
|
|
||||||
+ Changes from V3.2.4
|
Changes from V3.2.4
|
||||||
+
|
|
||||||
+ Removed the use of the %0 parameter within the assembler macros and
|
+ Removed the use of the %0 parameter within the assembler macros and
|
||||||
+ replaced them with hard coded registers. This will ensure the
|
replaced them with hard coded registers. This will ensure the
|
||||||
+ assembler does not select the link register as the temp register as
|
assembler does not select the link register as the temp register as
|
||||||
+ was occasionally happening previously.
|
was occasionally happening previously.
|
||||||
+
|
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
+ than each line having its own asm block.
|
than each line having its own asm block.
|
||||||
+
|
|
||||||
+ Changes from V4.5.0
|
Changes from V4.5.0
|
||||||
+
|
|
||||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||||
+ and replaced them with portYIELD_FROM_ISR() macro. Application code
|
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||||
+ should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||||
+ macros as per the V4.5.1 demo code.
|
macros as per the V4.5.1 demo code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -66,32 +66,32 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 portLONG
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP() __asm volatile ( "NOP" );
|
#define portNOP() __asm volatile ( "NOP" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,92 +104,92 @@
|
||||||
* THUMB mode code will result in a compile time error.
|
* THUMB mode code will result in a compile time error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Set the LR to the task stack. */ \
|
/* Set the LR to the task stack. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"LDR R0, =pxCurrentTCB \n\t"\
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t"\
|
"LDR R0, [R0] \n\t" \
|
||||||
"LDR LR, [R0] \n\t"\
|
"LDR LR, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* The critical nesting depth is the first item on the stack. */ \
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
/* Load it into the ulCriticalNesting variable. */ \
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
"LDR R0, =ulCriticalNesting \n\t"\
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDMFD LR!, {R1} \n\t"\
|
"LDMFD LR!, {R1} \n\t" \
|
||||||
"STR R1, [R0] \n\t"\
|
"STR R1, [R0] \n\t" \
|
||||||
\
|
\
|
||||||
/* Get the SPSR from the stack. */ \
|
/* Get the SPSR from the stack. */ \
|
||||||
"LDMFD LR!, {R0} \n\t"\
|
"LDMFD LR!, {R0} \n\t" \
|
||||||
"MSR SPSR, R0 \n\t"\
|
"MSR SPSR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore all system mode registers for the task. */ \
|
/* Restore all system mode registers for the task. */ \
|
||||||
"LDMFD LR, {R0-R14}^ \n\t"\
|
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||||
"NOP \n\t"\
|
"NOP \n\t" \
|
||||||
\
|
\
|
||||||
/* Restore the return address. */ \
|
/* Restore the return address. */ \
|
||||||
"LDR LR, [LR, #+60] \n\t"\
|
"LDR LR, [LR, #+60] \n\t" \
|
||||||
\
|
\
|
||||||
/* And return - correcting the offset in the LR to obtain the */ \
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
/* correct address. */ \
|
/* correct address. */ \
|
||||||
"SUBS PC, LR, #4 \n\t"\
|
"SUBS PC, LR, #4 \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Push R0 as we are going to use the register. */ \
|
/* Push R0 as we are going to use the register. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t"\
|
"STMDB SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Set R0 to point to the task stack pointer. */ \
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
"STMDB SP,{SP}^ \n\t"\
|
"STMDB SP,{SP}^ \n\t" \
|
||||||
"NOP \n\t"\
|
"NOP \n\t" \
|
||||||
"SUB SP, SP, #4 \n\t"\
|
"SUB SP, SP, #4 \n\t" \
|
||||||
"LDMIA SP!,{R0} \n\t"\
|
"LDMIA SP!,{R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the return address onto the stack. */ \
|
/* Push the return address onto the stack. */ \
|
||||||
"STMDB R0!, {LR} \n\t"\
|
"STMDB R0!, {LR} \n\t" \
|
||||||
\
|
\
|
||||||
/* Now we have saved LR we can use it instead of R0. */ \
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
"MOV LR, R0 \n\t"\
|
"MOV LR, R0 \n\t" \
|
||||||
\
|
\
|
||||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
"LDMIA SP!, {R0} \n\t"\
|
"LDMIA SP!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Push all the system mode registers onto the task stack. */ \
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
"STMDB LR,{R0-LR}^ \n\t"\
|
"STMDB LR,{R0-LR}^ \n\t" \
|
||||||
"NOP \n\t"\
|
"NOP \n\t" \
|
||||||
"SUB LR, LR, #60 \n\t"\
|
"SUB LR, LR, #60 \n\t" \
|
||||||
\
|
\
|
||||||
/* Push the SPSR onto the task stack. */ \
|
/* Push the SPSR onto the task stack. */ \
|
||||||
"MRS R0, SPSR \n\t"\
|
"MRS R0, SPSR \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t"\
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
"LDR R0, =ulCriticalNesting \n\t"\
|
"LDR R0, =ulCriticalNesting \n\t" \
|
||||||
"LDR R0, [R0] \n\t"\
|
"LDR R0, [R0] \n\t" \
|
||||||
"STMDB LR!, {R0} \n\t"\
|
"STMDB LR!, {R0} \n\t" \
|
||||||
\
|
\
|
||||||
/* Store the new top of stack for the task. */ \
|
/* Store the new top of stack for the task. */ \
|
||||||
"LDR R0, =pxCurrentTCB \n\t"\
|
"LDR R0, =pxCurrentTCB \n\t" \
|
||||||
"LDR R0, [R0] \n\t"\
|
"LDR R0, [R0] \n\t" \
|
||||||
"STR LR, [R0] \n\t"\
|
"STR LR, [R0] \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -202,47 +202,48 @@
|
||||||
* defined then the utilities are defined as macros here - as per other ports.
|
* defined then the utilities are defined as macros here - as per other ports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */\
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */\
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */\
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */\
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} ") /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t"/* Push R0. */\
|
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||||
"MRS R0, CPSR \n\t"/* Get CPSR. */\
|
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||||
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */\
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||||
"MSR CPSR, R0 \n\t"/* Write back modified value. */\
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||||
"LDMIA SP!, {R0} ") /* Pop R0. */
|
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -33,23 +33,23 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
||||||
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
||||||
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
||||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configSETUP_TICK_INTERRUPT
|
#ifndef configSETUP_TICK_INTERRUPT
|
||||||
#error configSETUP_TICK_INTERRUPT() must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
#error configSETUP_TICK_INTERRUPT() must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||||
#endif /* configSETUP_TICK_INTERRUPT */
|
#endif /* configSETUP_TICK_INTERRUPT */
|
||||||
|
|
||||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if ( configMAX_PRIORITIES > 32 )
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
@ -73,24 +73,24 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||||
* portmacro.h. */
|
portmacro.h. */
|
||||||
#ifndef configCLEAR_TICK_INTERRUPT
|
#ifndef configCLEAR_TICK_INTERRUPT
|
||||||
#define configCLEAR_TICK_INTERRUPT()
|
#define configCLEAR_TICK_INTERRUPT()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* A critical section is exited when the critical section nesting count reaches
|
/* A critical section is exited when the critical section nesting count reaches
|
||||||
* this value. */
|
this value. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
||||||
|
|
||||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||||
* (but the lowest) interrupt priority. */
|
(but the lowest) interrupt priority. */
|
||||||
#define portUNMASK_VALUE ( 0xFFUL )
|
#define portUNMASK_VALUE ( 0xFFUL )
|
||||||
|
|
||||||
/* Tasks are not created with a floating point context, but can be given a
|
/* Tasks are not created with a floating point context, but can be given a
|
||||||
* floating point context after they have been created. A variable is stored as
|
floating point context after they have been created. A variable is stored as
|
||||||
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||||
* does not have an FPU context, or any other value if the task does have an FPU
|
does not have an FPU context, or any other value if the task does have an FPU
|
||||||
* context. */
|
context. */
|
||||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to setup the initial task context. */
|
/* Constants required to setup the initial task context. */
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
|
|
||||||
|
|
||||||
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
||||||
* point is zero. */
|
point is zero. */
|
||||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||||
|
|
||||||
/* Masks all bits in the APSR other than the mode bits. */
|
/* Masks all bits in the APSR other than the mode bits. */
|
||||||
|
@ -119,13 +119,13 @@
|
||||||
|
|
||||||
/* Macro to unmask all interrupt priorities. */
|
/* Macro to unmask all interrupt priorities. */
|
||||||
#define portCLEAR_INTERRUPT_MASK() \
|
#define portCLEAR_INTERRUPT_MASK() \
|
||||||
{ \
|
{ \
|
||||||
portDISABLE_INTERRUPTS(); \
|
portDISABLE_INTERRUPTS(); \
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
||||||
__asm volatile ( "DSB SY \n" \
|
__asm volatile ( "DSB SY \n" \
|
||||||
"ISB SY \n"); \
|
"ISB SY \n" ); \
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hardware specifics used when sanity checking the configuration. */
|
/* Hardware specifics used when sanity checking the configuration. */
|
||||||
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
||||||
|
@ -143,40 +143,38 @@ extern void vPortRestoreTaskContext( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* A variable is used to keep track of the critical section nesting. This
|
/* A variable is used to keep track of the critical section nesting. This
|
||||||
* variable has to be stored as part of the task context and must be initialised to
|
variable has to be stored as part of the task context and must be initialised to
|
||||||
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||||
* the scheduler starts. As it is stored as part of the task context it will
|
the scheduler starts. As it is stored as part of the task context it will
|
||||||
* automatically be set to 0 when the first task is started. */
|
automatically be set to 0 when the first task is started. */
|
||||||
volatile uint64_t ullCriticalNesting = 9999ULL;
|
volatile uint64_t ullCriticalNesting = 9999ULL;
|
||||||
|
|
||||||
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
|
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
|
||||||
* then floating point context must be saved and restored for the task. */
|
then floating point context must be saved and restored for the task. */
|
||||||
uint64_t ullPortTaskHasFPUContext = pdFALSE;
|
uint64_t ullPortTaskHasFPUContext = pdFALSE;
|
||||||
|
|
||||||
/* Set to 1 to pend a context switch from an ISR. */
|
/* Set to 1 to pend a context switch from an ISR. */
|
||||||
uint64_t ullPortYieldRequired = pdFALSE;
|
uint64_t ullPortYieldRequired = pdFALSE;
|
||||||
|
|
||||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||||
* if the nesting depth is 0. */
|
if the nesting depth is 0. */
|
||||||
uint64_t ullPortInterruptNesting = 0;
|
uint64_t ullPortInterruptNesting = 0;
|
||||||
|
|
||||||
/* Used in the ASM code. */
|
/* Used in the ASM code. */
|
||||||
__attribute__( ( used ) ) const uint64_t ullICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
__attribute__(( used )) const uint64_t ullICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
||||||
__attribute__( ( used ) ) const uint64_t ullICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
__attribute__(( used )) const uint64_t ullICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
||||||
__attribute__( ( used ) ) const uint64_t ullICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
__attribute__(( used )) const uint64_t ullICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
||||||
__attribute__( ( used ) ) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
__attribute__(( used )) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 )
|
|
||||||
{
|
{
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
* expected by the portRESTORE_CONTEXT() macro. */
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First all the general purpose registers. */
|
/* First all the general purpose registers. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -252,13 +250,13 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||||
* enabled. */
|
enabled. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start without a floating point context. A task that uses
|
/* The task will start without a floating point context. A task that uses
|
||||||
* the floating point hardware must call vPortTaskUsesFPU() before executing
|
the floating point hardware must call vPortTaskUsesFPU() before executing
|
||||||
* any floating point instructions. */
|
any floating point instructions. */
|
||||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -267,21 +265,21 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulAPSR;
|
uint32_t ulAPSR;
|
||||||
|
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
volatile uint32_t ulOriginalPriority;
|
||||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine how many priority bits are implemented in the GIC.
|
/* Determine how many priority bits are implemented in the GIC.
|
||||||
*
|
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to
|
/* Determine the number of priority bits available. First write to
|
||||||
* all possible bits. */
|
all possible bits. */
|
||||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -294,13 +292,13 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
||||||
* value. */
|
value. */
|
||||||
|
|
||||||
configASSERT( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY );
|
configASSERT( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY );
|
||||||
|
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
* value. */
|
value. */
|
||||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||||
}
|
}
|
||||||
#endif /* conifgASSERT_DEFINED */
|
#endif /* conifgASSERT_DEFINED */
|
||||||
|
@ -310,28 +308,26 @@ BaseType_t xPortStartScheduler( void )
|
||||||
__asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) );
|
__asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) );
|
||||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||||
|
|
||||||
#if defined( GUEST )
|
#if defined( GUEST )
|
||||||
#warning Building for execution as a guest under XEN. THIS IS NOT A FULLY TESTED PATH.
|
#warning Building for execution as a guest under XEN. THIS IS NOT A FULLY TESTED PATH.
|
||||||
configASSERT( ulAPSR == portEL1 );
|
configASSERT( ulAPSR == portEL1 );
|
||||||
|
|
||||||
if( ulAPSR == portEL1 )
|
if( ulAPSR == portEL1 )
|
||||||
#else
|
#else
|
||||||
configASSERT( ulAPSR == portEL3 );
|
configASSERT( ulAPSR == portEL3 );
|
||||||
|
|
||||||
if( ulAPSR == portEL3 )
|
if( ulAPSR == portEL3 )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* Only continue if the binary point value is set to its lowest possible
|
/* Only continue if the binary point value is set to its lowest possible
|
||||||
* setting. See the comments in vPortValidateInterruptPriority() below for
|
setting. See the comments in vPortValidateInterruptPriority() below for
|
||||||
* more information. */
|
more information. */
|
||||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||||
|
|
||||||
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
||||||
{
|
{
|
||||||
/* Interrupts are turned off in the CPU itself to ensure a tick does
|
/* Interrupts are turned off in the CPU itself to ensure a tick does
|
||||||
* not execute while the scheduler is being started. Interrupts are
|
not execute while the scheduler is being started. Interrupts are
|
||||||
* automatically turned back on in the CPU when the first task starts
|
automatically turned back on in the CPU when the first task starts
|
||||||
* executing. */
|
executing. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. */
|
/* Start the timer that generates the tick ISR. */
|
||||||
|
@ -349,7 +345,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
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( ullCriticalNesting == 1000ULL );
|
configASSERT( ullCriticalNesting == 1000ULL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -360,15 +356,15 @@ void vPortEnterCritical( void )
|
||||||
uxPortSetInterruptMask();
|
uxPortSetInterruptMask();
|
||||||
|
|
||||||
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
||||||
* directly. Increment ullCriticalNesting to keep a count of how many times
|
directly. Increment ullCriticalNesting to keep a count of how many times
|
||||||
* portENTER_CRITICAL() has been called. */
|
portENTER_CRITICAL() has been called. */
|
||||||
ullCriticalNesting++;
|
ullCriticalNesting++;
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
* assert() if it is being called from an interrupt context. Only API
|
assert() if it is being called from an interrupt context. Only API
|
||||||
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
* the critical nesting count is 1 to protect against recursive calls if the
|
the critical nesting count is 1 to protect against recursive calls if the
|
||||||
* assert function also uses a critical section. */
|
assert function also uses a critical section. */
|
||||||
if( ullCriticalNesting == 1ULL )
|
if( ullCriticalNesting == 1ULL )
|
||||||
{
|
{
|
||||||
configASSERT( ullPortInterruptNesting == 0 );
|
configASSERT( ullPortInterruptNesting == 0 );
|
||||||
|
@ -381,15 +377,15 @@ void vPortExitCritical( void )
|
||||||
if( ullCriticalNesting > portNO_CRITICAL_NESTING )
|
if( ullCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Decrement the nesting count as the critical section is being
|
/* Decrement the nesting count as the critical section is being
|
||||||
* exited. */
|
exited. */
|
||||||
ullCriticalNesting--;
|
ullCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then all interrupt
|
/* If the nesting level has reached zero then all interrupt
|
||||||
* priorities must be re-enabled. */
|
priorities must be re-enabled. */
|
||||||
if( ullCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ullCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Critical nesting has reached zero so all interrupt priorities
|
/* Critical nesting has reached zero so all interrupt priorities
|
||||||
* should be unmasked. */
|
should be unmasked. */
|
||||||
portCLEAR_INTERRUPT_MASK();
|
portCLEAR_INTERRUPT_MASK();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -406,23 +402,23 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Interrupts should not be enabled before this point. */
|
/* Interrupts should not be enabled before this point. */
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
uint32_t ulMaskBits;
|
uint32_t ulMaskBits;
|
||||||
|
|
||||||
__asm volatile ( "mrs %0, daif" : "=r" ( ulMaskBits )::"memory" );
|
__asm volatile( "mrs %0, daif" : "=r"( ulMaskBits ) :: "memory" );
|
||||||
configASSERT( ( ulMaskBits & portDAIF_I ) != 0 );
|
configASSERT( ( ulMaskBits & portDAIF_I ) != 0 );
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/* Set interrupt mask before altering scheduler structures. The tick
|
/* Set interrupt mask before altering scheduler structures. The tick
|
||||||
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||||
* so there is no need to save and restore the current mask value. It is
|
so there is no need to save and restore the current mask value. It is
|
||||||
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||||
* updated. */
|
updated. */
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
__asm volatile ( "dsb sy \n"
|
__asm volatile ( "dsb sy \n"
|
||||||
"isb sy \n"::: "memory" );
|
"isb sy \n" ::: "memory" );
|
||||||
|
|
||||||
/* Ok to enable interrupts after the interrupt source has been cleared. */
|
/* Ok to enable interrupts after the interrupt source has been cleared. */
|
||||||
configCLEAR_TICK_INTERRUPT();
|
configCLEAR_TICK_INTERRUPT();
|
||||||
|
@ -442,11 +438,11 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
void vPortTaskUsesFPU( void )
|
void vPortTaskUsesFPU( void )
|
||||||
{
|
{
|
||||||
/* A task is registering the fact that it needs an FPU context. Set the
|
/* A task is registering the fact that it needs an FPU context. Set the
|
||||||
* FPU flag (which is saved as part of the task context). */
|
FPU flag (which is saved as part of the task context). */
|
||||||
ullPortTaskHasFPUContext = pdTRUE;
|
ullPortTaskHasFPUContext = pdTRUE;
|
||||||
|
|
||||||
/* Consider initialising the FPSR here - but probably not necessary in
|
/* Consider initialising the FPSR here - but probably not necessary in
|
||||||
* AArch64. */
|
AArch64. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -461,12 +457,11 @@ void vPortClearInterruptMask( UBaseType_t uxNewMaskValue )
|
||||||
|
|
||||||
UBaseType_t uxPortSetInterruptMask( void )
|
UBaseType_t uxPortSetInterruptMask( void )
|
||||||
{
|
{
|
||||||
uint32_t ulReturn;
|
uint32_t ulReturn;
|
||||||
|
|
||||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||||
* updated. */
|
updated. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||||
{
|
{
|
||||||
/* Interrupts were already masked. */
|
/* Interrupts were already masked. */
|
||||||
|
@ -477,47 +472,47 @@ UBaseType_t uxPortSetInterruptMask( void )
|
||||||
ulReturn = pdFALSE;
|
ulReturn = pdFALSE;
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
__asm volatile ( "dsb sy \n"
|
__asm volatile ( "dsb sy \n"
|
||||||
"isb sy \n"::: "memory" );
|
"isb sy \n" ::: "memory" );
|
||||||
}
|
}
|
||||||
|
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
return ulReturn;
|
return ulReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
void vPortValidateInterruptPriority( void )
|
||||||
{
|
{
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
/* The following assertion will fail if a service routine (ISR) for
|
||||||
* an interrupt that has been assigned a priority above
|
an interrupt that has been assigned a priority above
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||||
* function. ISR safe FreeRTOS API functions must *only* be called
|
function. ISR safe FreeRTOS API functions must *only* be called
|
||||||
* from interrupts that have been assigned a priority at or below
|
from interrupts that have been assigned a priority at or below
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
*
|
|
||||||
* Numerically low interrupt priority numbers represent logically high
|
Numerically low interrupt priority numbers represent logically high
|
||||||
* interrupt priorities, therefore the priority of the interrupt must
|
interrupt priorities, therefore the priority of the interrupt must
|
||||||
* be set to a value equal to or numerically *higher* than
|
be set to a value equal to or numerically *higher* than
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
*
|
|
||||||
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||||
* interrupt entry is as fast and simple as possible. */
|
interrupt entry is as fast and simple as possible. */
|
||||||
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
||||||
* that define each interrupt's priority to be split between bits that
|
that define each interrupt's priority to be split between bits that
|
||||||
* define the interrupt's pre-emption priority bits and bits that define
|
define the interrupt's pre-emption priority bits and bits that define
|
||||||
* the interrupt's sub-priority. For simplicity all bits must be defined
|
the interrupt's sub-priority. For simplicity all bits must be defined
|
||||||
* to be pre-emption priority bits. The following assertion will fail if
|
to be pre-emption priority bits. The following assertion will fail if
|
||||||
* this is not the case (if some bits represent a sub-priority).
|
this is not the case (if some bits represent a sub-priority).
|
||||||
*
|
|
||||||
* The priority grouping is configured by the GIC's binary point register
|
The priority grouping is configured by the GIC's binary point register
|
||||||
* (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||||
* possible value (which may be above 0). */
|
possible value (which may be above 0). */
|
||||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -43,169 +43,169 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 size_t
|
#define portSTACK_TYPE size_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef portBASE_TYPE BaseType_t;
|
typedef portBASE_TYPE BaseType_t;
|
||||||
typedef uint64_t UBaseType_t;
|
typedef uint64_t UBaseType_t;
|
||||||
|
|
||||||
typedef uint64_t TickType_t;
|
typedef uint64_t TickType_t;
|
||||||
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
||||||
|
|
||||||
/* 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
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 16
|
#define portBYTE_ALIGNMENT 16
|
||||||
#define portPOINTER_SIZE_TYPE uint64_t
|
#define portPOINTER_SIZE_TYPE uint64_t
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
/* Called at the end of an ISR that can cause a context switch. */
|
/* Called at the end of an ISR that can cause a context switch. */
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
#define portEND_SWITCHING_ISR( xSwitchRequired )\
|
||||||
{ \
|
{ \
|
||||||
extern uint64_t ullPortYieldRequired; \
|
extern uint64_t ullPortYieldRequired; \
|
||||||
\
|
\
|
||||||
if( xSwitchRequired != pdFALSE ) \
|
if( xSwitchRequired != pdFALSE ) \
|
||||||
{ \
|
{ \
|
||||||
ullPortYieldRequired = pdTRUE; \
|
ullPortYieldRequired = pdTRUE; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
#if defined( GUEST )
|
#if defined( GUEST )
|
||||||
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
||||||
#else
|
#else
|
||||||
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Critical section control
|
* Critical section control
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
extern UBaseType_t uxPortSetInterruptMask( void );
|
extern UBaseType_t uxPortSetInterruptMask( void );
|
||||||
extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
|
extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
|
||||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB SY" ); \
|
__asm volatile ( "DSB SY" ); \
|
||||||
__asm volatile ( "ISB SY" );
|
__asm volatile ( "ISB SY" );
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB SY" ); \
|
__asm volatile ( "DSB SY" ); \
|
||||||
__asm volatile ( "ISB SY" );
|
__asm volatile ( "ISB SY" );
|
||||||
|
|
||||||
|
|
||||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||||
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
* not required for this port but included in case common demo code that uses these
|
not required for this port but included in case common demo code that uses these
|
||||||
* macros is used. */
|
macros is used. */
|
||||||
#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 )
|
||||||
|
|
||||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||||
* handler for whichever peripheral is used to generate the RTOS tick. */
|
handler for whichever peripheral is used to generate the RTOS tick. */
|
||||||
void FreeRTOS_Tick_Handler( void );
|
void FreeRTOS_Tick_Handler( void );
|
||||||
|
|
||||||
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
||||||
* before any floating point instructions are executed. */
|
before any floating point instructions are executed. */
|
||||||
void vPortTaskUsesFPU( void );
|
void vPortTaskUsesFPU( void );
|
||||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||||
|
|
||||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif /* configASSERT */
|
#endif /* configASSERT */
|
||||||
|
|
||||||
#define portNOP() __asm volatile ( "NOP" )
|
#define portNOP() __asm volatile( "NOP" )
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern C */
|
} /* extern C */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||||
* number of bits implemented by the interrupt controller. */
|
number of bits implemented by the interrupt controller. */
|
||||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||||
#define portPRIORITY_SHIFT 4
|
#define portPRIORITY_SHIFT 4
|
||||||
#define portMAX_BINARY_POINT_VALUE 3
|
#define portMAX_BINARY_POINT_VALUE 3
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
||||||
#define portPRIORITY_SHIFT 3
|
#define portPRIORITY_SHIFT 3
|
||||||
#define portMAX_BINARY_POINT_VALUE 2
|
#define portMAX_BINARY_POINT_VALUE 2
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
||||||
#define portPRIORITY_SHIFT 2
|
#define portPRIORITY_SHIFT 2
|
||||||
#define portMAX_BINARY_POINT_VALUE 1
|
#define portMAX_BINARY_POINT_VALUE 1
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
||||||
#define portPRIORITY_SHIFT 1
|
#define portPRIORITY_SHIFT 1
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||||
#define portPRIORITY_SHIFT 0
|
#define portPRIORITY_SHIFT 0
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
#else
|
||||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||||
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
#endif
|
||||||
|
|
||||||
/* Interrupt controller access addresses. */
|
/* Interrupt controller access addresses. */
|
||||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
||||||
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
||||||
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
||||||
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
||||||
|
|
||||||
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
||||||
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
||||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
||||||
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
||||||
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
||||||
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
||||||
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
||||||
|
|
||||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -33,23 +33,23 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
||||||
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
||||||
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
||||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configSETUP_TICK_INTERRUPT
|
#ifndef configSETUP_TICK_INTERRUPT
|
||||||
#error configSETUP_TICK_INTERRUPT() must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
#error configSETUP_TICK_INTERRUPT() must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||||
#endif /* configSETUP_TICK_INTERRUPT */
|
#endif /* configSETUP_TICK_INTERRUPT */
|
||||||
|
|
||||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if ( configMAX_PRIORITIES > 32 )
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
@ -73,24 +73,24 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||||
* portmacro.h. */
|
portmacro.h. */
|
||||||
#ifndef configCLEAR_TICK_INTERRUPT
|
#ifndef configCLEAR_TICK_INTERRUPT
|
||||||
#define configCLEAR_TICK_INTERRUPT()
|
#define configCLEAR_TICK_INTERRUPT()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* A critical section is exited when the critical section nesting count reaches
|
/* A critical section is exited when the critical section nesting count reaches
|
||||||
* this value. */
|
this value. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||||
|
|
||||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||||
* (but the lowest) interrupt priority. */
|
(but the lowest) interrupt priority. */
|
||||||
#define portUNMASK_VALUE ( 0xFFUL )
|
#define portUNMASK_VALUE ( 0xFFUL )
|
||||||
|
|
||||||
/* Tasks are not created with a floating point context, but can be given a
|
/* Tasks are not created with a floating point context, but can be given a
|
||||||
* floating point context after they have been created. A variable is stored as
|
floating point context after they have been created. A variable is stored as
|
||||||
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||||
* does not have an FPU context, or any other value if the task does have an FPU
|
does not have an FPU context, or any other value if the task does have an FPU
|
||||||
* context. */
|
context. */
|
||||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to setup the initial task context. */
|
/* Constants required to setup the initial task context. */
|
||||||
|
@ -100,19 +100,19 @@
|
||||||
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
||||||
|
|
||||||
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
||||||
* point is zero. */
|
point is zero. */
|
||||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||||
|
|
||||||
/* Masks all bits in the APSR other than the mode bits. */
|
/* Masks all bits in the APSR other than the mode bits. */
|
||||||
#define portAPSR_MODE_BITS_MASK ( 0x1F )
|
#define portAPSR_MODE_BITS_MASK ( 0x1F )
|
||||||
|
|
||||||
/* The value of the mode bits in the APSR when the CPU is executing in user
|
/* The value of the mode bits in the APSR when the CPU is executing in user
|
||||||
* mode. */
|
mode. */
|
||||||
#define portAPSR_USER_MODE ( 0x10 )
|
#define portAPSR_USER_MODE ( 0x10 )
|
||||||
|
|
||||||
/* The critical section macros only mask interrupts up to an application
|
/* The critical section macros only mask interrupts up to an application
|
||||||
* determined priority level. Sometimes it is necessary to turn interrupt off in
|
determined priority level. Sometimes it is necessary to turn interrupt off in
|
||||||
* the CPU itself before modifying certain hardware registers. */
|
the CPU itself before modifying certain hardware registers. */
|
||||||
#define portCPU_IRQ_DISABLE() \
|
#define portCPU_IRQ_DISABLE() \
|
||||||
__asm volatile ( "CPSID i" ::: "memory" ); \
|
__asm volatile ( "CPSID i" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB" ); \
|
__asm volatile ( "DSB" ); \
|
||||||
|
@ -126,21 +126,21 @@
|
||||||
|
|
||||||
/* Macro to unmask all interrupt priorities. */
|
/* Macro to unmask all interrupt priorities. */
|
||||||
#define portCLEAR_INTERRUPT_MASK() \
|
#define portCLEAR_INTERRUPT_MASK() \
|
||||||
{ \
|
{ \
|
||||||
portCPU_IRQ_DISABLE(); \
|
portCPU_IRQ_DISABLE(); \
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
||||||
__asm volatile ( "DSB \n" \
|
__asm volatile ( "DSB \n" \
|
||||||
"ISB \n"); \
|
"ISB \n" ); \
|
||||||
portCPU_IRQ_ENABLE(); \
|
portCPU_IRQ_ENABLE(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
||||||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||||
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
||||||
|
|
||||||
/* Let the user override the pre-loading of the initial LR with the address of
|
/* Let the user override the pre-loading of the initial LR with the address of
|
||||||
* prvTaskExitError() in case it messes up unwinding of the stack in the
|
prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||||
* debugger. */
|
debugger. */
|
||||||
#ifdef configTASK_RETURN_ADDRESS
|
#ifdef configTASK_RETURN_ADDRESS
|
||||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||||
#else
|
#else
|
||||||
|
@ -148,7 +148,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The space on the stack required to hold the FPU registers. This is 32 64-bit
|
/* The space on the stack required to hold the FPU registers. This is 32 64-bit
|
||||||
* registers, plus a 32-bit status register. */
|
registers, plus a 32-bit status register. */
|
||||||
#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 )
|
#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -183,49 +183,47 @@ static void prvTaskExitError( void );
|
||||||
* FPU registers to be saved on interrupt entry their IRQ handler must be
|
* FPU registers to be saved on interrupt entry their IRQ handler must be
|
||||||
* called vApplicationIRQHandler().
|
* called vApplicationIRQHandler().
|
||||||
*/
|
*/
|
||||||
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__( ( weak ) );
|
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* A variable is used to keep track of the critical section nesting. This
|
/* A variable is used to keep track of the critical section nesting. This
|
||||||
* variable has to be stored as part of the task context and must be initialised to
|
variable has to be stored as part of the task context and must be initialised to
|
||||||
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||||
* the scheduler starts. As it is stored as part of the task context it will
|
the scheduler starts. As it is stored as part of the task context it will
|
||||||
* automatically be set to 0 when the first task is started. */
|
automatically be set to 0 when the first task is started. */
|
||||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
|
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
|
||||||
* a floating point context must be saved and restored for the task. */
|
a floating point context must be saved and restored for the task. */
|
||||||
volatile uint32_t ulPortTaskHasFPUContext = pdFALSE;
|
volatile uint32_t ulPortTaskHasFPUContext = pdFALSE;
|
||||||
|
|
||||||
/* Set to 1 to pend a context switch from an ISR. */
|
/* Set to 1 to pend a context switch from an ISR. */
|
||||||
volatile uint32_t ulPortYieldRequired = pdFALSE;
|
volatile uint32_t ulPortYieldRequired = pdFALSE;
|
||||||
|
|
||||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||||
* if the nesting depth is 0. */
|
if the nesting depth is 0. */
|
||||||
volatile uint32_t ulPortInterruptNesting = 0UL;
|
volatile uint32_t ulPortInterruptNesting = 0UL;
|
||||||
|
|
||||||
/* Used in the asm file. */
|
/* Used in the asm file. */
|
||||||
__attribute__( ( used ) ) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
__attribute__(( used )) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
||||||
__attribute__( ( used ) ) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
__attribute__(( used )) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
||||||
__attribute__( ( used ) ) const uint32_t ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
__attribute__(( used )) const uint32_t ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
||||||
__attribute__( ( used ) ) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
__attribute__(( used )) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 )
|
|
||||||
{
|
{
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
* expected by the portRESTORE_CONTEXT() macro.
|
expected by the portRESTORE_CONTEXT() macro.
|
||||||
*
|
|
||||||
* The fist real value on the stack is the status register, which is set for
|
The fist real value on the stack is the status register, which is set for
|
||||||
* system mode, with interrupts enabled. A few NULLs are added first to ensure
|
system mode, with interrupts enabled. A few NULLs are added first to ensure
|
||||||
* GDB does not try decoding a non-existent return address. */
|
GDB does not try decoding a non-existent return address. */
|
||||||
*pxTopOfStack = ( StackType_t ) NULL;
|
*pxTopOfStack = ( StackType_t ) NULL;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) NULL;
|
*pxTopOfStack = ( StackType_t ) NULL;
|
||||||
|
@ -277,21 +275,21 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||||
* enabled. */
|
enabled. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||||
|
|
||||||
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
|
#if( configUSE_TASK_FPU_SUPPORT == 1 )
|
||||||
{
|
{
|
||||||
/* The task will start without a floating point context. A task that
|
/* The task will start without a floating point context. A task that
|
||||||
* uses the floating point hardware must call vPortTaskUsesFPU() before
|
uses the floating point hardware must call vPortTaskUsesFPU() before
|
||||||
* executing any floating point instructions. */
|
executing any floating point instructions. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||||
}
|
}
|
||||||
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
|
#elif( configUSE_TASK_FPU_SUPPORT == 2 )
|
||||||
{
|
{
|
||||||
/* The task will start with a floating point context. Leave enough
|
/* The task will start with a floating point context. Leave enough
|
||||||
* space for the registers - and ensure they are initialised to 0. */
|
space for the registers - and ensure they are initialised to 0. */
|
||||||
pxTopOfStack -= portFPU_REGISTER_WORDS;
|
pxTopOfStack -= portFPU_REGISTER_WORDS;
|
||||||
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
|
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
|
||||||
|
|
||||||
|
@ -299,11 +297,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
*pxTopOfStack = pdTRUE;
|
*pxTopOfStack = pdTRUE;
|
||||||
ulPortTaskHasFPUContext = pdTRUE;
|
ulPortTaskHasFPUContext = pdTRUE;
|
||||||
}
|
}
|
||||||
#else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
|
#else
|
||||||
{
|
{
|
||||||
#error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined.
|
#error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined.
|
||||||
}
|
}
|
||||||
#endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
|
#endif
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
|
@ -312,37 +310,34 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* A function that implements a task must not exit or attempt to return to
|
||||||
* its caller as there is nothing to return to. If a task wants to exit it
|
its caller as there is nothing to return to. If a task wants to exit it
|
||||||
* should instead call vTaskDelete( NULL ).
|
should instead call vTaskDelete( NULL ).
|
||||||
*
|
|
||||||
* Artificially force an assert() to be triggered if configASSERT() is
|
Artificially force an assert() to be triggered if configASSERT() is
|
||||||
* defined, then stop here so application writers can catch the error. */
|
defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( ulPortInterruptNesting == ~0UL );
|
configASSERT( ulPortInterruptNesting == ~0UL );
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
for( ;; );
|
||||||
for( ; ; )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulAPSR;
|
uint32_t ulAPSR;
|
||||||
|
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
volatile uint32_t ulOriginalPriority;
|
||||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine how many priority bits are implemented in the GIC.
|
/* Determine how many priority bits are implemented in the GIC.
|
||||||
*
|
|
||||||
* Save the interrupt priority value that is about to be clobbered. */
|
Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to
|
/* Determine the number of priority bits available. First write to
|
||||||
* all possible bits. */
|
all possible bits. */
|
||||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
@ -355,35 +350,35 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
||||||
* value. */
|
value. */
|
||||||
configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY );
|
configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY );
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
* value. */
|
value. */
|
||||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||||
}
|
}
|
||||||
#endif /* conifgASSERT_DEFINED */
|
#endif /* conifgASSERT_DEFINED */
|
||||||
|
|
||||||
|
|
||||||
/* Only continue if the CPU is not in User mode. The CPU must be in a
|
/* Only continue if the CPU is not in User mode. The CPU must be in a
|
||||||
* Privileged mode for the scheduler to start. */
|
Privileged mode for the scheduler to start. */
|
||||||
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" );
|
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) :: "memory" );
|
||||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||||
configASSERT( ulAPSR != portAPSR_USER_MODE );
|
configASSERT( ulAPSR != portAPSR_USER_MODE );
|
||||||
|
|
||||||
if( ulAPSR != portAPSR_USER_MODE )
|
if( ulAPSR != portAPSR_USER_MODE )
|
||||||
{
|
{
|
||||||
/* Only continue if the binary point value is set to its lowest possible
|
/* Only continue if the binary point value is set to its lowest possible
|
||||||
* setting. See the comments in vPortValidateInterruptPriority() below for
|
setting. See the comments in vPortValidateInterruptPriority() below for
|
||||||
* more information. */
|
more information. */
|
||||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||||
|
|
||||||
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
||||||
{
|
{
|
||||||
/* Interrupts are turned off in the CPU itself to ensure tick does
|
/* Interrupts are turned off in the CPU itself to ensure tick does
|
||||||
* not execute while the scheduler is being started. Interrupts are
|
not execute while the scheduler is being started. Interrupts are
|
||||||
* automatically turned back on in the CPU when the first task starts
|
automatically turned back on in the CPU when the first task starts
|
||||||
* executing. */
|
executing. */
|
||||||
portCPU_IRQ_DISABLE();
|
portCPU_IRQ_DISABLE();
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. */
|
/* Start the timer that generates the tick ISR. */
|
||||||
|
@ -395,10 +390,10 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
||||||
* a non-privileged mode or the binary point register was not set to its lowest
|
a non-privileged mode or the binary point register was not set to its lowest
|
||||||
* possible value. prvTaskExitError() is referenced to prevent a compiler
|
possible value. prvTaskExitError() is referenced to prevent a compiler
|
||||||
* warning about it being defined but not referenced in the case that the user
|
warning about it being defined but not referenced in the case that the user
|
||||||
* defines their own exit address. */
|
defines their own exit address. */
|
||||||
( void ) prvTaskExitError;
|
( void ) prvTaskExitError;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -407,7 +402,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
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( ulCriticalNesting == 1000UL );
|
configASSERT( ulCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -418,15 +413,15 @@ void vPortEnterCritical( void )
|
||||||
ulPortSetInterruptMask();
|
ulPortSetInterruptMask();
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
* portENTER_CRITICAL() has been called. */
|
portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
* assert() if it is being called from an interrupt context. Only API
|
assert() if it is being called from an interrupt context. Only API
|
||||||
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
* the critical nesting count is 1 to protect against recursive calls if the
|
the critical nesting count is 1 to protect against recursive calls if the
|
||||||
* assert function also uses a critical section. */
|
assert function also uses a critical section. */
|
||||||
if( ulCriticalNesting == 1 )
|
if( ulCriticalNesting == 1 )
|
||||||
{
|
{
|
||||||
configASSERT( ulPortInterruptNesting == 0 );
|
configASSERT( ulPortInterruptNesting == 0 );
|
||||||
|
@ -439,15 +434,15 @@ void vPortExitCritical( void )
|
||||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Decrement the nesting count as the critical section is being
|
/* Decrement the nesting count as the critical section is being
|
||||||
* exited. */
|
exited. */
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then all interrupt
|
/* If the nesting level has reached zero then all interrupt
|
||||||
* priorities must be re-enabled. */
|
priorities must be re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Critical nesting has reached zero so all interrupt priorities
|
/* Critical nesting has reached zero so all interrupt priorities
|
||||||
* should be unmasked. */
|
should be unmasked. */
|
||||||
portCLEAR_INTERRUPT_MASK();
|
portCLEAR_INTERRUPT_MASK();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -457,14 +452,14 @@ void vPortExitCritical( void )
|
||||||
void FreeRTOS_Tick_Handler( void )
|
void FreeRTOS_Tick_Handler( void )
|
||||||
{
|
{
|
||||||
/* Set interrupt mask before altering scheduler structures. The tick
|
/* Set interrupt mask before altering scheduler structures. The tick
|
||||||
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||||
* so there is no need to save and restore the current mask value. It is
|
so there is no need to save and restore the current mask value. It is
|
||||||
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||||
* updated. */
|
updated. */
|
||||||
portCPU_IRQ_DISABLE();
|
portCPU_IRQ_DISABLE();
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
__asm volatile ( "dsb \n"
|
__asm volatile ( "dsb \n"
|
||||||
"isb \n"::: "memory" );
|
"isb \n" ::: "memory" );
|
||||||
portCPU_IRQ_ENABLE();
|
portCPU_IRQ_ENABLE();
|
||||||
|
|
||||||
/* Increment the RTOS tick. */
|
/* Increment the RTOS tick. */
|
||||||
|
@ -479,18 +474,18 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
|
#if( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||||
|
|
||||||
void vPortTaskUsesFPU( void )
|
void vPortTaskUsesFPU( void )
|
||||||
{
|
{
|
||||||
uint32_t ulInitialFPSCR = 0;
|
uint32_t ulInitialFPSCR = 0;
|
||||||
|
|
||||||
/* A task is registering the fact that it needs an FPU context. Set the
|
/* A task is registering the fact that it needs an FPU context. Set the
|
||||||
* FPU flag (which is saved as part of the task context). */
|
FPU flag (which is saved as part of the task context). */
|
||||||
ulPortTaskHasFPUContext = pdTRUE;
|
ulPortTaskHasFPUContext = pdTRUE;
|
||||||
|
|
||||||
/* Initialise the floating point status register. */
|
/* Initialise the floating point status register. */
|
||||||
__asm volatile ( "FMXR FPSCR, %0" ::"r" ( ulInitialFPSCR ) : "memory" );
|
__asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) : "memory" );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configUSE_TASK_FPU_SUPPORT */
|
#endif /* configUSE_TASK_FPU_SUPPORT */
|
||||||
|
@ -507,12 +502,11 @@ void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
||||||
|
|
||||||
uint32_t ulPortSetInterruptMask( void )
|
uint32_t ulPortSetInterruptMask( void )
|
||||||
{
|
{
|
||||||
uint32_t ulReturn;
|
uint32_t ulReturn;
|
||||||
|
|
||||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||||
* updated. */
|
updated. */
|
||||||
portCPU_IRQ_DISABLE();
|
portCPU_IRQ_DISABLE();
|
||||||
|
|
||||||
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||||
{
|
{
|
||||||
/* Interrupts were already masked. */
|
/* Interrupts were already masked. */
|
||||||
|
@ -523,45 +517,44 @@ uint32_t ulPortSetInterruptMask( void )
|
||||||
ulReturn = pdFALSE;
|
ulReturn = pdFALSE;
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
__asm volatile ( "dsb \n"
|
__asm volatile ( "dsb \n"
|
||||||
"isb \n"::: "memory" );
|
"isb \n" ::: "memory" );
|
||||||
}
|
}
|
||||||
|
|
||||||
portCPU_IRQ_ENABLE();
|
portCPU_IRQ_ENABLE();
|
||||||
|
|
||||||
return ulReturn;
|
return ulReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
void vPortValidateInterruptPriority( void )
|
||||||
{
|
{
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
/* The following assertion will fail if a service routine (ISR) for
|
||||||
* an interrupt that has been assigned a priority above
|
an interrupt that has been assigned a priority above
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||||
* function. ISR safe FreeRTOS API functions must *only* be called
|
function. ISR safe FreeRTOS API functions must *only* be called
|
||||||
* from interrupts that have been assigned a priority at or below
|
from interrupts that have been assigned a priority at or below
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
*
|
|
||||||
* Numerically low interrupt priority numbers represent logically high
|
Numerically low interrupt priority numbers represent logically high
|
||||||
* interrupt priorities, therefore the priority of the interrupt must
|
interrupt priorities, therefore the priority of the interrupt must
|
||||||
* be set to a value equal to or numerically *higher* than
|
be set to a value equal to or numerically *higher* than
|
||||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
*
|
|
||||||
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||||
* interrupt entry is as fast and simple as possible. */
|
interrupt entry is as fast and simple as possible. */
|
||||||
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
||||||
* that define each interrupt's priority to be split between bits that
|
that define each interrupt's priority to be split between bits that
|
||||||
* define the interrupt's pre-emption priority bits and bits that define
|
define the interrupt's pre-emption priority bits and bits that define
|
||||||
* the interrupt's sub-priority. For simplicity all bits must be defined
|
the interrupt's sub-priority. For simplicity all bits must be defined
|
||||||
* to be pre-emption priority bits. The following assertion will fail if
|
to be pre-emption priority bits. The following assertion will fail if
|
||||||
* this is not the case (if some bits represent a sub-priority).
|
this is not the case (if some bits represent a sub-priority).
|
||||||
*
|
|
||||||
* The priority grouping is configured by the GIC's binary point register
|
The priority grouping is configured by the GIC's binary point register
|
||||||
* (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||||
* possible value (which may be above 0). */
|
possible value (which may be above 0). */
|
||||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -43,166 +43,166 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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;
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
/* Called at the end of an ISR that can cause a context switch. */
|
/* Called at the end of an ISR that can cause a context switch. */
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
#define portEND_SWITCHING_ISR( xSwitchRequired )\
|
||||||
{ \
|
{ \
|
||||||
extern uint32_t ulPortYieldRequired; \
|
extern uint32_t ulPortYieldRequired; \
|
||||||
\
|
\
|
||||||
if( xSwitchRequired != pdFALSE ) \
|
if( xSwitchRequired != pdFALSE ) \
|
||||||
{ \
|
{ \
|
||||||
ulPortYieldRequired = pdTRUE; \
|
ulPortYieldRequired = pdTRUE; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
#define portYIELD() __asm volatile ( "SWI 0" ::: "memory" );
|
#define portYIELD() __asm volatile ( "SWI 0" ::: "memory" );
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Critical section control
|
* Critical section control
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
extern uint32_t ulPortSetInterruptMask( void );
|
extern uint32_t ulPortSetInterruptMask( void );
|
||||||
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||||
|
|
||||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||||
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
* not required for this port but included in case common demo code that uses these
|
not required for this port but included in case common demo code that uses these
|
||||||
* macros is used. */
|
macros is used. */
|
||||||
#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 )
|
||||||
|
|
||||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||||
* handler for whichever peripheral is used to generate the RTOS tick. */
|
handler for whichever peripheral is used to generate the RTOS tick. */
|
||||||
void FreeRTOS_Tick_Handler( void );
|
void FreeRTOS_Tick_Handler( void );
|
||||||
|
|
||||||
/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
|
/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
|
||||||
* created without an FPU context and must call vPortTaskUsesFPU() to give
|
created without an FPU context and must call vPortTaskUsesFPU() to give
|
||||||
* themselves an FPU context before using any FPU instructions. If
|
themselves an FPU context before using any FPU instructions. If
|
||||||
* configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
|
configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
|
||||||
* by default. */
|
by default. */
|
||||||
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
|
#if( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||||
void vPortTaskUsesFPU( void );
|
void vPortTaskUsesFPU( void );
|
||||||
#else
|
#else
|
||||||
|
/* Each task has an FPU context already, so define this function away to
|
||||||
/* Each task has an FPU context already, so define this function away to
|
nothing to prevent it being called accidentally. */
|
||||||
* nothing to prevent it being called accidentally. */
|
|
||||||
#define vPortTaskUsesFPU()
|
#define vPortTaskUsesFPU()
|
||||||
#endif
|
#endif
|
||||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||||
|
|
||||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif /* configASSERT */
|
#endif /* configASSERT */
|
||||||
|
|
||||||
#define portNOP() __asm volatile ( "NOP" )
|
#define portNOP() __asm volatile( "NOP" )
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern C */
|
} /* extern C */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||||
* number of bits implemented by the interrupt controller. */
|
number of bits implemented by the interrupt controller. */
|
||||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||||
#define portPRIORITY_SHIFT 4
|
#define portPRIORITY_SHIFT 4
|
||||||
#define portMAX_BINARY_POINT_VALUE 3
|
#define portMAX_BINARY_POINT_VALUE 3
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
||||||
#define portPRIORITY_SHIFT 3
|
#define portPRIORITY_SHIFT 3
|
||||||
#define portMAX_BINARY_POINT_VALUE 2
|
#define portMAX_BINARY_POINT_VALUE 2
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
||||||
#define portPRIORITY_SHIFT 2
|
#define portPRIORITY_SHIFT 2
|
||||||
#define portMAX_BINARY_POINT_VALUE 1
|
#define portMAX_BINARY_POINT_VALUE 1
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
||||||
#define portPRIORITY_SHIFT 1
|
#define portPRIORITY_SHIFT 1
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||||
#define portPRIORITY_SHIFT 0
|
#define portPRIORITY_SHIFT 0
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
#else
|
||||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||||
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
#endif
|
||||||
|
|
||||||
/* Interrupt controller access addresses. */
|
/* Interrupt controller access addresses. */
|
||||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
||||||
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
||||||
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
||||||
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
||||||
|
|
||||||
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
||||||
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
||||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
||||||
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
||||||
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
||||||
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
||||||
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
||||||
|
|
||||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -1051,7 +1051,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||||
int32_t lIndex = 0;
|
int32_t lIndex = 0;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* Declaration when these variable are defined in code instead of being
|
||||||
* exported from linker scripts. */
|
* exported from linker scripts. */
|
||||||
extern uint32_t * __privileged_sram_start__;
|
extern uint32_t * __privileged_sram_start__;
|
||||||
|
@ -1079,8 +1081,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* using a separate MPU region. This is needed because privileged
|
* using a separate MPU region. This is needed because privileged
|
||||||
* SRAM is already protected using an MPU region and ARMv8-M does
|
* SRAM is already protected using an MPU region and ARMv8-M does
|
||||||
* not allow overlapping MPU regions. */
|
* not allow overlapping MPU regions. */
|
||||||
if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&
|
if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) &&
|
||||||
ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )
|
( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) )
|
||||||
{
|
{
|
||||||
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;
|
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;
|
||||||
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;
|
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;
|
||||||
|
|
|
@ -877,6 +877,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
StackType_t * pxEndOfStack,
|
StackType_t * pxEndOfStack,
|
||||||
|
@ -889,6 +890,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
TaskFunction_t pxCode,
|
TaskFunction_t pxCode,
|
||||||
void * pvParameters ) /* PRIVILEGED_FUNCTION */
|
void * pvParameters ) /* PRIVILEGED_FUNCTION */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
/* *INDENT-ON* */
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
* interrupt. */
|
* interrupt. */
|
||||||
|
@ -1051,7 +1053,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||||
int32_t lIndex = 0;
|
int32_t lIndex = 0;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* Declaration when these variable are defined in code instead of being
|
||||||
* exported from linker scripts. */
|
* exported from linker scripts. */
|
||||||
extern uint32_t * __privileged_sram_start__;
|
extern uint32_t * __privileged_sram_start__;
|
||||||
|
@ -1079,8 +1083,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* using a separate MPU region. This is needed because privileged
|
* using a separate MPU region. This is needed because privileged
|
||||||
* SRAM is already protected using an MPU region and ARMv8-M does
|
* SRAM is already protected using an MPU region and ARMv8-M does
|
||||||
* not allow overlapping MPU regions. */
|
* not allow overlapping MPU regions. */
|
||||||
if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&
|
if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) &&
|
||||||
ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )
|
( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) )
|
||||||
{
|
{
|
||||||
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;
|
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;
|
||||||
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;
|
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;
|
||||||
|
|
|
@ -877,6 +877,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
StackType_t * pxEndOfStack,
|
StackType_t * pxEndOfStack,
|
||||||
|
@ -889,6 +890,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
TaskFunction_t pxCode,
|
TaskFunction_t pxCode,
|
||||||
void * pvParameters ) /* PRIVILEGED_FUNCTION */
|
void * pvParameters ) /* PRIVILEGED_FUNCTION */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
/* *INDENT-ON* */
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
* interrupt. */
|
* interrupt. */
|
||||||
|
@ -1051,7 +1053,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||||
int32_t lIndex = 0;
|
int32_t lIndex = 0;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* Declaration when these variable are defined in code instead of being
|
||||||
* exported from linker scripts. */
|
* exported from linker scripts. */
|
||||||
extern uint32_t * __privileged_sram_start__;
|
extern uint32_t * __privileged_sram_start__;
|
||||||
|
@ -1079,8 +1083,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* using a separate MPU region. This is needed because privileged
|
* using a separate MPU region. This is needed because privileged
|
||||||
* SRAM is already protected using an MPU region and ARMv8-M does
|
* SRAM is already protected using an MPU region and ARMv8-M does
|
||||||
* not allow overlapping MPU regions. */
|
* not allow overlapping MPU regions. */
|
||||||
if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&
|
if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) &&
|
||||||
ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )
|
( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) )
|
||||||
{
|
{
|
||||||
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;
|
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;
|
||||||
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;
|
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;
|
||||||
|
|
|
@ -877,6 +877,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
#if ( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
StackType_t * pxEndOfStack,
|
StackType_t * pxEndOfStack,
|
||||||
|
@ -889,6 +890,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
|
||||||
TaskFunction_t pxCode,
|
TaskFunction_t pxCode,
|
||||||
void * pvParameters ) /* PRIVILEGED_FUNCTION */
|
void * pvParameters ) /* PRIVILEGED_FUNCTION */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
/* *INDENT-ON* */
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
* interrupt. */
|
* interrupt. */
|
||||||
|
@ -1051,7 +1053,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||||
int32_t lIndex = 0;
|
int32_t lIndex = 0;
|
||||||
|
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* Declaration when these variable are defined in code instead of being
|
||||||
* exported from linker scripts. */
|
* exported from linker scripts. */
|
||||||
extern uint32_t * __privileged_sram_start__;
|
extern uint32_t * __privileged_sram_start__;
|
||||||
|
@ -1079,8 +1083,8 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
* using a separate MPU region. This is needed because privileged
|
* using a separate MPU region. This is needed because privileged
|
||||||
* SRAM is already protected using an MPU region and ARMv8-M does
|
* SRAM is already protected using an MPU region and ARMv8-M does
|
||||||
* not allow overlapping MPU regions. */
|
* not allow overlapping MPU regions. */
|
||||||
if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&
|
if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) &&
|
||||||
ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )
|
( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) )
|
||||||
{
|
{
|
||||||
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;
|
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;
|
||||||
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;
|
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;
|
||||||
|
|
|
@ -360,14 +360,14 @@ static void prvRestoreContextOfFirstTask( void )
|
||||||
" str r3, [r2] \n"/* Disable MPU. */
|
" str r3, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, =0xe000ed9c \n"/* Region Base Address register. */
|
" ldr r2, =0xe000ed9c \n"/* Region Base Address register. */
|
||||||
" ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */
|
" ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */
|
" stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */
|
||||||
" \n"
|
" \n"
|
||||||
#if ( portTOTAL_NUM_REGIONS == 16 )
|
#if ( portTOTAL_NUM_REGIONS == 16 )
|
||||||
" ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */
|
" ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */
|
" stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */
|
||||||
" ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */
|
" ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */
|
" stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */
|
||||||
#endif /* portTOTAL_NUM_REGIONS == 16. */
|
#endif /* portTOTAL_NUM_REGIONS == 16. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */
|
" ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */
|
||||||
|
@ -584,14 +584,14 @@ void xPortPendSVHandler( void )
|
||||||
" str r3, [r2] \n"/* Disable MPU. */
|
" str r3, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, =0xe000ed9c \n"/* Region Base Address register. */
|
" ldr r2, =0xe000ed9c \n"/* Region Base Address register. */
|
||||||
" ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */
|
" ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 4 - 7]. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */
|
" stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers [MPU Region # 4 - 7]. */
|
||||||
" \n"
|
" \n"
|
||||||
#if ( portTOTAL_NUM_REGIONS == 16 )
|
#if ( portTOTAL_NUM_REGIONS == 16 )
|
||||||
" ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */
|
" ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 8 - 11]. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */
|
" stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers. [MPU Region # 8 - 11]. */
|
||||||
" ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */
|
" ldmia r1!, {r4-r11} \n"/* Read 4 sets of MPU registers [MPU Region # 12 - 15]. */
|
||||||
" stmia r2, {r4-r11} \n" /* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */
|
" stmia r2, {r4-r11} \n"/* Write 4 sets of MPU registers. [MPU Region # 12 - 15]. */
|
||||||
#endif /* portTOTAL_NUM_REGIONS == 16. */
|
#endif /* portTOTAL_NUM_REGIONS == 16. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */
|
" ldr r2, =0xe000ed94 \n"/* MPU_CTRL register. */
|
||||||
|
|
|
@ -27,11 +27,14 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -44,54 +47,55 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 ( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
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
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* MPU specific constants. */
|
/* MPU specific constants. */
|
||||||
#define portUSING_MPU_WRAPPERS 1
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
|
|
||||||
#define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL )
|
#define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL )
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL )
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL )
|
||||||
#define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL )
|
#define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL )
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL )
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL )
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ( 0x02UL << 24UL )
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ( 0x02UL << 24UL )
|
||||||
#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL )
|
#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL )
|
||||||
#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL )
|
#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL )
|
||||||
/* Location of the TEX,S,C,B bits in the MPU Region Attribute and Size
|
|
||||||
|
/* Location of the TEX,S,C,B bits in the MPU Region Attribute and Size
|
||||||
* Register (RASR). */
|
* Register (RASR). */
|
||||||
#define portMPU_RASR_TEX_S_C_B_LOCATION ( 16UL )
|
#define portMPU_RASR_TEX_S_C_B_LOCATION ( 16UL )
|
||||||
#define portMPU_RASR_TEX_S_C_B_MASK ( 0x3FUL )
|
#define portMPU_RASR_TEX_S_C_B_MASK ( 0x3FUL )
|
||||||
|
|
||||||
/* MPU settings that can be overriden in FreeRTOSConfig.h. */
|
/* MPU settings that can be overriden in FreeRTOSConfig.h. */
|
||||||
#ifndef configTOTAL_MPU_REGIONS
|
#ifndef configTOTAL_MPU_REGIONS
|
||||||
/* Define to 8 for backward compatibility. */
|
/* Define to 8 for backward compatibility. */
|
||||||
#define configTOTAL_MPU_REGIONS ( 8UL )
|
#define configTOTAL_MPU_REGIONS ( 8UL )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits define the
|
* The TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits define the
|
||||||
* memory type, and where necessary the cacheable and shareable properties
|
* memory type, and where necessary the cacheable and shareable properties
|
||||||
* of the memory region.
|
* of the memory region.
|
||||||
|
@ -139,7 +143,7 @@
|
||||||
| | | | | bus. See the table below for the cacheability policy | |
|
| | | | | bus. See the table below for the cacheability policy | |
|
||||||
| | | | | encoding. memory, BB=Outer policy, AA=Inner policy. | |
|
| | | | | encoding. memory, BB=Outer policy, AA=Inner policy. | |
|
||||||
+-----+---+---+------------------------+--------------------------------------------------------+-------------------------+
|
+-----+---+---+------------------------+--------------------------------------------------------+-------------------------+
|
||||||
|
|
|
||||||
+-----------------------------------------+----------------------------------------+
|
+-----------------------------------------+----------------------------------------+
|
||||||
| AA or BB subfield of {TEX,C,B} encoding | Cacheability policy |
|
| AA or BB subfield of {TEX,C,B} encoding | Cacheability policy |
|
||||||
+-----------------------------------------+----------------------------------------+
|
+-----------------------------------------+----------------------------------------+
|
||||||
|
@ -153,60 +157,60 @@
|
||||||
+-----------------------------------------+----------------------------------------+
|
+-----------------------------------------+----------------------------------------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for flash
|
/* TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for flash
|
||||||
* region. */
|
* region. */
|
||||||
#ifndef configTEX_S_C_B_FLASH
|
#ifndef configTEX_S_C_B_FLASH
|
||||||
/* Default to TEX=000, S=1, C=1, B=1 for backward compatibility. */
|
/* Default to TEX=000, S=1, C=1, B=1 for backward compatibility. */
|
||||||
#define configTEX_S_C_B_FLASH ( 0x07UL )
|
#define configTEX_S_C_B_FLASH ( 0x07UL )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for RAM
|
/* TEX, Shareable (S), Cacheable (C) and Bufferable (B) bits for RAM
|
||||||
* region. */
|
* region. */
|
||||||
#ifndef configTEX_S_C_B_SRAM
|
#ifndef configTEX_S_C_B_SRAM
|
||||||
/* Default to TEX=000, S=1, C=1, B=1 for backward compatibility. */
|
/* Default to TEX=000, S=1, C=1, B=1 for backward compatibility. */
|
||||||
#define configTEX_S_C_B_SRAM ( 0x07UL )
|
#define configTEX_S_C_B_SRAM ( 0x07UL )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define portUNPRIVILEGED_FLASH_REGION ( 0UL )
|
#define portUNPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
#define portPRIVILEGED_FLASH_REGION ( 1UL )
|
#define portPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
#define portPRIVILEGED_RAM_REGION ( 2UL )
|
#define portPRIVILEGED_RAM_REGION ( 2UL )
|
||||||
#define portGENERAL_PERIPHERALS_REGION ( 3UL )
|
#define portGENERAL_PERIPHERALS_REGION ( 3UL )
|
||||||
#define portSTACK_REGION ( 4UL )
|
#define portSTACK_REGION ( 4UL )
|
||||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
#define portTOTAL_NUM_REGIONS ( configTOTAL_MPU_REGIONS )
|
#define portTOTAL_NUM_REGIONS ( configTOTAL_MPU_REGIONS )
|
||||||
#define portNUM_CONFIGURABLE_REGIONS ( portTOTAL_NUM_REGIONS - portFIRST_CONFIGURABLE_REGION )
|
#define portNUM_CONFIGURABLE_REGIONS ( portTOTAL_NUM_REGIONS - portFIRST_CONFIGURABLE_REGION )
|
||||||
#define portLAST_CONFIGURABLE_REGION ( portTOTAL_NUM_REGIONS - 1 )
|
#define portLAST_CONFIGURABLE_REGION ( portTOTAL_NUM_REGIONS - 1 )
|
||||||
|
|
||||||
#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " ::: "r0", "memory" )
|
#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " ::: "r0", "memory" )
|
||||||
|
|
||||||
typedef struct MPU_REGION_REGISTERS
|
typedef struct MPU_REGION_REGISTERS
|
||||||
{
|
{
|
||||||
uint32_t ulRegionBaseAddress;
|
uint32_t ulRegionBaseAddress;
|
||||||
uint32_t ulRegionAttribute;
|
uint32_t ulRegionAttribute;
|
||||||
} xMPU_REGION_REGISTERS;
|
} xMPU_REGION_REGISTERS;
|
||||||
|
|
||||||
/* Plus 1 to create space for the stack region. */
|
/* Plus 1 to create space for the stack region. */
|
||||||
typedef struct MPU_SETTINGS
|
typedef struct MPU_SETTINGS
|
||||||
{
|
{
|
||||||
xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS ];
|
xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS ];
|
||||||
} xMPU_SETTINGS;
|
} xMPU_SETTINGS;
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* SVC numbers for various services. */
|
/* SVC numbers for various services. */
|
||||||
#define portSVC_START_SCHEDULER 0
|
#define portSVC_START_SCHEDULER 0
|
||||||
#define portSVC_YIELD 1
|
#define portSVC_YIELD 1
|
||||||
#define portSVC_RAISE_PRIVILEGE 2
|
#define portSVC_RAISE_PRIVILEGE 2
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
|
|
||||||
#define portYIELD() __asm volatile ( " SVC %0 \n"::"i" ( portSVC_YIELD ) : "memory" )
|
#define portYIELD() __asm volatile ( " SVC %0 \n"::"i" ( portSVC_YIELD ) : "memory" )
|
||||||
#define portYIELD_WITHIN_API() \
|
#define portYIELD_WITHIN_API() \
|
||||||
{ \
|
{ \
|
||||||
/* Set a PendSV to request a context switch. */ \
|
/* Set a PendSV to request a context switch. */ \
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
@ -217,37 +221,37 @@
|
||||||
__asm volatile ( "isb" ); \
|
__asm volatile ( "isb" ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )
|
||||||
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
* not necessary for to use this port. They are defined so the common demo files
|
* not necessary for to use this port. They are defined so the common demo files
|
||||||
* (which build with all the ports) will build. */
|
* (which build with all the ports) will build. */
|
||||||
#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 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Generic helper function. */
|
/* Generic helper function. */
|
||||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
|
@ -272,49 +276,49 @@
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* portNOP() is not required by this port. */
|
/* portNOP() is not required by this port. */
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
|
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
|
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
extern BaseType_t xIsPrivileged( void );
|
extern BaseType_t xIsPrivileged( void );
|
||||||
extern void vResetPrivilege( void );
|
extern void vResetPrivilege( void );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raise an SVC request to raise privilege.
|
* @brief Raise an SVC request to raise privilege.
|
||||||
*/
|
*/
|
||||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||||
{
|
{
|
||||||
uint32_t ulCurrentInterrupt;
|
uint32_t ulCurrentInterrupt;
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
@ -331,12 +335,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||||
{
|
{
|
||||||
uint32_t ulNewBASEPRI;
|
uint32_t ulNewBASEPRI;
|
||||||
|
|
||||||
__asm volatile
|
__asm volatile
|
||||||
|
@ -347,12 +351,12 @@
|
||||||
" dsb \n"\
|
" dsb \n"\
|
||||||
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||||
{
|
{
|
||||||
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||||
|
|
||||||
__asm volatile
|
__asm volatile
|
||||||
|
@ -368,27 +372,30 @@
|
||||||
/* This return will not be reached but is necessary to prevent compiler
|
/* This return will not be reached but is necessary to prevent compiler
|
||||||
* warnings. */
|
* warnings. */
|
||||||
return ulOriginalBASEPRI;
|
return ulOriginalBASEPRI;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory"
|
" msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
|
||||||
#ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY
|
#ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY
|
||||||
#warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. https: /*www.freertos.org/FreeRTOS-V10.3.x.html" */
|
#warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. https: /*www.freertos.org/FreeRTOS-V10.3.x.html" */
|
||||||
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0
|
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
@ -149,17 +149,18 @@
|
||||||
|
|
||||||
|
|
||||||
/* Adding the necessary stuff in order to be able to determine from C code wheter or not the IRQs are enabled at the processor level (not interrupt controller level) */
|
/* Adding the necessary stuff in order to be able to determine from C code wheter or not the IRQs are enabled at the processor level (not interrupt controller level) */
|
||||||
#define GET_CPSR() ({u32 rval = 0U; \
|
#define GET_CPSR() \
|
||||||
__asm__ __volatile__(\
|
( { u32 rval = 0U; \
|
||||||
|
__asm__ __volatile__ ( \
|
||||||
"mrs %0, cpsr\n"\
|
"mrs %0, cpsr\n"\
|
||||||
: "=r" (rval)\
|
: "=r" ( rval ) \
|
||||||
);\
|
); \
|
||||||
rval;\
|
rval; \
|
||||||
})
|
} )
|
||||||
|
|
||||||
#define CPSR_IRQ_ENABLE_MASK 0x80U
|
#define CPSR_IRQ_ENABLE_MASK 0x80U
|
||||||
|
|
||||||
#define IS_IRQ_DISABLED() ({unsigned int val = 0; val = (GET_CPSR() & CPSR_IRQ_ENABLE_MASK) ? 1 : 0; val;})
|
#define IS_IRQ_DISABLED() ( { unsigned int val = 0; val = ( GET_CPSR() & CPSR_IRQ_ENABLE_MASK ) ? 1 : 0; val; } )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -515,8 +516,10 @@ uint32_t ulPortSetInterruptMask( void )
|
||||||
* against the CPU traping into recursive interrupt was the IRQ Enable bit in the CPSR. By not taking it into acount, the very code that protects the CPU against
|
* against the CPU traping into recursive interrupt was the IRQ Enable bit in the CPSR. By not taking it into acount, the very code that protects the CPU against
|
||||||
* critical section violation just enabled it to happen : A SysTick was waiting to happen, and calling 'portCPU_IRQ_ENABLE' would enable it to occur... Thus triggering a
|
* critical section violation just enabled it to happen : A SysTick was waiting to happen, and calling 'portCPU_IRQ_ENABLE' would enable it to occur... Thus triggering a
|
||||||
* switch of context while already performing a switch context. */
|
* switch of context while already performing a switch context. */
|
||||||
if(!wasIRQDisabled)
|
if( !wasIRQDisabled )
|
||||||
|
{
|
||||||
portCPU_IRQ_ENABLE();
|
portCPU_IRQ_ENABLE();
|
||||||
|
}
|
||||||
|
|
||||||
return ulReturn;
|
return ulReturn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if ( configMAX_PRIORITIES > 32 )
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
@ -48,14 +48,14 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* A critical section is exited when the critical section nesting count reaches
|
/* A critical section is exited when the critical section nesting count reaches
|
||||||
* this value. */
|
this value. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||||
|
|
||||||
/* Tasks are not created with a floating point context, but can be given a
|
/* Tasks are not created with a floating point context, but can be given a
|
||||||
* floating point context after they have been created. A variable is stored as
|
floating point context after they have been created. A variable is stored as
|
||||||
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||||
* does not have an FPU context, or any other value if the task does have an FPU
|
does not have an FPU context, or any other value if the task does have an FPU
|
||||||
* context. */
|
context. */
|
||||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to setup the initial task context. */
|
/* Constants required to setup the initial task context. */
|
||||||
|
@ -67,12 +67,12 @@
|
||||||
#define portAPSR_MODE_BITS_MASK ( 0x1F )
|
#define portAPSR_MODE_BITS_MASK ( 0x1F )
|
||||||
|
|
||||||
/* The value of the mode bits in the APSR when the CPU is executing in user
|
/* The value of the mode bits in the APSR when the CPU is executing in user
|
||||||
* mode. */
|
mode. */
|
||||||
#define portAPSR_USER_MODE ( 0x10 )
|
#define portAPSR_USER_MODE ( 0x10 )
|
||||||
|
|
||||||
/* Let the user override the pre-loading of the initial LR with the address of
|
/* Let the user override the pre-loading of the initial LR with the address of
|
||||||
* prvTaskExitError() in case it messes up unwinding of the stack in the
|
prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||||
* debugger. */
|
debugger. */
|
||||||
#ifdef configTASK_RETURN_ADDRESS
|
#ifdef configTASK_RETURN_ADDRESS
|
||||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||||
#else
|
#else
|
||||||
|
@ -95,41 +95,39 @@ static void prvTaskExitError( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* A variable is used to keep track of the critical section nesting. This
|
/* A variable is used to keep track of the critical section nesting. This
|
||||||
* variable has to be stored as part of the task context and must be initialised to
|
variable has to be stored as part of the task context and must be initialised to
|
||||||
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||||
* the scheduler starts. As it is stored as part of the task context it will
|
the scheduler starts. As it is stored as part of the task context it will
|
||||||
* automatically be set to 0 when the first task is started. */
|
automatically be set to 0 when the first task is started. */
|
||||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
|
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
|
||||||
* a floating point context must be saved and restored for the task. */
|
a floating point context must be saved and restored for the task. */
|
||||||
volatile uint32_t ulPortTaskHasFPUContext = pdFALSE;
|
volatile uint32_t ulPortTaskHasFPUContext = pdFALSE;
|
||||||
|
|
||||||
/* Set to 1 to pend a context switch from an ISR. */
|
/* Set to 1 to pend a context switch from an ISR. */
|
||||||
volatile uint32_t ulPortYieldRequired = pdFALSE;
|
volatile uint32_t ulPortYieldRequired = pdFALSE;
|
||||||
|
|
||||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||||
* if the nesting depth is 0. */
|
if the nesting depth is 0. */
|
||||||
volatile uint32_t ulPortInterruptNesting = 0UL;
|
volatile uint32_t ulPortInterruptNesting = 0UL;
|
||||||
|
|
||||||
/* Used in the asm file to clear an interrupt. */
|
/* Used in the asm file to clear an interrupt. */
|
||||||
__attribute__( ( used ) ) const uint32_t ulICCEOIR = configEOI_ADDRESS;
|
__attribute__(( used )) const uint32_t ulICCEOIR = configEOI_ADDRESS;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 )
|
|
||||||
{
|
{
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
* expected by the portRESTORE_CONTEXT() macro.
|
expected by the portRESTORE_CONTEXT() macro.
|
||||||
*
|
|
||||||
* The fist real value on the stack is the status register, which is set for
|
The fist real value on the stack is the status register, which is set for
|
||||||
* system mode, with interrupts enabled. A few NULLs are added first to ensure
|
system mode, with interrupts enabled. A few NULLs are added first to ensure
|
||||||
* GDB does not try decoding a non-existent return address. */
|
GDB does not try decoding a non-existent return address. */
|
||||||
*pxTopOfStack = ( StackType_t ) NULL;
|
*pxTopOfStack = ( StackType_t ) NULL;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) NULL;
|
*pxTopOfStack = ( StackType_t ) NULL;
|
||||||
|
@ -181,13 +179,13 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||||
* enabled. */
|
enabled. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start without a floating point context. A task that uses
|
/* The task will start without a floating point context. A task that uses
|
||||||
* the floating point hardware must call vPortTaskUsesFPU() before executing
|
the floating point hardware must call vPortTaskUsesFPU() before executing
|
||||||
* any floating point instructions. */
|
any floating point instructions. */
|
||||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -197,28 +195,24 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* A function that implements a task must not exit or attempt to return to
|
||||||
* its caller as there is nothing to return to. If a task wants to exit it
|
its caller as there is nothing to return to. If a task wants to exit it
|
||||||
* should instead call vTaskDelete( NULL ).
|
should instead call vTaskDelete( NULL ).
|
||||||
*
|
|
||||||
* Artificially force an assert() to be triggered if configASSERT() is
|
Artificially force an assert() to be triggered if configASSERT() is
|
||||||
* defined, then stop here so application writers can catch the error. */
|
defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( ulPortInterruptNesting == ~0UL );
|
configASSERT( ulPortInterruptNesting == ~0UL );
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
for( ;; );
|
||||||
for( ; ; )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulAPSR;
|
uint32_t ulAPSR;
|
||||||
|
|
||||||
/* Only continue if the CPU is not in User mode. The CPU must be in a
|
/* Only continue if the CPU is not in User mode. The CPU must be in a
|
||||||
* Privileged mode for the scheduler to start. */
|
Privileged mode for the scheduler to start. */
|
||||||
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" );
|
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) :: "memory" );
|
||||||
|
|
||||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||||
configASSERT( ulAPSR != portAPSR_USER_MODE );
|
configASSERT( ulAPSR != portAPSR_USER_MODE );
|
||||||
|
|
||||||
|
@ -233,10 +227,10 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
||||||
* a non-privileged mode or the binary point register was not set to its lowest
|
a non-privileged mode or the binary point register was not set to its lowest
|
||||||
* possible value. prvTaskExitError() is referenced to prevent a compiler
|
possible value. prvTaskExitError() is referenced to prevent a compiler
|
||||||
* warning about it being defined but not referenced in the case that the user
|
warning about it being defined but not referenced in the case that the user
|
||||||
* defines their own exit address. */
|
defines their own exit address. */
|
||||||
( void ) prvTaskExitError;
|
( void ) prvTaskExitError;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +239,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
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( ulCriticalNesting == 1000UL );
|
configASSERT( ulCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -255,15 +249,15 @@ void vPortEnterCritical( void )
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
* portENTER_CRITICAL() has been called. */
|
portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
* assert() if it is being called from an interrupt context. Only API
|
assert() if it is being called from an interrupt context. Only API
|
||||||
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
* the critical nesting count is 1 to protect against recursive calls if the
|
the critical nesting count is 1 to protect against recursive calls if the
|
||||||
* assert function also uses a critical section. */
|
assert function also uses a critical section. */
|
||||||
if( ulCriticalNesting == 1 )
|
if( ulCriticalNesting == 1 )
|
||||||
{
|
{
|
||||||
configASSERT( ulPortInterruptNesting == 0 );
|
configASSERT( ulPortInterruptNesting == 0 );
|
||||||
|
@ -276,15 +270,15 @@ void vPortExitCritical( void )
|
||||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Decrement the nesting count as the critical section is being
|
/* Decrement the nesting count as the critical section is being
|
||||||
* exited. */
|
exited. */
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then all interrupt
|
/* If the nesting level has reached zero then all interrupt
|
||||||
* priorities must be re-enabled. */
|
priorities must be re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Critical nesting has reached zero so all interrupt priorities
|
/* Critical nesting has reached zero so all interrupt priorities
|
||||||
* should be unmasked. */
|
should be unmasked. */
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,7 +287,7 @@ void vPortExitCritical( void )
|
||||||
|
|
||||||
void FreeRTOS_Tick_Handler( void )
|
void FreeRTOS_Tick_Handler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulInterruptStatus;
|
uint32_t ulInterruptStatus;
|
||||||
|
|
||||||
ulInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
|
||||||
|
@ -311,13 +305,15 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
|
|
||||||
void vPortTaskUsesFPU( void )
|
void vPortTaskUsesFPU( void )
|
||||||
{
|
{
|
||||||
uint32_t ulInitialFPSCR = 0;
|
uint32_t ulInitialFPSCR = 0;
|
||||||
|
|
||||||
/* A task is registering the fact that it needs an FPU context. Set the
|
/* A task is registering the fact that it needs an FPU context. Set the
|
||||||
* FPU flag (which is saved as part of the task context). */
|
FPU flag (which is saved as part of the task context). */
|
||||||
ulPortTaskHasFPUContext = pdTRUE;
|
ulPortTaskHasFPUContext = pdTRUE;
|
||||||
|
|
||||||
/* Initialise the floating point status register. */
|
/* Initialise the floating point status register. */
|
||||||
__asm volatile ( "FMXR FPSCR, %0" ::"r" ( ulInitialFPSCR ) : "memory" );
|
__asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) : "memory" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -43,141 +43,139 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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;
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
/* Called at the end of an ISR that can cause a context switch. */
|
/* Called at the end of an ISR that can cause a context switch. */
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
#define portEND_SWITCHING_ISR( xSwitchRequired )\
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint32_t ulPortYieldRequired; \
|
extern volatile uint32_t ulPortYieldRequired; \
|
||||||
\
|
\
|
||||||
if( xSwitchRequired != pdFALSE ) \
|
if( xSwitchRequired != pdFALSE ) \
|
||||||
{ \
|
{ \
|
||||||
ulPortYieldRequired = pdTRUE; \
|
ulPortYieldRequired = pdTRUE; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
#define portYIELD() \
|
#define portYIELD() __asm volatile ( "SWI 0 \n" \
|
||||||
__asm volatile ( "SWI 0 \n"\
|
"ISB " ::: "memory" );
|
||||||
"ISB "::: "memory" );
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Critical section control
|
* Critical section control
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
extern uint32_t ulPortSetInterruptMask( void );
|
extern uint32_t ulPortSetInterruptMask( void );
|
||||||
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||||
|
|
||||||
/* The I bit within the CPSR. */
|
/* The I bit within the CPSR. */
|
||||||
#define portINTERRUPT_ENABLE_BIT ( 1 << 7 )
|
#define portINTERRUPT_ENABLE_BIT ( 1 << 7 )
|
||||||
|
|
||||||
/* In the absence of a priority mask register, these functions and macros
|
/* In the absence of a priority mask register, these functions and macros
|
||||||
* globally enable and disable interrupts. */
|
globally enable and disable interrupts. */
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
#define portENABLE_INTERRUPTS() __asm volatile ( "CPSIE i \n"::: "memory" );
|
#define portENABLE_INTERRUPTS() __asm volatile ( "CPSIE i \n" ::: "memory" );
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() __asm volatile ( "CPSID i \n" \
|
||||||
__asm volatile ( "CPSID i \n" \
|
|
||||||
"DSB \n" \
|
"DSB \n" \
|
||||||
"ISB "::: "memory" );
|
"ISB " ::: "memory" );
|
||||||
|
|
||||||
__attribute__( ( always_inline ) ) static __inline uint32_t portINLINE_SET_INTERRUPT_MASK_FROM_ISR( void )
|
__attribute__( ( always_inline ) ) static __inline uint32_t portINLINE_SET_INTERRUPT_MASK_FROM_ISR( void )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulCPSR;
|
volatile uint32_t ulCPSR;
|
||||||
|
|
||||||
__asm volatile ( "MRS %0, CPSR" : "=r" ( ulCPSR )::"memory" );
|
|
||||||
|
|
||||||
|
__asm volatile ( "MRS %0, CPSR" : "=r" (ulCPSR) :: "memory" );
|
||||||
ulCPSR &= portINTERRUPT_ENABLE_BIT;
|
ulCPSR &= portINTERRUPT_ENABLE_BIT;
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
return ulCPSR;
|
return ulCPSR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() portINLINE_SET_INTERRUPT_MASK_FROM_ISR()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() portINLINE_SET_INTERRUPT_MASK_FROM_ISR()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) if( x == 0 ) portENABLE_INTERRUPTS()
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) if( x == 0 ) portENABLE_INTERRUPTS()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
* not required for this port but included in case common demo code that uses these
|
not required for this port but included in case common demo code that uses these
|
||||||
* macros is used. */
|
macros is used. */
|
||||||
#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 )
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
/* Tickless idle/low power functionality. */
|
||||||
#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
|
||||||
|
|
||||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||||
* handler for whichever peripheral is used to generate the RTOS tick. */
|
handler for whichever peripheral is used to generate the RTOS tick. */
|
||||||
void FreeRTOS_Tick_Handler( void );
|
void FreeRTOS_Tick_Handler( void );
|
||||||
|
|
||||||
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
||||||
* before any floating point instructions are executed. */
|
before any floating point instructions are executed. */
|
||||||
void vPortTaskUsesFPU( void );
|
void vPortTaskUsesFPU( void );
|
||||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||||
|
|
||||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
#define portNOP() __asm volatile ( "NOP" )
|
#define portNOP() __asm volatile( "NOP" )
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
|
|
||||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern C */
|
} /* extern C */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
|
||||||
* Changes from V2.6.0
|
Changes from V2.6.0
|
||||||
*
|
|
||||||
+ AVR port - Replaced the inb() and outb() functions with direct memory
|
+ AVR port - Replaced the inb() and outb() functions with direct memory
|
||||||
+ access. This allows the port to be built with the 20050414 build of
|
access. This allows the port to be built with the 20050414 build of
|
||||||
+ WinAVR.
|
WinAVR.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
@ -41,8 +41,8 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the AVR port.
|
* Implementation of functions defined in portable.h for the AVR port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Start tasks with interrupts enables. */
|
/* Start tasks with interrupts enables. */
|
||||||
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x80 )
|
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x80 )
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
||||||
* any details of its type. */
|
any details of its type. */
|
||||||
typedef void TCB_t;
|
typedef void TCB_t;
|
||||||
extern volatile TCB_t * volatile pxCurrentTCB;
|
extern volatile TCB_t * volatile pxCurrentTCB;
|
||||||
|
|
||||||
|
@ -79,48 +79,48 @@ extern volatile TCB_t * volatile pxCurrentTCB;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
asm volatile ( "push r0 \n\t"\
|
asm volatile ( "push r0 \n\t" \
|
||||||
"in r0, __SREG__ \n\t"\
|
"in r0, __SREG__ \n\t" \
|
||||||
"cli \n\t"\
|
"cli \n\t" \
|
||||||
"push r0 \n\t"\
|
"push r0 \n\t" \
|
||||||
"push r1 \n\t"\
|
"push r1 \n\t" \
|
||||||
"clr r1 \n\t"\
|
"clr r1 \n\t" \
|
||||||
"push r2 \n\t"\
|
"push r2 \n\t" \
|
||||||
"push r3 \n\t"\
|
"push r3 \n\t" \
|
||||||
"push r4 \n\t"\
|
"push r4 \n\t" \
|
||||||
"push r5 \n\t"\
|
"push r5 \n\t" \
|
||||||
"push r6 \n\t"\
|
"push r6 \n\t" \
|
||||||
"push r7 \n\t"\
|
"push r7 \n\t" \
|
||||||
"push r8 \n\t"\
|
"push r8 \n\t" \
|
||||||
"push r9 \n\t"\
|
"push r9 \n\t" \
|
||||||
"push r10 \n\t"\
|
"push r10 \n\t" \
|
||||||
"push r11 \n\t"\
|
"push r11 \n\t" \
|
||||||
"push r12 \n\t"\
|
"push r12 \n\t" \
|
||||||
"push r13 \n\t"\
|
"push r13 \n\t" \
|
||||||
"push r14 \n\t"\
|
"push r14 \n\t" \
|
||||||
"push r15 \n\t"\
|
"push r15 \n\t" \
|
||||||
"push r16 \n\t"\
|
"push r16 \n\t" \
|
||||||
"push r17 \n\t"\
|
"push r17 \n\t" \
|
||||||
"push r18 \n\t"\
|
"push r18 \n\t" \
|
||||||
"push r19 \n\t"\
|
"push r19 \n\t" \
|
||||||
"push r20 \n\t"\
|
"push r20 \n\t" \
|
||||||
"push r21 \n\t"\
|
"push r21 \n\t" \
|
||||||
"push r22 \n\t"\
|
"push r22 \n\t" \
|
||||||
"push r23 \n\t"\
|
"push r23 \n\t" \
|
||||||
"push r24 \n\t"\
|
"push r24 \n\t" \
|
||||||
"push r25 \n\t"\
|
"push r25 \n\t" \
|
||||||
"push r26 \n\t"\
|
"push r26 \n\t" \
|
||||||
"push r27 \n\t"\
|
"push r27 \n\t" \
|
||||||
"push r28 \n\t"\
|
"push r28 \n\t" \
|
||||||
"push r29 \n\t"\
|
"push r29 \n\t" \
|
||||||
"push r30 \n\t"\
|
"push r30 \n\t" \
|
||||||
"push r31 \n\t"\
|
"push r31 \n\t" \
|
||||||
"lds r26, pxCurrentTCB \n\t"\
|
"lds r26, pxCurrentTCB \n\t" \
|
||||||
"lds r27, pxCurrentTCB + 1 \n\t"\
|
"lds r27, pxCurrentTCB + 1 \n\t" \
|
||||||
"in r0, 0x3d \n\t"\
|
"in r0, 0x3d \n\t" \
|
||||||
"st x+, r0 \n\t"\
|
"st x+, r0 \n\t" \
|
||||||
"in r0, 0x3e \n\t"\
|
"in r0, 0x3e \n\t" \
|
||||||
"st x+, r0 \n\t"\
|
"st x+, r0 \n\t" \
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -129,46 +129,46 @@ extern volatile TCB_t * volatile pxCurrentTCB;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
asm volatile ( "lds r26, pxCurrentTCB \n\t"\
|
asm volatile ( "lds r26, pxCurrentTCB \n\t" \
|
||||||
"lds r27, pxCurrentTCB + 1 \n\t"\
|
"lds r27, pxCurrentTCB + 1 \n\t" \
|
||||||
"ld r28, x+ \n\t"\
|
"ld r28, x+ \n\t" \
|
||||||
"out __SP_L__, r28 \n\t"\
|
"out __SP_L__, r28 \n\t" \
|
||||||
"ld r29, x+ \n\t"\
|
"ld r29, x+ \n\t" \
|
||||||
"out __SP_H__, r29 \n\t"\
|
"out __SP_H__, r29 \n\t" \
|
||||||
"pop r31 \n\t"\
|
"pop r31 \n\t" \
|
||||||
"pop r30 \n\t"\
|
"pop r30 \n\t" \
|
||||||
"pop r29 \n\t"\
|
"pop r29 \n\t" \
|
||||||
"pop r28 \n\t"\
|
"pop r28 \n\t" \
|
||||||
"pop r27 \n\t"\
|
"pop r27 \n\t" \
|
||||||
"pop r26 \n\t"\
|
"pop r26 \n\t" \
|
||||||
"pop r25 \n\t"\
|
"pop r25 \n\t" \
|
||||||
"pop r24 \n\t"\
|
"pop r24 \n\t" \
|
||||||
"pop r23 \n\t"\
|
"pop r23 \n\t" \
|
||||||
"pop r22 \n\t"\
|
"pop r22 \n\t" \
|
||||||
"pop r21 \n\t"\
|
"pop r21 \n\t" \
|
||||||
"pop r20 \n\t"\
|
"pop r20 \n\t" \
|
||||||
"pop r19 \n\t"\
|
"pop r19 \n\t" \
|
||||||
"pop r18 \n\t"\
|
"pop r18 \n\t" \
|
||||||
"pop r17 \n\t"\
|
"pop r17 \n\t" \
|
||||||
"pop r16 \n\t"\
|
"pop r16 \n\t" \
|
||||||
"pop r15 \n\t"\
|
"pop r15 \n\t" \
|
||||||
"pop r14 \n\t"\
|
"pop r14 \n\t" \
|
||||||
"pop r13 \n\t"\
|
"pop r13 \n\t" \
|
||||||
"pop r12 \n\t"\
|
"pop r12 \n\t" \
|
||||||
"pop r11 \n\t"\
|
"pop r11 \n\t" \
|
||||||
"pop r10 \n\t"\
|
"pop r10 \n\t" \
|
||||||
"pop r9 \n\t"\
|
"pop r9 \n\t" \
|
||||||
"pop r8 \n\t"\
|
"pop r8 \n\t" \
|
||||||
"pop r7 \n\t"\
|
"pop r7 \n\t" \
|
||||||
"pop r6 \n\t"\
|
"pop r6 \n\t" \
|
||||||
"pop r5 \n\t"\
|
"pop r5 \n\t" \
|
||||||
"pop r4 \n\t"\
|
"pop r4 \n\t" \
|
||||||
"pop r3 \n\t"\
|
"pop r3 \n\t" \
|
||||||
"pop r2 \n\t"\
|
"pop r2 \n\t" \
|
||||||
"pop r1 \n\t"\
|
"pop r1 \n\t" \
|
||||||
"pop r0 \n\t"\
|
"pop r0 \n\t" \
|
||||||
"out __SREG__, r0 \n\t"\
|
"out __SREG__, r0 \n\t" \
|
||||||
"pop r0 \n\t"\
|
"pop r0 \n\t" \
|
||||||
);
|
);
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -182,14 +182,12 @@ static void prvSetupTimerInterrupt( 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 )
|
|
||||||
{
|
{
|
||||||
uint16_t usAddress;
|
uint16_t usAddress;
|
||||||
|
|
||||||
/* Place a few bytes of known values on the bottom of the stack.
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
* This is just useful for debugging. */
|
This is just useful for debugging. */
|
||||||
|
|
||||||
*pxTopOfStack = 0x11;
|
*pxTopOfStack = 0x11;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -199,12 +197,12 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Simulate how the stack would look after a call to vPortYield() generated by
|
/* Simulate how the stack would look after a call to vPortYield() generated by
|
||||||
* the compiler. */
|
the compiler. */
|
||||||
|
|
||||||
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||||
|
|
||||||
/* The start of the task code will be popped off the stack last, so place
|
/* The start of the task code will be popped off the stack last, so place
|
||||||
* it on first. */
|
it on first. */
|
||||||
usAddress = ( uint16_t ) pxCode;
|
usAddress = ( uint16_t ) pxCode;
|
||||||
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -214,9 +212,9 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Next simulate the stack as if after a call to portSAVE_CONTEXT().
|
/* Next simulate the stack as if after a call to portSAVE_CONTEXT().
|
||||||
* portSAVE_CONTEXT places the flags on the stack immediately after r0
|
portSAVE_CONTEXT places the flags on the stack immediately after r0
|
||||||
* to ensure the interrupts get disabled as soon as possible, and so ensuring
|
to ensure the interrupts get disabled as soon as possible, and so ensuring
|
||||||
* the stack use is minimal should a context switch interrupt occur. */
|
the stack use is minimal should a context switch interrupt occur. */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00; /* R0 */
|
*pxTopOfStack = ( StackType_t ) 0x00; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portFLAGS_INT_ENABLED;
|
*pxTopOfStack = portFLAGS_INT_ENABLED;
|
||||||
|
@ -308,7 +306,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
/* Simulate a function call end as generated by the compiler. We will now
|
/* Simulate a function call end as generated by the compiler. We will now
|
||||||
* jump to the start of the task the context of which we have just restored. */
|
jump to the start of the task the context of which we have just restored. */
|
||||||
asm volatile ( "ret" );
|
asm volatile ( "ret" );
|
||||||
|
|
||||||
/* Should not get here. */
|
/* Should not get here. */
|
||||||
|
@ -319,7 +317,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the AVR port will get stopped. If required simply
|
/* It is unlikely that the AVR port will get stopped. If required simply
|
||||||
* disable the tick interrupt here. */
|
disable the tick interrupt here. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -327,7 +325,7 @@ void vPortEndScheduler( void )
|
||||||
* Manual context switch. The first thing we do is save the registers so we
|
* Manual context switch. The first thing we do is save the registers so we
|
||||||
* can use a naked attribute.
|
* can use a naked attribute.
|
||||||
*/
|
*/
|
||||||
void vPortYield( void ) __attribute__( ( naked ) );
|
void vPortYield( void ) __attribute__ ( ( naked ) );
|
||||||
void vPortYield( void )
|
void vPortYield( void )
|
||||||
{
|
{
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
@ -344,16 +342,14 @@ void vPortYield( void )
|
||||||
* difference from vPortYield() is the tick count is incremented as the
|
* difference from vPortYield() is the tick count is incremented as the
|
||||||
* call comes from the tick ISR.
|
* call comes from the tick ISR.
|
||||||
*/
|
*/
|
||||||
void vPortYieldFromTick( void ) __attribute__( ( naked ) );
|
void vPortYieldFromTick( void ) __attribute__ ( ( naked ) );
|
||||||
void vPortYieldFromTick( void )
|
void vPortYieldFromTick( void )
|
||||||
{
|
{
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
{
|
{
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
asm volatile ( "ret" );
|
asm volatile ( "ret" );
|
||||||
|
@ -365,11 +361,11 @@ void vPortYieldFromTick( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
uint32_t ulCompareMatch;
|
uint32_t ulCompareMatch;
|
||||||
uint8_t ucHighByte, ucLowByte;
|
uint8_t ucHighByte, ucLowByte;
|
||||||
|
|
||||||
/* Using 16bit timer 1 to generate the tick. Correct fuses must be
|
/* Using 16bit timer 1 to generate the tick. Correct fuses must be
|
||||||
* selected for the configCPU_CLOCK_HZ clock. */
|
selected for the configCPU_CLOCK_HZ clock. */
|
||||||
|
|
||||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
|
@ -380,7 +376,7 @@ static void prvSetupTimerInterrupt( void )
|
||||||
ulCompareMatch -= ( uint32_t ) 1;
|
ulCompareMatch -= ( uint32_t ) 1;
|
||||||
|
|
||||||
/* Setup compare match value for compare match A. Interrupts are disabled
|
/* Setup compare match value for compare match A. Interrupts are disabled
|
||||||
* before this is called so we need not worry here. */
|
before this is called so we need not worry here. */
|
||||||
ucLowByte = ( uint8_t ) ( ulCompareMatch & ( uint32_t ) 0xff );
|
ucLowByte = ( uint8_t ) ( ulCompareMatch & ( uint32_t ) 0xff );
|
||||||
ulCompareMatch >>= 8;
|
ulCompareMatch >>= 8;
|
||||||
ucHighByte = ( uint8_t ) ( ulCompareMatch & ( uint32_t ) 0xff );
|
ucHighByte = ( uint8_t ) ( ulCompareMatch & ( uint32_t ) 0xff );
|
||||||
|
@ -392,7 +388,7 @@ static void prvSetupTimerInterrupt( void )
|
||||||
TCCR1B = ucLowByte;
|
TCCR1B = ucLowByte;
|
||||||
|
|
||||||
/* Enable the interrupt - this is okay as interrupt are currently globally
|
/* Enable the interrupt - this is okay as interrupt are currently globally
|
||||||
* disabled. */
|
disabled. */
|
||||||
ucLowByte = TIMSK;
|
ucLowByte = TIMSK;
|
||||||
ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE;
|
ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE;
|
||||||
TIMSK = ucLowByte;
|
TIMSK = ucLowByte;
|
||||||
|
@ -401,12 +397,12 @@ static void prvSetupTimerInterrupt( void )
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 1
|
#if configUSE_PREEMPTION == 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tick ISR for preemptive scheduler. We can use a naked attribute as
|
* Tick ISR for preemptive scheduler. We can use a naked attribute as
|
||||||
* the context is saved at the start of vPortYieldFromTick(). The tick
|
* the context is saved at the start of vPortYieldFromTick(). The tick
|
||||||
* count is incremented after the context is saved.
|
* count is incremented after the context is saved.
|
||||||
*/
|
*/
|
||||||
void SIG_OUTPUT_COMPARE1A( void ) __attribute__( ( signal, naked ) );
|
void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal, naked ) );
|
||||||
void SIG_OUTPUT_COMPARE1A( void )
|
void SIG_OUTPUT_COMPARE1A( void )
|
||||||
{
|
{
|
||||||
vPortYieldFromTick();
|
vPortYieldFromTick();
|
||||||
|
@ -414,14 +410,17 @@ static void prvSetupTimerInterrupt( void )
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tick ISR for the cooperative scheduler. All this does is increment the
|
* Tick ISR for the cooperative scheduler. All this does is increment the
|
||||||
* tick count. We don't need to switch context, this can only be done by
|
* tick count. We don't need to switch context, this can only be done by
|
||||||
* manual calls to taskYIELD();
|
* manual calls to taskYIELD();
|
||||||
*/
|
*/
|
||||||
void SIG_OUTPUT_COMPARE1A( void ) __attribute__( ( signal ) );
|
void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal ) );
|
||||||
void SIG_OUTPUT_COMPARE1A( void )
|
void SIG_OUTPUT_COMPARE1A( void )
|
||||||
{
|
{
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
}
|
}
|
||||||
#endif /* if configUSE_PREEMPTION == 1 */
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,18 +26,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes from V1.2.3
|
Changes from V1.2.3
|
||||||
*
|
|
||||||
+ portCPU_CLOSK_HZ definition changed to 8MHz base 10, previously it
|
+ portCPU_CLOSK_HZ definition changed to 8MHz base 10, previously it
|
||||||
+ base 16.
|
base 16.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -50,59 +50,58 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 int
|
#define portSHORT int
|
||||||
#define portSTACK_TYPE uint8_t
|
#define portSTACK_TYPE uint8_t
|
||||||
#define portBASE_TYPE char
|
#define portBASE_TYPE char
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef signed char BaseType_t;
|
typedef signed char BaseType_t;
|
||||||
typedef unsigned char UBaseType_t;
|
typedef unsigned char UBaseType_t;
|
||||||
|
|
||||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() asm volatile ( "in __tmp_reg__, __SREG__" :: ); \
|
||||||
asm volatile ( "in __tmp_reg__, __SREG__"::); \
|
asm volatile ( "cli" :: ); \
|
||||||
asm volatile ( "cli" ::); \
|
asm volatile ( "push __tmp_reg__" :: )
|
||||||
asm volatile ( "push __tmp_reg__"::)
|
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() asm volatile ( "pop __tmp_reg__" :: ); \
|
||||||
asm volatile ( "pop __tmp_reg__"::); \
|
asm volatile ( "out __SREG__, __tmp_reg__" :: )
|
||||||
asm volatile ( "out __SREG__, __tmp_reg__"::)
|
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() asm volatile ( "cli" ::);
|
#define portDISABLE_INTERRUPTS() asm volatile ( "cli" :: );
|
||||||
#define portENABLE_INTERRUPTS() asm volatile ( "sei" ::);
|
#define portENABLE_INTERRUPTS() asm volatile ( "sei" :: );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 1
|
#define portBYTE_ALIGNMENT 1
|
||||||
#define portNOP() asm volatile ( "nop" );
|
#define portNOP() asm volatile ( "nop" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Kernel utilities. */
|
/* Kernel utilities. */
|
||||||
extern void vPortYield( void ) __attribute__( ( naked ) );
|
extern void vPortYield( void ) __attribute__ ( ( naked ) );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
/*This file has been prepared for Doxygen automatic documentation generation.*/
|
/*This file has been prepared for Doxygen automatic documentation generation.*/
|
||||||
|
|
||||||
/*! \file *********************************************************************
|
/*! \file *********************************************************************
|
||||||
*
|
*
|
||||||
* \brief FreeRTOS port source for AVR32 UC3.
|
* \brief FreeRTOS port source for AVR32 UC3.
|
||||||
|
@ -53,7 +52,7 @@
|
||||||
/* AVR32 UC3 includes. */
|
/* AVR32 UC3 includes. */
|
||||||
#include <avr32/io.h>
|
#include <avr32/io.h>
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#if ( configTICK_USE_TC == 1 )
|
#if( configTICK_USE_TC==1 )
|
||||||
#include "tc.h"
|
#include "tc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -66,7 +65,7 @@
|
||||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
#if ( configTICK_USE_TC == 0 )
|
#if( configTICK_USE_TC==0 )
|
||||||
static void prvScheduleNextTick( void );
|
static void prvScheduleNextTick( void );
|
||||||
#else
|
#else
|
||||||
static void prvClearTcInt( void );
|
static void prvClearTcInt( void );
|
||||||
|
@ -85,7 +84,7 @@ static void prvSetupTimerInterrupt( void );
|
||||||
* vectors are not compatible with the SCALL management in the current FreeRTOS
|
* vectors are not compatible with the SCALL management in the current FreeRTOS
|
||||||
* port. More low-level initializations are besides added here.
|
* port. More low-level initializations are besides added here.
|
||||||
*/
|
*/
|
||||||
void _init_startup( void )
|
void _init_startup(void)
|
||||||
{
|
{
|
||||||
/* Import the Exception Vector Base Address. */
|
/* Import the Exception Vector Base Address. */
|
||||||
extern void _evba;
|
extern void _evba;
|
||||||
|
@ -93,7 +92,7 @@ void _init_startup( void )
|
||||||
#if configHEAP_INIT
|
#if configHEAP_INIT
|
||||||
extern void __heap_start__;
|
extern void __heap_start__;
|
||||||
extern void __heap_end__;
|
extern void __heap_end__;
|
||||||
BaseType_t * pxMem;
|
BaseType_t *pxMem;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Load the Exception Vector Base Address in the corresponding system register. */
|
/* Load the Exception Vector Base Address in the corresponding system register. */
|
||||||
|
@ -106,11 +105,13 @@ void _init_startup( void )
|
||||||
INTC_init_interrupts();
|
INTC_init_interrupts();
|
||||||
|
|
||||||
#if configHEAP_INIT
|
#if configHEAP_INIT
|
||||||
|
|
||||||
/* Initialize the heap used by malloc. */
|
/* Initialize the heap used by malloc. */
|
||||||
for( pxMem = &__heap_start__; pxMem < ( BaseType_t * ) &__heap_end__; )
|
for( pxMem = &__heap_start__; pxMem < ( BaseType_t * )&__heap_end__; )
|
||||||
{
|
{
|
||||||
*pxMem++ = 0xA5A5A5A5;
|
*pxMem++ = 0xA5A5A5A5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Give the used CPU clock frequency to Newlib, so it can work properly. */
|
/* Give the used CPU clock frequency to Newlib, so it can work properly. */
|
||||||
|
@ -128,10 +129,10 @@ void _init_startup( void )
|
||||||
/* Initialize the USART used for the debug trace with the configured parameters. */
|
/* Initialize the USART used for the debug trace with the configured parameters. */
|
||||||
set_usart_base( ( void * ) configDBG_USART );
|
set_usart_base( ( void * ) configDBG_USART );
|
||||||
gpio_enable_module( DBG_USART_GPIO_MAP,
|
gpio_enable_module( DBG_USART_GPIO_MAP,
|
||||||
sizeof( DBG_USART_GPIO_MAP ) / sizeof( DBG_USART_GPIO_MAP[ 0 ] ) );
|
sizeof( DBG_USART_GPIO_MAP ) / sizeof( DBG_USART_GPIO_MAP[0] ) );
|
||||||
usart_init( configDBG_USART_BAUDRATE );
|
usart_init( configDBG_USART_BAUDRATE );
|
||||||
}
|
}
|
||||||
#endif /* if configDBG */
|
#endif
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -154,7 +155,7 @@ void _init_startup( void )
|
||||||
* safe section as memory allocation management uses global data.
|
* safe section as memory allocation management uses global data.
|
||||||
* See the aforementioned details.
|
* See the aforementioned details.
|
||||||
*/
|
*/
|
||||||
void __malloc_lock( struct _reent * ptr )
|
void __malloc_lock(struct _reent *ptr)
|
||||||
{
|
{
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
}
|
}
|
||||||
|
@ -164,17 +165,16 @@ void __malloc_lock( struct _reent * ptr )
|
||||||
* a safe section as memory allocation management uses global data.
|
* a safe section as memory allocation management uses global data.
|
||||||
* See the aforementioned details.
|
* See the aforementioned details.
|
||||||
*/
|
*/
|
||||||
void __malloc_unlock( struct _reent * ptr )
|
void __malloc_unlock(struct _reent *ptr)
|
||||||
{
|
{
|
||||||
xTaskResumeAll();
|
xTaskResumeAll();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Added as there is no such function in FreeRTOS. */
|
/* Added as there is no such function in FreeRTOS. */
|
||||||
void * pvPortRealloc( void * pv,
|
void *pvPortRealloc( void *pv, size_t xWantedSize )
|
||||||
size_t xWantedSize )
|
|
||||||
{
|
{
|
||||||
void * pvReturn;
|
void *pvReturn;
|
||||||
|
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
{
|
{
|
||||||
|
@ -187,27 +187,25 @@ void * pvPortRealloc( void * pv,
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
* simply increment the system tick. */
|
simply increment the system tick. */
|
||||||
|
|
||||||
/* The preemptive scheduler is defined as "naked" as the full context is saved
|
/* The preemptive scheduler is defined as "naked" as the full context is saved
|
||||||
* on entry as part of the context switch. */
|
on entry as part of the context switch. */
|
||||||
__attribute__( ( __naked__ ) ) static void vTick( void )
|
__attribute__((__naked__)) static void vTick( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT_OS_INT();
|
portSAVE_CONTEXT_OS_INT();
|
||||||
|
|
||||||
#if ( configTICK_USE_TC == 1 )
|
#if( configTICK_USE_TC==1 )
|
||||||
/* Clear the interrupt flag. */
|
/* Clear the interrupt flag. */
|
||||||
prvClearTcInt();
|
prvClearTcInt();
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
|
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
|
||||||
* clock cycles from now. */
|
clock cycles from now. */
|
||||||
prvScheduleNextTick();
|
prvScheduleNextTick();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
|
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
|
||||||
* calls in a critical section . */
|
calls in a critical section . */
|
||||||
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
portEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
||||||
|
@ -217,7 +215,7 @@ __attribute__( ( __naked__ ) ) static void vTick( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__attribute__( ( __naked__ ) ) void SCALLYield( void )
|
__attribute__((__naked__)) void SCALLYield( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT_SCALL();
|
portSAVE_CONTEXT_SCALL();
|
||||||
|
@ -227,27 +225,26 @@ __attribute__( ( __naked__ ) ) void SCALLYield( void )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
* different optimisation levels. The interrupt flags can therefore not always
|
different optimisation levels. The interrupt flags can therefore not always
|
||||||
* be saved to the stack. Instead the critical section nesting level is stored
|
be saved to the stack. Instead the critical section nesting level is stored
|
||||||
* in a variable, which is then saved as part of the stack context. */
|
in a variable, which is then saved as part of the stack context. */
|
||||||
__attribute__( ( __noinline__ ) ) void vPortEnterCritical( void )
|
__attribute__((__noinline__)) void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts */
|
/* Disable interrupts */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
* portENTER_CRITICAL() has been called. */
|
portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__attribute__( ( __noinline__ ) ) void vPortExitCritical( void )
|
__attribute__((__noinline__)) void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
if(ulCriticalNesting > portNO_CRITICAL_NESTING)
|
||||||
{
|
{
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable all interrupt/exception. */
|
/* Enable all interrupt/exception. */
|
||||||
|
@ -263,12 +260,10 @@ __attribute__( ( __noinline__ ) ) void vPortExitCritical( 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 )
|
|
||||||
{
|
{
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
* expected by the portRESTORE_CONTEXT() macro. */
|
expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* When the task starts, it will expect to find the function parameter in R12. */
|
/* When the task starts, it will expect to find the function parameter in R12. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -297,7 +292,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
* here already. */
|
here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
@ -311,68 +306,63 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the AVR32 port will require this function as there
|
/* It is unlikely that the AVR32 port will require this function as there
|
||||||
* is nothing to return to. */
|
is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
|
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
|
||||||
* clock cycles from now. */
|
clock cycles from now. */
|
||||||
#if ( configTICK_USE_TC == 0 )
|
#if( configTICK_USE_TC==0 )
|
||||||
static void prvScheduleFirstTick( void )
|
static void prvScheduleFirstTick(void)
|
||||||
{
|
{
|
||||||
uint32_t lCycles;
|
uint32_t lCycles;
|
||||||
|
|
||||||
lCycles = Get_system_register( AVR32_COUNT );
|
lCycles = Get_system_register(AVR32_COUNT);
|
||||||
lCycles += ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );
|
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
||||||
|
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
|
||||||
/* If lCycles ends up to be 0, make it 1 so that the COMPARE and exception */
|
// generation feature does not get disabled.
|
||||||
/* generation feature does not get disabled. */
|
if(0 == lCycles)
|
||||||
if( 0 == lCycles )
|
|
||||||
{
|
{
|
||||||
lCycles++;
|
lCycles++;
|
||||||
}
|
}
|
||||||
|
Set_system_register(AVR32_COMPARE, lCycles);
|
||||||
Set_system_register( AVR32_COMPARE, lCycles );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__( ( __noinline__ ) ) static void prvScheduleNextTick( void )
|
__attribute__((__noinline__)) static void prvScheduleNextTick(void)
|
||||||
{
|
{
|
||||||
uint32_t lCycles, lCount;
|
uint32_t lCycles, lCount;
|
||||||
|
|
||||||
lCycles = Get_system_register( AVR32_COMPARE );
|
lCycles = Get_system_register(AVR32_COMPARE);
|
||||||
lCycles += ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );
|
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
||||||
|
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
|
||||||
/* If lCycles ends up to be 0, make it 1 so that the COMPARE and exception */
|
// generation feature does not get disabled.
|
||||||
/* generation feature does not get disabled. */
|
if(0 == lCycles)
|
||||||
if( 0 == lCycles )
|
|
||||||
{
|
{
|
||||||
lCycles++;
|
lCycles++;
|
||||||
}
|
}
|
||||||
|
lCount = Get_system_register(AVR32_COUNT);
|
||||||
lCount = Get_system_register( AVR32_COUNT );
|
|
||||||
|
|
||||||
if( lCycles < lCount )
|
if( lCycles < lCount )
|
||||||
{ /* We missed a tick, recover for the next. */
|
{ // We missed a tick, recover for the next.
|
||||||
lCycles += ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );
|
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
||||||
}
|
}
|
||||||
|
Set_system_register(AVR32_COMPARE, lCycles);
|
||||||
Set_system_register( AVR32_COMPARE, lCycles );
|
|
||||||
}
|
}
|
||||||
#else /* if ( configTICK_USE_TC == 0 ) */
|
#else
|
||||||
__attribute__( ( __noinline__ ) ) static void prvClearTcInt( void )
|
__attribute__((__noinline__)) static void prvClearTcInt(void)
|
||||||
{
|
{
|
||||||
AVR32_TC.channel[ configTICK_TC_CHANNEL ].sr;
|
AVR32_TC.channel[configTICK_TC_CHANNEL].sr;
|
||||||
}
|
}
|
||||||
#endif /* if ( configTICK_USE_TC == 0 ) */
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Setup the timer to generate the tick interrupts. */
|
/* Setup the timer to generate the tick interrupts. */
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt(void)
|
||||||
{
|
{
|
||||||
#if ( configTICK_USE_TC == 1 )
|
#if( configTICK_USE_TC==1 )
|
||||||
volatile avr32_tc_t * tc = &AVR32_TC;
|
|
||||||
|
|
||||||
/* Options for waveform genration. */
|
volatile avr32_tc_t *tc = &AVR32_TC;
|
||||||
|
|
||||||
|
// Options for waveform genration.
|
||||||
tc_waveform_opt_t waveform_opt =
|
tc_waveform_opt_t waveform_opt =
|
||||||
{
|
{
|
||||||
.channel = configTICK_TC_CHANNEL, /* Channel selection. */
|
.channel = configTICK_TC_CHANNEL, /* Channel selection. */
|
||||||
|
@ -387,7 +377,7 @@ static void prvSetupTimerInterrupt( void )
|
||||||
.acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */
|
.acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */
|
||||||
.acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */
|
.acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */
|
||||||
|
|
||||||
.wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER, /* Waveform selection: Up mode without automatic trigger on RC compare. */
|
.wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,/* Waveform selection: Up mode without automatic trigger on RC compare. */
|
||||||
.enetrg = FALSE, /* External event trigger enable. */
|
.enetrg = FALSE, /* External event trigger enable. */
|
||||||
.eevt = 0, /* External event selection. */
|
.eevt = 0, /* External event selection. */
|
||||||
.eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */
|
.eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */
|
||||||
|
@ -401,44 +391,45 @@ static void prvSetupTimerInterrupt( void )
|
||||||
|
|
||||||
tc_interrupt_t tc_interrupt =
|
tc_interrupt_t tc_interrupt =
|
||||||
{
|
{
|
||||||
.etrgs = 0,
|
.etrgs=0,
|
||||||
.ldrbs = 0,
|
.ldrbs=0,
|
||||||
.ldras = 0,
|
.ldras=0,
|
||||||
.cpcs = 1,
|
.cpcs =1,
|
||||||
.cpbs = 0,
|
.cpbs =0,
|
||||||
.cpas = 0,
|
.cpas =0,
|
||||||
.lovrs = 0,
|
.lovrs=0,
|
||||||
.covfs = 0,
|
.covfs=0,
|
||||||
};
|
};
|
||||||
#endif /* if ( configTICK_USE_TC == 1 ) */
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Disable all interrupt/exception. */
|
/* Disable all interrupt/exception. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
/* Register the compare interrupt handler to the interrupt controller and
|
/* Register the compare interrupt handler to the interrupt controller and
|
||||||
* enable the compare interrupt. */
|
enable the compare interrupt. */
|
||||||
|
|
||||||
#if ( configTICK_USE_TC == 1 )
|
#if( configTICK_USE_TC==1 )
|
||||||
{
|
{
|
||||||
INTC_register_interrupt( &vTick, configTICK_TC_IRQ, INT0 );
|
INTC_register_interrupt(&vTick, configTICK_TC_IRQ, INT0);
|
||||||
|
|
||||||
/* Initialize the timer/counter. */
|
/* Initialize the timer/counter. */
|
||||||
tc_init_waveform( tc, &waveform_opt );
|
tc_init_waveform(tc, &waveform_opt);
|
||||||
|
|
||||||
/* Set the compare triggers.
|
/* Set the compare triggers.
|
||||||
* Remember TC counter is 16-bits, so counting second is not possible!
|
Remember TC counter is 16-bits, so counting second is not possible!
|
||||||
* That's why we configure it to count ms. */
|
That's why we configure it to count ms. */
|
||||||
tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ / 4 ) / configTICK_RATE_HZ );
|
tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ / 4) / configTICK_RATE_HZ );
|
||||||
|
|
||||||
tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt );
|
tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt );
|
||||||
|
|
||||||
/* Start the timer/counter. */
|
/* Start the timer/counter. */
|
||||||
tc_start( tc, configTICK_TC_CHANNEL );
|
tc_start(tc, configTICK_TC_CHANNEL);
|
||||||
}
|
}
|
||||||
#else /* if ( configTICK_USE_TC == 1 ) */
|
#else
|
||||||
{
|
{
|
||||||
INTC_register_interrupt( &vTick, AVR32_CORE_COMPARE_IRQ, INT0 );
|
INTC_register_interrupt(&vTick, AVR32_CORE_COMPARE_IRQ, INT0);
|
||||||
prvScheduleFirstTick();
|
prvScheduleFirstTick();
|
||||||
}
|
}
|
||||||
#endif /* if ( configTICK_USE_TC == 1 ) */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
/*This file has been prepared for Doxygen automatic documentation generation.*/
|
/*This file has been prepared for Doxygen automatic documentation generation.*/
|
||||||
|
|
||||||
/*! \file *********************************************************************
|
/*! \file *********************************************************************
|
||||||
*
|
*
|
||||||
* \brief FreeRTOS port source for AVR32 UC3.
|
* \brief FreeRTOS port source for AVR32 UC3.
|
||||||
|
@ -42,7 +41,7 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -53,62 +52,62 @@
|
||||||
* These settings should not be altered.
|
* These settings should not be altered.
|
||||||
*-----------------------------------------------------------
|
*-----------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include <avr32/io.h>
|
#include <avr32/io.h>
|
||||||
#include "intc.h"
|
#include "intc.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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;
|
||||||
|
|
||||||
#define TASK_DELAY_MS( x ) ( ( x ) / portTICK_PERIOD_MS )
|
#define TASK_DELAY_MS(x) ( (x) /portTICK_PERIOD_MS )
|
||||||
#define TASK_DELAY_S( x ) ( ( x ) * 1000 / portTICK_PERIOD_MS )
|
#define TASK_DELAY_S(x) ( (x)*1000 /portTICK_PERIOD_MS )
|
||||||
#define TASK_DELAY_MIN( x ) ( ( x ) * 60 * 1000 / portTICK_PERIOD_MS )
|
#define TASK_DELAY_MIN(x) ( (x)*60*1000/portTICK_PERIOD_MS )
|
||||||
|
|
||||||
#define configTICK_TC_IRQ ATPASTE2( AVR32_TC_IRQ, configTICK_TC_CHANNEL )
|
#define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL)
|
||||||
|
|
||||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#define portNOP() { __asm__ __volatile__ ( "nop" ); }
|
#define portNOP() {__asm__ __volatile__ ("nop");}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* INTC-specific. */
|
/* INTC-specific. */
|
||||||
#define DISABLE_ALL_EXCEPTIONS() Disable_global_exception()
|
#define DISABLE_ALL_EXCEPTIONS() Disable_global_exception()
|
||||||
#define ENABLE_ALL_EXCEPTIONS() Enable_global_exception()
|
#define ENABLE_ALL_EXCEPTIONS() Enable_global_exception()
|
||||||
|
|
||||||
#define DISABLE_ALL_INTERRUPTS() Disable_global_interrupt()
|
#define DISABLE_ALL_INTERRUPTS() Disable_global_interrupt()
|
||||||
#define ENABLE_ALL_INTERRUPTS() Enable_global_interrupt()
|
#define ENABLE_ALL_INTERRUPTS() Enable_global_interrupt()
|
||||||
|
|
||||||
#define DISABLE_INT_LEVEL( int_lev ) Disable_interrupt_level( int_lev )
|
#define DISABLE_INT_LEVEL(int_lev) Disable_interrupt_level(int_lev)
|
||||||
#define ENABLE_INT_LEVEL( int_lev ) Enable_interrupt_level( int_lev )
|
#define ENABLE_INT_LEVEL(int_lev) Enable_interrupt_level(int_lev)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -124,33 +123,32 @@
|
||||||
* SHALL NOT BE CALLED FROM WITHIN AN INTERRUPT as fputs and printf use malloc,
|
* SHALL NOT BE CALLED FROM WITHIN AN INTERRUPT as fputs and printf use malloc,
|
||||||
* which is interrupt-unsafe with the current __malloc_lock and __malloc_unlock.
|
* which is interrupt-unsafe with the current __malloc_lock and __malloc_unlock.
|
||||||
*/
|
*/
|
||||||
#if configDBG
|
#if configDBG
|
||||||
#define portDBG_TRACE( ... ) \
|
#define portDBG_TRACE(...) \
|
||||||
{ \
|
{\
|
||||||
fputs( __FILE__ ":" ASTRINGZ( __LINE__ ) ": ", stdout ); \
|
fputs(__FILE__ ":" ASTRINGZ(__LINE__) ": ", stdout);\
|
||||||
printf( __VA_ARGS__ ); \
|
printf(__VA_ARGS__);\
|
||||||
fputs( "\r\n", stdout ); \
|
fputs("\r\n", stdout);\
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define portDBG_TRACE( ... )
|
#define portDBG_TRACE(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
#define portDISABLE_INTERRUPTS() DISABLE_ALL_INTERRUPTS()
|
#define portDISABLE_INTERRUPTS() DISABLE_ALL_INTERRUPTS()
|
||||||
#define portENABLE_INTERRUPTS() ENABLE_ALL_INTERRUPTS()
|
#define portENABLE_INTERRUPTS() ENABLE_ALL_INTERRUPTS()
|
||||||
|
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
|
|
||||||
|
|
||||||
/* Added as there is no such function in FreeRTOS. */
|
/* Added as there is no such function in FreeRTOS. */
|
||||||
extern void * pvPortRealloc( void * pv,
|
extern void *pvPortRealloc( void *pv, size_t xSize );
|
||||||
size_t xSize );
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,10 +157,10 @@
|
||||||
/*
|
/*
|
||||||
* Restore Context for cases other than INTi.
|
* Restore Context for cases other than INTi.
|
||||||
*/
|
*/
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
\
|
\
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
/* Set SP to point to new stack */ \
|
/* Set SP to point to new stack */ \
|
||||||
|
@ -192,11 +190,11 @@
|
||||||
/* Restore PC */ \
|
/* Restore PC */ \
|
||||||
"ld.w pc, sp[-7*4]" /* Get PC from stack - PC is the 7th register saved */ \
|
"ld.w pc, sp[-7*4]" /* Get PC from stack - PC is the 7th register saved */ \
|
||||||
: \
|
: \
|
||||||
:[ ulCriticalNesting ] "i" ( &ulCriticalNesting ), \
|
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
|
||||||
[ pxCurrentTCB ] "i" ( &pxCurrentTCB ), \
|
[pxCurrentTCB] "i" (&pxCurrentTCB), \
|
||||||
[ SR ] "i" ( AVR32_SR ) \
|
[SR] "i" (AVR32_SR) \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -207,49 +205,49 @@
|
||||||
* are not the same between INT0..3 exceptions and the scall exception.
|
* are not the same between INT0..3 exceptions and the scall exception.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Task context stack layout: */
|
// Task context stack layout:
|
||||||
/* R8 (*) */
|
// R8 (*)
|
||||||
/* R9 (*) */
|
// R9 (*)
|
||||||
/* R10 (*) */
|
// R10 (*)
|
||||||
/* R11 (*) */
|
// R11 (*)
|
||||||
/* R12 (*) */
|
// R12 (*)
|
||||||
/* R14/LR (*) */
|
// R14/LR (*)
|
||||||
/* R15/PC (*) */
|
// R15/PC (*)
|
||||||
/* SR (*) */
|
// SR (*)
|
||||||
/* R0 */
|
// R0
|
||||||
/* R1 */
|
// R1
|
||||||
/* R2 */
|
// R2
|
||||||
/* R3 */
|
// R3
|
||||||
/* R4 */
|
// R4
|
||||||
/* R5 */
|
// R5
|
||||||
/* R6 */
|
// R6
|
||||||
/* R7 */
|
// R7
|
||||||
/* ulCriticalNesting */
|
// ulCriticalNesting
|
||||||
/* (*) automatically done for INT0..INT3, but not for SCALL */
|
// (*) automatically done for INT0..INT3, but not for SCALL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The ISR used for the scheduler tick depends on whether the cooperative or
|
* The ISR used for the scheduler tick depends on whether the cooperative or
|
||||||
* the preemptive scheduler is being used.
|
* the preemptive scheduler is being used.
|
||||||
*/
|
*/
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
|
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
|
||||||
*/
|
*/
|
||||||
#define portSAVE_CONTEXT_OS_INT() \
|
#define portSAVE_CONTEXT_OS_INT() \
|
||||||
{ \
|
{ \
|
||||||
/* Save R0..R7 */ \
|
/* Save R0..R7 */ \
|
||||||
__asm__ __volatile__ ( "stm --sp, r0-r7" ); \
|
__asm__ __volatile__ ("stm --sp, r0-r7"); \
|
||||||
\
|
\
|
||||||
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
|
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
|
||||||
/* there is also no context save. */ \
|
/* there is also no context save. */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
|
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
|
||||||
*/
|
*/
|
||||||
#define portRESTORE_CONTEXT_OS_INT() \
|
#define portRESTORE_CONTEXT_OS_INT() \
|
||||||
{ \
|
{ \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
/* Restore R0..R7 */ \
|
/* Restore R0..R7 */ \
|
||||||
"ldm sp++, r0-r7\n\t" \
|
"ldm sp++, r0-r7\n\t" \
|
||||||
|
@ -258,17 +256,17 @@
|
||||||
/* there is also no context restore. */ \
|
/* there is also no context restore. */ \
|
||||||
"rete" \
|
"rete" \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* if configUSE_PREEMPTION == 0 */
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
|
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
|
||||||
*/
|
*/
|
||||||
#define portSAVE_CONTEXT_OS_INT() \
|
#define portSAVE_CONTEXT_OS_INT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
\
|
\
|
||||||
/* When we come here */ \
|
/* When we come here */ \
|
||||||
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
|
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
|
||||||
|
@ -308,19 +306,19 @@
|
||||||
\
|
\
|
||||||
"LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE]:" \
|
"LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE]:" \
|
||||||
: \
|
: \
|
||||||
:[ ulCriticalNesting ] "i" ( &ulCriticalNesting ), \
|
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
|
||||||
[ pxCurrentTCB ] "i" ( &pxCurrentTCB ), \
|
[pxCurrentTCB] "i" (&pxCurrentTCB), \
|
||||||
[ LINE ] "i" ( __LINE__ ) \
|
[LINE] "i" (__LINE__) \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
|
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
|
||||||
*/
|
*/
|
||||||
#define portRESTORE_CONTEXT_OS_INT() \
|
#define portRESTORE_CONTEXT_OS_INT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
\
|
\
|
||||||
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
||||||
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
|
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
|
||||||
|
@ -335,12 +333,12 @@
|
||||||
"cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ \
|
"cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ \
|
||||||
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]" \
|
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]" \
|
||||||
: \
|
: \
|
||||||
:[ LINE ] "i" ( __LINE__ ) \
|
: [LINE] "i" (__LINE__) \
|
||||||
); \
|
); \
|
||||||
\
|
\
|
||||||
/* Else */ \
|
/* Else */ \
|
||||||
/* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ \
|
/* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ \
|
||||||
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ \
|
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\
|
||||||
portENTER_CRITICAL(); \
|
portENTER_CRITICAL(); \
|
||||||
vTaskSwitchContext(); \
|
vTaskSwitchContext(); \
|
||||||
portEXIT_CRITICAL(); \
|
portEXIT_CRITICAL(); \
|
||||||
|
@ -357,7 +355,7 @@
|
||||||
"LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]: \n\t"\
|
"LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]: \n\t"\
|
||||||
\
|
\
|
||||||
/* Restore ulCriticalNesting variable */ \
|
/* Restore ulCriticalNesting variable */ \
|
||||||
"ld.w r0, sp++ \n\t"\
|
"ld.w r0, sp++ \n\t" \
|
||||||
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
|
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
|
||||||
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
|
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
|
||||||
"st.w r8[0], r0 \n\t"\
|
"st.w r8[0], r0 \n\t"\
|
||||||
|
@ -368,13 +366,13 @@
|
||||||
/* Now, the stack should be R8..R12, LR, PC and SR */ \
|
/* Now, the stack should be R8..R12, LR, PC and SR */ \
|
||||||
"rete" \
|
"rete" \
|
||||||
: \
|
: \
|
||||||
:[ ulCriticalNesting ] "i" ( &ulCriticalNesting ), \
|
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
|
||||||
[ pxCurrentTCB ] "i" ( &pxCurrentTCB ), \
|
[pxCurrentTCB] "i" (&pxCurrentTCB), \
|
||||||
[ LINE ] "i" ( __LINE__ ) \
|
[LINE] "i" (__LINE__) \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* if configUSE_PREEMPTION == 0 */
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -383,10 +381,10 @@
|
||||||
* NOTE: taskYIELD()(== SCALL) MUST NOT be called in a mode > supervisor mode.
|
* NOTE: taskYIELD()(== SCALL) MUST NOT be called in a mode > supervisor mode.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define portSAVE_CONTEXT_SCALL() \
|
#define portSAVE_CONTEXT_SCALL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
\
|
\
|
||||||
/* Warning: the stack layout after SCALL doesn't match the one after an interrupt. */ \
|
/* Warning: the stack layout after SCALL doesn't match the one after an interrupt. */ \
|
||||||
/* If SR[M2:M0] == 001 */ \
|
/* If SR[M2:M0] == 001 */ \
|
||||||
|
@ -408,10 +406,10 @@
|
||||||
/* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
|
/* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
|
||||||
"sub r7, sp,-16*4 \n\t"\
|
"sub r7, sp,-16*4 \n\t"\
|
||||||
/* Copy PC and SR in other places in the stack. */ \
|
/* Copy PC and SR in other places in the stack. */ \
|
||||||
"ld.w r0, r7[-2*4] \n\t"/* Read SR */\
|
"ld.w r0, r7[-2*4] \n\t" /* Read SR */\
|
||||||
"st.w r7[-8*4], r0 \n\t"/* Copy SR */\
|
"st.w r7[-8*4], r0 \n\t" /* Copy SR */\
|
||||||
"ld.w r0, r7[-1*4] \n\t"/* Read PC */\
|
"ld.w r0, r7[-1*4] \n\t" /* Read PC */\
|
||||||
"st.w r7[-7*4], r0 \n\t"/* Copy PC */\
|
"st.w r7[-7*4], r0 \n\t" /* Copy PC */\
|
||||||
\
|
\
|
||||||
/* Save R8..R12 and LR on the stack. */ \
|
/* Save R8..R12 and LR on the stack. */ \
|
||||||
"stm --r7, r8-r12, lr \n\t"\
|
"stm --r7, r8-r12, lr \n\t"\
|
||||||
|
@ -427,7 +425,7 @@
|
||||||
"ld.w r0, r8[0] \n\t"\
|
"ld.w r0, r8[0] \n\t"\
|
||||||
"st.w --sp, r0" \
|
"st.w --sp, r0" \
|
||||||
: \
|
: \
|
||||||
:[ ulCriticalNesting ] "i" ( &ulCriticalNesting ) \
|
: [ulCriticalNesting] "i" (&ulCriticalNesting) \
|
||||||
); \
|
); \
|
||||||
\
|
\
|
||||||
/* Disable the its which may cause a context switch (i.e. cause a change of */ \
|
/* Disable the its which may cause a context switch (i.e. cause a change of */ \
|
||||||
|
@ -443,17 +441,17 @@
|
||||||
"ld.w r0, r8[0] \n\t"\
|
"ld.w r0, r8[0] \n\t"\
|
||||||
"st.w r0[0], sp" \
|
"st.w r0[0], sp" \
|
||||||
: \
|
: \
|
||||||
:[ pxCurrentTCB ] "i" ( &pxCurrentTCB ) \
|
: [pxCurrentTCB] "i" (&pxCurrentTCB) \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* portRESTORE_CONTEXT() for SupervisorCALL exception.
|
* portRESTORE_CONTEXT() for SupervisorCALL exception.
|
||||||
*/
|
*/
|
||||||
#define portRESTORE_CONTEXT_SCALL() \
|
#define portRESTORE_CONTEXT_SCALL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
\
|
\
|
||||||
/* Restore all registers */ \
|
/* Restore all registers */ \
|
||||||
\
|
\
|
||||||
|
@ -464,7 +462,7 @@
|
||||||
"ld.w r0, r8[0] \n\t"\
|
"ld.w r0, r8[0] \n\t"\
|
||||||
"ld.w sp, r0[0]" \
|
"ld.w sp, r0[0]" \
|
||||||
: \
|
: \
|
||||||
:[ pxCurrentTCB ] "i" ( &pxCurrentTCB ) \
|
: [pxCurrentTCB] "i" (&pxCurrentTCB) \
|
||||||
); \
|
); \
|
||||||
\
|
\
|
||||||
/* Leave pxCurrentTCB variable access critical section */ \
|
/* Leave pxCurrentTCB variable access critical section */ \
|
||||||
|
@ -485,10 +483,10 @@
|
||||||
\
|
\
|
||||||
/* RETS will take care of the extra PC and SR restore. */ \
|
/* RETS will take care of the extra PC and SR restore. */ \
|
||||||
/* So, we have to prepare the stack for this. */ \
|
/* So, we have to prepare the stack for this. */ \
|
||||||
"ld.w r0, r7[-8*4] \n\t"/* Read SR */\
|
"ld.w r0, r7[-8*4] \n\t" /* Read SR */\
|
||||||
"st.w r7[-2*4], r0 \n\t"/* Copy SR */\
|
"st.w r7[-2*4], r0 \n\t" /* Copy SR */\
|
||||||
"ld.w r0, r7[-7*4] \n\t"/* Read PC */\
|
"ld.w r0, r7[-7*4] \n\t" /* Read PC */\
|
||||||
"st.w r7[-1*4], r0 \n\t"/* Copy PC */\
|
"st.w r7[-1*4], r0 \n\t" /* Copy PC */\
|
||||||
\
|
\
|
||||||
/* Restore R0..R7 */ \
|
/* Restore R0..R7 */ \
|
||||||
"ldm sp++, r0-r7 \n\t"\
|
"ldm sp++, r0-r7 \n\t"\
|
||||||
|
@ -497,35 +495,35 @@
|
||||||
\
|
\
|
||||||
"rets" \
|
"rets" \
|
||||||
: \
|
: \
|
||||||
:[ ulCriticalNesting ] "i" ( &ulCriticalNesting ) \
|
: [ulCriticalNesting] "i" (&ulCriticalNesting) \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The ISR used depends on whether the cooperative or
|
* The ISR used depends on whether the cooperative or
|
||||||
* the preemptive scheduler is being used.
|
* the preemptive scheduler is being used.
|
||||||
*/
|
*/
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ISR entry and exit macros. These are only required if a task switch
|
* ISR entry and exit macros. These are only required if a task switch
|
||||||
* is required from the ISR.
|
* is required from the ISR.
|
||||||
*/
|
*/
|
||||||
#define portENTER_SWITCHING_ISR() \
|
#define portENTER_SWITCHING_ISR() \
|
||||||
{ \
|
{ \
|
||||||
/* Save R0..R7 */ \
|
/* Save R0..R7 */ \
|
||||||
__asm__ __volatile__ ( "stm --sp, r0-r7" ); \
|
__asm__ __volatile__ ("stm --sp, r0-r7"); \
|
||||||
\
|
\
|
||||||
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
|
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
|
||||||
/* there is also no context save. */ \
|
/* there is also no context save. */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
|
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
|
||||||
*/
|
*/
|
||||||
#define portEXIT_SWITCHING_ISR() \
|
#define portEXIT_SWITCHING_ISR() \
|
||||||
{ \
|
{ \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
/* Restore R0..R7 */ \
|
/* Restore R0..R7 */ \
|
||||||
"ldm sp++, r0-r7 \n\t"\
|
"ldm sp++, r0-r7 \n\t"\
|
||||||
|
@ -534,31 +532,31 @@
|
||||||
/* there is also no context restore. */ \
|
/* there is also no context restore. */ \
|
||||||
"rete" \
|
"rete" \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* if configUSE_PREEMPTION == 0 */
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ISR entry and exit macros. These are only required if a task switch
|
* ISR entry and exit macros. These are only required if a task switch
|
||||||
* is required from the ISR.
|
* is required from the ISR.
|
||||||
*/
|
*/
|
||||||
#define portENTER_SWITCHING_ISR() \
|
#define portENTER_SWITCHING_ISR() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
\
|
\
|
||||||
/* When we come here */ \
|
/* When we come here */ \
|
||||||
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
|
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
|
||||||
\
|
\
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
/* Save R0..R7 */ \
|
/* Save R0..R7 */ \
|
||||||
"stm --sp, r0-r7 \n\t" \
|
"stm --sp, r0-r7 \n\t"\
|
||||||
\
|
\
|
||||||
/* Save ulCriticalNesting variable - R0 is overwritten */ \
|
/* Save ulCriticalNesting variable - R0 is overwritten */ \
|
||||||
"mov r8, LO(%[ulCriticalNesting]) \n\t" \
|
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
|
||||||
"orh r8, HI(%[ulCriticalNesting]) \n\t" \
|
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
|
||||||
"ld.w r0, r8[0] \n\t" \
|
"ld.w r0, r8[0] \n\t"\
|
||||||
"st.w --sp, r0 \n\t" \
|
"st.w --sp, r0 \n\t"\
|
||||||
\
|
\
|
||||||
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
||||||
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
|
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
|
||||||
|
@ -568,32 +566,32 @@
|
||||||
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
|
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
|
||||||
/* will just be restoring the interrupt handler, no way!!! */ \
|
/* will just be restoring the interrupt handler, no way!!! */ \
|
||||||
/* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
|
/* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
|
||||||
"ld.w r0, sp[9*4] \n\t"/* Read SR in stack */\
|
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
|
||||||
"bfextu r0, r0, 22, 3 \n\t"/* Extract the mode bits to R0. */\
|
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
|
||||||
"cp.w r0, 1 \n\t"/* Compare the mode bits with supervisor mode(b'001) */\
|
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
|
||||||
"brhi LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE] \n\t" \
|
"brhi LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE] \n\t"\
|
||||||
\
|
\
|
||||||
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
|
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
|
||||||
"mov r8, LO(%[pxCurrentTCB]) \n\t" \
|
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
|
||||||
"orh r8, HI(%[pxCurrentTCB]) \n\t" \
|
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
|
||||||
"ld.w r0, r8[0] \n\t" \
|
"ld.w r0, r8[0] \n\t"\
|
||||||
"st.w r0[0], sp \n" \
|
"st.w r0[0], sp \n"\
|
||||||
\
|
\
|
||||||
"LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE]:" \
|
"LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE]:" \
|
||||||
: \
|
: \
|
||||||
:[ ulCriticalNesting ] "i" ( &ulCriticalNesting ), \
|
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
|
||||||
[ pxCurrentTCB ] "i" ( &pxCurrentTCB ), \
|
[pxCurrentTCB] "i" (&pxCurrentTCB), \
|
||||||
[ LINE ] "i" ( __LINE__ ) \
|
[LINE] "i" (__LINE__) \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
|
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
|
||||||
*/
|
*/
|
||||||
#define portEXIT_SWITCHING_ISR() \
|
#define portEXIT_SWITCHING_ISR() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void *volatile pxCurrentTCB; \
|
||||||
\
|
\
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
||||||
|
@ -601,18 +599,18 @@
|
||||||
/* level and allow other lower interrupt level to occur). */ \
|
/* level and allow other lower interrupt level to occur). */ \
|
||||||
/* In this case it's of no use to switch context and restore a new SP because we purposedly */ \
|
/* In this case it's of no use to switch context and restore a new SP because we purposedly */ \
|
||||||
/* did not previously save SP in its TCB. */ \
|
/* did not previously save SP in its TCB. */ \
|
||||||
"ld.w r0, sp[9*4] \n\t"/* Read SR in stack */\
|
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
|
||||||
"bfextu r0, r0, 22, 3 \n\t"/* Extract the mode bits to R0. */\
|
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
|
||||||
"cp.w r0, 1 \n\t"/* Compare the mode bits with supervisor mode(b'001) */\
|
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
|
||||||
"brhi LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE] \n\t" \
|
"brhi LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE] \n\t"\
|
||||||
\
|
\
|
||||||
/* If a switch is required then we just need to call */ \
|
/* If a switch is required then we just need to call */ \
|
||||||
/* vTaskSwitchContext() as the context has already been */ \
|
/* vTaskSwitchContext() as the context has already been */ \
|
||||||
/* saved. */ \
|
/* saved. */ \
|
||||||
"cp.w r12, 1 \n\t"/* Check if Switch context is required. */\
|
"cp.w r12, 1 \n\t" /* Check if Switch context is required. */\
|
||||||
"brne LABEL_ISR_RESTORE_CONTEXT_%[LINE]" \
|
"brne LABEL_ISR_RESTORE_CONTEXT_%[LINE]" \
|
||||||
: \
|
: \
|
||||||
:[ LINE ] "i" ( __LINE__ ) \
|
: [LINE] "i" (__LINE__) \
|
||||||
); \
|
); \
|
||||||
\
|
\
|
||||||
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ \
|
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ \
|
||||||
|
@ -621,49 +619,49 @@
|
||||||
portEXIT_CRITICAL(); \
|
portEXIT_CRITICAL(); \
|
||||||
\
|
\
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
"LABEL_ISR_RESTORE_CONTEXT_%[LINE]: \n\t" \
|
"LABEL_ISR_RESTORE_CONTEXT_%[LINE]: \n\t"\
|
||||||
/* Restore the context of which ever task is now the highest */ \
|
/* Restore the context of which ever task is now the highest */ \
|
||||||
/* priority that is ready to run. */ \
|
/* priority that is ready to run. */ \
|
||||||
\
|
\
|
||||||
/* Restore all registers */ \
|
/* Restore all registers */ \
|
||||||
\
|
\
|
||||||
/* Set SP to point to new stack */ \
|
/* Set SP to point to new stack */ \
|
||||||
"mov r8, LO(%[pxCurrentTCB]) \n\t" \
|
"mov r8, LO(%[pxCurrentTCB]) \n\t"\
|
||||||
"orh r8, HI(%[pxCurrentTCB]) \n\t" \
|
"orh r8, HI(%[pxCurrentTCB]) \n\t"\
|
||||||
"ld.w r0, r8[0] \n\t" \
|
"ld.w r0, r8[0] \n\t"\
|
||||||
"ld.w sp, r0[0] \n" \
|
"ld.w sp, r0[0] \n"\
|
||||||
\
|
\
|
||||||
"LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE]: \n\t" \
|
"LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE]: \n\t"\
|
||||||
\
|
\
|
||||||
/* Restore ulCriticalNesting variable */ \
|
/* Restore ulCriticalNesting variable */ \
|
||||||
"ld.w r0, sp++ \n\t" \
|
"ld.w r0, sp++ \n\t"\
|
||||||
"mov r8, LO(%[ulCriticalNesting]) \n\t" \
|
"mov r8, LO(%[ulCriticalNesting]) \n\t"\
|
||||||
"orh r8, HI(%[ulCriticalNesting]) \n\t" \
|
"orh r8, HI(%[ulCriticalNesting]) \n\t"\
|
||||||
"st.w r8[0], r0 \n\t" \
|
"st.w r8[0], r0 \n\t"\
|
||||||
\
|
\
|
||||||
/* Restore R0..R7 */ \
|
/* Restore R0..R7 */ \
|
||||||
"ldm sp++, r0-r7 \n\t" \
|
"ldm sp++, r0-r7 \n\t"\
|
||||||
\
|
\
|
||||||
/* Now, the stack should be R8..R12, LR, PC and SR */ \
|
/* Now, the stack should be R8..R12, LR, PC and SR */ \
|
||||||
"rete" \
|
"rete" \
|
||||||
: \
|
: \
|
||||||
:[ ulCriticalNesting ] "i" ( &ulCriticalNesting ), \
|
: [ulCriticalNesting] "i" (&ulCriticalNesting), \
|
||||||
[ pxCurrentTCB ] "i" ( &pxCurrentTCB ), \
|
[pxCurrentTCB] "i" (&pxCurrentTCB), \
|
||||||
[ LINE ] "i" ( __LINE__ ) \
|
[LINE] "i" (__LINE__) \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* if configUSE_PREEMPTION == 0 */
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define portYIELD() { __asm__ __volatile__ ( "scall" ); }
|
#define portYIELD() {__asm__ __volatile__ ("scall");}
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
@ -34,18 +34,18 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the AVR port.
|
* Implementation of functions defined in portable.h for the AVR port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Start tasks with interrupts enables. */
|
/* Start tasks with interrupts enables. */
|
||||||
#define portFLAGS_INT_ENABLED ((StackType_t) 0x80)
|
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x80 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
||||||
any details of its type. */
|
* any details of its type. */
|
||||||
typedef void RTOS_TCB_t;
|
typedef void RTOS_TCB_t;
|
||||||
extern volatile RTOS_TCB_t *volatile pxCurrentTCB;
|
extern volatile RTOS_TCB_t * volatile pxCurrentTCB;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ extern volatile RTOS_TCB_t *volatile pxCurrentTCB;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
asm volatile("push r0 \n\t" \
|
asm volatile ( "push r0 \n\t" \
|
||||||
"in r0, __SREG__ \n\t" \
|
"in r0, __SREG__ \n\t" \
|
||||||
"cli \n\t" \
|
"cli \n\t" \
|
||||||
"push r0 \n\t" \
|
"push r0 \n\t" \
|
||||||
|
@ -109,7 +109,7 @@ extern volatile RTOS_TCB_t *volatile pxCurrentTCB;
|
||||||
"in r0, __SP_L__ \n\t" \
|
"in r0, __SP_L__ \n\t" \
|
||||||
"st x+, r0 \n\t" \
|
"st x+, r0 \n\t" \
|
||||||
"in r0, __SP_H__ \n\t" \
|
"in r0, __SP_H__ \n\t" \
|
||||||
"st x+, r0 \n\t");
|
"st x+, r0 \n\t" );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during
|
* Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during
|
||||||
|
@ -117,7 +117,7 @@ extern volatile RTOS_TCB_t *volatile pxCurrentTCB;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
asm volatile("lds r26, pxCurrentTCB \n\t" \
|
asm volatile ( "lds r26, pxCurrentTCB \n\t" \
|
||||||
"lds r27, pxCurrentTCB + 1 \n\t" \
|
"lds r27, pxCurrentTCB + 1 \n\t" \
|
||||||
"ld r28, x+ \n\t" \
|
"ld r28, x+ \n\t" \
|
||||||
"out __SP_L__, r28 \n\t" \
|
"out __SP_L__, r28 \n\t" \
|
||||||
|
@ -158,49 +158,51 @@ extern volatile RTOS_TCB_t *volatile pxCurrentTCB;
|
||||||
"out __RAMPZ__, r0 \n\t" \
|
"out __RAMPZ__, r0 \n\t" \
|
||||||
"pop r0 \n\t" \
|
"pop r0 \n\t" \
|
||||||
"out __SREG__, r0 \n\t" \
|
"out __SREG__, r0 \n\t" \
|
||||||
"pop r0 \n\t");
|
"pop r0 \n\t" );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform hardware setup to enable ticks from timer.
|
* Perform hardware setup to enable ticks from timer.
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt(void);
|
static void prvSetupTimerInterrupt( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters)
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
uint16_t usAddress;
|
uint16_t usAddress;
|
||||||
|
|
||||||
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||||
|
|
||||||
/* Place a few bytes of known values on the bottom of the stack.
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
This is just useful for debugging. Uncomment if needed. */
|
* This is just useful for debugging. Uncomment if needed. */
|
||||||
// *pxTopOfStack = 0x11;
|
/* *pxTopOfStack = 0x11; */
|
||||||
// pxTopOfStack--;
|
/* pxTopOfStack--; */
|
||||||
// *pxTopOfStack = 0x22;
|
/* *pxTopOfStack = 0x22; */
|
||||||
// pxTopOfStack--;
|
/* pxTopOfStack--; */
|
||||||
// *pxTopOfStack = 0x33;
|
/* *pxTopOfStack = 0x33; */
|
||||||
// pxTopOfStack--;
|
/* pxTopOfStack--; */
|
||||||
|
|
||||||
/* The start of the task code will be popped off the stack last, so place
|
/* The start of the task code will be popped off the stack last, so place
|
||||||
it on first. */
|
* it on first. */
|
||||||
usAddress = (uint16_t)pxCode;
|
usAddress = ( uint16_t ) pxCode;
|
||||||
*pxTopOfStack = (StackType_t)(usAddress & (uint16_t)0x00ff);
|
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
usAddress >>= 8;
|
usAddress >>= 8;
|
||||||
*pxTopOfStack = (StackType_t)(usAddress & (uint16_t)0x00ff);
|
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Next simulate the stack as if after a call to portSAVE_CONTEXT().
|
/* Next simulate the stack as if after a call to portSAVE_CONTEXT().
|
||||||
portSAVE_CONTEXT places the flags on the stack immediately after r0
|
* portSAVE_CONTEXT places the flags on the stack immediately after r0
|
||||||
to ensure the interrupts get disabled as soon as possible, and so ensuring
|
* to ensure the interrupts get disabled as soon as possible, and so ensuring
|
||||||
the stack use is minimal should a context switch interrupt occur. */
|
* the stack use is minimal should a context switch interrupt occur. */
|
||||||
*pxTopOfStack = (StackType_t)0x00; /* R0 */
|
*pxTopOfStack = ( StackType_t ) 0x00; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portFLAGS_INT_ENABLED;
|
*pxTopOfStack = portFLAGS_INT_ENABLED;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -208,18 +210,18 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Now the remaining registers. The compiler expects R1 to be 0. */
|
/* Now the remaining registers. The compiler expects R1 to be 0. */
|
||||||
*pxTopOfStack = (StackType_t)0x00; /* R1 */
|
*pxTopOfStack = ( StackType_t ) 0x00; /* R1 */
|
||||||
|
|
||||||
/* Leave R2 - R23 untouched */
|
/* Leave R2 - R23 untouched */
|
||||||
pxTopOfStack -= 23;
|
pxTopOfStack -= 23;
|
||||||
|
|
||||||
/* Place the parameter on the stack in the expected location. */
|
/* Place the parameter on the stack in the expected location. */
|
||||||
usAddress = (uint16_t)pvParameters;
|
usAddress = ( uint16_t ) pvParameters;
|
||||||
*pxTopOfStack = (StackType_t)(usAddress & (uint16_t)0x00ff);
|
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
usAddress >>= 8;
|
usAddress >>= 8;
|
||||||
*pxTopOfStack = (StackType_t)(usAddress & (uint16_t)0x00ff);
|
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||||
|
|
||||||
/* Leave register R26 - R31 untouched */
|
/* Leave register R26 - R31 untouched */
|
||||||
pxTopOfStack -= 7;
|
pxTopOfStack -= 7;
|
||||||
|
@ -230,7 +232,7 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler(void)
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Setup the hardware to generate the tick. */
|
/* Setup the hardware to generate the tick. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
@ -239,15 +241,15 @@ BaseType_t xPortStartScheduler(void)
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
/* Simulate a function call end as generated by the compiler. We will now
|
/* Simulate a function call end as generated by the compiler. We will now
|
||||||
jump to the start of the task the context of which we have just restored. */
|
* jump to the start of the task the context of which we have just restored. */
|
||||||
asm volatile("ret");
|
asm volatile ( "ret" );
|
||||||
|
|
||||||
/* Should not get here. */
|
/* Should not get here. */
|
||||||
return pdTRUE;
|
return pdTRUE;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortEndScheduler(void)
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* vPortEndScheduler is not implemented in this port. */
|
/* vPortEndScheduler is not implemented in this port. */
|
||||||
}
|
}
|
||||||
|
@ -257,13 +259,13 @@ void vPortEndScheduler(void)
|
||||||
* Manual context switch. The first thing we do is save the registers so we
|
* Manual context switch. The first thing we do is save the registers so we
|
||||||
* can use a naked attribute.
|
* can use a naked attribute.
|
||||||
*/
|
*/
|
||||||
void vPortYield(void) __attribute__((naked));
|
void vPortYield( void ) __attribute__( ( naked ) );
|
||||||
void vPortYield(void)
|
void vPortYield( void )
|
||||||
{
|
{
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
asm volatile("ret");
|
asm volatile ( "ret" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -271,13 +273,13 @@ void vPortYield(void)
|
||||||
* Manual context switch callable from ISRs. The first thing
|
* Manual context switch callable from ISRs. The first thing
|
||||||
* we do is save the registers so we can use a naked attribute.
|
* we do is save the registers so we can use a naked attribute.
|
||||||
*/
|
*/
|
||||||
void vPortYieldFromISR(void) __attribute__((naked));
|
void vPortYieldFromISR( void ) __attribute__( ( naked ) );
|
||||||
void vPortYieldFromISR(void)
|
void vPortYieldFromISR( void )
|
||||||
{
|
{
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
asm volatile("reti");
|
asm volatile ( "reti" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -287,24 +289,26 @@ void vPortYieldFromISR(void)
|
||||||
* difference from vPortYield() is the tick count is incremented as the
|
* difference from vPortYield() is the tick count is incremented as the
|
||||||
* call comes from the tick ISR.
|
* call comes from the tick ISR.
|
||||||
*/
|
*/
|
||||||
void vPortYieldFromTick(void) __attribute__((naked));
|
void vPortYieldFromTick( void ) __attribute__( ( naked ) );
|
||||||
void vPortYieldFromTick(void)
|
void vPortYieldFromTick( void )
|
||||||
{
|
{
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
if (xTaskIncrementTick() != pdFALSE) {
|
|
||||||
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
|
{
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
asm volatile("reti");
|
asm volatile ( "reti" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup timer to generate a tick interrupt.
|
* Setup timer to generate a tick interrupt.
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt(void)
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
TICK_init();
|
TICK_init();
|
||||||
}
|
}
|
||||||
|
@ -317,26 +321,26 @@ static void prvSetupTimerInterrupt(void)
|
||||||
* the context is saved at the start of vPortYieldFromTick(). The tick
|
* the context is saved at the start of vPortYieldFromTick(). The tick
|
||||||
* count is incremented after the context is saved.
|
* count is incremented after the context is saved.
|
||||||
*/
|
*/
|
||||||
ISR(TICK_INT_vect, ISR_NAKED)
|
ISR( TICK_INT_vect, ISR_NAKED )
|
||||||
{
|
{
|
||||||
/* Clear tick interrupt flag. */
|
/* Clear tick interrupt flag. */
|
||||||
CLR_INT(INT_FLAGS, INT_MASK);
|
CLR_INT( INT_FLAGS, INT_MASK );
|
||||||
|
|
||||||
vPortYieldFromTick();
|
vPortYieldFromTick();
|
||||||
|
|
||||||
asm volatile("reti");
|
asm volatile ( "reti" );
|
||||||
}
|
}
|
||||||
#else
|
#else /* if configUSE_PREEMPTION == 1 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tick ISR for the cooperative scheduler. All this does is increment the
|
* Tick ISR for the cooperative scheduler. All this does is increment the
|
||||||
* tick count. We don't need to switch context, this can only be done by
|
* tick count. We don't need to switch context, this can only be done by
|
||||||
* manual calls to taskYIELD();
|
* manual calls to taskYIELD();
|
||||||
*/
|
*/
|
||||||
ISR(TICK_INT_vect)
|
ISR( TICK_INT_vect )
|
||||||
{
|
{
|
||||||
/* Clear tick interrupt flag. */
|
/* Clear tick interrupt flag. */
|
||||||
INT_FLAGS = INT_MASK;
|
INT_FLAGS = INT_MASK;
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* if configUSE_PREEMPTION == 1 */
|
||||||
|
|
|
@ -5,14 +5,14 @@
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define CLR_INT(FLAG_REG, FLAG_MASK) \
|
#define CLR_INT( FLAG_REG, FLAG_MASK ) \
|
||||||
asm volatile( \
|
asm volatile ( \
|
||||||
"push r16\n\t" \
|
"push r16\n\t" \
|
||||||
"ldi r16, %1\n\t" \
|
"ldi r16, %1\n\t" \
|
||||||
"sts %0, r16\n\t" \
|
"sts %0, r16\n\t" \
|
||||||
"pop r16\n\t" \
|
"pop r16\n\t" \
|
||||||
: \
|
: \
|
||||||
: "i"(_SFR_MEM_ADDR(FLAG_REG)),"i"((uint8_t)(FLAG_MASK)) \
|
: "i" ( _SFR_MEM_ADDR( FLAG_REG ) ), "i" ( ( uint8_t ) ( FLAG_MASK ) ) \
|
||||||
);
|
);
|
||||||
|
|
||||||
#if ( configUSE_TIMER_INSTANCE == 0 )
|
#if ( configUSE_TIMER_INSTANCE == 0 )
|
||||||
|
@ -21,7 +21,8 @@
|
||||||
#define INT_FLAGS TCB0_INTFLAGS
|
#define INT_FLAGS TCB0_INTFLAGS
|
||||||
#define INT_MASK TCB_CAPT_bm
|
#define INT_MASK TCB_CAPT_bm
|
||||||
|
|
||||||
#define TICK_init() { \
|
#define TICK_init() \
|
||||||
|
{ \
|
||||||
TCB0.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
TCB0.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
||||||
TCB0.INTCTRL = TCB_CAPT_bm; \
|
TCB0.INTCTRL = TCB_CAPT_bm; \
|
||||||
TCB0.CTRLA = TCB_ENABLE_bm; \
|
TCB0.CTRLA = TCB_ENABLE_bm; \
|
||||||
|
@ -33,7 +34,8 @@
|
||||||
#define INT_FLAGS TCB1_INTFLAGS
|
#define INT_FLAGS TCB1_INTFLAGS
|
||||||
#define INT_MASK TCB_CAPT_bm
|
#define INT_MASK TCB_CAPT_bm
|
||||||
|
|
||||||
#define TICK_init() { \
|
#define TICK_init() \
|
||||||
|
{ \
|
||||||
TCB1.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
TCB1.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
||||||
TCB1.INTCTRL = TCB_CAPT_bm; \
|
TCB1.INTCTRL = TCB_CAPT_bm; \
|
||||||
TCB1.CTRLA = TCB_ENABLE_bm; \
|
TCB1.CTRLA = TCB_ENABLE_bm; \
|
||||||
|
@ -45,7 +47,8 @@
|
||||||
#define INT_FLAGS TCB2_INTFLAGS
|
#define INT_FLAGS TCB2_INTFLAGS
|
||||||
#define INT_MASK TCB_CAPT_bm
|
#define INT_MASK TCB_CAPT_bm
|
||||||
|
|
||||||
#define TICK_init() { \
|
#define TICK_init() \
|
||||||
|
{ \
|
||||||
TCB2.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
TCB2.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
||||||
TCB2.INTCTRL = TCB_CAPT_bm; \
|
TCB2.INTCTRL = TCB_CAPT_bm; \
|
||||||
TCB2.CTRLA = TCB_ENABLE_bm; \
|
TCB2.CTRLA = TCB_ENABLE_bm; \
|
||||||
|
@ -57,7 +60,8 @@
|
||||||
#define INT_FLAGS TCB3_INTFLAGS
|
#define INT_FLAGS TCB3_INTFLAGS
|
||||||
#define INT_MASK TCB_CAPT_bm
|
#define INT_MASK TCB_CAPT_bm
|
||||||
|
|
||||||
#define TICK_init() { \
|
#define TICK_init() \
|
||||||
|
{ \
|
||||||
TCB3.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
TCB3.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
||||||
TCB3.INTCTRL = TCB_CAPT_bm; \
|
TCB3.INTCTRL = TCB_CAPT_bm; \
|
||||||
TCB3.CTRLA = TCB_ENABLE_bm; \
|
TCB3.CTRLA = TCB_ENABLE_bm; \
|
||||||
|
@ -69,7 +73,8 @@
|
||||||
#define INT_FLAGS TCB4_INTFLAGS
|
#define INT_FLAGS TCB4_INTFLAGS
|
||||||
#define INT_MASK TCB_CAPT_bm
|
#define INT_MASK TCB_CAPT_bm
|
||||||
|
|
||||||
#define TICK_init() { \
|
#define TICK_init() \
|
||||||
|
{ \
|
||||||
TCB4.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
TCB4.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
||||||
TCB4.INTCTRL = TCB_CAPT_bm; \
|
TCB4.INTCTRL = TCB_CAPT_bm; \
|
||||||
TCB4.CTRLA = TCB_ENABLE_bm; \
|
TCB4.CTRLA = TCB_ENABLE_bm; \
|
||||||
|
@ -81,22 +86,23 @@
|
||||||
#define INT_FLAGS RTC_INTFLAGS
|
#define INT_FLAGS RTC_INTFLAGS
|
||||||
#define INT_MASK RTC_OVF_bm
|
#define INT_MASK RTC_OVF_bm
|
||||||
|
|
||||||
/* Hertz to period for RTC setup */
|
/* Hertz to period for RTC setup */
|
||||||
#define RTC_PERIOD_HZ(x) ( 32768 * ( ( 1.0 / x ) ) )
|
#define RTC_PERIOD_HZ( x ) ( 32768 * ( ( 1.0 / x ) ) )
|
||||||
#define TICK_init() { \
|
#define TICK_init() \
|
||||||
while (RTC.STATUS > 0); \
|
{ \
|
||||||
|
while( RTC.STATUS > 0 ) {; } \
|
||||||
RTC.CTRLA = RTC_PRESCALER_DIV1_gc | 1 << RTC_RTCEN_bp; \
|
RTC.CTRLA = RTC_PRESCALER_DIV1_gc | 1 << RTC_RTCEN_bp; \
|
||||||
RTC.PER = RTC_PERIOD_HZ(configTICK_RATE_HZ); \
|
RTC.PER = RTC_PERIOD_HZ( configTICK_RATE_HZ ); \
|
||||||
RTC.INTCTRL |= 1 << RTC_OVF_bp; \
|
RTC.INTCTRL |= 1 << RTC_OVF_bp; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else /* if ( configUSE_TIMER_INSTANCE == 0 ) */
|
||||||
#undef TICK_INT_vect
|
#undef TICK_INT_vect
|
||||||
#undef INT_FLAGS
|
#undef INT_FLAGS
|
||||||
#undef INT_MASK
|
#undef INT_MASK
|
||||||
#undef TICK_init()
|
#undef TICK_init()
|
||||||
#error Invalid timer setting.
|
#error Invalid timer setting.
|
||||||
#endif
|
#endif /* if ( configUSE_TIMER_INSTANCE == 0 ) */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,16 @@
|
||||||
* http://aws.amazon.com/freertos
|
* http://aws.amazon.com/freertos
|
||||||
*
|
*
|
||||||
* 1 tab == 4 spaces!
|
* 1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/* *INDENT-OFF* */
|
||||||
extern "C" {
|
#ifdef __cplusplus
|
||||||
#endif
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -57,50 +59,52 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef signed char BaseType_t;
|
typedef signed char BaseType_t;
|
||||||
typedef unsigned char UBaseType_t;
|
typedef unsigned char UBaseType_t;
|
||||||
|
|
||||||
#if (configUSE_16_BIT_TICKS == 1)
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY (TickType_t)0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY (TickType_t)0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() \
|
||||||
asm volatile("in __tmp_reg__, __SREG__"); \
|
asm volatile ( "in __tmp_reg__, __SREG__" ); \
|
||||||
asm volatile("cli"); \
|
asm volatile ( "cli" ); \
|
||||||
asm volatile("push __tmp_reg__")
|
asm volatile ( "push __tmp_reg__" )
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() \
|
||||||
asm volatile("pop __tmp_reg__"); \
|
asm volatile ( "pop __tmp_reg__" ); \
|
||||||
asm volatile("out __SREG__, __tmp_reg__")
|
asm volatile ( "out __SREG__, __tmp_reg__" )
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() asm volatile("cli" ::);
|
#define portDISABLE_INTERRUPTS() asm volatile ( "cli" ::);
|
||||||
#define portENABLE_INTERRUPTS() asm volatile("sei" ::);
|
#define portENABLE_INTERRUPTS() asm volatile ( "sei" ::);
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 1
|
#define portBYTE_ALIGNMENT 1
|
||||||
#define portNOP() asm volatile("nop");
|
#define portNOP() asm volatile ( "nop" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Kernel utilities. */
|
/* Kernel utilities. */
|
||||||
extern void vPortYield(void) __attribute__((naked));
|
extern void vPortYield( void ) __attribute__( ( naked ) );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
|
|
||||||
extern void vPortYieldFromISR(void) __attribute__((naked));
|
extern void vPortYieldFromISR( void ) __attribute__( ( naked ) );
|
||||||
#define portYIELD_FROM_ISR() vPortYieldFromISR()
|
#define portYIELD_FROM_ISR() vPortYieldFromISR()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/* *INDENT-OFF* */
|
||||||
}
|
#ifdef __cplusplus
|
||||||
#endif
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
@ -34,18 +34,18 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the AVR port.
|
* Implementation of functions defined in portable.h for the AVR port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Start tasks with interrupts enables. */
|
/* Start tasks with interrupts enables. */
|
||||||
#define portFLAGS_INT_ENABLED ((StackType_t) 0x80)
|
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x80 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
||||||
any details of its type. */
|
* any details of its type. */
|
||||||
typedef void RTOS_TCB_t;
|
typedef void RTOS_TCB_t;
|
||||||
extern volatile RTOS_TCB_t *volatile pxCurrentTCB;
|
extern volatile RTOS_TCB_t * volatile pxCurrentTCB;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ extern volatile RTOS_TCB_t *volatile pxCurrentTCB;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
asm volatile("push r0 \n\t" \
|
asm volatile ( "push r0 \n\t" \
|
||||||
"in r0, __SREG__ \n\t" \
|
"in r0, __SREG__ \n\t" \
|
||||||
"cli \n\t" \
|
"cli \n\t" \
|
||||||
"push r0 \n\t" \
|
"push r0 \n\t" \
|
||||||
|
@ -107,7 +107,7 @@ extern volatile RTOS_TCB_t *volatile pxCurrentTCB;
|
||||||
"in r0, __SP_L__ \n\t" \
|
"in r0, __SP_L__ \n\t" \
|
||||||
"st x+, r0 \n\t" \
|
"st x+, r0 \n\t" \
|
||||||
"in r0, __SP_H__ \n\t" \
|
"in r0, __SP_H__ \n\t" \
|
||||||
"st x+, r0 \n\t");
|
"st x+, r0 \n\t" );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during
|
* Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during
|
||||||
|
@ -115,7 +115,7 @@ extern volatile RTOS_TCB_t *volatile pxCurrentTCB;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
asm volatile("lds r26, pxCurrentTCB \n\t" \
|
asm volatile ( "lds r26, pxCurrentTCB \n\t" \
|
||||||
"lds r27, pxCurrentTCB + 1 \n\t" \
|
"lds r27, pxCurrentTCB + 1 \n\t" \
|
||||||
"ld r28, x+ \n\t" \
|
"ld r28, x+ \n\t" \
|
||||||
"out __SP_L__, r28 \n\t" \
|
"out __SP_L__, r28 \n\t" \
|
||||||
|
@ -154,66 +154,68 @@ extern volatile RTOS_TCB_t *volatile pxCurrentTCB;
|
||||||
"pop r1 \n\t" \
|
"pop r1 \n\t" \
|
||||||
"pop r0 \n\t" \
|
"pop r0 \n\t" \
|
||||||
"out __SREG__, r0 \n\t" \
|
"out __SREG__, r0 \n\t" \
|
||||||
"pop r0 \n\t");
|
"pop r0 \n\t" );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform hardware setup to enable ticks from timer.
|
* Perform hardware setup to enable ticks from timer.
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt(void);
|
static void prvSetupTimerInterrupt( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters)
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
uint16_t usAddress;
|
uint16_t usAddress;
|
||||||
|
|
||||||
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||||
|
|
||||||
/* Place a few bytes of known values on the bottom of the stack.
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
This is just useful for debugging. Uncomment if needed. */
|
* This is just useful for debugging. Uncomment if needed. */
|
||||||
// *pxTopOfStack = 0x11;
|
/* *pxTopOfStack = 0x11; */
|
||||||
// pxTopOfStack--;
|
/* pxTopOfStack--; */
|
||||||
// *pxTopOfStack = 0x22;
|
/* *pxTopOfStack = 0x22; */
|
||||||
// pxTopOfStack--;
|
/* pxTopOfStack--; */
|
||||||
// *pxTopOfStack = 0x33;
|
/* *pxTopOfStack = 0x33; */
|
||||||
// pxTopOfStack--;
|
/* pxTopOfStack--; */
|
||||||
|
|
||||||
/* The start of the task code will be popped off the stack last, so place
|
/* The start of the task code will be popped off the stack last, so place
|
||||||
it on first. */
|
* it on first. */
|
||||||
usAddress = (uint16_t)pxCode;
|
usAddress = ( uint16_t ) pxCode;
|
||||||
*pxTopOfStack = (StackType_t)(usAddress & (uint16_t)0x00ff);
|
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
usAddress >>= 8;
|
usAddress >>= 8;
|
||||||
*pxTopOfStack = (StackType_t)(usAddress & (uint16_t)0x00ff);
|
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Next simulate the stack as if after a call to portSAVE_CONTEXT().
|
/* Next simulate the stack as if after a call to portSAVE_CONTEXT().
|
||||||
portSAVE_CONTEXT places the flags on the stack immediately after r0
|
* portSAVE_CONTEXT places the flags on the stack immediately after r0
|
||||||
to ensure the interrupts get disabled as soon as possible, and so ensuring
|
* to ensure the interrupts get disabled as soon as possible, and so ensuring
|
||||||
the stack use is minimal should a context switch interrupt occur. */
|
* the stack use is minimal should a context switch interrupt occur. */
|
||||||
*pxTopOfStack = (StackType_t)0x00; /* R0 */
|
*pxTopOfStack = ( StackType_t ) 0x00; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portFLAGS_INT_ENABLED;
|
*pxTopOfStack = portFLAGS_INT_ENABLED;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Now the remaining registers. The compiler expects R1 to be 0. */
|
/* Now the remaining registers. The compiler expects R1 to be 0. */
|
||||||
*pxTopOfStack = (StackType_t)0x00; /* R1 */
|
*pxTopOfStack = ( StackType_t ) 0x00; /* R1 */
|
||||||
|
|
||||||
/* Leave R2 - R23 untouched */
|
/* Leave R2 - R23 untouched */
|
||||||
pxTopOfStack -= 23;
|
pxTopOfStack -= 23;
|
||||||
|
|
||||||
/* Place the parameter on the stack in the expected location. */
|
/* Place the parameter on the stack in the expected location. */
|
||||||
usAddress = (uint16_t)pvParameters;
|
usAddress = ( uint16_t ) pvParameters;
|
||||||
*pxTopOfStack = (StackType_t)(usAddress & (uint16_t)0x00ff);
|
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
usAddress >>= 8;
|
usAddress >>= 8;
|
||||||
*pxTopOfStack = (StackType_t)(usAddress & (uint16_t)0x00ff);
|
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
|
||||||
|
|
||||||
/* Leave register R26 - R31 untouched */
|
/* Leave register R26 - R31 untouched */
|
||||||
pxTopOfStack -= 7;
|
pxTopOfStack -= 7;
|
||||||
|
@ -224,7 +226,7 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler(void)
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Setup the hardware to generate the tick. */
|
/* Setup the hardware to generate the tick. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
@ -233,15 +235,15 @@ BaseType_t xPortStartScheduler(void)
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
/* Simulate a function call end as generated by the compiler. We will now
|
/* Simulate a function call end as generated by the compiler. We will now
|
||||||
jump to the start of the task the context of which we have just restored. */
|
* jump to the start of the task the context of which we have just restored. */
|
||||||
asm volatile("ret");
|
asm volatile ( "ret" );
|
||||||
|
|
||||||
/* Should not get here. */
|
/* Should not get here. */
|
||||||
return pdTRUE;
|
return pdTRUE;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortEndScheduler(void)
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* vPortEndScheduler is not implemented in this port. */
|
/* vPortEndScheduler is not implemented in this port. */
|
||||||
}
|
}
|
||||||
|
@ -251,13 +253,13 @@ void vPortEndScheduler(void)
|
||||||
* Manual context switch. The first thing we do is save the registers so we
|
* Manual context switch. The first thing we do is save the registers so we
|
||||||
* can use a naked attribute.
|
* can use a naked attribute.
|
||||||
*/
|
*/
|
||||||
void vPortYield(void) __attribute__((naked));
|
void vPortYield( void ) __attribute__( ( naked ) );
|
||||||
void vPortYield(void)
|
void vPortYield( void )
|
||||||
{
|
{
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
asm volatile("ret");
|
asm volatile ( "ret" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -265,13 +267,13 @@ void vPortYield(void)
|
||||||
* Manual context switch callable from ISRs. The first thing
|
* Manual context switch callable from ISRs. The first thing
|
||||||
* we do is save the registers so we can use a naked attribute.
|
* we do is save the registers so we can use a naked attribute.
|
||||||
*/
|
*/
|
||||||
void vPortYieldFromISR(void) __attribute__((naked));
|
void vPortYieldFromISR( void ) __attribute__( ( naked ) );
|
||||||
void vPortYieldFromISR(void)
|
void vPortYieldFromISR( void )
|
||||||
{
|
{
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
asm volatile("reti");
|
asm volatile ( "reti" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -281,24 +283,26 @@ void vPortYieldFromISR(void)
|
||||||
* difference from vPortYield() is the tick count is incremented as the
|
* difference from vPortYield() is the tick count is incremented as the
|
||||||
* call comes from the tick ISR.
|
* call comes from the tick ISR.
|
||||||
*/
|
*/
|
||||||
void vPortYieldFromTick(void) __attribute__((naked));
|
void vPortYieldFromTick( void ) __attribute__( ( naked ) );
|
||||||
void vPortYieldFromTick(void)
|
void vPortYieldFromTick( void )
|
||||||
{
|
{
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
if (xTaskIncrementTick() != pdFALSE) {
|
|
||||||
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
|
{
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
asm volatile("reti");
|
asm volatile ( "reti" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup timer to generate a tick interrupt.
|
* Setup timer to generate a tick interrupt.
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt(void)
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
TICK_init();
|
TICK_init();
|
||||||
}
|
}
|
||||||
|
@ -311,26 +315,26 @@ static void prvSetupTimerInterrupt(void)
|
||||||
* the context is saved at the start of vPortYieldFromTick(). The tick
|
* the context is saved at the start of vPortYieldFromTick(). The tick
|
||||||
* count is incremented after the context is saved.
|
* count is incremented after the context is saved.
|
||||||
*/
|
*/
|
||||||
ISR(TICK_INT_vect, ISR_NAKED)
|
ISR( TICK_INT_vect, ISR_NAKED )
|
||||||
{
|
{
|
||||||
/* Clear tick interrupt flag. */
|
/* Clear tick interrupt flag. */
|
||||||
CLR_INT(INT_FLAGS, INT_MASK);
|
CLR_INT( INT_FLAGS, INT_MASK );
|
||||||
|
|
||||||
vPortYieldFromTick();
|
vPortYieldFromTick();
|
||||||
|
|
||||||
asm volatile("reti");
|
asm volatile ( "reti" );
|
||||||
}
|
}
|
||||||
#else
|
#else /* if configUSE_PREEMPTION == 1 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tick ISR for the cooperative scheduler. All this does is increment the
|
* Tick ISR for the cooperative scheduler. All this does is increment the
|
||||||
* tick count. We don't need to switch context, this can only be done by
|
* tick count. We don't need to switch context, this can only be done by
|
||||||
* manual calls to taskYIELD();
|
* manual calls to taskYIELD();
|
||||||
*/
|
*/
|
||||||
ISR(TICK_INT_vect)
|
ISR( TICK_INT_vect )
|
||||||
{
|
{
|
||||||
/* Clear tick interrupt flag. */
|
/* Clear tick interrupt flag. */
|
||||||
INT_FLAGS = INT_MASK;
|
INT_FLAGS = INT_MASK;
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* if configUSE_PREEMPTION == 1 */
|
||||||
|
|
|
@ -5,14 +5,14 @@
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define CLR_INT(FLAG_REG, FLAG_MASK) \
|
#define CLR_INT( FLAG_REG, FLAG_MASK ) \
|
||||||
asm volatile( \
|
asm volatile ( \
|
||||||
"push r16\n\t" \
|
"push r16\n\t" \
|
||||||
"ldi r16, %1\n\t" \
|
"ldi r16, %1\n\t" \
|
||||||
"sts %0, r16\n\t" \
|
"sts %0, r16\n\t" \
|
||||||
"pop r16\n\t" \
|
"pop r16\n\t" \
|
||||||
: \
|
: \
|
||||||
: "i"(_SFR_MEM_ADDR(FLAG_REG)),"i"((uint8_t)(FLAG_MASK)) \
|
: "i" ( _SFR_MEM_ADDR( FLAG_REG ) ), "i" ( ( uint8_t ) ( FLAG_MASK ) ) \
|
||||||
);
|
);
|
||||||
|
|
||||||
#if ( configUSE_TIMER_INSTANCE == 0 )
|
#if ( configUSE_TIMER_INSTANCE == 0 )
|
||||||
|
@ -21,7 +21,8 @@
|
||||||
#define INT_FLAGS TCB0_INTFLAGS
|
#define INT_FLAGS TCB0_INTFLAGS
|
||||||
#define INT_MASK TCB_CAPT_bm
|
#define INT_MASK TCB_CAPT_bm
|
||||||
|
|
||||||
#define TICK_init() { \
|
#define TICK_init() \
|
||||||
|
{ \
|
||||||
TCB0.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
TCB0.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
||||||
TCB0.INTCTRL = TCB_CAPT_bm; \
|
TCB0.INTCTRL = TCB_CAPT_bm; \
|
||||||
TCB0.CTRLA = TCB_ENABLE_bm; \
|
TCB0.CTRLA = TCB_ENABLE_bm; \
|
||||||
|
@ -33,7 +34,8 @@
|
||||||
#define INT_FLAGS TCB1_INTFLAGS
|
#define INT_FLAGS TCB1_INTFLAGS
|
||||||
#define INT_MASK TCB_CAPT_bm
|
#define INT_MASK TCB_CAPT_bm
|
||||||
|
|
||||||
#define TICK_init() { \
|
#define TICK_init() \
|
||||||
|
{ \
|
||||||
TCB1.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
TCB1.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
||||||
TCB1.INTCTRL = TCB_CAPT_bm; \
|
TCB1.INTCTRL = TCB_CAPT_bm; \
|
||||||
TCB1.CTRLA = TCB_ENABLE_bm; \
|
TCB1.CTRLA = TCB_ENABLE_bm; \
|
||||||
|
@ -45,7 +47,8 @@
|
||||||
#define INT_FLAGS TCB2_INTFLAGS
|
#define INT_FLAGS TCB2_INTFLAGS
|
||||||
#define INT_MASK TCB_CAPT_bm
|
#define INT_MASK TCB_CAPT_bm
|
||||||
|
|
||||||
#define TICK_init() { \
|
#define TICK_init() \
|
||||||
|
{ \
|
||||||
TCB2.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
TCB2.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
||||||
TCB2.INTCTRL = TCB_CAPT_bm; \
|
TCB2.INTCTRL = TCB_CAPT_bm; \
|
||||||
TCB2.CTRLA = TCB_ENABLE_bm; \
|
TCB2.CTRLA = TCB_ENABLE_bm; \
|
||||||
|
@ -57,7 +60,8 @@
|
||||||
#define INT_FLAGS TCB3_INTFLAGS
|
#define INT_FLAGS TCB3_INTFLAGS
|
||||||
#define INT_MASK TCB_CAPT_bm
|
#define INT_MASK TCB_CAPT_bm
|
||||||
|
|
||||||
#define TICK_init() { \
|
#define TICK_init() \
|
||||||
|
{ \
|
||||||
TCB3.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
TCB3.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \
|
||||||
TCB3.INTCTRL = TCB_CAPT_bm; \
|
TCB3.INTCTRL = TCB_CAPT_bm; \
|
||||||
TCB3.CTRLA = TCB_ENABLE_bm; \
|
TCB3.CTRLA = TCB_ENABLE_bm; \
|
||||||
|
@ -69,22 +73,23 @@
|
||||||
#define INT_FLAGS RTC_INTFLAGS
|
#define INT_FLAGS RTC_INTFLAGS
|
||||||
#define INT_MASK RTC_OVF_bm
|
#define INT_MASK RTC_OVF_bm
|
||||||
|
|
||||||
/* Hertz to period for RTC setup */
|
/* Hertz to period for RTC setup */
|
||||||
#define RTC_PERIOD_HZ(x) ( 32768 * ( ( 1.0 / x ) ) )
|
#define RTC_PERIOD_HZ( x ) ( 32768 * ( ( 1.0 / x ) ) )
|
||||||
#define TICK_init() { \
|
#define TICK_init() \
|
||||||
while (RTC.STATUS > 0); \
|
{ \
|
||||||
|
while( RTC.STATUS > 0 ) {; } \
|
||||||
RTC.CTRLA = RTC_PRESCALER_DIV1_gc | 1 << RTC_RTCEN_bp; \
|
RTC.CTRLA = RTC_PRESCALER_DIV1_gc | 1 << RTC_RTCEN_bp; \
|
||||||
RTC.PER = RTC_PERIOD_HZ(configTICK_RATE_HZ); \
|
RTC.PER = RTC_PERIOD_HZ( configTICK_RATE_HZ ); \
|
||||||
RTC.INTCTRL |= 1 << RTC_OVF_bp; \
|
RTC.INTCTRL |= 1 << RTC_OVF_bp; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else /* if ( configUSE_TIMER_INSTANCE == 0 ) */
|
||||||
#undef TICK_INT_vect
|
#undef TICK_INT_vect
|
||||||
#undef INT_FLAGS
|
#undef INT_FLAGS
|
||||||
#undef INT_MASK
|
#undef INT_MASK
|
||||||
#undef TICK_init()
|
#undef TICK_init()
|
||||||
#error Invalid timer setting.
|
#error Invalid timer setting.
|
||||||
#endif
|
#endif /* if ( configUSE_TIMER_INSTANCE == 0 ) */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,16 @@
|
||||||
* http://aws.amazon.com/freertos
|
* http://aws.amazon.com/freertos
|
||||||
*
|
*
|
||||||
* 1 tab == 4 spaces!
|
* 1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -57,50 +59,52 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef signed char BaseType_t;
|
typedef signed char BaseType_t;
|
||||||
typedef unsigned char UBaseType_t;
|
typedef unsigned char UBaseType_t;
|
||||||
|
|
||||||
#if (configUSE_16_BIT_TICKS == 1)
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY (TickType_t)0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY (TickType_t)0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() \
|
||||||
asm volatile("in __tmp_reg__, __SREG__"); \
|
asm volatile ( "in __tmp_reg__, __SREG__" ); \
|
||||||
asm volatile("cli"); \
|
asm volatile ( "cli" ); \
|
||||||
asm volatile("push __tmp_reg__")
|
asm volatile ( "push __tmp_reg__" )
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() \
|
||||||
asm volatile("pop __tmp_reg__"); \
|
asm volatile ( "pop __tmp_reg__" ); \
|
||||||
asm volatile("out __SREG__, __tmp_reg__")
|
asm volatile ( "out __SREG__, __tmp_reg__" )
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() asm volatile("cli" ::);
|
#define portDISABLE_INTERRUPTS() asm volatile ( "cli" ::);
|
||||||
#define portENABLE_INTERRUPTS() asm volatile("sei" ::);
|
#define portENABLE_INTERRUPTS() asm volatile ( "sei" ::);
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 1
|
#define portBYTE_ALIGNMENT 1
|
||||||
#define portNOP() asm volatile("nop");
|
#define portNOP() asm volatile ( "nop" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Kernel utilities. */
|
/* Kernel utilities. */
|
||||||
extern void vPortYield(void) __attribute__((naked));
|
extern void vPortYield( void ) __attribute__( ( naked ) );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
|
|
||||||
extern void vPortYieldFromISR(void) __attribute__((naked));
|
extern void vPortYieldFromISR( void ) __attribute__( ( naked ) );
|
||||||
#define portYIELD_FROM_ISR() vPortYieldFromISR()
|
#define portYIELD_FROM_ISR() vPortYieldFromISR()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
@ -48,12 +48,10 @@
|
||||||
static void prvSetupTimerInterrupt( void );
|
static void prvSetupTimerInterrupt( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
TaskFunction_t pxCode,
|
|
||||||
void * pvParameters )
|
|
||||||
{
|
{
|
||||||
/* Make space on the stack for the context - this leaves a couple of spaces
|
/* Make space on the stack for the context - this leaves a couple of spaces
|
||||||
* empty. */
|
empty. */
|
||||||
pxTopOfStack -= 20;
|
pxTopOfStack -= 20;
|
||||||
|
|
||||||
/* Fill the registers with known values to assist debugging. */
|
/* Fill the registers with known values to assist debugging. */
|
||||||
|
@ -108,7 +106,7 @@ static void prvSetupTimerInterrupt( void )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Trap 31 handler. */
|
/* Trap 31 handler. */
|
||||||
void interrupt31_handler( void ) __attribute__( ( naked ) );
|
void interrupt31_handler( void ) __attribute__((naked));
|
||||||
void interrupt31_handler( void )
|
void interrupt31_handler( void )
|
||||||
{
|
{
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
@ -117,7 +115,7 @@ void interrupt31_handler( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvProcessTick( void ) __attribute__( ( noinline ) );
|
static void prvProcessTick( void ) __attribute__((noinline));
|
||||||
static void prvProcessTick( void )
|
static void prvProcessTick( void )
|
||||||
{
|
{
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
|
@ -131,7 +129,7 @@ static void prvProcessTick( void )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Timer 1 interrupt handler, used for tick interrupt. */
|
/* Timer 1 interrupt handler, used for tick interrupt. */
|
||||||
void interrupt7_handler( void ) __attribute__( ( naked ) );
|
void interrupt7_handler( void ) __attribute__((naked));
|
||||||
void interrupt7_handler( void )
|
void interrupt7_handler( void )
|
||||||
{
|
{
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
|
@ -26,13 +26,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <machine/cpu.h>
|
#include <machine/cpu.h>
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -45,65 +45,65 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#define portNOP() __asm__ volatile ( "mov r0, r0" )
|
#define portNOP() __asm__ volatile ( "mov r0, r0" )
|
||||||
#define portCRITICAL_NESTING_IN_TCB 1
|
#define portCRITICAL_NESTING_IN_TCB 1
|
||||||
#define portIRQ_TRAP_YIELD 31
|
#define portIRQ_TRAP_YIELD 31
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
extern void vPortYield( void );
|
extern void vPortYield( void );
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define portYIELD() asm __volatile__ ( " trap #%0 " : : "i" ( portIRQ_TRAP_YIELD ) : "memory" )
|
#define portYIELD() asm __volatile__( " trap #%0 "::"i"(portIRQ_TRAP_YIELD):"memory")
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
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()
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
#define portDISABLE_INTERRUPTS() cpu_int_disable()
|
#define portDISABLE_INTERRUPTS() cpu_int_disable()
|
||||||
#define portENABLE_INTERRUPTS() cpu_int_enable()
|
#define portENABLE_INTERRUPTS() cpu_int_enable()
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken != pdFALSE ) vTaskSwitchContext()
|
#define portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken != pdFALSE ) vTaskSwitchContext()
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
asm __volatile__ \
|
asm __volatile__ \
|
||||||
( \
|
( \
|
||||||
"sub r1, #68 \n"/* Make space on the stack for the context. */ \
|
"sub r1, #68 \n" /* Make space on the stack for the context. */ \
|
||||||
"std r2, [r1] + 0 \n" \
|
"std r2, [r1] + 0 \n" \
|
||||||
"stq r4, [r1] + 8 \n" \
|
"stq r4, [r1] + 8 \n" \
|
||||||
"stq r8, [r1] + 24 \n" \
|
"stq r8, [r1] + 24 \n" \
|
||||||
|
@ -114,15 +114,15 @@
|
||||||
"movhi r2, #16384 \n" /* Set the pointer to the IC. */ \
|
"movhi r2, #16384 \n" /* Set the pointer to the IC. */ \
|
||||||
"ldub r3, [r2] + 2 \n" /* Load the current interrupt mask. */ \
|
"ldub r3, [r2] + 2 \n" /* Load the current interrupt mask. */ \
|
||||||
"st r3, [r1]+ 64 \n" /* Store the interrupt mask on the stack. */ \
|
"st r3, [r1]+ 64 \n" /* Store the interrupt mask on the stack. */ \
|
||||||
"ld r2, [r0]+short(pxCurrentTCB) \n"/* Load the pointer to the TCB. */ \
|
"ld r2, [r0]+short(pxCurrentTCB) \n" /* Load the pointer to the TCB. */ \
|
||||||
"st r1, [r2] \n" /* Save the stack pointer into the TCB. */ \
|
"st r1, [r2] \n" /* Save the stack pointer into the TCB. */ \
|
||||||
"mov r14, r1 \n" /* Compiler expects r14 to be set to the function stack. */ \
|
"mov r14, r1 \n" /* Compiler expects r14 to be set to the function stack. */ \
|
||||||
);
|
);
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
asm __volatile__ ( \
|
asm __volatile__( \
|
||||||
"ld r2, [r0]+short(pxCurrentTCB) \n"/* Load the TCB to find the stack pointer and context. */\
|
"ld r2, [r0]+short(pxCurrentTCB) \n" /* Load the TCB to find the stack pointer and context. */ \
|
||||||
"ld r1, [r2] \n" \
|
"ld r1, [r2] \n" \
|
||||||
"movhi r2, #16384 \n" /* Set the pointer to the IC. */ \
|
"movhi r2, #16384 \n" /* Set the pointer to the IC. */ \
|
||||||
"ld r3, [r1] + 64 \n" /* Load the previous interrupt mask. */ \
|
"ld r3, [r1] + 64 \n" /* Load the previous interrupt mask. */ \
|
||||||
|
@ -141,12 +141,12 @@
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
@ -32,22 +32,20 @@
|
||||||
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
||||||
|
|
||||||
/* Supervisor mode set. */
|
/* Supervisor mode set. */
|
||||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000 )
|
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000)
|
||||||
|
|
||||||
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
||||||
* will be set to 0 prior to the first task being started. */
|
will be set to 0 prior to the first task being started. */
|
||||||
static uint32_t ulCriticalNesting = 0x9999UL;
|
static uint32_t ulCriticalNesting = 0x9999UL;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
TaskFunction_t pxCode,
|
|
||||||
void * pvParameters )
|
|
||||||
{
|
{
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = ( StackType_t ) 0xDEADBEEF;
|
*pxTopOfStack = (StackType_t) 0xDEADBEEF;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Exception stack frame starts with the return address. */
|
/* Exception stack frame starts with the return address. */
|
||||||
|
@ -66,7 +64,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void vPortStartFirstTask( void );
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
ulCriticalNesting = 0UL;
|
ulCriticalNesting = 0UL;
|
||||||
|
|
||||||
|
@ -91,20 +89,19 @@ void vPortEnterCritical( void )
|
||||||
if( ulCriticalNesting == 0UL )
|
if( ulCriticalNesting == 0UL )
|
||||||
{
|
{
|
||||||
/* Guard against context switches being pended simultaneously with a
|
/* Guard against context switches being pended simultaneously with a
|
||||||
* critical section being entered. */
|
critical section being entered. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( MCF_INTC0_INTFRCL == 0UL )
|
if( MCF_INTC0_INTFRCL == 0UL )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
} while( 1 );
|
} while( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -112,7 +109,6 @@ void vPortEnterCritical( void )
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
if( ulCriticalNesting == 0 )
|
if( ulCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
@ -122,7 +118,7 @@ void vPortExitCritical( void )
|
||||||
|
|
||||||
void vPortYieldHandler( void )
|
void vPortYieldHandler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulSavedInterruptMask;
|
uint32_t ulSavedInterruptMask;
|
||||||
|
|
||||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
/* Note this will clear all forced interrupts - this is done for speed. */
|
/* Note this will clear all forced interrupts - this is done for speed. */
|
||||||
|
@ -130,3 +126,9 @@ void vPortYieldHandler( void )
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -43,72 +43,72 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#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 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
uint32_t ulPortSetIPL( uint32_t );
|
uint32_t ulPortSetIPL( uint32_t );
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
||||||
|
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
||||||
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
#define portNOP() asm volatile ( "nop" )
|
#define portNOP() asm volatile ( "nop" )
|
||||||
|
|
||||||
/* Note this will overwrite all other bits in the force register, it is done this way for speed. */
|
/* Note this will overwrite all other bits in the force register, it is done this way for speed. */
|
||||||
#define portYIELD() MCF_INTC0_INTFRCL = ( 1UL << configYIELD_INTERRUPT_VECTOR ); portNOP(); portNOP()
|
#define portYIELD() MCF_INTC0_INTFRCL = ( 1UL << configYIELD_INTERRUPT_VECTOR ); portNOP(); portNOP()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 ) __attribute__( ( noreturn ) )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \
|
||||||
if( xSwitchRequired != pdFALSE ) \
|
|
||||||
{ \
|
{ \
|
||||||
portYIELD(); \
|
portYIELD(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the H8S port.
|
* Implementation of functions defined in portable.h for the H8S port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -56,29 +56,26 @@ static void prvSetupTimerInterrupt( void );
|
||||||
/*
|
/*
|
||||||
* The ISR used by portYIELD(). This is installed as a trap handler.
|
* The ISR used by portYIELD(). This is installed as a trap handler.
|
||||||
*/
|
*/
|
||||||
void vPortYield( void ) __attribute__( ( saveall, interrupt_handler ) );
|
void vPortYield( void ) __attribute__ ( ( saveall, interrupt_handler ) );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 )
|
|
||||||
{
|
{
|
||||||
uint32_t ulValue;
|
uint32_t ulValue;
|
||||||
|
|
||||||
/* This requires an even address. */
|
/* This requires an even address. */
|
||||||
ulValue = ( uint32_t ) pxTopOfStack;
|
ulValue = ( uint32_t ) pxTopOfStack;
|
||||||
|
|
||||||
if( ulValue & 1UL )
|
if( ulValue & 1UL )
|
||||||
{
|
{
|
||||||
pxTopOfStack = pxTopOfStack - 1;
|
pxTopOfStack = pxTopOfStack - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Place a few bytes of known values on the bottom of the stack.
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
* This is just useful for debugging. */
|
This is just useful for debugging. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0xaa;
|
*pxTopOfStack = 0xaa;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -89,7 +86,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
*pxTopOfStack = 0xdd;
|
*pxTopOfStack = 0xdd;
|
||||||
|
|
||||||
/* The initial stack mimics an interrupt stack. First there is the program
|
/* The initial stack mimics an interrupt stack. First there is the program
|
||||||
* counter (24 bits). */
|
counter (24 bits). */
|
||||||
ulValue = ( uint32_t ) pxCode;
|
ulValue = ( uint32_t ) pxCode;
|
||||||
|
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -106,8 +103,8 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
*pxTopOfStack = portINITIAL_CCR;
|
*pxTopOfStack = portINITIAL_CCR;
|
||||||
|
|
||||||
/* Next all the general purpose registers - with the parameters being passed
|
/* Next all the general purpose registers - with the parameters being passed
|
||||||
* in ER0. The parameter order must match that used by the compiler when the
|
in ER0. The parameter order must match that used by the compiler when the
|
||||||
* "saveall" function attribute is used. */
|
"saveall" function attribute is used. */
|
||||||
|
|
||||||
/* ER6 */
|
/* ER6 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -190,14 +187,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void * pxCurrentTCB;
|
extern void * pxCurrentTCB;
|
||||||
|
|
||||||
/* Setup the hardware to generate the tick. */
|
/* Setup the hardware to generate the tick. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Restore the context of the first task that is going to run. This
|
/* Restore the context of the first task that is going to run. This
|
||||||
* mirrors the function epilogue code generated by the compiler when the
|
mirrors the function epilogue code generated by the compiler when the
|
||||||
* "saveall" function attribute is used. */
|
"saveall" function attribute is used. */
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"MOV.L @_pxCurrentTCB, ER6 \n\t"
|
"MOV.L @_pxCurrentTCB, ER6 \n\t"
|
||||||
"MOV.L @ER6, ER7 \n\t"
|
"MOV.L @ER6, ER7 \n\t"
|
||||||
|
@ -237,14 +234,14 @@ void vPortYield( void )
|
||||||
* The interrupt handler installed for the RTOS tick depends on whether the
|
* The interrupt handler installed for the RTOS tick depends on whether the
|
||||||
* preemptive or cooperative scheduler is being used.
|
* preemptive or cooperative scheduler is being used.
|
||||||
*/
|
*/
|
||||||
#if ( configUSE_PREEMPTION == 1 )
|
#if( configUSE_PREEMPTION == 1 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The preemptive scheduler is used so the ISR calls vTaskSwitchContext().
|
* The preemptive scheduler is used so the ISR calls vTaskSwitchContext().
|
||||||
* The function prologue saves the context so all we have to do is save
|
* The function prologue saves the context so all we have to do is save
|
||||||
* the stack pointer.
|
* the stack pointer.
|
||||||
*/
|
*/
|
||||||
void vTickISR( void ) __attribute__( ( saveall, interrupt_handler ) );
|
void vTickISR( void ) __attribute__ ( ( saveall, interrupt_handler ) );
|
||||||
void vTickISR( void )
|
void vTickISR( void )
|
||||||
{
|
{
|
||||||
portSAVE_STACK_POINTER();
|
portSAVE_STACK_POINTER();
|
||||||
|
@ -260,14 +257,14 @@ void vPortYield( void )
|
||||||
portRESTORE_STACK_POINTER();
|
portRESTORE_STACK_POINTER();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The cooperative scheduler is being used so all we have to do is
|
* The cooperative scheduler is being used so all we have to do is
|
||||||
* periodically increment the tick. This can just be a normal ISR and
|
* periodically increment the tick. This can just be a normal ISR and
|
||||||
* the "saveall" attribute is not required.
|
* the "saveall" attribute is not required.
|
||||||
*/
|
*/
|
||||||
void vTickISR( void ) __attribute__( ( interrupt_handler ) );
|
void vTickISR( void ) __attribute__ ( ( interrupt_handler ) );
|
||||||
void vTickISR( void )
|
void vTickISR( void )
|
||||||
{
|
{
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
|
@ -276,7 +273,7 @@ void vPortYield( void )
|
||||||
TSR1 &= ~0x01;
|
TSR1 &= ~0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -284,7 +281,7 @@ void vPortYield( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
const uint32_t ulCompareMatch = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) / portCLOCK_DIV;
|
const uint32_t ulCompareMatch = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) / portCLOCK_DIV;
|
||||||
|
|
||||||
/* Turn the module on. */
|
/* Turn the module on. */
|
||||||
MSTPCR &= ~portMSTP13;
|
MSTPCR &= ~portMSTP13;
|
||||||
|
@ -296,8 +293,11 @@ static void prvSetupTimerInterrupt( void )
|
||||||
TGR1A = ulCompareMatch;
|
TGR1A = ulCompareMatch;
|
||||||
|
|
||||||
/* Start the timer and enable the interrupt - we can do this here as
|
/* Start the timer and enable the interrupt - we can do this here as
|
||||||
* interrupts are globally disabled when this function is called. */
|
interrupts are globally disabled when this function is called. */
|
||||||
TIER1 |= portTGRA_INTERRUPT_ENABLE;
|
TIER1 |= portTGRA_INTERRUPT_ENABLE;
|
||||||
TSTR |= portTIMER_CHANNEL;
|
TSTR |= portTIMER_CHANNEL;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,11 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -44,71 +44,70 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 uint8_t
|
#define portSTACK_TYPE uint8_t
|
||||||
#define portBASE_TYPE char
|
#define portBASE_TYPE char
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef signed char BaseType_t;
|
typedef signed char BaseType_t;
|
||||||
typedef unsigned char UBaseType_t;
|
typedef unsigned char UBaseType_t;
|
||||||
|
|
||||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 2
|
#define portBYTE_ALIGNMENT 2
|
||||||
#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 portYIELD() asm volatile ( "TRAPA #0" )
|
#define portYIELD() asm volatile( "TRAPA #0" )
|
||||||
#define portNOP() asm volatile ( "NOP" )
|
#define portNOP() asm volatile( "NOP" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
#define portENABLE_INTERRUPTS() asm volatile ( "ANDC #0x7F, CCR");
|
#define portENABLE_INTERRUPTS() asm volatile( "ANDC #0x7F, CCR" );
|
||||||
#define portDISABLE_INTERRUPTS() asm volatile ( "ORC #0x80, CCR" );
|
#define portDISABLE_INTERRUPTS() asm volatile( "ORC #0x80, CCR" );
|
||||||
|
|
||||||
/* Push the CCR then disable interrupts. */
|
/* Push the CCR then disable interrupts. */
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() asm volatile( "STC CCR, @-ER7" ); \
|
||||||
asm volatile ( "STC CCR, @-ER7" ); \
|
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
/* Pop the CCR to set the interrupt masking back to its previous state. */
|
/* Pop the CCR to set the interrupt masking back to its previous state. */
|
||||||
#define portEXIT_CRITICAL() asm volatile ( "LDC @ER7+, CCR" );
|
#define portEXIT_CRITICAL() asm volatile( "LDC @ER7+, CCR" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
/* Context switch macros. These macros are very simple as the context
|
/* Context switch macros. These macros are very simple as the context
|
||||||
* is saved simply by selecting the saveall attribute of the context switch
|
is saved simply by selecting the saveall attribute of the context switch
|
||||||
* interrupt service routines. These macros save and restore the stack
|
interrupt service routines. These macros save and restore the stack
|
||||||
* pointer to the TCB. */
|
pointer to the TCB. */
|
||||||
|
|
||||||
#define portSAVE_STACK_POINTER() \
|
#define portSAVE_STACK_POINTER() \
|
||||||
extern void * pxCurrentTCB; \
|
extern void* pxCurrentTCB; \
|
||||||
\
|
\
|
||||||
asm volatile ( \
|
asm volatile( \
|
||||||
"MOV.L @_pxCurrentTCB, ER5 \n\t"\
|
"MOV.L @_pxCurrentTCB, ER5 \n\t" \
|
||||||
"MOV.L ER7, @ER5 \n\t"\
|
"MOV.L ER7, @ER5 \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) pxCurrentTCB;
|
( void ) pxCurrentTCB;
|
||||||
|
|
||||||
|
|
||||||
#define portRESTORE_STACK_POINTER() \
|
#define portRESTORE_STACK_POINTER() \
|
||||||
extern void * pxCurrentTCB; \
|
extern void* pxCurrentTCB; \
|
||||||
\
|
\
|
||||||
asm volatile ( \
|
asm volatile( \
|
||||||
"MOV.L @_pxCurrentTCB, ER5 \n\t"\
|
"MOV.L @_pxCurrentTCB, ER5 \n\t" \
|
||||||
"MOV.L @ER5, ER7 \n\t"\
|
"MOV.L @ER5, ER7 \n\t" \
|
||||||
); \
|
); \
|
||||||
( void ) pxCurrentTCB;
|
( void ) pxCurrentTCB;
|
||||||
|
|
||||||
|
@ -116,23 +115,24 @@
|
||||||
|
|
||||||
/* Macros to allow a context switch from within an application ISR. */
|
/* Macros to allow a context switch from within an application ISR. */
|
||||||
|
|
||||||
#define portENTER_SWITCHING_ISR() portSAVE_STACK_POINTER(); {
|
#define portENTER_SWITCHING_ISR() portSAVE_STACK_POINTER(); {
|
||||||
#define portEXIT_SWITCHING_ISR( x ) \
|
|
||||||
|
#define portEXIT_SWITCHING_ISR( x ) \
|
||||||
if( x ) \
|
if( x ) \
|
||||||
{ \
|
{ \
|
||||||
extern void vTaskSwitchContext( void ); \
|
extern void vTaskSwitchContext( void ); \
|
||||||
vTaskSwitchContext(); \
|
vTaskSwitchContext(); \
|
||||||
} \
|
} \
|
||||||
} \
|
} portRESTORE_STACK_POINTER();
|
||||||
portRESTORE_STACK_POINTER();
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@
|
||||||
#include <sys/ports_def.h>
|
#include <sys/ports_def.h>
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the HCS12 port.
|
* Implementation of functions defined in portable.h for the HCS12 port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -46,45 +46,45 @@
|
||||||
static void prvSetupTimerInterrupt( void );
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/* NOTE: Interrupt service routines must be in non-banked memory - as does the
|
/* NOTE: Interrupt service routines must be in non-banked memory - as does the
|
||||||
* scheduler startup function. */
|
scheduler startup function. */
|
||||||
#define ATTR_NEAR __attribute__( ( near ) )
|
#define ATTR_NEAR __attribute__((near))
|
||||||
|
|
||||||
/* Manual context switch function. This is the SWI ISR. */
|
/* Manual context switch function. This is the SWI ISR. */
|
||||||
/* __attribute__((interrupt)) */
|
// __attribute__((interrupt))
|
||||||
void ATTR_NEAR vPortYield( void );
|
void ATTR_NEAR vPortYield( void );
|
||||||
|
|
||||||
/* Tick context switch function. This is the timer ISR. */
|
/* Tick context switch function. This is the timer ISR. */
|
||||||
/* __attribute__((interrupt)) */
|
// __attribute__((interrupt))
|
||||||
void ATTR_NEAR vPortTickInterrupt( void );
|
void ATTR_NEAR vPortTickInterrupt( void );
|
||||||
|
|
||||||
/* Function in non-banked memory which actually switches to first task. */
|
/* Function in non-banked memory which actually switches to first task. */
|
||||||
BaseType_t ATTR_NEAR xStartSchedulerNear( void );
|
BaseType_t ATTR_NEAR xStartSchedulerNear( void );
|
||||||
|
|
||||||
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
|
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
|
||||||
* critical section should not be left (i.e. interrupts should not be re-enabled)
|
critical section should not be left (i.e. interrupts should not be re-enabled)
|
||||||
* until the nesting depth reaches 0. This variable simply tracks the nesting
|
until the nesting depth reaches 0. This variable simply tracks the nesting
|
||||||
* depth. Each task maintains it's own critical nesting depth variable so
|
depth. Each task maintains it's own critical nesting depth variable so
|
||||||
* uxCriticalNesting is saved and restored from the task stack during a context
|
uxCriticalNesting is saved and restored from the task stack during a context
|
||||||
* switch. */
|
switch. */
|
||||||
volatile UBaseType_t uxCriticalNesting = 0x80; /* un-initialized */
|
volatile UBaseType_t uxCriticalNesting = 0x80; // un-initialized
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 )
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
* expected by the portRESTORE_CONTEXT() macro. In this case the stack as
|
expected by the portRESTORE_CONTEXT() macro. In this case the stack as
|
||||||
* expected by the HCS12 RTI instruction. */
|
expected by the HCS12 RTI instruction. */
|
||||||
|
|
||||||
|
|
||||||
/* The address of the task function is placed in the stack byte at a time. */
|
/* The address of the task function is placed in the stack byte at a time. */
|
||||||
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pxCode ) ) + 1 );
|
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pxCode) ) + 1 );
|
||||||
*--pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pxCode ) ) + 0 );
|
*--pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pxCode) ) + 0 );
|
||||||
|
|
||||||
/* Next are all the registers that form part of the task context. */
|
/* Next are all the registers that form part of the task context. */
|
||||||
|
|
||||||
|
@ -97,32 +97,32 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
*--pxTopOfStack = ( StackType_t ) 0xcc;
|
*--pxTopOfStack = ( StackType_t ) 0xcc;
|
||||||
|
|
||||||
/* A register contains parameter high byte. */
|
/* A register contains parameter high byte. */
|
||||||
*--pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pvParameters ) ) + 0 );
|
*--pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pvParameters) ) + 0 );
|
||||||
|
|
||||||
/* B register contains parameter low byte. */
|
/* B register contains parameter low byte. */
|
||||||
*--pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pvParameters ) ) + 1 );
|
*--pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pvParameters) ) + 1 );
|
||||||
|
|
||||||
/* CCR: Note that when the task starts interrupts will be enabled since
|
/* CCR: Note that when the task starts interrupts will be enabled since
|
||||||
* "I" bit of CCR is cleared */
|
"I" bit of CCR is cleared */
|
||||||
*--pxTopOfStack = ( StackType_t ) 0x80; /* keeps Stop disabled (MCU default) */
|
*--pxTopOfStack = ( StackType_t ) 0x80; // keeps Stop disabled (MCU default)
|
||||||
|
|
||||||
/* tmp softregs used by GCC. Values right now don't matter. */
|
/* tmp softregs used by GCC. Values right now don't matter. */
|
||||||
__asm( "\n\
|
__asm("\n\
|
||||||
movw _.frame, 2,-%0 \n\
|
movw _.frame, 2,-%0 \n\
|
||||||
movw _.tmp, 2,-%0 \n\
|
movw _.tmp, 2,-%0 \n\
|
||||||
movw _.z, 2,-%0 \n\
|
movw _.z, 2,-%0 \n\
|
||||||
movw _.xy, 2,-%0 \n\
|
movw _.xy, 2,-%0 \n\
|
||||||
;movw _.d2, 2,-%0 \n\
|
;movw _.d2, 2,-%0 \n\
|
||||||
;movw _.d1, 2,-%0 \n\
|
;movw _.d1, 2,-%0 \n\
|
||||||
" : "=A" ( pxTopOfStack ) : "0" ( pxTopOfStack ) );
|
": "=A"(pxTopOfStack) : "0"(pxTopOfStack) );
|
||||||
|
|
||||||
#ifdef BANKED_MODEL
|
#ifdef BANKED_MODEL
|
||||||
/* The page of the task. */
|
/* The page of the task. */
|
||||||
*--pxTopOfStack = 0x30; /* can only directly start in PPAGE 0x30 */
|
*--pxTopOfStack = 0x30; // can only directly start in PPAGE 0x30
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The critical nesting depth is initialised with 0 (meaning not in
|
/* The critical nesting depth is initialised with 0 (meaning not in
|
||||||
* a critical section). */
|
a critical section). */
|
||||||
*--pxTopOfStack = ( StackType_t ) 0x00;
|
*--pxTopOfStack = ( StackType_t ) 0x00;
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,22 +140,21 @@ static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
/* Enable hardware RTI timer */
|
/* Enable hardware RTI timer */
|
||||||
/* Ignores configTICK_RATE_HZ */
|
/* Ignores configTICK_RATE_HZ */
|
||||||
RTICTL = 0x50; /* 16 MHz xtal: 976.56 Hz, 1024mS */
|
RTICTL = 0x50; // 16 MHz xtal: 976.56 Hz, 1024mS
|
||||||
CRGINT |= 0x80; /* RTIE */
|
CRGINT |= 0x80; // RTIE
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* xPortStartScheduler() does not start the scheduler directly because
|
/* xPortStartScheduler() does not start the scheduler directly because
|
||||||
* the header file containing the xPortStartScheduler() prototype is part
|
the header file containing the xPortStartScheduler() prototype is part
|
||||||
* of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
||||||
* Instead it simply calls the locally defined xNearStartScheduler() -
|
Instead it simply calls the locally defined xNearStartScheduler() -
|
||||||
* which does use the CODE_SEG pragma. */
|
which does use the CODE_SEG pragma. */
|
||||||
|
|
||||||
int16_t register d;
|
int16_t register d;
|
||||||
|
__asm ("jmp xStartSchedulerNear ; will never return": "=d"(d));
|
||||||
__asm( "jmp xStartSchedulerNear ; will never return": "=d" ( d ) );
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -163,7 +162,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
BaseType_t xStartSchedulerNear( void )
|
BaseType_t xStartSchedulerNear( void )
|
||||||
{
|
{
|
||||||
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
||||||
* disabled when this function is called. */
|
disabled when this function is called. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Restore the context of the first task. */
|
/* Restore the context of the first task. */
|
||||||
|
@ -187,10 +186,9 @@ BaseType_t xStartSchedulerNear( void )
|
||||||
void vPortYield( void )
|
void vPortYield( void )
|
||||||
{
|
{
|
||||||
portISR_HEAD();
|
portISR_HEAD();
|
||||||
|
|
||||||
/* NOTE: This is the trap routine (swi) although not defined as a trap.
|
/* NOTE: This is the trap routine (swi) although not defined as a trap.
|
||||||
* It will fill the stack the same way as an ISR in order to mix preemtion
|
It will fill the stack the same way as an ISR in order to mix preemtion
|
||||||
* and cooperative yield. */
|
and cooperative yield. */
|
||||||
|
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
|
@ -225,14 +223,15 @@ void vPortTickInterrupt( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the context of a task - which may be a different task
|
/* Restore the context of a task - which may be a different task
|
||||||
* to that interrupted. */
|
to that interrupted. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
#else /* if configUSE_PREEMPTION == 1 */
|
#else
|
||||||
{
|
{
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
}
|
}
|
||||||
#endif /* if configUSE_PREEMPTION == 1 */
|
#endif
|
||||||
|
|
||||||
portISR_TAIL();
|
portISR_TAIL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,11 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -44,38 +44,38 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 uint8_t
|
#define portSTACK_TYPE uint8_t
|
||||||
#define portBASE_TYPE char
|
#define portBASE_TYPE char
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef signed char BaseType_t;
|
typedef signed char BaseType_t;
|
||||||
typedef unsigned char UBaseType_t;
|
typedef unsigned char UBaseType_t;
|
||||||
|
|
||||||
|
|
||||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 1
|
#define portBYTE_ALIGNMENT 1
|
||||||
#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 portYIELD() __asm( "swi" );
|
#define portYIELD() __asm( "swi" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
#define portENABLE_INTERRUPTS() __asm( "cli" )
|
#define portENABLE_INTERRUPTS() __asm( "cli" )
|
||||||
#define portDISABLE_INTERRUPTS() __asm( "sei" )
|
#define portDISABLE_INTERRUPTS() __asm( "sei" )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable interrupts before incrementing the count of critical section nesting.
|
* Disable interrupts before incrementing the count of critical section nesting.
|
||||||
|
@ -83,21 +83,21 @@
|
||||||
* re-enabled. Once interrupts are disabled the nesting count can be accessed
|
* re-enabled. Once interrupts are disabled the nesting count can be accessed
|
||||||
* directly. Each task maintains its own nesting count.
|
* directly. Each task maintains its own nesting count.
|
||||||
*/
|
*/
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
\
|
\
|
||||||
portDISABLE_INTERRUPTS(); \
|
portDISABLE_INTERRUPTS(); \
|
||||||
uxCriticalNesting++; \
|
uxCriticalNesting++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interrupts are disabled so we can access the nesting count directly. If the
|
* Interrupts are disabled so we can access the nesting count directly. If the
|
||||||
* nesting is found to be 0 (no nesting) then we are leaving the critical
|
* nesting is found to be 0 (no nesting) then we are leaving the critical
|
||||||
* section and interrupts can be re-enabled.
|
* section and interrupts can be re-enabled.
|
||||||
*/
|
*/
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
\
|
\
|
||||||
uxCriticalNesting--; \
|
uxCriticalNesting--; \
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
{ \
|
{ \
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
@ -120,9 +120,8 @@
|
||||||
* register is also stored as part of the tasks context.
|
* register is also stored as part of the tasks context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef BANKED_MODEL
|
#ifdef BANKED_MODEL
|
||||||
|
/*
|
||||||
/*
|
|
||||||
* Load the stack pointer for the task, then pull the critical nesting
|
* Load the stack pointer for the task, then pull the critical nesting
|
||||||
* count and PPAGE register from the stack. The remains of the
|
* count and PPAGE register from the stack. The remains of the
|
||||||
* context are restored by the RTI instruction.
|
* context are restored by the RTI instruction.
|
||||||
|
@ -141,7 +140,7 @@
|
||||||
" ); \
|
" ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* By the time this macro is called the processor has already stacked the
|
* By the time this macro is called the processor has already stacked the
|
||||||
* registers. Simply stack the nesting count and PPAGE value, then save
|
* registers. Simply stack the nesting count and PPAGE value, then save
|
||||||
* the task stack pointer.
|
* the task stack pointer.
|
||||||
|
@ -159,9 +158,9 @@
|
||||||
sts 0,x ; Stack \n\
|
sts 0,x ; Stack \n\
|
||||||
" ); \
|
" ); \
|
||||||
}
|
}
|
||||||
#else /* ifdef BANKED_MODEL */
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These macros are as per the BANKED versions above, but without saving
|
* These macros are as per the BANKED versions above, but without saving
|
||||||
* and restoring the PPAGE register.
|
* and restoring the PPAGE register.
|
||||||
*/
|
*/
|
||||||
|
@ -191,27 +190,27 @@
|
||||||
sts 0,x ; Stack \n\
|
sts 0,x ; Stack \n\
|
||||||
" ); \
|
" ); \
|
||||||
}
|
}
|
||||||
#endif /* ifdef BANKED_MODEL */
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility macros to save/restore correct software registers for GCC. This is
|
* Utility macros to save/restore correct software registers for GCC. This is
|
||||||
* useful when GCC does not generate appropriate ISR head/tail code.
|
* useful when GCC does not generate appropriate ISR head/tail code.
|
||||||
*/
|
*/
|
||||||
#define portISR_HEAD() \
|
#define portISR_HEAD() \
|
||||||
{ \
|
{ \
|
||||||
__asm( " \n\
|
__asm(" \n\
|
||||||
movw _.frame, 2,-sp \n\
|
movw _.frame, 2,-sp \n\
|
||||||
movw _.tmp, 2,-sp \n\
|
movw _.tmp, 2,-sp \n\
|
||||||
movw _.z, 2,-sp \n\
|
movw _.z, 2,-sp \n\
|
||||||
movw _.xy, 2,-sp \n\
|
movw _.xy, 2,-sp \n\
|
||||||
;movw _.d2, 2,-sp \n\
|
;movw _.d2, 2,-sp \n\
|
||||||
;movw _.d1, 2,-sp \n\
|
;movw _.d1, 2,-sp \n\
|
||||||
" ); \
|
"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portISR_TAIL() \
|
#define portISR_TAIL() \
|
||||||
{ \
|
{ \
|
||||||
__asm( " \n\
|
__asm(" \n\
|
||||||
movw 2,sp+, _.xy \n\
|
movw 2,sp+, _.xy \n\
|
||||||
movw 2,sp+, _.z \n\
|
movw 2,sp+, _.z \n\
|
||||||
movw 2,sp+, _.tmp \n\
|
movw 2,sp+, _.tmp \n\
|
||||||
|
@ -219,8 +218,8 @@
|
||||||
;movw 2,sp+, _.d1 \n\
|
;movw 2,sp+, _.d1 \n\
|
||||||
;movw 2,sp+, _.d2 \n\
|
;movw 2,sp+, _.d2 \n\
|
||||||
rti \n\
|
rti \n\
|
||||||
" ); \
|
"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility macro to call macros above in correct order in order to perform a
|
* Utility macro to call macros above in correct order in order to perform a
|
||||||
|
@ -229,18 +228,19 @@
|
||||||
* variables portYIELD() should be used in it's place.
|
* variables portYIELD() should be used in it's place.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portTASK_SWITCH_FROM_ISR() \
|
#define portTASK_SWITCH_FROM_ISR() \
|
||||||
portSAVE_CONTEXT(); \
|
portSAVE_CONTEXT(); \
|
||||||
vTaskSwitchContext(); \
|
vTaskSwitchContext(); \
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
|
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -25,102 +25,103 @@
|
||||||
* 1 tab == 4 spaces!
|
* 1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.extern ulTopOfSystemStack
|
.extern ulTopOfSystemStack
|
||||||
.extern ulInterruptNesting
|
.extern ulInterruptNesting
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
.macro portFREERTOS_INTERRUPT_ENTRY
|
.macro portFREERTOS_INTERRUPT_ENTRY
|
||||||
|
|
||||||
/* Save general purpose registers. */
|
/* Save general purpose registers. */
|
||||||
pusha
|
pusha
|
||||||
|
|
||||||
/* If ulInterruptNesting is zero the rest of the task context will need
|
/* If ulInterruptNesting is zero the rest of the task context will need
|
||||||
* saving and a stack switch might be required. */
|
saving and a stack switch might be required. */
|
||||||
movl ulInterruptNesting, % eax
|
movl ulInterruptNesting, %eax
|
||||||
test % eax, % eax
|
test %eax, %eax
|
||||||
jne 2f
|
jne 2f
|
||||||
|
|
||||||
/* Interrupts are not nested, so save the rest of the task context. */
|
/* Interrupts are not nested, so save the rest of the task context. */
|
||||||
.if configSUPPORT_FPU == 1
|
.if configSUPPORT_FPU == 1
|
||||||
|
|
||||||
/* If the task has a buffer allocated to save the FPU context then
|
/* If the task has a buffer allocated to save the FPU context then
|
||||||
* save the FPU context now. */
|
save the FPU context now. */
|
||||||
movl pucPortTaskFPUContextBuffer, % eax
|
movl pucPortTaskFPUContextBuffer, %eax
|
||||||
test % eax, % eax
|
test %eax, %eax
|
||||||
je 1f
|
je 1f
|
||||||
fnsave( % eax ) /* Save FLOP context into ucTempFPUBuffer array. */
|
fnsave ( %eax ) /* Save FLOP context into ucTempFPUBuffer array. */
|
||||||
fwait
|
fwait
|
||||||
|
|
||||||
1 :
|
1:
|
||||||
/* Save the address of the FPU context, if any. */
|
/* Save the address of the FPU context, if any. */
|
||||||
push pucPortTaskFPUContextBuffer
|
push pucPortTaskFPUContextBuffer
|
||||||
|
|
||||||
.endif /* configSUPPORT_FPU */
|
.endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
/* Find the TCB. */
|
/* Find the TCB. */
|
||||||
movl pxCurrentTCB, % eax
|
movl pxCurrentTCB, %eax
|
||||||
|
|
||||||
/* Stack location is first item in the TCB. */
|
/* Stack location is first item in the TCB. */
|
||||||
movl % esp, ( % eax )
|
movl %esp, (%eax)
|
||||||
|
|
||||||
/* Switch stacks. */
|
/* Switch stacks. */
|
||||||
movl ulTopOfSystemStack, % esp
|
movl ulTopOfSystemStack, %esp
|
||||||
movl % esp, % ebp
|
movl %esp, %ebp
|
||||||
|
|
||||||
2 :
|
2:
|
||||||
/* Increment nesting count. */
|
/* Increment nesting count. */
|
||||||
add $1, ulInterruptNesting
|
add $1, ulInterruptNesting
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
.macro portINTERRUPT_EPILOGUE
|
.macro portINTERRUPT_EPILOGUE
|
||||||
|
|
||||||
cli
|
cli
|
||||||
sub $1, ulInterruptNesting
|
sub $1, ulInterruptNesting
|
||||||
|
|
||||||
/* If the nesting has unwound to zero. */
|
/* If the nesting has unwound to zero. */
|
||||||
movl ulInterruptNesting, % eax
|
movl ulInterruptNesting, %eax
|
||||||
test % eax, % eax
|
test %eax, %eax
|
||||||
jne 2f
|
jne 2f
|
||||||
|
|
||||||
/* If a yield was requested then select a new TCB now. */
|
/* If a yield was requested then select a new TCB now. */
|
||||||
movl ulPortYieldPending, % eax
|
movl ulPortYieldPending, %eax
|
||||||
test % eax, % eax
|
test %eax, %eax
|
||||||
je 1f
|
je 1f
|
||||||
movl $0, ulPortYieldPending
|
movl $0, ulPortYieldPending
|
||||||
call vTaskSwitchContext
|
call vTaskSwitchContext
|
||||||
|
|
||||||
1 :
|
1:
|
||||||
/* Stack location is first item in the TCB. */
|
/* Stack location is first item in the TCB. */
|
||||||
movl pxCurrentTCB, % eax movl( % eax ), % esp
|
movl pxCurrentTCB, %eax
|
||||||
|
movl (%eax), %esp
|
||||||
|
|
||||||
.if configSUPPORT_FPU == 1
|
.if configSUPPORT_FPU == 1
|
||||||
|
|
||||||
/* Restore address of task's FPU context buffer. */
|
/* Restore address of task's FPU context buffer. */
|
||||||
pop pucPortTaskFPUContextBuffer
|
pop pucPortTaskFPUContextBuffer
|
||||||
|
|
||||||
/* If the task has a buffer allocated in which its FPU context is saved,
|
/* If the task has a buffer allocated in which its FPU context is saved,
|
||||||
* then restore it now. */
|
then restore it now. */
|
||||||
movl pucPortTaskFPUContextBuffer, % eax
|
movl pucPortTaskFPUContextBuffer, %eax
|
||||||
test % eax, % eax
|
test %eax, %eax
|
||||||
je 1f
|
je 1f
|
||||||
frstor( % eax )
|
frstor ( %eax )
|
||||||
1 :
|
1:
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
2 :
|
2:
|
||||||
popa
|
popa
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
.macro portFREERTOS_INTERRUPT_EXIT
|
.macro portFREERTOS_INTERRUPT_EXIT
|
||||||
|
|
||||||
portINTERRUPT_EPILOGUE
|
portINTERRUPT_EPILOGUE
|
||||||
/* EOI. */
|
/* EOI. */
|
||||||
movl $0x00, ( 0xFEE000B0 )
|
movl $0x00, (0xFEE000B0)
|
||||||
iret
|
iret
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
|
@ -34,32 +34,32 @@
|
||||||
|
|
||||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if ( configMAX_PRIORITIES > 32 )
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
#if ( configISR_STACK_SIZE < ( configMINIMAL_STACK_SIZE * 2 ) )
|
#if( configISR_STACK_SIZE < ( configMINIMAL_STACK_SIZE * 2 ) )
|
||||||
#warning configISR_STACK_SIZE is probably too small!
|
#warning configISR_STACK_SIZE is probably too small!
|
||||||
#endif /* ( configISR_STACK_SIZE < configMINIMAL_STACK_SIZE * 2 ) */
|
#endif /* ( configISR_STACK_SIZE < configMINIMAL_STACK_SIZE * 2 ) */
|
||||||
|
|
||||||
#if ( ( configMAX_API_CALL_INTERRUPT_PRIORITY > portMAX_PRIORITY ) || ( configMAX_API_CALL_INTERRUPT_PRIORITY < 2 ) )
|
#if( ( configMAX_API_CALL_INTERRUPT_PRIORITY > portMAX_PRIORITY ) || ( configMAX_API_CALL_INTERRUPT_PRIORITY < 2 ) )
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be between 2 and 15
|
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be between 2 and 15
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( ( configSUPPORT_FPU == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) )
|
#if( ( configSUPPORT_FPU == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) )
|
||||||
#error configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 to use this port with an FPU
|
#error configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 to use this port with an FPU
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* A critical section is exited when the critical section nesting count reaches
|
/* A critical section is exited when the critical section nesting count reaches
|
||||||
* this value. */
|
this value. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||||
|
|
||||||
/* Tasks are not created with a floating point context, but can be given a
|
/* Tasks are not created with a floating point context, but can be given a
|
||||||
* floating point context after they have been created. A variable is stored as
|
floating point context after they have been created. A variable is stored as
|
||||||
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||||
* does not have an FPU context, or any other value if the task does have an FPU
|
does not have an FPU context, or any other value if the task does have an FPU
|
||||||
* context. */
|
context. */
|
||||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Only the IF bit is set so tasks start with interrupts enabled. */
|
/* Only the IF bit is set so tasks start with interrupts enabled. */
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
#define portFPU_CONTEXT_SIZE_BYTES 108
|
#define portFPU_CONTEXT_SIZE_BYTES 108
|
||||||
|
|
||||||
/* The expected size of each entry in the IDT. Used to check structure packing
|
/* The expected size of each entry in the IDT. Used to check structure packing
|
||||||
* is set correctly. */
|
is set correctly. */
|
||||||
#define portEXPECTED_IDT_ENTRY_SIZE 8
|
#define portEXPECTED_IDT_ENTRY_SIZE 8
|
||||||
|
|
||||||
/* Default flags setting for entries in the IDT. */
|
/* Default flags setting for entries in the IDT. */
|
||||||
|
@ -86,7 +86,7 @@
|
||||||
#define portAPIC_MIN_ALLOWABLE_VECTOR ( 0x20 )
|
#define portAPIC_MIN_ALLOWABLE_VECTOR ( 0x20 )
|
||||||
|
|
||||||
/* If configASSERT() is defined then the system stack is filled with this value
|
/* If configASSERT() is defined then the system stack is filled with this value
|
||||||
* to allow for a crude stack overflow check. */
|
to allow for a crude stack overflow check. */
|
||||||
#define portSTACK_WORD ( 0xecececec )
|
#define portSTACK_WORD ( 0xecececec )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -103,9 +103,7 @@ static void prvTaskExitError( void );
|
||||||
/*
|
/*
|
||||||
* Complete one descriptor in the IDT.
|
* Complete one descriptor in the IDT.
|
||||||
*/
|
*/
|
||||||
static void prvSetInterruptGate( uint8_t ucNumber,
|
static void prvSetInterruptGate( uint8_t ucNumber, ISR_Handler_t pxHandlerFunction, uint8_t ucFlags );
|
||||||
ISR_Handler_t pxHandlerFunction,
|
|
||||||
uint8_t ucFlags );
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The default handler installed in each IDT position.
|
* The default handler installed in each IDT position.
|
||||||
|
@ -136,13 +134,13 @@ static BaseType_t prvCheckValidityOfVectorNumber( uint32_t ulVectorNumber );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* A variable is used to keep track of the critical section nesting. This
|
/* A variable is used to keep track of the critical section nesting. This
|
||||||
* variable must be initialised to a non zero value to ensure interrupts don't
|
variable must be initialised to a non zero value to ensure interrupts don't
|
||||||
* inadvertently become unmasked before the scheduler starts. It is set to zero
|
inadvertently become unmasked before the scheduler starts. It is set to zero
|
||||||
* before the first task starts executing. */
|
before the first task starts executing. */
|
||||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
/* A structure used to map the various fields of an IDT entry into separate
|
/* A structure used to map the various fields of an IDT entry into separate
|
||||||
* structure members. */
|
structure members. */
|
||||||
struct IDTEntry
|
struct IDTEntry
|
||||||
{
|
{
|
||||||
uint16_t usISRLow; /* Low 16 bits of handler address. */
|
uint16_t usISRLow; /* Low 16 bits of handler address. */
|
||||||
|
@ -150,8 +148,7 @@ struct IDTEntry
|
||||||
uint8_t ucZero; /* Must be set to zero. */
|
uint8_t ucZero; /* Must be set to zero. */
|
||||||
uint8_t ucFlags; /* Flags for this entry. */
|
uint8_t ucFlags; /* Flags for this entry. */
|
||||||
uint16_t usISRHigh; /* High 16 bits of handler address. */
|
uint16_t usISRHigh; /* High 16 bits of handler address. */
|
||||||
}
|
} __attribute__( ( packed ) );
|
||||||
__attribute__( ( packed ) );
|
|
||||||
typedef struct IDTEntry IDTEntry_t;
|
typedef struct IDTEntry IDTEntry_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,58 +157,55 @@ struct IDTPointer
|
||||||
{
|
{
|
||||||
uint16_t usTableLimit;
|
uint16_t usTableLimit;
|
||||||
uint32_t ulTableBase; /* The address of the first entry in xInterruptDescriptorTable. */
|
uint32_t ulTableBase; /* The address of the first entry in xInterruptDescriptorTable. */
|
||||||
}
|
} __attribute__( ( __packed__ ) );
|
||||||
__attribute__( ( __packed__ ) );
|
|
||||||
typedef struct IDTPointer IDTPointer_t;
|
typedef struct IDTPointer IDTPointer_t;
|
||||||
|
|
||||||
/* The IDT itself. */
|
/* The IDT itself. */
|
||||||
static __attribute__( ( aligned( 32 ) ) ) IDTEntry_t xInterruptDescriptorTable[ portNUM_VECTORS ];
|
static __attribute__ ( ( aligned( 32 ) ) ) IDTEntry_t xInterruptDescriptorTable[ portNUM_VECTORS ];
|
||||||
|
|
||||||
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
||||||
|
|
||||||
/* A table in which application defined interrupt handlers are stored. These
|
/* A table in which application defined interrupt handlers are stored. These
|
||||||
* are called by the central interrupt handler if a common interrupt entry
|
are called by the central interrupt handler if a common interrupt entry
|
||||||
* point it used. */
|
point it used. */
|
||||||
static ISR_Handler_t xInterruptHandlerTable[ portNUM_VECTORS ] = { NULL };
|
static ISR_Handler_t xInterruptHandlerTable[ portNUM_VECTORS ] = { NULL };
|
||||||
|
|
||||||
#endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
#endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
||||||
|
|
||||||
#if ( configSUPPORT_FPU == 1 )
|
#if ( configSUPPORT_FPU == 1 )
|
||||||
|
|
||||||
/* Saved as part of the task context. If pucPortTaskFPUContextBuffer is NULL
|
/* Saved as part of the task context. If pucPortTaskFPUContextBuffer is NULL
|
||||||
* then the task does not have an FPU context. If pucPortTaskFPUContextBuffer is
|
then the task does not have an FPU context. If pucPortTaskFPUContextBuffer is
|
||||||
* not NULL then it points to a buffer into which the FPU context can be saved. */
|
not NULL then it points to a buffer into which the FPU context can be saved. */
|
||||||
uint8_t * pucPortTaskFPUContextBuffer __attribute__( ( used ) ) = pdFALSE;
|
uint8_t *pucPortTaskFPUContextBuffer __attribute__((used)) = pdFALSE;
|
||||||
|
|
||||||
#endif /* configSUPPORT_FPU */
|
#endif /* configSUPPORT_FPU */
|
||||||
|
|
||||||
/* The stack used by interrupt handlers. */
|
/* The stack used by interrupt handlers. */
|
||||||
static uint32_t ulSystemStack[ configISR_STACK_SIZE ] __attribute__( ( used ) ) = { 0 };
|
static uint32_t ulSystemStack[ configISR_STACK_SIZE ] __attribute__((used)) = { 0 };
|
||||||
|
|
||||||
/* Don't use the very top of the system stack so the return address
|
/* Don't use the very top of the system stack so the return address
|
||||||
* appears as 0 if the debugger tries to unwind the stack. */
|
appears as 0 if the debugger tries to unwind the stack. */
|
||||||
volatile uint32_t ulTopOfSystemStack __attribute__( ( used ) ) = ( uint32_t ) &( ulSystemStack[ configISR_STACK_SIZE - 5 ] );
|
volatile uint32_t ulTopOfSystemStack __attribute__((used)) = ( uint32_t ) &( ulSystemStack[ configISR_STACK_SIZE - 5 ] );
|
||||||
|
|
||||||
/* If a yield is requested from an interrupt or from a critical section then
|
/* If a yield is requested from an interrupt or from a critical section then
|
||||||
* the yield is not performed immediately, and ulPortYieldPending is set to pdTRUE
|
the yield is not performed immediately, and ulPortYieldPending is set to pdTRUE
|
||||||
* instead to indicate the yield should be performed at the end of the interrupt
|
instead to indicate the yield should be performed at the end of the interrupt
|
||||||
* when the critical section is exited. */
|
when the critical section is exited. */
|
||||||
volatile uint32_t ulPortYieldPending __attribute__( ( used ) ) = pdFALSE;
|
volatile uint32_t ulPortYieldPending __attribute__((used)) = pdFALSE;
|
||||||
|
|
||||||
/* Counts the interrupt nesting depth. Used to know when to switch to the
|
/* Counts the interrupt nesting depth. Used to know when to switch to the
|
||||||
* interrupt/system stack and when to save/restore a complete context. */
|
interrupt/system stack and when to save/restore a complete context. */
|
||||||
volatile uint32_t ulInterruptNesting __attribute__( ( used ) ) = 0;
|
volatile uint32_t ulInterruptNesting __attribute__((used)) = 0;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 )
|
|
||||||
{
|
{
|
||||||
uint32_t ulCodeSegment;
|
uint32_t ulCodeSegment;
|
||||||
|
|
||||||
/* Setup the initial stack as expected by the portFREERTOS_INTERRUPT_EXIT macro. */
|
/* Setup the initial stack as expected by the portFREERTOS_INTERRUPT_EXIT macro. */
|
||||||
|
|
||||||
|
@ -225,7 +219,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* There is nothing to return to so assert if attempting to use the return
|
/* There is nothing to return to so assert if attempting to use the return
|
||||||
* address. */
|
address. */
|
||||||
*pxTopOfStack = ( StackType_t ) prvTaskExitError;
|
*pxTopOfStack = ( StackType_t ) prvTaskExitError;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
@ -234,7 +228,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* CS */
|
/* CS */
|
||||||
__asm volatile ( "movl %%cs, %0" : "=r" ( ulCodeSegment ) );
|
__asm volatile( "movl %%cs, %0" : "=r" ( ulCodeSegment ) );
|
||||||
*pxTopOfStack = ulCodeSegment;
|
*pxTopOfStack = ulCodeSegment;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
@ -271,7 +265,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Buffer for FPU context, which is initialised to NULL as tasks are not
|
/* Buffer for FPU context, which is initialised to NULL as tasks are not
|
||||||
* created with an FPU context. */
|
created with an FPU context. */
|
||||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||||
}
|
}
|
||||||
#endif /* configSUPPORT_FPU */
|
#endif /* configSUPPORT_FPU */
|
||||||
|
@ -280,18 +274,16 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvSetInterruptGate( uint8_t ucNumber,
|
static void prvSetInterruptGate( uint8_t ucNumber, ISR_Handler_t pxHandlerFunction, uint8_t ucFlags )
|
||||||
ISR_Handler_t pxHandlerFunction,
|
|
||||||
uint8_t ucFlags )
|
|
||||||
{
|
{
|
||||||
uint16_t usCodeSegment;
|
uint16_t usCodeSegment;
|
||||||
uint32_t ulBase = ( uint32_t ) pxHandlerFunction;
|
uint32_t ulBase = ( uint32_t ) pxHandlerFunction;
|
||||||
|
|
||||||
xInterruptDescriptorTable[ ucNumber ].usISRLow = ( uint16_t ) ( ulBase & USHRT_MAX );
|
xInterruptDescriptorTable[ ucNumber ].usISRLow = ( uint16_t ) ( ulBase & USHRT_MAX );
|
||||||
xInterruptDescriptorTable[ ucNumber ].usISRHigh = ( uint16_t ) ( ( ulBase >> 16UL ) & USHRT_MAX );
|
xInterruptDescriptorTable[ ucNumber ].usISRHigh = ( uint16_t ) ( ( ulBase >> 16UL ) & USHRT_MAX );
|
||||||
|
|
||||||
/* When the flat model is used the CS will never change. */
|
/* When the flat model is used the CS will never change. */
|
||||||
__asm volatile ( "mov %%cs, %0" : "=r" ( usCodeSegment ) );
|
__asm volatile( "mov %%cs, %0" : "=r" ( usCodeSegment ) );
|
||||||
xInterruptDescriptorTable[ ucNumber ].usSegmentSelector = usCodeSegment;
|
xInterruptDescriptorTable[ ucNumber ].usSegmentSelector = usCodeSegment;
|
||||||
xInterruptDescriptorTable[ ucNumber ].ucZero = 0;
|
xInterruptDescriptorTable[ ucNumber ].ucZero = 0;
|
||||||
xInterruptDescriptorTable[ ucNumber ].ucFlags = ucFlags;
|
xInterruptDescriptorTable[ ucNumber ].ucFlags = ucFlags;
|
||||||
|
@ -300,8 +292,8 @@ static void prvSetInterruptGate( uint8_t ucNumber,
|
||||||
|
|
||||||
void vPortSetupIDT( void )
|
void vPortSetupIDT( void )
|
||||||
{
|
{
|
||||||
uint32_t ulNum;
|
uint32_t ulNum;
|
||||||
IDTPointer_t xIDT;
|
IDTPointer_t xIDT;
|
||||||
|
|
||||||
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
||||||
{
|
{
|
||||||
|
@ -321,31 +313,28 @@ void vPortSetupIDT( void )
|
||||||
xIDT.usTableLimit = sizeof( xInterruptDescriptorTable ) - 1;
|
xIDT.usTableLimit = sizeof( xInterruptDescriptorTable ) - 1;
|
||||||
|
|
||||||
/* Set IDT in CPU. */
|
/* Set IDT in CPU. */
|
||||||
__asm volatile ( "lidt %0" ::"m" ( xIDT ) );
|
__asm volatile( "lidt %0" :: "m" (xIDT) );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* A function that implements a task must not exit or attempt to return to
|
||||||
* its caller as there is nothing to return to. If a task wants to exit it
|
its caller as there is nothing to return to. If a task wants to exit it
|
||||||
* should instead call vTaskDelete( NULL ).
|
should instead call vTaskDelete( NULL ).
|
||||||
*
|
|
||||||
* Artificially force an assert() to be triggered if configASSERT() is
|
Artificially force an assert() to be triggered if configASSERT() is
|
||||||
* defined, then stop here so application writers can catch the error. */
|
defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( ulCriticalNesting == ~0UL );
|
configASSERT( ulCriticalNesting == ~0UL );
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
for( ;; );
|
||||||
for( ; ; )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
extern void vPortAPICErrorHandlerWrapper( void );
|
extern void vPortAPICErrorHandlerWrapper( void );
|
||||||
extern void vPortAPICSpuriousHandler( void );
|
extern void vPortAPICSpuriousHandler( void );
|
||||||
|
|
||||||
/* Initialise LAPIC to a well known state. */
|
/* Initialise LAPIC to a well known state. */
|
||||||
portAPIC_LDR = 0xFFFFFFFF;
|
portAPIC_LDR = 0xFFFFFFFF;
|
||||||
|
@ -382,15 +371,15 @@ static void prvSetupTimerInterrupt( void )
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
BaseType_t xWord;
|
BaseType_t xWord;
|
||||||
|
|
||||||
/* Some versions of GCC require the -mno-ms-bitfields command line option
|
/* Some versions of GCC require the -mno-ms-bitfields command line option
|
||||||
* for packing to work. */
|
for packing to work. */
|
||||||
configASSERT( sizeof( struct IDTEntry ) == portEXPECTED_IDT_ENTRY_SIZE );
|
configASSERT( sizeof( struct IDTEntry ) == portEXPECTED_IDT_ENTRY_SIZE );
|
||||||
|
|
||||||
/* Fill part of the system stack with a known value to help detect stack
|
/* Fill part of the system stack with a known value to help detect stack
|
||||||
* overflow. A few zeros are left so GDB doesn't get confused unwinding
|
overflow. A few zeros are left so GDB doesn't get confused unwinding
|
||||||
* the stack. */
|
the stack. */
|
||||||
for( xWord = 0; xWord < configISR_STACK_SIZE - 20; xWord++ )
|
for( xWord = 0; xWord < configISR_STACK_SIZE - 20; xWord++ )
|
||||||
{
|
{
|
||||||
ulSystemStack[ xWord ] = portSTACK_WORD;
|
ulSystemStack[ xWord ] = portSTACK_WORD;
|
||||||
|
@ -414,7 +403,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
portAPIC_TMRDIV = portAPIC_DIV_16;
|
portAPIC_TMRDIV = portAPIC_DIV_16;
|
||||||
|
|
||||||
/* Should not return from the following function as the scheduler will then
|
/* Should not return from the following function as the scheduler will then
|
||||||
* be executing the tasks. */
|
be executing the tasks. */
|
||||||
vPortStartFirstTask();
|
vPortStartFirstTask();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -424,7 +413,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
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( ulCriticalNesting == 1000UL );
|
configASSERT( ulCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -433,9 +422,9 @@ void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
if( ulCriticalNesting == 0 )
|
if( ulCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
#if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
#if( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||||
{
|
{
|
||||||
__asm volatile ( "cli" );
|
__asm volatile( "cli" );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
|
@ -446,8 +435,8 @@ void vPortEnterCritical( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
* portENTER_CRITICAL() has been called. */
|
portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -457,18 +446,18 @@ void vPortExitCritical( void )
|
||||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Decrement the nesting count as the critical section is being
|
/* Decrement the nesting count as the critical section is being
|
||||||
* exited. */
|
exited. */
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then all interrupt
|
/* If the nesting level has reached zero then all interrupt
|
||||||
* priorities must be re-enabled. */
|
priorities must be re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Critical nesting has reached zero so all interrupt priorities
|
/* Critical nesting has reached zero so all interrupt priorities
|
||||||
* should be unmasked. */
|
should be unmasked. */
|
||||||
#if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
#if( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||||
{
|
{
|
||||||
__asm volatile ( "sti" );
|
__asm volatile( "sti" );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
|
@ -477,11 +466,11 @@ void vPortExitCritical( void )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If a yield was pended from within the critical section then
|
/* If a yield was pended from within the critical section then
|
||||||
* perform the yield now. */
|
perform the yield now. */
|
||||||
if( ulPortYieldPending != pdFALSE )
|
if( ulPortYieldPending != pdFALSE )
|
||||||
{
|
{
|
||||||
ulPortYieldPending = pdFALSE;
|
ulPortYieldPending = pdFALSE;
|
||||||
__asm volatile ( portYIELD_INTERRUPT );
|
__asm volatile( portYIELD_INTERRUPT );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -490,17 +479,17 @@ void vPortExitCritical( void )
|
||||||
|
|
||||||
uint32_t ulPortSetInterruptMask( void )
|
uint32_t ulPortSetInterruptMask( void )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalMask;
|
volatile uint32_t ulOriginalMask;
|
||||||
|
|
||||||
/* Set mask to max syscall priority. */
|
/* Set mask to max syscall priority. */
|
||||||
#if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
#if( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||||
{
|
{
|
||||||
/* Return whether interrupts were already enabled or not. Pop adjusts
|
/* Return whether interrupts were already enabled or not. Pop adjusts
|
||||||
* the stack first. */
|
the stack first. */
|
||||||
__asm volatile ( "pushf \t\n"
|
__asm volatile( "pushf \t\n"
|
||||||
"pop %0 \t\n"
|
"pop %0 \t\n"
|
||||||
"cli "
|
"cli "
|
||||||
: "=rm" ( ulOriginalMask )::"memory" );
|
: "=rm" (ulOriginalMask) :: "memory" );
|
||||||
|
|
||||||
ulOriginalMask &= portEFLAGS_IF;
|
ulOriginalMask &= portEFLAGS_IF;
|
||||||
}
|
}
|
||||||
|
@ -511,7 +500,7 @@ uint32_t ulPortSetInterruptMask( void )
|
||||||
portAPIC_TASK_PRIORITY = portMAX_API_CALL_PRIORITY;
|
portAPIC_TASK_PRIORITY = portMAX_API_CALL_PRIORITY;
|
||||||
configASSERT( portAPIC_TASK_PRIORITY == portMAX_API_CALL_PRIORITY );
|
configASSERT( portAPIC_TASK_PRIORITY == portMAX_API_CALL_PRIORITY );
|
||||||
}
|
}
|
||||||
#endif /* if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY ) */
|
#endif
|
||||||
|
|
||||||
return ulOriginalMask;
|
return ulOriginalMask;
|
||||||
}
|
}
|
||||||
|
@ -519,11 +508,11 @@ uint32_t ulPortSetInterruptMask( void )
|
||||||
|
|
||||||
void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
||||||
{
|
{
|
||||||
#if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
#if( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY )
|
||||||
{
|
{
|
||||||
if( ulNewMaskValue != pdFALSE )
|
if( ulNewMaskValue != pdFALSE )
|
||||||
{
|
{
|
||||||
__asm volatile ( "sti" );
|
__asm volatile( "sti" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -531,7 +520,7 @@ void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
||||||
portAPIC_TASK_PRIORITY = ulNewMaskValue;
|
portAPIC_TASK_PRIORITY = ulNewMaskValue;
|
||||||
configASSERT( portAPIC_TASK_PRIORITY == ulNewMaskValue );
|
configASSERT( portAPIC_TASK_PRIORITY == ulNewMaskValue );
|
||||||
}
|
}
|
||||||
#endif /* if ( configMAX_API_CALL_INTERRUPT_PRIORITY == portMAX_PRIORITY ) */
|
#endif
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -540,12 +529,12 @@ void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
||||||
void vPortTaskUsesFPU( void )
|
void vPortTaskUsesFPU( void )
|
||||||
{
|
{
|
||||||
/* A task is registering the fact that it needs an FPU context. Allocate a
|
/* A task is registering the fact that it needs an FPU context. Allocate a
|
||||||
* buffer into which the context can be saved. */
|
buffer into which the context can be saved. */
|
||||||
pucPortTaskFPUContextBuffer = ( uint8_t * ) pvPortMalloc( portFPU_CONTEXT_SIZE_BYTES );
|
pucPortTaskFPUContextBuffer = ( uint8_t * ) pvPortMalloc( portFPU_CONTEXT_SIZE_BYTES );
|
||||||
configASSERT( pucPortTaskFPUContextBuffer );
|
configASSERT( pucPortTaskFPUContextBuffer );
|
||||||
|
|
||||||
/* Initialise the floating point registers. */
|
/* Initialise the floating point registers. */
|
||||||
__asm volatile ( "fninit" );
|
__asm volatile( "fninit" );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configSUPPORT_FPU */
|
#endif /* configSUPPORT_FPU */
|
||||||
|
@ -554,7 +543,7 @@ void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
||||||
void vPortAPICErrorHandler( void )
|
void vPortAPICErrorHandler( void )
|
||||||
{
|
{
|
||||||
/* Variable to hold the APIC error status for viewing in the debugger. */
|
/* Variable to hold the APIC error status for viewing in the debugger. */
|
||||||
volatile uint32_t ulErrorStatus = 0;
|
volatile uint32_t ulErrorStatus = 0;
|
||||||
|
|
||||||
portAPIC_ERROR_STATUS = 0;
|
portAPIC_ERROR_STATUS = 0;
|
||||||
ulErrorStatus = portAPIC_ERROR_STATUS;
|
ulErrorStatus = portAPIC_ERROR_STATUS;
|
||||||
|
@ -565,7 +554,7 @@ void vPortAPICErrorHandler( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
#if( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
||||||
|
|
||||||
void vPortCentralInterruptHandler( uint32_t ulVector )
|
void vPortCentralInterruptHandler( uint32_t ulVector )
|
||||||
{
|
{
|
||||||
|
@ -588,8 +577,7 @@ void vPortAPICErrorHandler( void )
|
||||||
|
|
||||||
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
#if ( configUSE_COMMON_INTERRUPT_ENTRY_POINT == 1 )
|
||||||
|
|
||||||
BaseType_t xPortRegisterCInterruptHandler( ISR_Handler_t pxHandler,
|
BaseType_t xPortRegisterCInterruptHandler( ISR_Handler_t pxHandler, uint32_t ulVectorNumber )
|
||||||
uint32_t ulVectorNumber )
|
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
@ -598,8 +586,8 @@ void vPortAPICErrorHandler( void )
|
||||||
if( xReturn != pdFAIL )
|
if( xReturn != pdFAIL )
|
||||||
{
|
{
|
||||||
/* Save the handler passed in by the application in the vector number
|
/* Save the handler passed in by the application in the vector number
|
||||||
* passed in. The addresses are then called from the central interrupt
|
passed in. The addresses are then called from the central interrupt
|
||||||
* handler. */
|
handler. */
|
||||||
xInterruptHandlerTable[ ulVectorNumber ] = pxHandler;
|
xInterruptHandlerTable[ ulVectorNumber ] = pxHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,10 +597,9 @@ void vPortAPICErrorHandler( void )
|
||||||
#endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
#endif /* configUSE_COMMON_INTERRUPT_ENTRY_POINT */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortInstallInterruptHandler( ISR_Handler_t pxHandler,
|
BaseType_t xPortInstallInterruptHandler( ISR_Handler_t pxHandler, uint32_t ulVectorNumber )
|
||||||
uint32_t ulVectorNumber )
|
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
xReturn = prvCheckValidityOfVectorNumber( ulVectorNumber );
|
xReturn = prvCheckValidityOfVectorNumber( ulVectorNumber );
|
||||||
|
|
||||||
|
@ -632,7 +619,7 @@ BaseType_t xPortInstallInterruptHandler( ISR_Handler_t pxHandler,
|
||||||
|
|
||||||
static BaseType_t prvCheckValidityOfVectorNumber( uint32_t ulVectorNumber )
|
static BaseType_t prvCheckValidityOfVectorNumber( uint32_t ulVectorNumber )
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
/* Check validity of vector number. */
|
/* Check validity of vector number. */
|
||||||
if( ulVectorNumber >= portNUM_VECTORS )
|
if( ulVectorNumber >= portNUM_VECTORS )
|
||||||
|
@ -681,5 +668,19 @@ static BaseType_t prvCheckValidityOfVectorNumber( uint32_t ulVectorNumber )
|
||||||
|
|
||||||
void vGenerateYieldInterrupt( void )
|
void vGenerateYieldInterrupt( void )
|
||||||
{
|
{
|
||||||
__asm volatile ( portYIELD_INTERRUPT );
|
__asm volatile( portYIELD_INTERRUPT );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -43,255 +43,249 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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;
|
||||||
|
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffUL )
|
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffUL )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 32
|
#define portBYTE_ALIGNMENT 32
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
/* The interrupt priority (for vectors 16 to 255) is determined using vector/16.
|
/* The interrupt priority (for vectors 16 to 255) is determined using vector/16.
|
||||||
* The quotient is rounded to the nearest integer with 1 being the lowest priority
|
The quotient is rounded to the nearest integer with 1 being the lowest priority
|
||||||
* and 15 is the highest. Therefore the following two interrupts are at the lowest
|
and 15 is the highest. Therefore the following two interrupts are at the lowest
|
||||||
* priority. *NOTE 1* If the yield vector is changed then it must also be changed
|
priority. *NOTE 1* If the yield vector is changed then it must also be changed
|
||||||
* in the portYIELD_INTERRUPT definition immediately below. */
|
in the portYIELD_INTERRUPT definition immediately below. */
|
||||||
#define portAPIC_TIMER_INT_VECTOR ( 0x21 )
|
#define portAPIC_TIMER_INT_VECTOR ( 0x21 )
|
||||||
#define portAPIC_YIELD_INT_VECTOR ( 0x20 )
|
#define portAPIC_YIELD_INT_VECTOR ( 0x20 )
|
||||||
|
|
||||||
/* Build yield interrupt instruction. */
|
/* Build yield interrupt instruction. */
|
||||||
#define portYIELD_INTERRUPT "int $0x20"
|
#define portYIELD_INTERRUPT "int $0x20"
|
||||||
|
|
||||||
/* APIC register addresses. */
|
/* APIC register addresses. */
|
||||||
#define portAPIC_EOI ( *( ( volatile uint32_t * ) 0xFEE000B0UL ) )
|
#define portAPIC_EOI ( *( ( volatile uint32_t * ) 0xFEE000B0UL ) )
|
||||||
|
|
||||||
/* APIC bit definitions. */
|
/* APIC bit definitions. */
|
||||||
#define portAPIC_ENABLE_BIT ( 1UL << 8UL )
|
#define portAPIC_ENABLE_BIT ( 1UL << 8UL )
|
||||||
#define portAPIC_TIMER_PERIODIC ( 1UL << 17UL )
|
#define portAPIC_TIMER_PERIODIC ( 1UL << 17UL )
|
||||||
#define portAPIC_DISABLE ( 1UL << 16UL )
|
#define portAPIC_DISABLE ( 1UL << 16UL )
|
||||||
#define portAPIC_NMI ( 4 << 8 )
|
#define portAPIC_NMI ( 4 << 8)
|
||||||
#define portAPIC_DIV_16 ( 0x03 )
|
#define portAPIC_DIV_16 ( 0x03 )
|
||||||
|
|
||||||
/* Define local API register addresses. */
|
/* Define local API register addresses. */
|
||||||
#define portAPIC_ID_REGISTER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x20UL ) ) )
|
#define portAPIC_ID_REGISTER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x20UL ) ) )
|
||||||
#define portAPIC_SPURIOUS_INT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xF0UL ) ) )
|
#define portAPIC_SPURIOUS_INT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xF0UL ) ) )
|
||||||
#define portAPIC_LVT_TIMER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x320UL ) ) )
|
#define portAPIC_LVT_TIMER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x320UL ) ) )
|
||||||
#define portAPIC_TIMER_INITIAL_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x380UL ) ) )
|
#define portAPIC_TIMER_INITIAL_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x380UL ) ) )
|
||||||
#define portAPIC_TIMER_CURRENT_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x390UL ) ) )
|
#define portAPIC_TIMER_CURRENT_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x390UL ) ) )
|
||||||
#define portAPIC_TASK_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x80UL ) ) )
|
#define portAPIC_TASK_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x80UL ) ) )
|
||||||
#define portAPIC_LVT_ERROR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x370UL ) ) )
|
#define portAPIC_LVT_ERROR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x370UL ) ) )
|
||||||
#define portAPIC_ERROR_STATUS ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x280UL ) ) )
|
#define portAPIC_ERROR_STATUS ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x280UL ) ) )
|
||||||
#define portAPIC_LDR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xD0UL ) ) )
|
#define portAPIC_LDR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xD0UL ) ) )
|
||||||
#define portAPIC_TMRDIV ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x3E0UL ) ) )
|
#define portAPIC_TMRDIV ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x3E0UL ) ) )
|
||||||
#define portAPIC_LVT_PERF ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x340UL ) ) )
|
#define portAPIC_LVT_PERF ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x340UL ) ) )
|
||||||
#define portAPIC_LVT_LINT0 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x350UL ) ) )
|
#define portAPIC_LVT_LINT0 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x350UL ) ) )
|
||||||
#define portAPIC_LVT_LINT1 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x360UL ) ) )
|
#define portAPIC_LVT_LINT1 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x360UL ) ) )
|
||||||
|
|
||||||
/* Don't yield if inside a critical section - instead hold the yield pending
|
/* Don't yield if inside a critical section - instead hold the yield pending
|
||||||
* so it is performed when the critical section is exited. */
|
so it is performed when the critical section is exited. */
|
||||||
#define portYIELD() \
|
#define portYIELD() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
extern volatile uint32_t ulPortYieldPending; \
|
extern volatile uint32_t ulPortYieldPending; \
|
||||||
if( ulCriticalNesting != 0 ) \
|
if( ulCriticalNesting != 0 ) \
|
||||||
{ \
|
{ \
|
||||||
ulPortYieldPending = pdTRUE; \
|
ulPortYieldPending = pdTRUE; \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
__asm volatile ( portYIELD_INTERRUPT ); \
|
__asm volatile( portYIELD_INTERRUPT ); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called at the end of an ISR that can cause a context switch - pend a yield if
|
/* Called at the end of an ISR that can cause a context switch - pend a yield if
|
||||||
* xSwithcRequired is not false. */
|
xSwithcRequired is not false. */
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint32_t ulPortYieldPending; \
|
extern volatile uint32_t ulPortYieldPending; \
|
||||||
if( xSwitchRequired != pdFALSE ) \
|
if( xSwitchRequired != pdFALSE ) \
|
||||||
{ \
|
{ \
|
||||||
ulPortYieldPending = 1; \
|
ulPortYieldPending = 1; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Same as portEND_SWITCHING_ISR() - take your pick which name to use. */
|
/* Same as portEND_SWITCHING_ISR() - take your pick which name to use. */
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Critical section control
|
* Critical section control
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical sections for use in interrupts. */
|
/* Critical sections for use in interrupts. */
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask( x )
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
extern uint32_t ulPortSetInterruptMask( void );
|
extern uint32_t ulPortSetInterruptMask( void );
|
||||||
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||||
|
|
||||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||||
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile ( "cli" )
|
#define portDISABLE_INTERRUPTS() __asm volatile( "cli" )
|
||||||
#define portENABLE_INTERRUPTS() __asm volatile ( "sti" )
|
#define portENABLE_INTERRUPTS() __asm volatile( "sti" )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
* not required for this port but included in case common demo code that uses these
|
not required for this port but included in case common demo code that uses these
|
||||||
* macros is used. */
|
macros is used. */
|
||||||
#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 )
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \
|
||||||
__asm volatile ( "bsr %1, %0\n\t" \
|
__asm volatile( "bsr %1, %0\n\t" \
|
||||||
: "=r" ( uxTopPriority ) : "rm" ( uxReadyPriorities ) : "cc" )
|
:"=r"(uxTopPriority) : "rm"(uxReadyPriorities) : "cc" )
|
||||||
|
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
#define portNOP() __asm volatile ( "NOP" )
|
#define portNOP() __asm volatile( "NOP" )
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Misc
|
* Misc
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portNUM_VECTORS 256
|
#define portNUM_VECTORS 256
|
||||||
#define portMAX_PRIORITY 15
|
#define portMAX_PRIORITY 15
|
||||||
typedef void ( * ISR_Handler_t ) ( void );
|
typedef void ( *ISR_Handler_t ) ( void );
|
||||||
|
|
||||||
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
||||||
* before any floating point instructions are executed. */
|
before any floating point instructions are executed. */
|
||||||
#ifndef configSUPPORT_FPU
|
#ifndef configSUPPORT_FPU
|
||||||
#define configSUPPORT_FPU 0
|
#define configSUPPORT_FPU 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configSUPPORT_FPU == 1
|
#if configSUPPORT_FPU == 1
|
||||||
void vPortTaskUsesFPU( void );
|
void vPortTaskUsesFPU( void );
|
||||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* See the comments under the configUSE_COMMON_INTERRUPT_ENTRY_POINT definition
|
/* See the comments under the configUSE_COMMON_INTERRUPT_ENTRY_POINT definition
|
||||||
* below. */
|
below. */
|
||||||
BaseType_t xPortRegisterCInterruptHandler( ISR_Handler_t pxHandler,
|
BaseType_t xPortRegisterCInterruptHandler( ISR_Handler_t pxHandler, uint32_t ulVectorNumber );
|
||||||
uint32_t ulVectorNumber );
|
BaseType_t xPortInstallInterruptHandler( ISR_Handler_t pxHandler, uint32_t ulVectorNumber );
|
||||||
BaseType_t xPortInstallInterruptHandler( ISR_Handler_t pxHandler,
|
|
||||||
uint32_t ulVectorNumber );
|
|
||||||
|
|
||||||
#ifndef configAPIC_BASE
|
#ifndef configAPIC_BASE
|
||||||
|
/* configAPIC_BASE_ADDRESS sets the base address of the local APIC. It can
|
||||||
/* configAPIC_BASE_ADDRESS sets the base address of the local APIC. It can
|
be overridden in FreeRTOSConfig.h should it not be constant. */
|
||||||
* be overridden in FreeRTOSConfig.h should it not be constant. */
|
|
||||||
#define configAPIC_BASE 0xFEE00000UL
|
#define configAPIC_BASE 0xFEE00000UL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
/* The FreeRTOS scheduling algorithm selects the task that will enter the
|
||||||
|
Running state. configUSE_PORT_OPTIMISED_TASK_SELECTION is used to set how
|
||||||
|
that is done.
|
||||||
|
|
||||||
/* The FreeRTOS scheduling algorithm selects the task that will enter the
|
If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 0 then the task to
|
||||||
* Running state. configUSE_PORT_OPTIMISED_TASK_SELECTION is used to set how
|
enter the Running state is selected using a portable algorithm written in
|
||||||
* that is done.
|
C. This is the slowest method, but the algorithm does not restrict the
|
||||||
*
|
maximum number of unique RTOS task priorities that are available.
|
||||||
* If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 0 then the task to
|
|
||||||
* enter the Running state is selected using a portable algorithm written in
|
If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 1 then the task to
|
||||||
* C. This is the slowest method, but the algorithm does not restrict the
|
enter the Running state is selected using a single assembly instruction.
|
||||||
* maximum number of unique RTOS task priorities that are available.
|
This is the fastest method, but restricts the maximum number of unique RTOS
|
||||||
*
|
task priorities to 32 (the same task priority can be assigned to any number
|
||||||
* If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 1 then the task to
|
of RTOS tasks). */
|
||||||
* enter the Running state is selected using a single assembly instruction.
|
|
||||||
* This is the fastest method, but restricts the maximum number of unique RTOS
|
|
||||||
* task priorities to 32 (the same task priority can be assigned to any number
|
|
||||||
* of RTOS tasks). */
|
|
||||||
#warning configUSE_PORT_OPTIMISED_TASK_SELECTION was not defined in FreeRTOSConfig.h and has been defaulted to 1
|
#warning configUSE_PORT_OPTIMISED_TASK_SELECTION was not defined in FreeRTOSConfig.h and has been defaulted to 1
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUSE_COMMON_INTERRUPT_ENTRY_POINT
|
#ifndef configUSE_COMMON_INTERRUPT_ENTRY_POINT
|
||||||
|
/* There are two ways of implementing interrupt handlers:
|
||||||
|
|
||||||
/* There are two ways of implementing interrupt handlers:
|
1) As standard C functions -
|
||||||
*
|
|
||||||
* 1) As standard C functions -
|
This method can only be used if configUSE_COMMON_INTERRUPT_ENTRY_POINT
|
||||||
*
|
is set to 1. The C function is installed using
|
||||||
* This method can only be used if configUSE_COMMON_INTERRUPT_ENTRY_POINT
|
xPortRegisterCInterruptHandler().
|
||||||
* is set to 1. The C function is installed using
|
|
||||||
* xPortRegisterCInterruptHandler().
|
This is the simplest of the two methods but incurs a slightly longer
|
||||||
*
|
interrupt entry time.
|
||||||
* This is the simplest of the two methods but incurs a slightly longer
|
|
||||||
* interrupt entry time.
|
2) By using an assembly stub that wraps the handler in the FreeRTOS
|
||||||
*
|
portFREERTOS_INTERRUPT_ENTRY and portFREERTOS_INTERRUPT_EXIT macros.
|
||||||
* 2) By using an assembly stub that wraps the handler in the FreeRTOS
|
|
||||||
* portFREERTOS_INTERRUPT_ENTRY and portFREERTOS_INTERRUPT_EXIT macros.
|
This method can always be used. It is slightly more complex than
|
||||||
*
|
method 1 but benefits from a faster interrupt entry time. */
|
||||||
* This method can always be used. It is slightly more complex than
|
|
||||||
* method 1 but benefits from a faster interrupt entry time. */
|
|
||||||
#warning configUSE_COMMON_INTERRUPT_ENTRY_POINT was not defined in FreeRTOSConfig.h and has been defaulted to 1.
|
#warning configUSE_COMMON_INTERRUPT_ENTRY_POINT was not defined in FreeRTOSConfig.h and has been defaulted to 1.
|
||||||
#define configUSE_COMMON_INTERRUPT_ENTRY_POINT 1
|
#define configUSE_COMMON_INTERRUPT_ENTRY_POINT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configISR_STACK_SIZE
|
#ifndef configISR_STACK_SIZE
|
||||||
|
/* Interrupt entry code will switch the stack in use to a dedicated system
|
||||||
|
stack.
|
||||||
|
|
||||||
/* Interrupt entry code will switch the stack in use to a dedicated system
|
configISR_STACK_SIZE defines the number of 32-bit values that can be stored
|
||||||
* stack.
|
on the system stack, and must be large enough to hold a potentially nested
|
||||||
*
|
interrupt stack frame. */
|
||||||
* configISR_STACK_SIZE defines the number of 32-bit values that can be stored
|
|
||||||
* on the system stack, and must be large enough to hold a potentially nested
|
|
||||||
* interrupt stack frame. */
|
|
||||||
|
|
||||||
#error configISR_STACK_SIZE was not defined in FreeRTOSConfig.h.
|
#error configISR_STACK_SIZE was not defined in FreeRTOSConfig.h.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||||
|
/* Interrupt safe FreeRTOS functions (those that end in "FromISR" must not
|
||||||
/* Interrupt safe FreeRTOS functions (those that end in "FromISR" must not
|
be called from an interrupt that has a priority above that set by
|
||||||
* be called from an interrupt that has a priority above that set by
|
configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||||
* configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
|
||||||
#warning configMAX_API_CALL_INTERRUPT_PRIORITY was not defined in FreeRTOSConfig.h and has been defaulted to 10
|
#warning configMAX_API_CALL_INTERRUPT_PRIORITY was not defined in FreeRTOSConfig.h and has been defaulted to 10
|
||||||
#define configMAX_API_CALL_INTERRUPT_PRIORITY 10
|
#define configMAX_API_CALL_INTERRUPT_PRIORITY 10
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configSUPPORT_FPU
|
#ifndef configSUPPORT_FPU
|
||||||
#warning configSUPPORT_FPU was not defined in FreeRTOSConfig.h and has been defaulted to 0
|
#warning configSUPPORT_FPU was not defined in FreeRTOSConfig.h and has been defaulted to 0
|
||||||
#define configSUPPORT_FPU 0
|
#define configSUPPORT_FPU 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The value written to the task priority register to raise the interrupt mask
|
/* The value written to the task priority register to raise the interrupt mask
|
||||||
* to the maximum from which FreeRTOS API calls can be made. */
|
to the maximum from which FreeRTOS API calls can be made. */
|
||||||
#define portAPIC_PRIORITY_SHIFT ( 4UL )
|
#define portAPIC_PRIORITY_SHIFT ( 4UL )
|
||||||
#define portAPIC_MAX_SUB_PRIORITY ( 0x0fUL )
|
#define portAPIC_MAX_SUB_PRIORITY ( 0x0fUL )
|
||||||
#define portMAX_API_CALL_PRIORITY ( ( configMAX_API_CALL_INTERRUPT_PRIORITY << portAPIC_PRIORITY_SHIFT ) | portAPIC_MAX_SUB_PRIORITY )
|
#define portMAX_API_CALL_PRIORITY ( ( configMAX_API_CALL_INTERRUPT_PRIORITY << portAPIC_PRIORITY_SHIFT ) | portAPIC_MAX_SUB_PRIORITY )
|
||||||
|
|
||||||
/* Asserts if interrupt safe FreeRTOS functions are called from a priority
|
/* Asserts if interrupt safe FreeRTOS functions are called from a priority
|
||||||
* above the max system call interrupt priority. */
|
above the max system call interrupt priority. */
|
||||||
#define portAPIC_PROCESSOR_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xA0UL ) ) )
|
#define portAPIC_PROCESSOR_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xA0UL ) ) )
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( portAPIC_PROCESSOR_PRIORITY ) <= ( portMAX_API_CALL_PRIORITY ) )
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( portAPIC_PROCESSOR_PRIORITY ) <= ( portMAX_API_CALL_PRIORITY ) )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern C */
|
} /* extern C */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V4.1.1 - Copyright (C) 2003-2006 Richard Barry.
|
FreeRTOS V4.1.1 - Copyright (C) 2003-2006 Richard Barry.
|
||||||
* MCF5235 Port - Copyright (C) 2006 Christian Walter.
|
MCF5235 Port - Copyright (C) 2006 Christian Walter.
|
||||||
*
|
|
||||||
* This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
*
|
|
||||||
* FreeRTOS is free software; you can redistribute it and/or modify
|
FreeRTOS is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License** as published by
|
it under the terms of the GNU General Public License** as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
(at your option) any later version.
|
||||||
*
|
|
||||||
* FreeRTOS is distributed in the hope that it will be useful,
|
FreeRTOS is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
* along with FreeRTOS; if not, write to the Free Software
|
along with FreeRTOS; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
|
||||||
* A special exception to the GPL can be applied should you wish to distribute
|
A special exception to the GPL can be applied should you wish to distribute
|
||||||
* a combined work that includes FreeRTOS, without being obliged to provide
|
a combined work that includes FreeRTOS, without being obliged to provide
|
||||||
* the source code for any proprietary components. See the licensing section
|
the source code for any proprietary components. See the licensing section
|
||||||
* of http://www.FreeRTOS.org for full details of how and when the exception
|
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||||
* can be applied.
|
can be applied.
|
||||||
*
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
|
@ -37,19 +37,19 @@
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
*
|
|
||||||
* Please ensure to read the configuration and relevant port sections of the
|
Please ensure to read the configuration and relevant port sections of the
|
||||||
* online documentation.
|
online documentation.
|
||||||
*
|
|
||||||
* http://www.FreeRTOS.org - Documentation, latest information, license and
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
* contact details.
|
contact details.
|
||||||
*
|
|
||||||
* http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
* critical systems.
|
critical systems.
|
||||||
*
|
|
||||||
* http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
* licensing and training services.
|
licensing and training services.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -69,22 +69,22 @@ typedef volatile uint8_t vuint8;
|
||||||
|
|
||||||
#define MCF_PIT_PRESCALER 512UL
|
#define MCF_PIT_PRESCALER 512UL
|
||||||
#define MCF_PIT_TIMER_TICKS ( FSYS_2 / MCF_PIT_PRESCALER )
|
#define MCF_PIT_TIMER_TICKS ( FSYS_2 / MCF_PIT_PRESCALER )
|
||||||
#define MCF_PIT_MODULUS_REGISTER( freq ) ( MCF_PIT_TIMER_TICKS / ( freq ) - 1UL )
|
#define MCF_PIT_MODULUS_REGISTER(freq) ( MCF_PIT_TIMER_TICKS / ( freq ) - 1UL)
|
||||||
|
|
||||||
#define MCF_PIT_PMR0 ( *( vuint16 * ) ( void * ) ( &__IPSBAR[ 0x150002 ] ) )
|
#define MCF_PIT_PMR0 ( *( vuint16 * )( void * )( &__IPSBAR[ 0x150002 ] ) )
|
||||||
#define MCF_PIT_PCSR0 ( *( vuint16 * ) ( void * ) ( &__IPSBAR[ 0x150000 ] ) )
|
#define MCF_PIT_PCSR0 ( *( vuint16 * )( void * )( &__IPSBAR[ 0x150000 ] ) )
|
||||||
#define MCF_PIT_PCSR_PRE( x ) ( ( ( x ) & 0x000F ) << 8 )
|
#define MCF_PIT_PCSR_PRE(x) ( ( ( x ) & 0x000F ) << 8 )
|
||||||
#define MCF_PIT_PCSR_EN ( 0x0001 )
|
#define MCF_PIT_PCSR_EN ( 0x0001 )
|
||||||
#define MCF_PIT_PCSR_RLD ( 0x0002 )
|
#define MCF_PIT_PCSR_RLD ( 0x0002 )
|
||||||
#define MCF_PIT_PCSR_PIF ( 0x0004 )
|
#define MCF_PIT_PCSR_PIF ( 0x0004 )
|
||||||
#define MCF_PIT_PCSR_PIE ( 0x0008 )
|
#define MCF_PIT_PCSR_PIE ( 0x0008 )
|
||||||
#define MCF_PIT_PCSR_OVW ( 0x0010 )
|
#define MCF_PIT_PCSR_OVW ( 0x0010 )
|
||||||
#define MCF_INTC0_ICR36 ( *( vuint8 * ) ( void * ) ( &__IPSBAR[ 0x000C64 ] ) )
|
#define MCF_INTC0_ICR36 ( *( vuint8 * )( void * )( &__IPSBAR[ 0x000C64 ] ) )
|
||||||
#define MCF_INTC0_IMRH ( *( vuint32 * ) ( void * ) ( &__IPSBAR[ 0x000C08 ] ) )
|
#define MCF_INTC0_IMRH ( *( vuint32 * )( void * )( &__IPSBAR[ 0x000C08 ] ) )
|
||||||
#define MCF_INTC0_IMRH_INT_MASK36 ( 0x00000010 )
|
#define MCF_INTC0_IMRH_INT_MASK36 ( 0x00000010 )
|
||||||
#define MCF_INTC0_IMRH_MASKALL ( 0x00000001 )
|
#define MCF_INTC0_IMRH_MASKALL ( 0x00000001 )
|
||||||
#define MCF_INTC0_ICRn_IP( x ) ( ( ( x ) & 0x07 ) << 0 )
|
#define MCF_INTC0_ICRn_IP(x) ( ( ( x ) & 0x07 ) << 0 )
|
||||||
#define MCF_INTC0_ICRn_IL( x ) ( ( ( x ) & 0x07 ) << 3 )
|
#define MCF_INTC0_ICRn_IL(x) ( ( ( x ) & 0x07 ) << 3 )
|
||||||
|
|
||||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||||
#define portINITIAL_CRITICAL_NESTING ( ( uint32_t ) 10 )
|
#define portINITIAL_CRITICAL_NESTING ( ( uint32_t ) 10 )
|
||||||
|
@ -94,16 +94,16 @@ volatile uint32_t ulCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
|
|
||||||
/* ------------------------ Static functions ------------------------------ */
|
/* ------------------------ Static functions ------------------------------ */
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
static void prvPortPreemptiveTick( void ) __attribute__( ( interrupt_handler ) );
|
static void prvPortPreemptiveTick ( void ) __attribute__ ((interrupt_handler));
|
||||||
#else
|
#else
|
||||||
static void prvPortPreemptiveTick( void );
|
static void prvPortPreemptiveTick ( void );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ------------------------ Start implementation -------------------------- */
|
/* ------------------------ Start implementation -------------------------- */
|
||||||
|
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *
|
||||||
TaskFunction_t pxCode,
|
pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode,
|
||||||
void * pvParameters )
|
void *pvParameters )
|
||||||
{
|
{
|
||||||
/* Place the parameter on the stack in the expected location. */
|
/* Place the parameter on the stack in the expected location. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||||
|
@ -165,64 +165,65 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
/*
|
/*
|
||||||
* Called by portYIELD() or taskYIELD() to manually force a context switch.
|
* Called by portYIELD() or taskYIELD() to manually force a context switch.
|
||||||
*/
|
*/
|
||||||
static void prvPortYield( void )
|
static void
|
||||||
|
prvPortYield( void )
|
||||||
{
|
{
|
||||||
asm volatile ( "move.w #0x2700, %sr\n\t" );
|
asm volatile ( "move.w #0x2700, %sr\n\t" );
|
||||||
#if _GCC_USES_FP == 1
|
#if _GCC_USES_FP == 1
|
||||||
asm volatile ( "unlk %fp\n\t" );
|
asm volatile ( "unlk %fp\n\t" );
|
||||||
#endif
|
#endif
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT( );
|
||||||
|
|
||||||
/* Find the highest priority task that is ready to run. */
|
/* Find the highest priority task that is ready to run. */
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext( );
|
||||||
|
|
||||||
/* Restore the context of the new task. */
|
/* Restore the context of the new task. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT( );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The ISR used for the scheduler tick depends on whether the cooperative or
|
* The ISR used for the scheduler tick depends on whether the cooperative or
|
||||||
* the preemptive scheduler is being used.
|
* the preemptive scheduler is being used.
|
||||||
*/
|
*/
|
||||||
static void prvPortPreemptiveTick( void )
|
static void
|
||||||
{
|
prvPortPreemptiveTick ( void )
|
||||||
|
{
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
* simply increment the system tick.
|
* simply increment the system tick.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
|
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* if configUSE_PREEMPTION == 0 */
|
#else
|
||||||
|
|
||||||
static void prvPortPreemptiveTick( void )
|
static void
|
||||||
{
|
prvPortPreemptiveTick( void )
|
||||||
|
{
|
||||||
asm volatile ( "move.w #0x2700, %sr\n\t" );
|
asm volatile ( "move.w #0x2700, %sr\n\t" );
|
||||||
#if _GCC_USES_FP == 1
|
#if _GCC_USES_FP == 1
|
||||||
asm volatile ( "unlk %fp\n\t" );
|
asm volatile ( "unlk %fp\n\t" );
|
||||||
#endif
|
#endif
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT( );
|
||||||
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
|
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
|
||||||
|
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
{
|
{
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext( );
|
||||||
}
|
}
|
||||||
|
portRESTORE_CONTEXT( );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
portRESTORE_CONTEXT();
|
void
|
||||||
}
|
vPortEnterCritical()
|
||||||
#endif /* if configUSE_PREEMPTION == 0 */
|
|
||||||
|
|
||||||
void vPortEnterCritical()
|
|
||||||
{
|
{
|
||||||
/* FIXME: We should store the old IPL here - How are we supposed to do
|
/* FIXME: We should store the old IPL here - How are we supposed to do
|
||||||
* this.
|
* this.
|
||||||
*/
|
*/
|
||||||
( void ) portSET_IPL( portIPL_MAX );
|
( void )portSET_IPL( portIPL_MAX );
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
|
@ -230,7 +231,8 @@ void vPortEnterCritical()
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortExitCritical()
|
void
|
||||||
|
vPortExitCritical()
|
||||||
{
|
{
|
||||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
|
@ -238,17 +240,18 @@ void vPortExitCritical()
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
* re-enabled. */
|
re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
( void ) portSET_IPL( 0 );
|
( void )portSET_IPL( 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t
|
||||||
|
xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void ( * portVECTOR_TABLE[] ) ();
|
extern void ( *portVECTOR_TABLE[ ] ) ( );
|
||||||
|
|
||||||
/* Add entry in vector table for yield system call. */
|
/* Add entry in vector table for yield system call. */
|
||||||
portVECTOR_TABLE[ portVECTOR_SYSCALL ] = prvPortYield;
|
portVECTOR_TABLE[ portVECTOR_SYSCALL ] = prvPortYield;
|
||||||
|
@ -256,7 +259,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
portVECTOR_TABLE[ portVECTOR_TIMER ] = prvPortPreemptiveTick;
|
portVECTOR_TABLE[ portVECTOR_TIMER ] = prvPortPreemptiveTick;
|
||||||
|
|
||||||
/* Configure the timer for the system clock. */
|
/* Configure the timer for the system clock. */
|
||||||
if( configTICK_RATE_HZ > 0 )
|
if ( configTICK_RATE_HZ > 0)
|
||||||
{
|
{
|
||||||
/* Configure prescaler */
|
/* Configure prescaler */
|
||||||
MCF_PIT_PCSR0 = MCF_PIT_PCSR_PRE( 0x9 ) | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_OVW;
|
MCF_PIT_PCSR0 = MCF_PIT_PCSR_PRE( 0x9 ) | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_OVW;
|
||||||
|
@ -270,12 +273,13 @@ BaseType_t xPortStartScheduler( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the context of the first task that is going to run. */
|
/* Restore the context of the first task that is going to run. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT( );
|
||||||
|
|
||||||
/* Should not get here. */
|
/* Should not get here. */
|
||||||
return pdTRUE;
|
return pdTRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEndScheduler( void )
|
void
|
||||||
|
vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V4.1.1 - Copyright (C) 2003-2006 Richard Barry.
|
FreeRTOS V4.1.1 - Copyright (C) 2003-2006 Richard Barry.
|
||||||
* MCF5235 Port - Copyright (C) 2006 Christian Walter.
|
MCF5235 Port - Copyright (C) 2006 Christian Walter.
|
||||||
*
|
|
||||||
* This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
*
|
|
||||||
* FreeRTOS is free software; you can redistribute it and/or modify
|
FreeRTOS is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License** as published by
|
it under the terms of the GNU General Public License** as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
(at your option) any later version.
|
||||||
*
|
|
||||||
* FreeRTOS is distributed in the hope that it will be useful,
|
FreeRTOS is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
* along with FreeRTOS; if not, write to the Free Software
|
along with FreeRTOS; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
|
||||||
* A special exception to the GPL can be applied should you wish to distribute
|
A special exception to the GPL can be applied should you wish to distribute
|
||||||
* a combined work that includes FreeRTOS, without being obliged to provide
|
a combined work that includes FreeRTOS, without being obliged to provide
|
||||||
* the source code for any proprietary components. See the licensing section
|
the source code for any proprietary components. See the licensing section
|
||||||
* of http://www.FreeRTOS.org for full details of how and when the exception
|
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||||
* can be applied.
|
can be applied.
|
||||||
*
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
|
@ -37,55 +37,55 @@
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
*
|
|
||||||
* Please ensure to read the configuration and relevant port sections of the
|
Please ensure to read the configuration and relevant port sections of the
|
||||||
* online documentation.
|
online documentation.
|
||||||
*
|
|
||||||
* http://www.FreeRTOS.org - Documentation, latest information, license and
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
* contact details.
|
contact details.
|
||||||
*
|
|
||||||
* http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
* critical systems.
|
critical systems.
|
||||||
*
|
|
||||||
* http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
* licensing and training services.
|
licensing and training services.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ------------------------ Data types for Coldfire ----------------------- */
|
/* ------------------------ Data types for Coldfire ----------------------- */
|
||||||
#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 unsigned int
|
#define portSTACK_TYPE unsigned int
|
||||||
#define portBASE_TYPE int
|
#define portBASE_TYPE int
|
||||||
|
|
||||||
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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ------------------------ Architecture specifics ------------------------ */
|
/* ------------------------ Architecture specifics ------------------------ */
|
||||||
#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 portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
|
|
||||||
#define portTRAP_YIELD 0 /* Trap 0 */
|
#define portTRAP_YIELD 0 /* Trap 0 */
|
||||||
#define portIPL_MAX 7 /* Only NMI interrupt 7 allowed. */
|
#define portIPL_MAX 7 /* Only NMI interrupt 7 allowed. */
|
||||||
|
|
||||||
/* ------------------------ FreeRTOS macros for port ---------------------- */
|
/* ------------------------ FreeRTOS macros for port ---------------------- */
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@
|
||||||
* the stack for the CPU registers and other task dependent values (e.g
|
* the stack for the CPU registers and other task dependent values (e.g
|
||||||
* ulCriticalNesting) and updates the top of the stack in the TCB.
|
* ulCriticalNesting) and updates the top of the stack in the TCB.
|
||||||
*/
|
*/
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
asm volatile ( /* reserve space for task state. */ \
|
asm volatile ( /* reserve space for task state. */ \
|
||||||
"lea.l (-64, %sp), %sp\n\t" \
|
"lea.l (-64, %sp), %sp\n\t" \
|
||||||
/* push data register %d0-%d7/%a0-%a6 on stack. */ \
|
/* push data register %d0-%d7/%a0-%a6 on stack. */ \
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
"move.l ulCriticalNesting, (%a0)\n\t" \
|
"move.l ulCriticalNesting, (%a0)\n\t" \
|
||||||
/* set the new top of the stack in the TCB. */ \
|
/* set the new top of the stack in the TCB. */ \
|
||||||
"move.l pxCurrentTCB, %a0\n\t" \
|
"move.l pxCurrentTCB, %a0\n\t" \
|
||||||
"move.l %sp, (%a0)" );
|
"move.l %sp, (%a0)");
|
||||||
|
|
||||||
/*.
|
/*.
|
||||||
* This function restores the current active and continues its execution.
|
* This function restores the current active and continues its execution.
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
* task dependent values (e.g ulCriticalNesting). Finally execution
|
* task dependent values (e.g ulCriticalNesting). Finally execution
|
||||||
* is continued by executing an rte instruction.
|
* is continued by executing an rte instruction.
|
||||||
*/
|
*/
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
asm volatile ( "move.l pxCurrentTCB, %sp\n\t" \
|
asm volatile ( "move.l pxCurrentTCB, %sp\n\t" \
|
||||||
"move.l (%sp), %sp\n\t" \
|
"move.l (%sp), %sp\n\t" \
|
||||||
/* stack pointer now points to the saved registers. */ \
|
/* stack pointer now points to the saved registers. */ \
|
||||||
|
@ -126,55 +126,57 @@
|
||||||
/* stack pointer now points to exception frame. */ \
|
/* stack pointer now points to exception frame. */ \
|
||||||
"rte\n\t" );
|
"rte\n\t" );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() \
|
||||||
vPortEnterCritical();
|
vPortEnterCritical();
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() \
|
||||||
vPortExitCritical();
|
vPortExitCritical();
|
||||||
|
|
||||||
#define portSET_IPL( xIPL ) \
|
#define portSET_IPL( xIPL ) \
|
||||||
asm_set_ipl( xIPL )
|
asm_set_ipl( xIPL )
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
do { ( void ) portSET_IPL( portIPL_MAX ); } while( 0 )
|
do { ( void )portSET_IPL( portIPL_MAX ); } while( 0 )
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
do { ( void ) portSET_IPL( 0 ); } while( 0 )
|
do { ( void )portSET_IPL( 0 ); } while( 0 )
|
||||||
|
|
||||||
#define portYIELD() \
|
#define portYIELD() \
|
||||||
asm volatile ( " trap %0\n\t" : : "i" ( portTRAP_YIELD ) )
|
asm volatile ( " trap %0\n\t" : : "i"(portTRAP_YIELD) )
|
||||||
|
|
||||||
#define portNOP() \
|
#define portNOP() \
|
||||||
asm volatile ( "nop\n\t" )
|
asm volatile ( "nop\n\t" )
|
||||||
|
|
||||||
#define portENTER_SWITCHING_ISR() \
|
#define portENTER_SWITCHING_ISR() \
|
||||||
asm volatile ( "move.w #0x2700, %sr" ); \
|
asm volatile ( "move.w #0x2700, %sr" ); \
|
||||||
/* Save the context of the interrupted task. */ \
|
/* Save the context of the interrupted task. */ \
|
||||||
portSAVE_CONTEXT(); \
|
portSAVE_CONTEXT( ); \
|
||||||
{
|
{
|
||||||
#define portEXIT_SWITCHING_ISR( SwitchRequired ) \
|
|
||||||
|
#define portEXIT_SWITCHING_ISR( SwitchRequired ) \
|
||||||
/* If a switch is required we call vTaskSwitchContext(). */ \
|
/* If a switch is required we call vTaskSwitchContext(). */ \
|
||||||
if( SwitchRequired ) \
|
if( SwitchRequired ) \
|
||||||
{ \
|
{ \
|
||||||
vTaskSwitchContext(); \
|
vTaskSwitchContext( ); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT( );
|
||||||
|
|
||||||
/* ------------------------ Function prototypes --------------------------- */
|
/* ------------------------ Function prototypes --------------------------- */
|
||||||
void vPortEnterCritical( void );
|
void vPortEnterCritical( void );
|
||||||
void vPortExitCritical( void );
|
void vPortExitCritical( void );
|
||||||
int asm_set_ipl( uint32_t int uiNewIPL );
|
int asm_set_ipl( uint32_t int uiNewIPL );
|
||||||
|
|
||||||
/* ------------------------ Compiler specifics ---------------------------- */
|
/* ------------------------ Compiler specifics ---------------------------- */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \
|
||||||
void vFunction( void * pvParameters )
|
void vFunction( void *pvParameters )
|
||||||
|
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) \
|
#define portTASK_FUNCTION( vFunction, pvParameters ) \
|
||||||
void vFunction( void * pvParameters )
|
void vFunction( void *pvParameters )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes from V2.5.2
|
Changes from V2.5.2
|
||||||
*
|
|
||||||
+ usCriticalNesting now has a volatile qualifier.
|
+ usCriticalNesting now has a volatile qualifier.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -40,32 +40,32 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the MSP430 port.
|
* Implementation of functions defined in portable.h for the MSP430 port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
|
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
|
||||||
* not the MCLK. */
|
not the MCLK. */
|
||||||
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
|
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
|
||||||
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
|
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
|
||||||
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 )
|
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 )
|
||||||
|
|
||||||
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
||||||
* any details of its type. */
|
any details of its type. */
|
||||||
typedef void TCB_t;
|
typedef void TCB_t;
|
||||||
extern volatile TCB_t * volatile pxCurrentTCB;
|
extern volatile TCB_t * volatile pxCurrentTCB;
|
||||||
|
|
||||||
/* Most ports implement critical sections by placing the interrupt flags on
|
/* Most ports implement critical sections by placing the interrupt flags on
|
||||||
* the stack before disabling interrupts. Exiting the critical section is then
|
the stack before disabling interrupts. Exiting the critical section is then
|
||||||
* simply a case of popping the flags from the stack. As mspgcc does not use
|
simply a case of popping the flags from the stack. As mspgcc does not use
|
||||||
* a frame pointer this cannot be done as modifying the stack will clobber all
|
a frame pointer this cannot be done as modifying the stack will clobber all
|
||||||
* the stack variables. Instead each task maintains a count of the critical
|
the stack variables. Instead each task maintains a count of the critical
|
||||||
* section nesting depth. Each time a critical section is entered the count is
|
section nesting depth. Each time a critical section is entered the count is
|
||||||
* incremented. Each time a critical section is left the count is decremented -
|
incremented. Each time a critical section is left the count is decremented -
|
||||||
* with interrupts only being re-enabled if the count is zero.
|
with interrupts only being re-enabled if the count is zero.
|
||||||
*
|
|
||||||
* usCriticalNesting will get set to zero when the scheduler starts, but must
|
usCriticalNesting will get set to zero when the scheduler starts, but must
|
||||||
* not be initialised to zero as this will cause problems during the startup
|
not be initialised to zero as this will cause problems during the startup
|
||||||
* sequence. */
|
sequence. */
|
||||||
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -77,22 +77,22 @@ volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
* the next time the task executes.
|
* the next time the task executes.
|
||||||
*/
|
*/
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
asm volatile ( "push r4 \n\t"\
|
asm volatile ( "push r4 \n\t" \
|
||||||
"push r5 \n\t"\
|
"push r5 \n\t" \
|
||||||
"push r6 \n\t"\
|
"push r6 \n\t" \
|
||||||
"push r7 \n\t"\
|
"push r7 \n\t" \
|
||||||
"push r8 \n\t"\
|
"push r8 \n\t" \
|
||||||
"push r9 \n\t"\
|
"push r9 \n\t" \
|
||||||
"push r10 \n\t"\
|
"push r10 \n\t" \
|
||||||
"push r11 \n\t"\
|
"push r11 \n\t" \
|
||||||
"push r12 \n\t"\
|
"push r12 \n\t" \
|
||||||
"push r13 \n\t"\
|
"push r13 \n\t" \
|
||||||
"push r14 \n\t"\
|
"push r14 \n\t" \
|
||||||
"push r15 \n\t"\
|
"push r15 \n\t" \
|
||||||
"mov.w usCriticalNesting, r14 \n\t"\
|
"mov.w usCriticalNesting, r14 \n\t" \
|
||||||
"push r14 \n\t"\
|
"push r14 \n\t" \
|
||||||
"mov.w pxCurrentTCB, r12 \n\t"\
|
"mov.w pxCurrentTCB, r12 \n\t" \
|
||||||
"mov.w r1, @r12 \n\t"\
|
"mov.w r1, @r12 \n\t" \
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -106,10 +106,10 @@ volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
* register that is about to be popped from the stack.
|
* register that is about to be popped from the stack.
|
||||||
*/
|
*/
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
asm volatile ( "mov.w pxCurrentTCB, r12 \n\t"\
|
asm volatile ( "mov.w pxCurrentTCB, r12 \n\t" \
|
||||||
"mov.w @r12, r1 \n\t"\
|
"mov.w @r12, r1 \n\t" \
|
||||||
"pop r15 \n\t" \
|
"pop r15 \n\t" \
|
||||||
"mov.w r15, usCriticalNesting \n\t"\
|
"mov.w r15, usCriticalNesting \n\t" \
|
||||||
"pop r15 \n\t" \
|
"pop r15 \n\t" \
|
||||||
"pop r14 \n\t" \
|
"pop r14 \n\t" \
|
||||||
"pop r13 \n\t" \
|
"pop r13 \n\t" \
|
||||||
|
@ -123,7 +123,7 @@ volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
"pop r5 \n\t" \
|
"pop r5 \n\t" \
|
||||||
"pop r4 \n\t" \
|
"pop r4 \n\t" \
|
||||||
"bic #(0xf0),0(r1) \n\t" \
|
"bic #(0xf0),0(r1) \n\t" \
|
||||||
"reti \n\t"\
|
"reti \n\t" \
|
||||||
);
|
);
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -140,26 +140,24 @@ static void prvSetupTimerInterrupt( void );
|
||||||
*
|
*
|
||||||
* See the header file portable.h.
|
* See the header file portable.h.
|
||||||
*/
|
*/
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
TaskFunction_t pxCode,
|
|
||||||
void * pvParameters )
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Place a few bytes of known values on the bottom of the stack.
|
Place a few bytes of known values on the bottom of the stack.
|
||||||
* This is just useful for debugging and can be included if required.
|
This is just useful for debugging and can be included if required.
|
||||||
*
|
|
||||||
* pxTopOfStack = ( StackType_t ) 0x1111;
|
*pxTopOfStack = ( StackType_t ) 0x1111;
|
||||||
* pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
* pxTopOfStack = ( StackType_t ) 0x2222;
|
*pxTopOfStack = ( StackType_t ) 0x2222;
|
||||||
* pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
* pxTopOfStack = ( StackType_t ) 0x3333;
|
*pxTopOfStack = ( StackType_t ) 0x3333;
|
||||||
* pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* The msp430 automatically pushes the PC then SR onto the stack before
|
/* The msp430 automatically pushes the PC then SR onto the stack before
|
||||||
* executing an ISR. We want the stack to look just as if this has happened
|
executing an ISR. We want the stack to look just as if this has happened
|
||||||
* so place a pointer to the start of the task on the stack first - followed
|
so place a pointer to the start of the task on the stack first - followed
|
||||||
* by the flags we want the task to use when it starts up. */
|
by the flags we want the task to use when it starts up. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode;
|
*pxTopOfStack = ( StackType_t ) pxCode;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portFLAGS_INT_ENABLED;
|
*pxTopOfStack = portFLAGS_INT_ENABLED;
|
||||||
|
@ -190,19 +188,19 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
* R15. */
|
R15. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The code generated by the mspgcc compiler does not maintain separate
|
/* The code generated by the mspgcc compiler does not maintain separate
|
||||||
* stack and frame pointers. The portENTER_CRITICAL macro cannot therefore
|
stack and frame pointers. The portENTER_CRITICAL macro cannot therefore
|
||||||
* use the stack as per other ports. Instead a variable is used to keep
|
use the stack as per other ports. Instead a variable is used to keep
|
||||||
* track of the critical section nesting. This variable has to be stored
|
track of the critical section nesting. This variable has to be stored
|
||||||
* as part of the task context and is initially set to zero. */
|
as part of the task context and is initially set to zero. */
|
||||||
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
/* Return a pointer to the top of the stack we have generated so this can
|
/* Return a pointer to the top of the stack we have generated so this can
|
||||||
* be stored in the task control block for the task. */
|
be stored in the task control block for the task. */
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -210,7 +208,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
||||||
* this function is called. */
|
this function is called. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Restore the context of the first task that is going to run. */
|
/* Restore the context of the first task that is going to run. */
|
||||||
|
@ -224,7 +222,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the MSP430 port will get stopped. If required simply
|
/* It is unlikely that the MSP430 port will get stopped. If required simply
|
||||||
* disable the tick interrupt here. */
|
disable the tick interrupt here. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -233,14 +231,14 @@ void vPortEndScheduler( void )
|
||||||
*
|
*
|
||||||
* The first thing we do is save the registers so we can use a naked attribute.
|
* The first thing we do is save the registers so we can use a naked attribute.
|
||||||
*/
|
*/
|
||||||
void vPortYield( void ) __attribute__( ( naked ) );
|
void vPortYield( void ) __attribute__ ( ( naked ) );
|
||||||
void vPortYield( void )
|
void vPortYield( void )
|
||||||
{
|
{
|
||||||
/* We want the stack of the task being saved to look exactly as if the task
|
/* We want the stack of the task being saved to look exactly as if the task
|
||||||
* was saved during a pre-emptive RTOS tick ISR. Before calling an ISR the
|
was saved during a pre-emptive RTOS tick ISR. Before calling an ISR the
|
||||||
* msp430 places the status register onto the stack. As this is a function
|
msp430 places the status register onto the stack. As this is a function
|
||||||
* call and not an ISR we have to do this manually. */
|
call and not an ISR we have to do this manually. */
|
||||||
asm volatile ( "push r2");
|
asm volatile ( "push r2" );
|
||||||
_DINT();
|
_DINT();
|
||||||
|
|
||||||
/* Save the context of the current task. */
|
/* Save the context of the current task. */
|
||||||
|
@ -290,19 +288,19 @@ static void prvSetupTimerInterrupt( void )
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 1
|
#if configUSE_PREEMPTION == 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tick ISR for preemptive scheduler. We can use a naked attribute as
|
* Tick ISR for preemptive scheduler. We can use a naked attribute as
|
||||||
* the context is saved at the start of vPortYieldFromTick(). The tick
|
* the context is saved at the start of vPortYieldFromTick(). The tick
|
||||||
* count is incremented after the context is saved.
|
* count is incremented after the context is saved.
|
||||||
*/
|
*/
|
||||||
interrupt( TIMERA0_VECTOR ) prvTickISR( void ) __attribute__( ( naked ) );
|
interrupt (TIMERA0_VECTOR) prvTickISR( void ) __attribute__ ( ( naked ) );
|
||||||
interrupt( TIMERA0_VECTOR ) prvTickISR( void )
|
interrupt (TIMERA0_VECTOR) prvTickISR( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* Increment the tick count then switch to the highest priority task
|
/* Increment the tick count then switch to the highest priority task
|
||||||
* that is ready to run. */
|
that is ready to run. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
{
|
{
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
|
@ -312,16 +310,19 @@ static void prvSetupTimerInterrupt( void )
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* if configUSE_PREEMPTION == 1 */
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tick ISR for the cooperative scheduler. All this does is increment the
|
* Tick ISR for the cooperative scheduler. All this does is increment the
|
||||||
* tick count. We don't need to switch context, this can only be done by
|
* tick count. We don't need to switch context, this can only be done by
|
||||||
* manual calls to taskYIELD();
|
* manual calls to taskYIELD();
|
||||||
*/
|
*/
|
||||||
interrupt( TIMERA0_VECTOR ) prvTickISR( void );
|
interrupt (TIMERA0_VECTOR) prvTickISR( void );
|
||||||
interrupt( TIMERA0_VECTOR ) prvTickISR( void )
|
interrupt (TIMERA0_VECTOR) prvTickISR( void )
|
||||||
{
|
{
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
}
|
}
|
||||||
#endif /* if configUSE_PREEMPTION == 1 */
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -43,38 +43,38 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 int
|
#define portSHORT int
|
||||||
#define portSTACK_TYPE uint16_t
|
#define portSTACK_TYPE uint16_t
|
||||||
#define portBASE_TYPE short
|
#define portBASE_TYPE short
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef short BaseType_t;
|
typedef short BaseType_t;
|
||||||
typedef unsigned short UBaseType_t;
|
typedef unsigned short UBaseType_t;
|
||||||
|
|
||||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Interrupt control macros. */
|
/* Interrupt control macros. */
|
||||||
#define portDISABLE_INTERRUPTS() asm volatile ( "DINT" ); asm volatile ( "NOP" )
|
#define portDISABLE_INTERRUPTS() asm volatile ( "DINT" ); asm volatile ( "NOP" )
|
||||||
#define portENABLE_INTERRUPTS() asm volatile ( "EINT" ); asm volatile ( "NOP" )
|
#define portENABLE_INTERRUPTS() asm volatile ( "EINT" ); asm volatile ( "NOP" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section control macros. */
|
/* Critical section control macros. */
|
||||||
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
|
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
|
||||||
|
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint16_t usCriticalNesting; \
|
extern volatile uint16_t usCriticalNesting; \
|
||||||
\
|
\
|
||||||
portDISABLE_INTERRUPTS(); \
|
portDISABLE_INTERRUPTS(); \
|
||||||
\
|
\
|
||||||
|
@ -82,11 +82,11 @@
|
||||||
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
||||||
/* times portENTER_CRITICAL() has been called. */ \
|
/* times portENTER_CRITICAL() has been called. */ \
|
||||||
usCriticalNesting++; \
|
usCriticalNesting++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint16_t usCriticalNesting; \
|
extern volatile uint16_t usCriticalNesting; \
|
||||||
\
|
\
|
||||||
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -100,27 +100,28 @@
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
extern void vPortYield( void ) __attribute__( ( naked ) );
|
extern void vPortYield( void ) __attribute__ ( ( naked ) );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portNOP() asm volatile ( "NOP" )
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardwware specifics. */
|
/* Hardwware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 2
|
#define portBYTE_ALIGNMENT 2
|
||||||
#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 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the MicroBlaze port.
|
* Implementation of functions defined in portable.h for the MicroBlaze port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
#include <xintc_i.h>
|
#include <xintc_i.h>
|
||||||
#include <xtmrctr.h>
|
#include <xtmrctr.h>
|
||||||
|
|
||||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
|
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
|
||||||
#error configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 to use this port.
|
#error configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 to use this port.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -50,25 +50,25 @@
|
||||||
#define portINITIAL_MSR_STATE ( ( StackType_t ) 0x02 )
|
#define portINITIAL_MSR_STATE ( ( StackType_t ) 0x02 )
|
||||||
|
|
||||||
/* Tasks are started with a critical section nesting of 0 - however prior
|
/* Tasks are started with a critical section nesting of 0 - however prior
|
||||||
* to the scheduler being commenced we don't want the critical nesting level
|
to the scheduler being commenced we don't want the critical nesting level
|
||||||
* to reach zero, so it is initialised to a high value. */
|
to reach zero, so it is initialised to a high value. */
|
||||||
#define portINITIAL_NESTING_VALUE ( 0xff )
|
#define portINITIAL_NESTING_VALUE ( 0xff )
|
||||||
|
|
||||||
/* Our hardware setup only uses one counter. */
|
/* Our hardware setup only uses one counter. */
|
||||||
#define portCOUNTER_0 0
|
#define portCOUNTER_0 0
|
||||||
|
|
||||||
/* The stack used by the ISR is filled with a known value to assist in
|
/* The stack used by the ISR is filled with a known value to assist in
|
||||||
* debugging. */
|
debugging. */
|
||||||
#define portISR_STACK_FILL_VALUE 0x55555555
|
#define portISR_STACK_FILL_VALUE 0x55555555
|
||||||
|
|
||||||
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
|
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
|
||||||
* maintains it's own count, so this variable is saved as part of the task
|
maintains it's own count, so this variable is saved as part of the task
|
||||||
* context. */
|
context. */
|
||||||
volatile UBaseType_t uxCriticalNesting = portINITIAL_NESTING_VALUE;
|
volatile UBaseType_t uxCriticalNesting = portINITIAL_NESTING_VALUE;
|
||||||
|
|
||||||
/* To limit the amount of stack required by each task, this port uses a
|
/* To limit the amount of stack required by each task, this port uses a
|
||||||
* separate stack for interrupts. */
|
separate stack for interrupts. */
|
||||||
uint32_t * pulISRStack;
|
uint32_t *pulISRStack;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -85,18 +85,16 @@ static void prvSetupTimerInterrupt( void );
|
||||||
*
|
*
|
||||||
* See the header file portable.h.
|
* See the header file portable.h.
|
||||||
*/
|
*/
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
TaskFunction_t pxCode,
|
|
||||||
void * pvParameters )
|
|
||||||
{
|
{
|
||||||
extern void * _SDA2_BASE_, * _SDA_BASE_;
|
extern void *_SDA2_BASE_, *_SDA_BASE_;
|
||||||
const uint32_t ulR2 = ( uint32_t ) &_SDA2_BASE_;
|
const uint32_t ulR2 = ( uint32_t ) &_SDA2_BASE_;
|
||||||
const uint32_t ulR13 = ( uint32_t ) &_SDA_BASE_;
|
const uint32_t ulR13 = ( uint32_t ) &_SDA_BASE_;
|
||||||
|
|
||||||
/* Place a few bytes of known values on the bottom of the stack.
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
* This is essential for the Microblaze port and these lines must
|
This is essential for the Microblaze port and these lines must
|
||||||
* not be omitted. The parameter value will overwrite the
|
not be omitted. The parameter value will overwrite the
|
||||||
* 0x22222222 value during the function prologue. */
|
0x22222222 value during the function prologue. */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x11111111;
|
*pxTopOfStack = ( StackType_t ) 0x11111111;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x22222222;
|
*pxTopOfStack = ( StackType_t ) 0x22222222;
|
||||||
|
@ -105,7 +103,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* First stack an initial value for the critical section nesting. This
|
/* First stack an initial value for the critical section nesting. This
|
||||||
* is initialised to zero as tasks are started with interrupts enabled. */
|
is initialised to zero as tasks are started with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00; /* R0. */
|
*pxTopOfStack = ( StackType_t ) 0x00; /* R0. */
|
||||||
|
|
||||||
/* Place an initial value for all the general purpose registers. */
|
/* Place an initial value for all the general purpose registers. */
|
||||||
|
@ -116,7 +114,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x04; /* R4. */
|
*pxTopOfStack = ( StackType_t ) 0x04; /* R4. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R5 contains the function call parameters. */
|
*pxTopOfStack = ( StackType_t ) pvParameters;/* R5 contains the function call parameters. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x06; /* R6. */
|
*pxTopOfStack = ( StackType_t ) 0x06; /* R6. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -177,26 +175,26 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Return a pointer to the top of the stack we have generated so this can
|
/* Return a pointer to the top of the stack we have generated so this can
|
||||||
* be stored in the task control block for the task. */
|
be stored in the task control block for the task. */
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void( __FreeRTOS_interrupt_Handler )( void );
|
extern void ( __FreeRTOS_interrupt_Handler )( void );
|
||||||
extern void( vStartFirstTask )( void );
|
extern void ( vStartFirstTask )( void );
|
||||||
|
|
||||||
|
|
||||||
/* Setup the FreeRTOS interrupt handler. Code copied from crt0.s. */
|
/* Setup the FreeRTOS interrupt handler. Code copied from crt0.s. */
|
||||||
asm volatile ( "la r6, r0, __FreeRTOS_interrupt_handler \n\t"\
|
asm volatile ( "la r6, r0, __FreeRTOS_interrupt_handler \n\t" \
|
||||||
"sw r6, r1, r0 \n\t"\
|
"sw r6, r1, r0 \n\t" \
|
||||||
"lhu r7, r1, r0 \n\t"\
|
"lhu r7, r1, r0 \n\t" \
|
||||||
"shi r7, r0, 0x12 \n\t"\
|
"shi r7, r0, 0x12 \n\t" \
|
||||||
"shi r6, r0, 0x16 " );
|
"shi r6, r0, 0x16 " );
|
||||||
|
|
||||||
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
||||||
* this function is called. */
|
this function is called. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Allocate the stack to be used by the interrupt handler. */
|
/* Allocate the stack to be used by the interrupt handler. */
|
||||||
|
@ -229,17 +227,16 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
void vPortYield( void )
|
void vPortYield( void )
|
||||||
{
|
{
|
||||||
extern void VPortYieldASM( void );
|
extern void VPortYieldASM( void );
|
||||||
|
|
||||||
/* Perform the context switch in a critical section to assure it is
|
/* Perform the context switch in a critical section to assure it is
|
||||||
* not interrupted by the tick ISR. It is not a problem to do this as
|
not interrupted by the tick ISR. It is not a problem to do this as
|
||||||
* each task maintains it's own interrupt status. */
|
each task maintains it's own interrupt status. */
|
||||||
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
|
|
||||||
/* Jump directly to the yield function to ensure there is no
|
/* Jump directly to the yield function to ensure there is no
|
||||||
* compiler generated prologue code. */
|
compiler generated prologue code. */
|
||||||
asm volatile ( "bralid r14, VPortYieldASM \n\t"\
|
asm volatile ( "bralid r14, VPortYieldASM \n\t" \
|
||||||
"or r0, r0, r0 \n\t");
|
"or r0, r0, r0 \n\t" );
|
||||||
portEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -249,25 +246,25 @@ void vPortYield( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
XTmrCtr xTimer;
|
XTmrCtr xTimer;
|
||||||
const uint32_t ulCounterValue = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
const uint32_t ulCounterValue = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
UBaseType_t uxMask;
|
UBaseType_t uxMask;
|
||||||
|
|
||||||
/* The OPB timer1 is used to generate the tick. Use the provided library
|
/* The OPB timer1 is used to generate the tick. Use the provided library
|
||||||
* functions to enable the timer and set the tick frequency. */
|
functions to enable the timer and set the tick frequency. */
|
||||||
XTmrCtr_mDisable( XPAR_OPB_TIMER_1_BASEADDR, XPAR_OPB_TIMER_1_DEVICE_ID );
|
XTmrCtr_mDisable( XPAR_OPB_TIMER_1_BASEADDR, XPAR_OPB_TIMER_1_DEVICE_ID );
|
||||||
XTmrCtr_Initialize( &xTimer, XPAR_OPB_TIMER_1_DEVICE_ID );
|
XTmrCtr_Initialize( &xTimer, XPAR_OPB_TIMER_1_DEVICE_ID );
|
||||||
XTmrCtr_mSetLoadReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCounterValue );
|
XTmrCtr_mSetLoadReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCounterValue );
|
||||||
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, XTC_CSR_LOAD_MASK | XTC_CSR_INT_OCCURED_MASK );
|
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, XTC_CSR_LOAD_MASK | XTC_CSR_INT_OCCURED_MASK );
|
||||||
|
|
||||||
/* Set the timer interrupt enable bit while maintaining the other bit
|
/* Set the timer interrupt enable bit while maintaining the other bit
|
||||||
* states. */
|
states. */
|
||||||
uxMask = XIntc_In32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ) );
|
uxMask = XIntc_In32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ) );
|
||||||
uxMask |= XPAR_OPB_TIMER_1_INTERRUPT_MASK;
|
uxMask |= XPAR_OPB_TIMER_1_INTERRUPT_MASK;
|
||||||
XIntc_Out32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ), ( uxMask ) );
|
XIntc_Out32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ), ( uxMask ) );
|
||||||
|
|
||||||
XTmrCtr_Start( &xTimer, XPAR_OPB_TIMER_1_DEVICE_ID );
|
XTmrCtr_Start( &xTimer, XPAR_OPB_TIMER_1_DEVICE_ID );
|
||||||
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK | XTC_CSR_INT_OCCURED_MASK );
|
XTmrCtr_mSetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK | XTC_CSR_INT_OCCURED_MASK );
|
||||||
XIntc_mAckIntr( XPAR_INTC_SINGLE_BASEADDR, 1 );
|
XIntc_mAckIntr( XPAR_INTC_SINGLE_BASEADDR, 1 );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -280,15 +277,15 @@ static void prvSetupTimerInterrupt( void )
|
||||||
*/
|
*/
|
||||||
void vTaskISRHandler( void )
|
void vTaskISRHandler( void )
|
||||||
{
|
{
|
||||||
static uint32_t ulPending;
|
static uint32_t ulPending;
|
||||||
|
|
||||||
/* Which interrupts are pending? */
|
/* Which interrupts are pending? */
|
||||||
ulPending = XIntc_In32( ( XPAR_INTC_SINGLE_BASEADDR + XIN_IVR_OFFSET ) );
|
ulPending = XIntc_In32( ( XPAR_INTC_SINGLE_BASEADDR + XIN_IVR_OFFSET ) );
|
||||||
|
|
||||||
if( ulPending < XPAR_INTC_MAX_NUM_INTR_INPUTS )
|
if( ulPending < XPAR_INTC_MAX_NUM_INTR_INPUTS )
|
||||||
{
|
{
|
||||||
static XIntc_VectorTableEntry * pxTablePtr;
|
static XIntc_VectorTableEntry *pxTablePtr;
|
||||||
static XIntc_Config * pxConfig;
|
static XIntc_Config *pxConfig;
|
||||||
static uint32_t ulInterruptMask;
|
static uint32_t ulInterruptMask;
|
||||||
|
|
||||||
ulInterruptMask = ( uint32_t ) 1 << ulPending;
|
ulInterruptMask = ( uint32_t ) 1 << ulPending;
|
||||||
|
@ -297,7 +294,6 @@ void vTaskISRHandler( void )
|
||||||
pxConfig = &XIntc_ConfigTable[ ( uint32_t ) XPAR_INTC_SINGLE_DEVICE_ID ];
|
pxConfig = &XIntc_ConfigTable[ ( uint32_t ) XPAR_INTC_SINGLE_DEVICE_ID ];
|
||||||
|
|
||||||
pxTablePtr = &( pxConfig->HandlerTable[ ulPending ] );
|
pxTablePtr = &( pxConfig->HandlerTable[ ulPending ] );
|
||||||
|
|
||||||
if( pxConfig->AckBeforeService & ( ulInterruptMask ) )
|
if( pxConfig->AckBeforeService & ( ulInterruptMask ) )
|
||||||
{
|
{
|
||||||
XIntc_mAckIntr( pxConfig->BaseAddress, ulInterruptMask );
|
XIntc_mAckIntr( pxConfig->BaseAddress, ulInterruptMask );
|
||||||
|
@ -315,9 +311,9 @@ void vTaskISRHandler( void )
|
||||||
/*
|
/*
|
||||||
* Handler for the timer interrupt.
|
* Handler for the timer interrupt.
|
||||||
*/
|
*/
|
||||||
void vTickISR( void * pvBaseAddress )
|
void vTickISR( void *pvBaseAddress )
|
||||||
{
|
{
|
||||||
uint32_t ulCSR;
|
uint32_t ulCSR;
|
||||||
|
|
||||||
/* Increment the RTOS tick - this might cause a task to unblock. */
|
/* Increment the RTOS tick - this might cause a task to unblock. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
|
@ -326,7 +322,12 @@ void vTickISR( void * pvBaseAddress )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the timer interrupt */
|
/* Clear the timer interrupt */
|
||||||
ulCSR = XTmrCtr_mGetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, 0 );
|
ulCSR = XTmrCtr_mGetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, 0);
|
||||||
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCSR );
|
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCSR );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -43,50 +43,48 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
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
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Interrupt control macros. */
|
/* Interrupt control macros. */
|
||||||
void microblaze_disable_interrupts( void );
|
void microblaze_disable_interrupts( void );
|
||||||
void microblaze_enable_interrupts( void );
|
void microblaze_enable_interrupts( void );
|
||||||
#define portDISABLE_INTERRUPTS() microblaze_disable_interrupts()
|
#define portDISABLE_INTERRUPTS() microblaze_disable_interrupts()
|
||||||
#define portENABLE_INTERRUPTS() microblaze_enable_interrupts()
|
#define portENABLE_INTERRUPTS() microblaze_enable_interrupts()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section macros. */
|
/* Critical section macros. */
|
||||||
void vPortEnterCritical( void );
|
void vPortEnterCritical( void );
|
||||||
void vPortExitCritical( void );
|
void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() { \
|
||||||
{ \
|
|
||||||
extern UBaseType_t uxCriticalNesting; \
|
extern UBaseType_t uxCriticalNesting; \
|
||||||
microblaze_disable_interrupts(); \
|
microblaze_disable_interrupts(); \
|
||||||
uxCriticalNesting++; \
|
uxCriticalNesting++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() { \
|
||||||
{ \
|
|
||||||
extern UBaseType_t uxCriticalNesting; \
|
extern UBaseType_t uxCriticalNesting; \
|
||||||
/* Interrupts are disabled, so we can */ \
|
/* Interrupts are disabled, so we can */ \
|
||||||
/* access the variable directly. */ \
|
/* access the variable directly. */ \
|
||||||
|
@ -94,7 +92,7 @@
|
||||||
if( uxCriticalNesting == 0 ) \
|
if( uxCriticalNesting == 0 ) \
|
||||||
{ \
|
{ \
|
||||||
/* The nesting has unwound and we \
|
/* The nesting has unwound and we \
|
||||||
* can enable interrupts again. */ \
|
can enable interrupts again. */ \
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
@ -102,26 +100,27 @@
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
void vPortYield( void );
|
void vPortYield( void );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
|
|
||||||
void vTaskSwitchContext();
|
void vTaskSwitchContext();
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#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() asm volatile ( "NOP" )
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the MicroBlaze port.
|
* Implementation of functions defined in portable.h for the MicroBlaze port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
|
@ -43,19 +43,19 @@
|
||||||
#include <microblaze_exceptions_g.h>
|
#include <microblaze_exceptions_g.h>
|
||||||
|
|
||||||
/* Tasks are started with a critical section nesting of 0 - however, prior to
|
/* Tasks are started with a critical section nesting of 0 - however, prior to
|
||||||
* the scheduler being commenced interrupts should not be enabled, so the critical
|
the scheduler being commenced interrupts should not be enabled, so the critical
|
||||||
* nesting variable is initialised to a non-zero value. */
|
nesting variable is initialised to a non-zero value. */
|
||||||
#define portINITIAL_NESTING_VALUE ( 0xff )
|
#define portINITIAL_NESTING_VALUE ( 0xff )
|
||||||
|
|
||||||
/* The bit within the MSR register that enabled/disables interrupts and
|
/* The bit within the MSR register that enabled/disables interrupts and
|
||||||
* exceptions respectively. */
|
exceptions respectively. */
|
||||||
#define portMSR_IE ( 0x02U )
|
#define portMSR_IE ( 0x02U )
|
||||||
#define portMSR_EE ( 0x100U )
|
#define portMSR_EE ( 0x100U )
|
||||||
|
|
||||||
/* If the floating point unit is included in the MicroBlaze build, then the
|
/* If the floating point unit is included in the MicroBlaze build, then the
|
||||||
* FSR register is saved as part of the task context. portINITIAL_FSR is the value
|
FSR register is saved as part of the task context. portINITIAL_FSR is the value
|
||||||
* given to the FSR register when the initial context is set up for a task being
|
given to the FSR register when the initial context is set up for a task being
|
||||||
* created. */
|
created. */
|
||||||
#define portINITIAL_FSR ( 0U )
|
#define portINITIAL_FSR ( 0U )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -72,27 +72,27 @@ static int32_t prvEnsureInterruptControllerIsInitialised( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
|
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
|
||||||
* maintains its own count, so this variable is saved as part of the task
|
maintains its own count, so this variable is saved as part of the task
|
||||||
* context. */
|
context. */
|
||||||
volatile UBaseType_t uxCriticalNesting = portINITIAL_NESTING_VALUE;
|
volatile UBaseType_t uxCriticalNesting = portINITIAL_NESTING_VALUE;
|
||||||
|
|
||||||
/* This port uses a separate stack for interrupts. This prevents the stack of
|
/* This port uses a separate stack for interrupts. This prevents the stack of
|
||||||
* every task needing to be large enough to hold an entire interrupt stack on top
|
every task needing to be large enough to hold an entire interrupt stack on top
|
||||||
* of the task stack. */
|
of the task stack. */
|
||||||
uint32_t * pulISRStack;
|
uint32_t *pulISRStack;
|
||||||
|
|
||||||
/* If an interrupt requests a context switch, then ulTaskSwitchRequested will
|
/* If an interrupt requests a context switch, then ulTaskSwitchRequested will
|
||||||
* get set to 1. ulTaskSwitchRequested is inspected just before the main interrupt
|
get set to 1. ulTaskSwitchRequested is inspected just before the main interrupt
|
||||||
* handler exits. If, at that time, ulTaskSwitchRequested is set to 1, the kernel
|
handler exits. If, at that time, ulTaskSwitchRequested is set to 1, the kernel
|
||||||
* will call vTaskSwitchContext() to ensure the task that runs immediately after
|
will call vTaskSwitchContext() to ensure the task that runs immediately after
|
||||||
* the interrupt exists is the highest priority task that is able to run. This is
|
the interrupt exists is the highest priority task that is able to run. This is
|
||||||
* an unusual mechanism, but is used for this port because a single interrupt can
|
an unusual mechanism, but is used for this port because a single interrupt can
|
||||||
* cause the servicing of multiple peripherals - and it is inefficient to call
|
cause the servicing of multiple peripherals - and it is inefficient to call
|
||||||
* vTaskSwitchContext() multiple times as each peripheral is serviced. */
|
vTaskSwitchContext() multiple times as each peripheral is serviced. */
|
||||||
volatile uint32_t ulTaskSwitchRequested = 0UL;
|
volatile uint32_t ulTaskSwitchRequested = 0UL;
|
||||||
|
|
||||||
/* The instance of the interrupt controller used by this port. This is required
|
/* The instance of the interrupt controller used by this port. This is required
|
||||||
* by the Xilinx library API functions. */
|
by the Xilinx library API functions. */
|
||||||
static XIntc xInterruptControllerInstance;
|
static XIntc xInterruptControllerInstance;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -103,17 +103,15 @@ static XIntc xInterruptControllerInstance;
|
||||||
*
|
*
|
||||||
* See the portable.h header file.
|
* See the portable.h header file.
|
||||||
*/
|
*/
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
TaskFunction_t pxCode,
|
|
||||||
void * pvParameters )
|
|
||||||
{
|
{
|
||||||
extern void * _SDA2_BASE_, * _SDA_BASE_;
|
extern void *_SDA2_BASE_, *_SDA_BASE_;
|
||||||
const uint32_t ulR2 = ( uint32_t ) &_SDA2_BASE_;
|
const uint32_t ulR2 = ( uint32_t ) &_SDA2_BASE_;
|
||||||
const uint32_t ulR13 = ( uint32_t ) &_SDA_BASE_;
|
const uint32_t ulR13 = ( uint32_t ) &_SDA_BASE_;
|
||||||
|
|
||||||
/* Place a few bytes of known values on the bottom of the stack.
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
* This is essential for the Microblaze port and these lines must
|
This is essential for the Microblaze port and these lines must
|
||||||
* not be omitted. */
|
not be omitted. */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
||||||
|
@ -121,18 +119,18 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
#if ( XPAR_MICROBLAZE_USE_FPU != 0 )
|
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
|
||||||
/* The FSR value placed in the initial task context is just 0. */
|
/* The FSR value placed in the initial task context is just 0. */
|
||||||
*pxTopOfStack = portINITIAL_FSR;
|
*pxTopOfStack = portINITIAL_FSR;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The MSR value placed in the initial task context should have interrupts
|
/* The MSR value placed in the initial task context should have interrupts
|
||||||
* disabled. Each task will enable interrupts automatically when it enters
|
disabled. Each task will enable interrupts automatically when it enters
|
||||||
* the running state for the first time. */
|
the running state for the first time. */
|
||||||
*pxTopOfStack = mfmsr() & ~portMSR_IE;
|
*pxTopOfStack = mfmsr() & ~portMSR_IE;
|
||||||
|
|
||||||
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 )
|
#if( MICROBLAZE_EXCEPTIONS_ENABLED == 1 )
|
||||||
{
|
{
|
||||||
/* Ensure exceptions are enabled for the task. */
|
/* Ensure exceptions are enabled for the task. */
|
||||||
*pxTopOfStack |= portMSR_EE;
|
*pxTopOfStack |= portMSR_EE;
|
||||||
|
@ -142,7 +140,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* First stack an initial value for the critical section nesting. This
|
/* First stack an initial value for the critical section nesting. This
|
||||||
* is initialised to zero. */
|
is initialised to zero. */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||||
|
|
||||||
/* R0 is always zero. */
|
/* R0 is always zero. */
|
||||||
|
@ -156,7 +154,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x04; /* R4 - return values and temporaries. */
|
*pxTopOfStack = ( StackType_t ) 0x04; /* R4 - return values and temporaries. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R5 contains the function call parameters. */
|
*pxTopOfStack = ( StackType_t ) pvParameters;/* R5 contains the function call parameters. */
|
||||||
|
|
||||||
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -174,9 +172,9 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x0c; /* R12 - temporaries. */
|
*pxTopOfStack = ( StackType_t ) 0x0c; /* R12 - temporaries. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
#else /* ifdef portPRE_LOAD_STACK_FOR_DEBUGGING */
|
#else
|
||||||
pxTopOfStack -= 8;
|
pxTopOfStack-= 8;
|
||||||
#endif /* ifdef portPRE_LOAD_STACK_FOR_DEBUGGING */
|
#endif
|
||||||
|
|
||||||
*pxTopOfStack = ( StackType_t ) ulR13; /* R13 - read/write small data area. */
|
*pxTopOfStack = ( StackType_t ) ulR13; /* R13 - read/write small data area. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -224,41 +222,41 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x1f; /* R31 - must be saved across function calls. Callee-save. */
|
*pxTopOfStack = ( StackType_t ) 0x1f; /* R31 - must be saved across function calls. Callee-save. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
#else /* ifdef portPRE_LOAD_STACK_FOR_DEBUGGING */
|
#else
|
||||||
pxTopOfStack -= 13;
|
pxTopOfStack -= 13;
|
||||||
#endif /* ifdef portPRE_LOAD_STACK_FOR_DEBUGGING */
|
#endif
|
||||||
|
|
||||||
/* Return a pointer to the top of the stack that has been generated so this
|
/* Return a pointer to the top of the stack that has been generated so this
|
||||||
* can be stored in the task control block for the task. */
|
can be stored in the task control block for the task. */
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void( vPortStartFirstTask )( void );
|
extern void ( vPortStartFirstTask )( void );
|
||||||
extern uint32_t _stack[];
|
extern uint32_t _stack[];
|
||||||
|
|
||||||
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
||||||
* this function is called.
|
this function is called.
|
||||||
*
|
|
||||||
* This port uses an application defined callback function to install the tick
|
This port uses an application defined callback function to install the tick
|
||||||
* interrupt handler because the kernel will run on lots of different
|
interrupt handler because the kernel will run on lots of different
|
||||||
* MicroBlaze and FPGA configurations - not all of which will have the same
|
MicroBlaze and FPGA configurations - not all of which will have the same
|
||||||
* timer peripherals defined or available. An example definition of
|
timer peripherals defined or available. An example definition of
|
||||||
* vApplicationSetupTimerInterrupt() is provided in the official demo
|
vApplicationSetupTimerInterrupt() is provided in the official demo
|
||||||
* application that accompanies this port. */
|
application that accompanies this port. */
|
||||||
vApplicationSetupTimerInterrupt();
|
vApplicationSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Reuse the stack from main() as the stack for the interrupts/exceptions. */
|
/* Reuse the stack from main() as the stack for the interrupts/exceptions. */
|
||||||
pulISRStack = ( uint32_t * ) _stack;
|
pulISRStack = ( uint32_t * ) _stack;
|
||||||
|
|
||||||
/* Ensure there is enough space for the functions called from the interrupt
|
/* Ensure there is enough space for the functions called from the interrupt
|
||||||
* service routines to write back into the stack frame of the caller. */
|
service routines to write back into the stack frame of the caller. */
|
||||||
pulISRStack -= 2;
|
pulISRStack -= 2;
|
||||||
|
|
||||||
/* Restore the context of the first task that is going to run. From here
|
/* Restore the context of the first task that is going to run. From here
|
||||||
* on, the created tasks will be executing. */
|
on, the created tasks will be executing. */
|
||||||
vPortStartFirstTask();
|
vPortStartFirstTask();
|
||||||
|
|
||||||
/* Should not get here as the tasks are now running! */
|
/* Should not get here as the tasks are now running! */
|
||||||
|
@ -269,7 +267,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
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( uxCriticalNesting == 1000UL );
|
configASSERT( uxCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -279,17 +277,17 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
void vPortYield( void )
|
void vPortYield( void )
|
||||||
{
|
{
|
||||||
extern void VPortYieldASM( void );
|
extern void VPortYieldASM( void );
|
||||||
|
|
||||||
/* Perform the context switch in a critical section to assure it is
|
/* Perform the context switch in a critical section to assure it is
|
||||||
* not interrupted by the tick ISR. It is not a problem to do this as
|
not interrupted by the tick ISR. It is not a problem to do this as
|
||||||
* each task maintains its own interrupt status. */
|
each task maintains its own interrupt status. */
|
||||||
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
/* Jump directly to the yield function to ensure there is no
|
/* Jump directly to the yield function to ensure there is no
|
||||||
* compiler generated prologue code. */
|
compiler generated prologue code. */
|
||||||
asm volatile ( "bralid r14, VPortYieldASM \n\t"\
|
asm volatile ( "bralid r14, VPortYieldASM \n\t" \
|
||||||
"or r0, r0, r0 \n\t");
|
"or r0, r0, r0 \n\t" );
|
||||||
}
|
}
|
||||||
portEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
||||||
}
|
}
|
||||||
|
@ -297,13 +295,12 @@ void vPortYield( void )
|
||||||
|
|
||||||
void vPortEnableInterrupt( uint8_t ucInterruptID )
|
void vPortEnableInterrupt( uint8_t ucInterruptID )
|
||||||
{
|
{
|
||||||
int32_t lReturn;
|
int32_t lReturn;
|
||||||
|
|
||||||
/* An API function is provided to enable an interrupt in the interrupt
|
/* An API function is provided to enable an interrupt in the interrupt
|
||||||
* controller because the interrupt controller instance variable is private
|
controller because the interrupt controller instance variable is private
|
||||||
* to this file. */
|
to this file. */
|
||||||
lReturn = prvEnsureInterruptControllerIsInitialised();
|
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||||
|
|
||||||
if( lReturn == pdPASS )
|
if( lReturn == pdPASS )
|
||||||
{
|
{
|
||||||
XIntc_Enable( &xInterruptControllerInstance, ucInterruptID );
|
XIntc_Enable( &xInterruptControllerInstance, ucInterruptID );
|
||||||
|
@ -315,11 +312,11 @@ void vPortEnableInterrupt( uint8_t ucInterruptID )
|
||||||
|
|
||||||
void vPortDisableInterrupt( uint8_t ucInterruptID )
|
void vPortDisableInterrupt( uint8_t ucInterruptID )
|
||||||
{
|
{
|
||||||
int32_t lReturn;
|
int32_t lReturn;
|
||||||
|
|
||||||
/* An API function is provided to disable an interrupt in the interrupt
|
/* An API function is provided to disable an interrupt in the interrupt
|
||||||
* controller because the interrupt controller instance variable is private
|
controller because the interrupt controller instance variable is private
|
||||||
* to this file. */
|
to this file. */
|
||||||
lReturn = prvEnsureInterruptControllerIsInitialised();
|
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||||
|
|
||||||
if( lReturn == pdPASS )
|
if( lReturn == pdPASS )
|
||||||
|
@ -331,14 +328,12 @@ void vPortDisableInterrupt( uint8_t ucInterruptID )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID,
|
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )
|
||||||
XInterruptHandler pxHandler,
|
|
||||||
void * pvCallBackRef )
|
|
||||||
{
|
{
|
||||||
int32_t lReturn;
|
int32_t lReturn;
|
||||||
|
|
||||||
/* An API function is provided to install an interrupt handler because the
|
/* An API function is provided to install an interrupt handler because the
|
||||||
* interrupt controller instance variable is private to this file. */
|
interrupt controller instance variable is private to this file. */
|
||||||
|
|
||||||
lReturn = prvEnsureInterruptControllerIsInitialised();
|
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||||
|
|
||||||
|
@ -360,11 +355,11 @@ BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID,
|
||||||
|
|
||||||
static int32_t prvEnsureInterruptControllerIsInitialised( void )
|
static int32_t prvEnsureInterruptControllerIsInitialised( void )
|
||||||
{
|
{
|
||||||
static int32_t lInterruptControllerInitialised = pdFALSE;
|
static int32_t lInterruptControllerInitialised = pdFALSE;
|
||||||
int32_t lReturn;
|
int32_t lReturn;
|
||||||
|
|
||||||
/* Ensure the interrupt controller instance variable is initialised before
|
/* Ensure the interrupt controller instance variable is initialised before
|
||||||
* it is used, and that the initialisation only happens once. */
|
it is used, and that the initialisation only happens once. */
|
||||||
if( lInterruptControllerInitialised != pdTRUE )
|
if( lInterruptControllerInitialised != pdTRUE )
|
||||||
{
|
{
|
||||||
lReturn = prvInitialiseInterruptController();
|
lReturn = prvInitialiseInterruptController();
|
||||||
|
@ -387,19 +382,19 @@ static int32_t prvEnsureInterruptControllerIsInitialised( void )
|
||||||
* Handler for the timer interrupt. This is the handler that the application
|
* Handler for the timer interrupt. This is the handler that the application
|
||||||
* defined callback function vApplicationSetupTimerInterrupt() should install.
|
* defined callback function vApplicationSetupTimerInterrupt() should install.
|
||||||
*/
|
*/
|
||||||
void vPortTickISR( void * pvUnused )
|
void vPortTickISR( void *pvUnused )
|
||||||
{
|
{
|
||||||
extern void vApplicationClearTimerInterrupt( void );
|
extern void vApplicationClearTimerInterrupt( void );
|
||||||
|
|
||||||
/* Ensure the unused parameter does not generate a compiler warning. */
|
/* Ensure the unused parameter does not generate a compiler warning. */
|
||||||
( void ) pvUnused;
|
( void ) pvUnused;
|
||||||
|
|
||||||
/* This port uses an application defined callback function to clear the tick
|
/* This port uses an application defined callback function to clear the tick
|
||||||
* interrupt because the kernel will run on lots of different MicroBlaze and
|
interrupt because the kernel will run on lots of different MicroBlaze and
|
||||||
* FPGA configurations - not all of which will have the same timer peripherals
|
FPGA configurations - not all of which will have the same timer peripherals
|
||||||
* defined or available. An example definition of
|
defined or available. An example definition of
|
||||||
* vApplicationClearTimerInterrupt() is provided in the official demo
|
vApplicationClearTimerInterrupt() is provided in the official demo
|
||||||
* application that accompanies this port. */
|
application that accompanies this port. */
|
||||||
vApplicationClearTimerInterrupt();
|
vApplicationClearTimerInterrupt();
|
||||||
|
|
||||||
/* Increment the RTOS tick - this might cause a task to unblock. */
|
/* Increment the RTOS tick - this might cause a task to unblock. */
|
||||||
|
@ -413,7 +408,7 @@ void vPortTickISR( void * pvUnused )
|
||||||
|
|
||||||
static int32_t prvInitialiseInterruptController( void )
|
static int32_t prvInitialiseInterruptController( void )
|
||||||
{
|
{
|
||||||
int32_t lStatus;
|
int32_t lStatus;
|
||||||
|
|
||||||
lStatus = XIntc_Initialize( &xInterruptControllerInstance, configINTERRUPT_CONTROLLER_TO_USE );
|
lStatus = XIntc_Initialize( &xInterruptControllerInstance, configINTERRUPT_CONTROLLER_TO_USE );
|
||||||
|
|
||||||
|
@ -426,8 +421,8 @@ static int32_t prvInitialiseInterruptController( void )
|
||||||
XIntc_SetIntrSvcOption( xInterruptControllerInstance.BaseAddress, XIN_SVC_ALL_ISRS_OPTION );
|
XIntc_SetIntrSvcOption( xInterruptControllerInstance.BaseAddress, XIN_SVC_ALL_ISRS_OPTION );
|
||||||
|
|
||||||
/* Install exception handlers if the MicroBlaze is configured to handle
|
/* Install exception handlers if the MicroBlaze is configured to handle
|
||||||
* exceptions, and the application defined constant
|
exceptions, and the application defined constant
|
||||||
* configINSTALL_EXCEPTION_HANDLERS is set to 1. */
|
configINSTALL_EXCEPTION_HANDLERS is set to 1. */
|
||||||
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
||||||
{
|
{
|
||||||
vPortExceptionsInstallHandlers();
|
vPortExceptionsInstallHandlers();
|
||||||
|
@ -435,7 +430,7 @@ static int32_t prvInitialiseInterruptController( void )
|
||||||
#endif /* MICROBLAZE_EXCEPTIONS_ENABLED */
|
#endif /* MICROBLAZE_EXCEPTIONS_ENABLED */
|
||||||
|
|
||||||
/* Start the interrupt controller. Interrupts are enabled when the
|
/* Start the interrupt controller. Interrupts are enabled when the
|
||||||
* scheduler starts. */
|
scheduler starts. */
|
||||||
lStatus = XIntc_Start( &xInterruptControllerInstance, XIN_REAL_MODE );
|
lStatus = XIntc_Start( &xInterruptControllerInstance, XIN_REAL_MODE );
|
||||||
|
|
||||||
if( lStatus == XST_SUCCESS )
|
if( lStatus == XST_SUCCESS )
|
||||||
|
@ -453,3 +448,5 @@ static int32_t prvInitialiseInterruptController( void )
|
||||||
return lStatus;
|
return lStatus;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
#include <microblaze_exceptions_g.h>
|
#include <microblaze_exceptions_g.h>
|
||||||
|
|
||||||
/* The Xilinx library defined exception entry point stacks a number of
|
/* The Xilinx library defined exception entry point stacks a number of
|
||||||
* registers. These definitions are offsets from the stack pointer to the various
|
registers. These definitions are offsets from the stack pointer to the various
|
||||||
* stacked register values. */
|
stacked register values. */
|
||||||
#define portexR3_STACK_OFFSET 4
|
#define portexR3_STACK_OFFSET 4
|
||||||
#define portexR4_STACK_OFFSET 5
|
#define portexR4_STACK_OFFSET 5
|
||||||
#define portexR5_STACK_OFFSET 6
|
#define portexR5_STACK_OFFSET 6
|
||||||
|
@ -52,69 +52,69 @@
|
||||||
#define portexR19_STACK_OFFSET -1
|
#define portexR19_STACK_OFFSET -1
|
||||||
|
|
||||||
/* This is defined to equal the size, in bytes, of the stack frame generated by
|
/* This is defined to equal the size, in bytes, of the stack frame generated by
|
||||||
* the Xilinx standard library exception entry point. It is required to determine
|
the Xilinx standard library exception entry point. It is required to determine
|
||||||
* the stack pointer value prior to the exception being entered. */
|
the stack pointer value prior to the exception being entered. */
|
||||||
#define portexASM_HANDLER_STACK_FRAME_SIZE 84UL
|
#define portexASM_HANDLER_STACK_FRAME_SIZE 84UL
|
||||||
|
|
||||||
/* The number of bytes a MicroBlaze instruction consumes. */
|
/* The number of bytes a MicroBlaze instruction consumes. */
|
||||||
#define portexINSTRUCTION_SIZE 4
|
#define portexINSTRUCTION_SIZE 4
|
||||||
|
|
||||||
/* Exclude this entire file if the MicroBlaze is not configured to handle
|
/* Exclude this entire file if the MicroBlaze is not configured to handle
|
||||||
* exceptions, or the application defined configuration constant
|
exceptions, or the application defined configuration constant
|
||||||
* configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
||||||
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
||||||
|
|
||||||
/* This variable is set in the exception entry code, before
|
/* This variable is set in the exception entry code, before
|
||||||
* vPortExceptionHandler is called. */
|
vPortExceptionHandler is called. */
|
||||||
uint32_t * pulStackPointerOnFunctionEntry = NULL;
|
uint32_t *pulStackPointerOnFunctionEntry = NULL;
|
||||||
|
|
||||||
/* This is the structure that is filled with the MicroBlaze context as it
|
/* This is the structure that is filled with the MicroBlaze context as it
|
||||||
* existed immediately prior to the exception occurrence. A pointer to this
|
existed immediately prior to the exception occurrence. A pointer to this
|
||||||
* structure is passed into the vApplicationExceptionRegisterDump() callback
|
structure is passed into the vApplicationExceptionRegisterDump() callback
|
||||||
* function, if one is defined. */
|
function, if one is defined. */
|
||||||
static xPortRegisterDump xRegisterDump;
|
static xPortRegisterDump xRegisterDump;
|
||||||
|
|
||||||
/* This is the FreeRTOS exception handler that is installed for all exception
|
/* This is the FreeRTOS exception handler that is installed for all exception
|
||||||
* types. It is called from vPortExceptionHanlderEntry() - which is itself defined
|
types. It is called from vPortExceptionHanlderEntry() - which is itself defined
|
||||||
* in portasm.S. */
|
in portasm.S. */
|
||||||
void vPortExceptionHandler( void * pvExceptionID );
|
void vPortExceptionHandler( void *pvExceptionID );
|
||||||
extern void vPortExceptionHandlerEntry( void * pvExceptionID );
|
extern void vPortExceptionHandlerEntry( void *pvExceptionID );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* vApplicationExceptionRegisterDump() is a callback function that the
|
/* vApplicationExceptionRegisterDump() is a callback function that the
|
||||||
* application can optionally define to receive a populated xPortRegisterDump
|
application can optionally define to receive a populated xPortRegisterDump
|
||||||
* structure. If the application chooses not to define a version of
|
structure. If the application chooses not to define a version of
|
||||||
* vApplicationExceptionRegisterDump() then this weekly defined default
|
vApplicationExceptionRegisterDump() then this weekly defined default
|
||||||
* implementation will be called instead. */
|
implementation will be called instead. */
|
||||||
extern void vApplicationExceptionRegisterDump( xPortRegisterDump * xRegisterDump ) __attribute__( ( weak ) );
|
extern void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump ) __attribute__((weak));
|
||||||
void vApplicationExceptionRegisterDump( xPortRegisterDump * xRegisterDump )
|
void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )
|
||||||
{
|
{
|
||||||
( void ) xRegisterDump;
|
( void ) xRegisterDump;
|
||||||
|
|
||||||
for( ; ; )
|
for( ;; )
|
||||||
{
|
{
|
||||||
portNOP();
|
portNOP();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortExceptionHandler( void * pvExceptionID )
|
void vPortExceptionHandler( void *pvExceptionID )
|
||||||
{
|
{
|
||||||
extern void * pxCurrentTCB;
|
extern void *pxCurrentTCB;
|
||||||
|
|
||||||
/* Fill an xPortRegisterDump structure with the MicroBlaze context as it
|
/* Fill an xPortRegisterDump structure with the MicroBlaze context as it
|
||||||
* was immediately before the exception occurrence. */
|
was immediately before the exception occurrence. */
|
||||||
|
|
||||||
/* First fill in the name and handle of the task that was in the Running
|
/* First fill in the name and handle of the task that was in the Running
|
||||||
* state when the exception occurred. */
|
state when the exception occurred. */
|
||||||
xRegisterDump.xCurrentTaskHandle = pxCurrentTCB;
|
xRegisterDump.xCurrentTaskHandle = pxCurrentTCB;
|
||||||
xRegisterDump.pcCurrentTaskName = pcTaskGetName( NULL );
|
xRegisterDump.pcCurrentTaskName = pcTaskGetName( NULL );
|
||||||
|
|
||||||
configASSERT( pulStackPointerOnFunctionEntry );
|
configASSERT( pulStackPointerOnFunctionEntry );
|
||||||
|
|
||||||
/* Obtain the values of registers that were stacked prior to this function
|
/* Obtain the values of registers that were stacked prior to this function
|
||||||
* being called, and may have changed since they were stacked. */
|
being called, and may have changed since they were stacked. */
|
||||||
xRegisterDump.ulR3 = pulStackPointerOnFunctionEntry[ portexR3_STACK_OFFSET ];
|
xRegisterDump.ulR3 = pulStackPointerOnFunctionEntry[ portexR3_STACK_OFFSET ];
|
||||||
xRegisterDump.ulR4 = pulStackPointerOnFunctionEntry[ portexR4_STACK_OFFSET ];
|
xRegisterDump.ulR4 = pulStackPointerOnFunctionEntry[ portexR4_STACK_OFFSET ];
|
||||||
xRegisterDump.ulR5 = pulStackPointerOnFunctionEntry[ portexR5_STACK_OFFSET ];
|
xRegisterDump.ulR5 = pulStackPointerOnFunctionEntry[ portexR5_STACK_OFFSET ];
|
||||||
|
@ -154,11 +154,11 @@
|
||||||
xRegisterDump.ulEDR = mfedr();
|
xRegisterDump.ulEDR = mfedr();
|
||||||
|
|
||||||
/* Move the saved program counter back to the instruction that was executed
|
/* Move the saved program counter back to the instruction that was executed
|
||||||
* when the exception occurred. This is only valid for certain types of
|
when the exception occurred. This is only valid for certain types of
|
||||||
* exception. */
|
exception. */
|
||||||
xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_exceptions - portexINSTRUCTION_SIZE;
|
xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_exceptions - portexINSTRUCTION_SIZE;
|
||||||
|
|
||||||
#if ( XPAR_MICROBLAZE_USE_FPU != 0 )
|
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
|
||||||
{
|
{
|
||||||
xRegisterDump.ulFSR = mffsr();
|
xRegisterDump.ulFSR = mffsr();
|
||||||
}
|
}
|
||||||
|
@ -169,63 +169,65 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Also fill in a string that describes what type of exception this is.
|
/* Also fill in a string that describes what type of exception this is.
|
||||||
* The string uses the same ID names as defined in the MicroBlaze standard
|
The string uses the same ID names as defined in the MicroBlaze standard
|
||||||
* library exception header files. */
|
library exception header files. */
|
||||||
switch( ( uint32_t ) pvExceptionID )
|
switch( ( uint32_t ) pvExceptionID )
|
||||||
{
|
{
|
||||||
case XEXC_ID_FSL:
|
case XEXC_ID_FSL :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_FSL";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_FSL";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEXC_ID_UNALIGNED_ACCESS:
|
case XEXC_ID_UNALIGNED_ACCESS :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_UNALIGNED_ACCESS";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_UNALIGNED_ACCESS";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEXC_ID_ILLEGAL_OPCODE:
|
case XEXC_ID_ILLEGAL_OPCODE :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_ILLEGAL_OPCODE";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_ILLEGAL_OPCODE";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEXC_ID_M_AXI_I_EXCEPTION:
|
case XEXC_ID_M_AXI_I_EXCEPTION :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_M_AXI_I_EXCEPTION or XEXC_ID_IPLB_EXCEPTION";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_M_AXI_I_EXCEPTION or XEXC_ID_IPLB_EXCEPTION";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEXC_ID_M_AXI_D_EXCEPTION:
|
case XEXC_ID_M_AXI_D_EXCEPTION :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_M_AXI_D_EXCEPTION or XEXC_ID_DPLB_EXCEPTION";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_M_AXI_D_EXCEPTION or XEXC_ID_DPLB_EXCEPTION";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEXC_ID_DIV_BY_ZERO:
|
case XEXC_ID_DIV_BY_ZERO :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_DIV_BY_ZERO";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_DIV_BY_ZERO";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEXC_ID_STACK_VIOLATION:
|
case XEXC_ID_STACK_VIOLATION :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_STACK_VIOLATION or XEXC_ID_MMU";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_STACK_VIOLATION or XEXC_ID_MMU";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if ( XPAR_MICROBLAZE_USE_FPU != 0 )
|
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
|
||||||
case XEXC_ID_FPU:
|
|
||||||
|
case XEXC_ID_FPU :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_FPU see ulFSR value";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_FPU see ulFSR value";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#endif /* XPAR_MICROBLAZE_USE_FPU */
|
#endif /* XPAR_MICROBLAZE_USE_FPU */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vApplicationExceptionRegisterDump() is a callback function that the
|
/* vApplicationExceptionRegisterDump() is a callback function that the
|
||||||
* application can optionally define to receive the populated xPortRegisterDump
|
application can optionally define to receive the populated xPortRegisterDump
|
||||||
* structure. If the application chooses not to define a version of
|
structure. If the application chooses not to define a version of
|
||||||
* vApplicationExceptionRegisterDump() then the weekly defined default
|
vApplicationExceptionRegisterDump() then the weekly defined default
|
||||||
* implementation within this file will be called instead. */
|
implementation within this file will be called instead. */
|
||||||
vApplicationExceptionRegisterDump( &xRegisterDump );
|
vApplicationExceptionRegisterDump( &xRegisterDump );
|
||||||
|
|
||||||
/* Must not attempt to leave this function! */
|
/* Must not attempt to leave this function! */
|
||||||
for( ; ; )
|
for( ;; )
|
||||||
{
|
{
|
||||||
portNOP();
|
portNOP();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortExceptionsInstallHandlers( void )
|
void vPortExceptionsInstallHandlers( void )
|
||||||
{
|
{
|
||||||
static uint32_t ulHandlersAlreadyInstalled = pdFALSE;
|
static uint32_t ulHandlersAlreadyInstalled = pdFALSE;
|
||||||
|
|
||||||
if( ulHandlersAlreadyInstalled == pdFALSE )
|
if( ulHandlersAlreadyInstalled == pdFALSE )
|
||||||
{
|
{
|
||||||
|
@ -269,9 +271,12 @@
|
||||||
|
|
||||||
microblaze_enable_exceptions();
|
microblaze_enable_exceptions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exclude the entire file if the MicroBlaze is not configured to handle
|
/* Exclude the entire file if the MicroBlaze is not configured to handle
|
||||||
* exceptions, or the application defined configuration item
|
exceptions, or the application defined configuration item
|
||||||
* configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
||||||
#endif /* ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) */
|
#endif /* ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,15 +26,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* BSP includes. */
|
/* BSP includes. */
|
||||||
#include <mb_interface.h>
|
#include <mb_interface.h>
|
||||||
#include <xparameters.h>
|
#include <xparameters.h>
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -47,50 +47,48 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
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
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Interrupt control macros and functions. */
|
/* Interrupt control macros and functions. */
|
||||||
void microblaze_disable_interrupts( void );
|
void microblaze_disable_interrupts( void );
|
||||||
void microblaze_enable_interrupts( void );
|
void microblaze_enable_interrupts( void );
|
||||||
#define portDISABLE_INTERRUPTS() microblaze_disable_interrupts()
|
#define portDISABLE_INTERRUPTS() microblaze_disable_interrupts()
|
||||||
#define portENABLE_INTERRUPTS() microblaze_enable_interrupts()
|
#define portENABLE_INTERRUPTS() microblaze_enable_interrupts()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section macros. */
|
/* Critical section macros. */
|
||||||
void vPortEnterCritical( void );
|
void vPortEnterCritical( void );
|
||||||
void vPortExitCritical( void );
|
void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() { \
|
||||||
{ \
|
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
microblaze_disable_interrupts(); \
|
microblaze_disable_interrupts(); \
|
||||||
uxCriticalNesting++; \
|
uxCriticalNesting++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() { \
|
||||||
{ \
|
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
/* Interrupts are disabled, so we can */ \
|
/* Interrupts are disabled, so we can */ \
|
||||||
/* access the variable directly. */ \
|
/* access the variable directly. */ \
|
||||||
|
@ -98,7 +96,7 @@
|
||||||
if( uxCriticalNesting == 0 ) \
|
if( uxCriticalNesting == 0 ) \
|
||||||
{ \
|
{ \
|
||||||
/* The nesting has unwound and we \
|
/* The nesting has unwound and we \
|
||||||
* can enable interrupts again. */ \
|
can enable interrupts again. */ \
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
@ -106,66 +104,65 @@
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The yield macro maps directly to the vPortYield() function. */
|
/* The yield macro maps directly to the vPortYield() function. */
|
||||||
void vPortYield( void );
|
void vPortYield( void );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
|
|
||||||
/* portYIELD_FROM_ISR() does not directly call vTaskSwitchContext(), but instead
|
/* portYIELD_FROM_ISR() does not directly call vTaskSwitchContext(), but instead
|
||||||
* sets a flag to say that a yield has been requested. The interrupt exit code
|
sets a flag to say that a yield has been requested. The interrupt exit code
|
||||||
* then checks this flag, and calls vTaskSwitchContext() before restoring a task
|
then checks this flag, and calls vTaskSwitchContext() before restoring a task
|
||||||
* context, if the flag is not false. This is done to prevent multiple calls to
|
context, if the flag is not false. This is done to prevent multiple calls to
|
||||||
* vTaskSwitchContext() being made from a single interrupt, as a single interrupt
|
vTaskSwitchContext() being made from a single interrupt, as a single interrupt
|
||||||
* can result in multiple peripherals being serviced. */
|
can result in multiple peripherals being serviced. */
|
||||||
extern volatile uint32_t ulTaskSwitchRequested;
|
extern volatile uint32_t ulTaskSwitchRequested;
|
||||||
#define portYIELD_FROM_ISR( x ) if( ( x ) != pdFALSE ) ulTaskSwitchRequested = 1
|
#define portYIELD_FROM_ISR( x ) if( ( x ) != pdFALSE ) ulTaskSwitchRequested = 1
|
||||||
|
|
||||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
#if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
/* Generic helper function. */
|
/* Generic helper function. */
|
||||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
{
|
{
|
||||||
uint8_t ucReturn;
|
uint8_t ucReturn;
|
||||||
|
|
||||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) );
|
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) );
|
||||||
|
|
||||||
return ucReturn;
|
return ucReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if ( configMAX_PRIORITIES > 32 )
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#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() asm volatile ( "NOP" )
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The following structure is used by the FreeRTOS exception handler. It is
|
/* The following structure is used by the FreeRTOS exception handler. It is
|
||||||
* filled with the MicroBlaze context as it was at the time the exception occurred.
|
filled with the MicroBlaze context as it was at the time the exception occurred.
|
||||||
* This is done as an aid to debugging exception occurrences. */
|
This is done as an aid to debugging exception occurrences. */
|
||||||
typedef struct PORT_REGISTER_DUMP
|
typedef struct PORT_REGISTER_DUMP
|
||||||
{
|
{
|
||||||
/* The following structure members hold the values of the MicroBlaze
|
/* The following structure members hold the values of the MicroBlaze
|
||||||
* registers at the time the exception was raised. */
|
registers at the time the exception was raised. */
|
||||||
uint32_t ulR1_SP;
|
uint32_t ulR1_SP;
|
||||||
uint32_t ulR2_small_data_area;
|
uint32_t ulR2_small_data_area;
|
||||||
uint32_t ulR3;
|
uint32_t ulR3;
|
||||||
|
@ -205,19 +202,20 @@
|
||||||
uint32_t ulEDR;
|
uint32_t ulEDR;
|
||||||
|
|
||||||
/* A human readable description of the exception cause. The strings used
|
/* A human readable description of the exception cause. The strings used
|
||||||
* are the same as the #define constant names found in the
|
are the same as the #define constant names found in the
|
||||||
* microblaze_exceptions_i.h header file */
|
microblaze_exceptions_i.h header file */
|
||||||
int8_t * pcExceptionCause;
|
int8_t *pcExceptionCause;
|
||||||
|
|
||||||
/* The human readable name of the task that was running at the time the
|
/* The human readable name of the task that was running at the time the
|
||||||
* exception occurred. This is the name that was given to the task when the
|
exception occurred. This is the name that was given to the task when the
|
||||||
* task was created using the FreeRTOS xTaskCreate() API function. */
|
task was created using the FreeRTOS xTaskCreate() API function. */
|
||||||
char * pcCurrentTaskName;
|
char *pcCurrentTaskName;
|
||||||
|
|
||||||
/* The handle of the task that was running a the time the exception
|
/* The handle of the task that was running a the time the exception
|
||||||
* occurred. */
|
occurred. */
|
||||||
void * xCurrentTaskHandle;
|
void * xCurrentTaskHandle;
|
||||||
} xPortRegisterDump;
|
|
||||||
|
} xPortRegisterDump;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -255,9 +253,7 @@
|
||||||
* pdPASS is returned if the function executes successfully. Any other value
|
* pdPASS is returned if the function executes successfully. Any other value
|
||||||
* being returned indicates that the function did not execute correctly.
|
* being returned indicates that the function did not execute correctly.
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID,
|
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );
|
||||||
XInterruptHandler pxHandler,
|
|
||||||
void * pvCallBackRef );
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -278,7 +274,7 @@
|
||||||
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void vPortEnableInterrupt( uint8_t ucInterruptID );
|
void vPortEnableInterrupt( uint8_t ucInterruptID );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disables the interrupt, within the interrupt controller, for the peripheral
|
* Disables the interrupt, within the interrupt controller, for the peripheral
|
||||||
|
@ -298,7 +294,7 @@
|
||||||
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void vPortDisableInterrupt( uint8_t ucInterruptID );
|
void vPortDisableInterrupt( uint8_t ucInterruptID );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is an application defined callback function used to install the tick
|
* This is an application defined callback function used to install the tick
|
||||||
|
@ -310,7 +306,7 @@
|
||||||
* The name of the interrupt handler that should be installed is vPortTickISR(),
|
* The name of the interrupt handler that should be installed is vPortTickISR(),
|
||||||
* which the function below declares as an extern.
|
* which the function below declares as an extern.
|
||||||
*/
|
*/
|
||||||
void vApplicationSetupTimerInterrupt( void );
|
void vApplicationSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is an application defined callback function used to clear whichever
|
* This is an application defined callback function used to clear whichever
|
||||||
|
@ -323,7 +319,7 @@
|
||||||
* implementation should not require modification provided the example definition
|
* implementation should not require modification provided the example definition
|
||||||
* of vApplicationSetupTimerInterrupt() is also not modified.
|
* of vApplicationSetupTimerInterrupt() is also not modified.
|
||||||
*/
|
*/
|
||||||
void vApplicationClearTimerInterrupt( void );
|
void vApplicationClearTimerInterrupt( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vPortExceptionsInstallHandlers() is only available when the MicroBlaze
|
* vPortExceptionsInstallHandlers() is only available when the MicroBlaze
|
||||||
|
@ -346,7 +342,7 @@
|
||||||
* See the description of vApplicationExceptionRegisterDump() for information
|
* See the description of vApplicationExceptionRegisterDump() for information
|
||||||
* on the processing performed by the FreeRTOS exception handler.
|
* on the processing performed by the FreeRTOS exception handler.
|
||||||
*/
|
*/
|
||||||
void vPortExceptionsInstallHandlers( void );
|
void vPortExceptionsInstallHandlers( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The FreeRTOS exception handler fills an xPortRegisterDump structure (defined
|
* The FreeRTOS exception handler fills an xPortRegisterDump structure (defined
|
||||||
|
@ -362,11 +358,12 @@
|
||||||
* register dump information. For example, an implementation could be provided
|
* register dump information. For example, an implementation could be provided
|
||||||
* that wrote the register dump data to a display, or a UART port.
|
* that wrote the register dump data to a display, or a UART port.
|
||||||
*/
|
*/
|
||||||
void vApplicationExceptionRegisterDump( xPortRegisterDump * xRegisterDump );
|
void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump );
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the MicroBlaze port.
|
* Implementation of functions defined in portable.h for the MicroBlaze port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
|
@ -43,19 +43,19 @@
|
||||||
#include <microblaze_exceptions_g.h>
|
#include <microblaze_exceptions_g.h>
|
||||||
|
|
||||||
/* Tasks are started with a critical section nesting of 0 - however, prior to
|
/* Tasks are started with a critical section nesting of 0 - however, prior to
|
||||||
* the scheduler being commenced interrupts should not be enabled, so the critical
|
the scheduler being commenced interrupts should not be enabled, so the critical
|
||||||
* nesting variable is initialised to a non-zero value. */
|
nesting variable is initialised to a non-zero value. */
|
||||||
#define portINITIAL_NESTING_VALUE ( 0xff )
|
#define portINITIAL_NESTING_VALUE ( 0xff )
|
||||||
|
|
||||||
/* The bit within the MSR register that enabled/disables interrupts and
|
/* The bit within the MSR register that enabled/disables interrupts and
|
||||||
* exceptions respectively. */
|
exceptions respectively. */
|
||||||
#define portMSR_IE ( 0x02U )
|
#define portMSR_IE ( 0x02U )
|
||||||
#define portMSR_EE ( 0x100U )
|
#define portMSR_EE ( 0x100U )
|
||||||
|
|
||||||
/* If the floating point unit is included in the MicroBlaze build, then the
|
/* If the floating point unit is included in the MicroBlaze build, then the
|
||||||
* FSR register is saved as part of the task context. portINITIAL_FSR is the value
|
FSR register is saved as part of the task context. portINITIAL_FSR is the value
|
||||||
* given to the FSR register when the initial context is set up for a task being
|
given to the FSR register when the initial context is set up for a task being
|
||||||
* created. */
|
created. */
|
||||||
#define portINITIAL_FSR ( 0U )
|
#define portINITIAL_FSR ( 0U )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -73,27 +73,27 @@ static int32_t prvEnsureInterruptControllerIsInitialised( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
|
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
|
||||||
* maintains its own count, so this variable is saved as part of the task
|
maintains its own count, so this variable is saved as part of the task
|
||||||
* context. */
|
context. */
|
||||||
volatile UBaseType_t uxCriticalNesting = portINITIAL_NESTING_VALUE;
|
volatile UBaseType_t uxCriticalNesting = portINITIAL_NESTING_VALUE;
|
||||||
|
|
||||||
/* This port uses a separate stack for interrupts. This prevents the stack of
|
/* This port uses a separate stack for interrupts. This prevents the stack of
|
||||||
* every task needing to be large enough to hold an entire interrupt stack on top
|
every task needing to be large enough to hold an entire interrupt stack on top
|
||||||
* of the task stack. */
|
of the task stack. */
|
||||||
uint32_t * pulISRStack;
|
uint32_t *pulISRStack;
|
||||||
|
|
||||||
/* If an interrupt requests a context switch, then ulTaskSwitchRequested will
|
/* If an interrupt requests a context switch, then ulTaskSwitchRequested will
|
||||||
* get set to 1. ulTaskSwitchRequested is inspected just before the main interrupt
|
get set to 1. ulTaskSwitchRequested is inspected just before the main interrupt
|
||||||
* handler exits. If, at that time, ulTaskSwitchRequested is set to 1, the kernel
|
handler exits. If, at that time, ulTaskSwitchRequested is set to 1, the kernel
|
||||||
* will call vTaskSwitchContext() to ensure the task that runs immediately after
|
will call vTaskSwitchContext() to ensure the task that runs immediately after
|
||||||
* the interrupt exists is the highest priority task that is able to run. This is
|
the interrupt exists is the highest priority task that is able to run. This is
|
||||||
* an unusual mechanism, but is used for this port because a single interrupt can
|
an unusual mechanism, but is used for this port because a single interrupt can
|
||||||
* cause the servicing of multiple peripherals - and it is inefficient to call
|
cause the servicing of multiple peripherals - and it is inefficient to call
|
||||||
* vTaskSwitchContext() multiple times as each peripheral is serviced. */
|
vTaskSwitchContext() multiple times as each peripheral is serviced. */
|
||||||
volatile uint32_t ulTaskSwitchRequested = 0UL;
|
volatile uint32_t ulTaskSwitchRequested = 0UL;
|
||||||
|
|
||||||
/* The instance of the interrupt controller used by this port. This is required
|
/* The instance of the interrupt controller used by this port. This is required
|
||||||
* by the Xilinx library API functions. */
|
by the Xilinx library API functions. */
|
||||||
static XIntc xInterruptControllerInstance;
|
static XIntc xInterruptControllerInstance;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -104,18 +104,16 @@ static XIntc xInterruptControllerInstance;
|
||||||
*
|
*
|
||||||
* See the portable.h header file.
|
* See the portable.h header file.
|
||||||
*/
|
*/
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
TaskFunction_t pxCode,
|
|
||||||
void * pvParameters )
|
|
||||||
{
|
{
|
||||||
extern void * _SDA2_BASE_, * _SDA_BASE_;
|
extern void *_SDA2_BASE_, *_SDA_BASE_;
|
||||||
const uint32_t ulR2 = ( uint32_t ) &_SDA2_BASE_;
|
const uint32_t ulR2 = ( uint32_t ) &_SDA2_BASE_;
|
||||||
const uint32_t ulR13 = ( uint32_t ) &_SDA_BASE_;
|
const uint32_t ulR13 = ( uint32_t ) &_SDA_BASE_;
|
||||||
extern void _start1( void );
|
extern void _start1( void );
|
||||||
|
|
||||||
/* Place a few bytes of known values on the bottom of the stack.
|
/* Place a few bytes of known values on the bottom of the stack.
|
||||||
* This is essential for the Microblaze port and these lines must
|
This is essential for the Microblaze port and these lines must
|
||||||
* not be omitted. */
|
not be omitted. */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
||||||
|
@ -123,18 +121,18 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
#if ( XPAR_MICROBLAZE_USE_FPU != 0 )
|
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
|
||||||
/* The FSR value placed in the initial task context is just 0. */
|
/* The FSR value placed in the initial task context is just 0. */
|
||||||
*pxTopOfStack = portINITIAL_FSR;
|
*pxTopOfStack = portINITIAL_FSR;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The MSR value placed in the initial task context should have interrupts
|
/* The MSR value placed in the initial task context should have interrupts
|
||||||
* disabled. Each task will enable interrupts automatically when it enters
|
disabled. Each task will enable interrupts automatically when it enters
|
||||||
* the running state for the first time. */
|
the running state for the first time. */
|
||||||
*pxTopOfStack = mfmsr() & ~portMSR_IE;
|
*pxTopOfStack = mfmsr() & ~portMSR_IE;
|
||||||
|
|
||||||
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 )
|
#if( MICROBLAZE_EXCEPTIONS_ENABLED == 1 )
|
||||||
{
|
{
|
||||||
/* Ensure exceptions are enabled for the task. */
|
/* Ensure exceptions are enabled for the task. */
|
||||||
*pxTopOfStack |= portMSR_EE;
|
*pxTopOfStack |= portMSR_EE;
|
||||||
|
@ -144,7 +142,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* First stack an initial value for the critical section nesting. This
|
/* First stack an initial value for the critical section nesting. This
|
||||||
* is initialised to zero. */
|
is initialised to zero. */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||||
|
|
||||||
/* R0 is always zero. */
|
/* R0 is always zero. */
|
||||||
|
@ -158,7 +156,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x04; /* R4 - return values and temporaries. */
|
*pxTopOfStack = ( StackType_t ) 0x04; /* R4 - return values and temporaries. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R5 contains the function call parameters. */
|
*pxTopOfStack = ( StackType_t ) pvParameters;/* R5 contains the function call parameters. */
|
||||||
|
|
||||||
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -176,9 +174,9 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x0c; /* R12 - temporaries. */
|
*pxTopOfStack = ( StackType_t ) 0x0c; /* R12 - temporaries. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
#else /* ifdef portPRE_LOAD_STACK_FOR_DEBUGGING */
|
#else
|
||||||
pxTopOfStack -= 8;
|
pxTopOfStack-= 8;
|
||||||
#endif /* ifdef portPRE_LOAD_STACK_FOR_DEBUGGING */
|
#endif
|
||||||
|
|
||||||
*pxTopOfStack = ( StackType_t ) ulR13; /* R13 - read/write small data area. */
|
*pxTopOfStack = ( StackType_t ) ulR13; /* R13 - read/write small data area. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -226,41 +224,41 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x1f; /* R31 - must be saved across function calls. Callee-save. */
|
*pxTopOfStack = ( StackType_t ) 0x1f; /* R31 - must be saved across function calls. Callee-save. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
#else /* ifdef portPRE_LOAD_STACK_FOR_DEBUGGING */
|
#else
|
||||||
pxTopOfStack -= 13;
|
pxTopOfStack -= 13;
|
||||||
#endif /* ifdef portPRE_LOAD_STACK_FOR_DEBUGGING */
|
#endif
|
||||||
|
|
||||||
/* Return a pointer to the top of the stack that has been generated so this
|
/* Return a pointer to the top of the stack that has been generated so this
|
||||||
* can be stored in the task control block for the task. */
|
can be stored in the task control block for the task. */
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void( vPortStartFirstTask )( void );
|
extern void ( vPortStartFirstTask )( void );
|
||||||
extern uint32_t _stack[];
|
extern uint32_t _stack[];
|
||||||
|
|
||||||
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
||||||
* this function is called.
|
this function is called.
|
||||||
*
|
|
||||||
* This port uses an application defined callback function to install the tick
|
This port uses an application defined callback function to install the tick
|
||||||
* interrupt handler because the kernel will run on lots of different
|
interrupt handler because the kernel will run on lots of different
|
||||||
* MicroBlaze and FPGA configurations - not all of which will have the same
|
MicroBlaze and FPGA configurations - not all of which will have the same
|
||||||
* timer peripherals defined or available. An example definition of
|
timer peripherals defined or available. An example definition of
|
||||||
* vApplicationSetupTimerInterrupt() is provided in the official demo
|
vApplicationSetupTimerInterrupt() is provided in the official demo
|
||||||
* application that accompanies this port. */
|
application that accompanies this port. */
|
||||||
vApplicationSetupTimerInterrupt();
|
vApplicationSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Reuse the stack from main() as the stack for the interrupts/exceptions. */
|
/* Reuse the stack from main() as the stack for the interrupts/exceptions. */
|
||||||
pulISRStack = ( uint32_t * ) _stack;
|
pulISRStack = ( uint32_t * ) _stack;
|
||||||
|
|
||||||
/* Ensure there is enough space for the functions called from the interrupt
|
/* Ensure there is enough space for the functions called from the interrupt
|
||||||
* service routines to write back into the stack frame of the caller. */
|
service routines to write back into the stack frame of the caller. */
|
||||||
pulISRStack -= 2;
|
pulISRStack -= 2;
|
||||||
|
|
||||||
/* Restore the context of the first task that is going to run. From here
|
/* Restore the context of the first task that is going to run. From here
|
||||||
* on, the created tasks will be executing. */
|
on, the created tasks will be executing. */
|
||||||
vPortStartFirstTask();
|
vPortStartFirstTask();
|
||||||
|
|
||||||
/* Should not get here as the tasks are now running! */
|
/* Should not get here as the tasks are now running! */
|
||||||
|
@ -271,7 +269,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
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( uxCriticalNesting == 1000UL );
|
configASSERT( uxCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -281,17 +279,17 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
void vPortYield( void )
|
void vPortYield( void )
|
||||||
{
|
{
|
||||||
extern void VPortYieldASM( void );
|
extern void VPortYieldASM( void );
|
||||||
|
|
||||||
/* Perform the context switch in a critical section to assure it is
|
/* Perform the context switch in a critical section to assure it is
|
||||||
* not interrupted by the tick ISR. It is not a problem to do this as
|
not interrupted by the tick ISR. It is not a problem to do this as
|
||||||
* each task maintains its own interrupt status. */
|
each task maintains its own interrupt status. */
|
||||||
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
/* Jump directly to the yield function to ensure there is no
|
/* Jump directly to the yield function to ensure there is no
|
||||||
* compiler generated prologue code. */
|
compiler generated prologue code. */
|
||||||
asm volatile ( "bralid r14, VPortYieldASM \n\t"\
|
asm volatile ( "bralid r14, VPortYieldASM \n\t" \
|
||||||
"or r0, r0, r0 \n\t");
|
"or r0, r0, r0 \n\t" );
|
||||||
}
|
}
|
||||||
portEXIT_CRITICAL();
|
portEXIT_CRITICAL();
|
||||||
}
|
}
|
||||||
|
@ -299,17 +297,16 @@ void vPortYield( void )
|
||||||
|
|
||||||
void vPortEnableInterrupt( uint8_t ucInterruptID )
|
void vPortEnableInterrupt( uint8_t ucInterruptID )
|
||||||
{
|
{
|
||||||
int32_t lReturn;
|
int32_t lReturn;
|
||||||
|
|
||||||
/* An API function is provided to enable an interrupt in the interrupt
|
/* An API function is provided to enable an interrupt in the interrupt
|
||||||
* controller because the interrupt controller instance variable is private
|
controller because the interrupt controller instance variable is private
|
||||||
* to this file. */
|
to this file. */
|
||||||
lReturn = prvEnsureInterruptControllerIsInitialised();
|
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||||
|
|
||||||
if( lReturn == pdPASS )
|
if( lReturn == pdPASS )
|
||||||
{
|
{
|
||||||
/* Critical section protects read/modify/writer operation inside
|
/* Critical section protects read/modify/writer operation inside
|
||||||
* XIntc_Enable(). */
|
XIntc_Enable(). */
|
||||||
portENTER_CRITICAL();
|
portENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
XIntc_Enable( &xInterruptControllerInstance, ucInterruptID );
|
XIntc_Enable( &xInterruptControllerInstance, ucInterruptID );
|
||||||
|
@ -323,11 +320,11 @@ void vPortEnableInterrupt( uint8_t ucInterruptID )
|
||||||
|
|
||||||
void vPortDisableInterrupt( uint8_t ucInterruptID )
|
void vPortDisableInterrupt( uint8_t ucInterruptID )
|
||||||
{
|
{
|
||||||
int32_t lReturn;
|
int32_t lReturn;
|
||||||
|
|
||||||
/* An API function is provided to disable an interrupt in the interrupt
|
/* An API function is provided to disable an interrupt in the interrupt
|
||||||
* controller because the interrupt controller instance variable is private
|
controller because the interrupt controller instance variable is private
|
||||||
* to this file. */
|
to this file. */
|
||||||
lReturn = prvEnsureInterruptControllerIsInitialised();
|
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||||
|
|
||||||
if( lReturn == pdPASS )
|
if( lReturn == pdPASS )
|
||||||
|
@ -339,14 +336,12 @@ void vPortDisableInterrupt( uint8_t ucInterruptID )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID,
|
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )
|
||||||
XInterruptHandler pxHandler,
|
|
||||||
void * pvCallBackRef )
|
|
||||||
{
|
{
|
||||||
int32_t lReturn;
|
int32_t lReturn;
|
||||||
|
|
||||||
/* An API function is provided to install an interrupt handler because the
|
/* An API function is provided to install an interrupt handler because the
|
||||||
* interrupt controller instance variable is private to this file. */
|
interrupt controller instance variable is private to this file. */
|
||||||
|
|
||||||
lReturn = prvEnsureInterruptControllerIsInitialised();
|
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||||
|
|
||||||
|
@ -368,11 +363,11 @@ BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID,
|
||||||
|
|
||||||
static int32_t prvEnsureInterruptControllerIsInitialised( void )
|
static int32_t prvEnsureInterruptControllerIsInitialised( void )
|
||||||
{
|
{
|
||||||
static int32_t lInterruptControllerInitialised = pdFALSE;
|
static int32_t lInterruptControllerInitialised = pdFALSE;
|
||||||
int32_t lReturn;
|
int32_t lReturn;
|
||||||
|
|
||||||
/* Ensure the interrupt controller instance variable is initialised before
|
/* Ensure the interrupt controller instance variable is initialised before
|
||||||
* it is used, and that the initialisation only happens once. */
|
it is used, and that the initialisation only happens once. */
|
||||||
if( lInterruptControllerInitialised != pdTRUE )
|
if( lInterruptControllerInitialised != pdTRUE )
|
||||||
{
|
{
|
||||||
lReturn = prvInitialiseInterruptController();
|
lReturn = prvInitialiseInterruptController();
|
||||||
|
@ -395,19 +390,19 @@ static int32_t prvEnsureInterruptControllerIsInitialised( void )
|
||||||
* Handler for the timer interrupt. This is the handler that the application
|
* Handler for the timer interrupt. This is the handler that the application
|
||||||
* defined callback function vApplicationSetupTimerInterrupt() should install.
|
* defined callback function vApplicationSetupTimerInterrupt() should install.
|
||||||
*/
|
*/
|
||||||
void vPortTickISR( void * pvUnused )
|
void vPortTickISR( void *pvUnused )
|
||||||
{
|
{
|
||||||
extern void vApplicationClearTimerInterrupt( void );
|
extern void vApplicationClearTimerInterrupt( void );
|
||||||
|
|
||||||
/* Ensure the unused parameter does not generate a compiler warning. */
|
/* Ensure the unused parameter does not generate a compiler warning. */
|
||||||
( void ) pvUnused;
|
( void ) pvUnused;
|
||||||
|
|
||||||
/* This port uses an application defined callback function to clear the tick
|
/* This port uses an application defined callback function to clear the tick
|
||||||
* interrupt because the kernel will run on lots of different MicroBlaze and
|
interrupt because the kernel will run on lots of different MicroBlaze and
|
||||||
* FPGA configurations - not all of which will have the same timer peripherals
|
FPGA configurations - not all of which will have the same timer peripherals
|
||||||
* defined or available. An example definition of
|
defined or available. An example definition of
|
||||||
* vApplicationClearTimerInterrupt() is provided in the official demo
|
vApplicationClearTimerInterrupt() is provided in the official demo
|
||||||
* application that accompanies this port. */
|
application that accompanies this port. */
|
||||||
vApplicationClearTimerInterrupt();
|
vApplicationClearTimerInterrupt();
|
||||||
|
|
||||||
/* Increment the RTOS tick - this might cause a task to unblock. */
|
/* Increment the RTOS tick - this might cause a task to unblock. */
|
||||||
|
@ -421,7 +416,7 @@ void vPortTickISR( void * pvUnused )
|
||||||
|
|
||||||
static int32_t prvInitialiseInterruptController( void )
|
static int32_t prvInitialiseInterruptController( void )
|
||||||
{
|
{
|
||||||
int32_t lStatus;
|
int32_t lStatus;
|
||||||
|
|
||||||
lStatus = XIntc_Initialize( &xInterruptControllerInstance, configINTERRUPT_CONTROLLER_TO_USE );
|
lStatus = XIntc_Initialize( &xInterruptControllerInstance, configINTERRUPT_CONTROLLER_TO_USE );
|
||||||
|
|
||||||
|
@ -434,8 +429,8 @@ static int32_t prvInitialiseInterruptController( void )
|
||||||
XIntc_SetIntrSvcOption( xInterruptControllerInstance.BaseAddress, XIN_SVC_ALL_ISRS_OPTION );
|
XIntc_SetIntrSvcOption( xInterruptControllerInstance.BaseAddress, XIN_SVC_ALL_ISRS_OPTION );
|
||||||
|
|
||||||
/* Install exception handlers if the MicroBlaze is configured to handle
|
/* Install exception handlers if the MicroBlaze is configured to handle
|
||||||
* exceptions, and the application defined constant
|
exceptions, and the application defined constant
|
||||||
* configINSTALL_EXCEPTION_HANDLERS is set to 1. */
|
configINSTALL_EXCEPTION_HANDLERS is set to 1. */
|
||||||
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
||||||
{
|
{
|
||||||
vPortExceptionsInstallHandlers();
|
vPortExceptionsInstallHandlers();
|
||||||
|
@ -443,7 +438,7 @@ static int32_t prvInitialiseInterruptController( void )
|
||||||
#endif /* MICROBLAZE_EXCEPTIONS_ENABLED */
|
#endif /* MICROBLAZE_EXCEPTIONS_ENABLED */
|
||||||
|
|
||||||
/* Start the interrupt controller. Interrupts are enabled when the
|
/* Start the interrupt controller. Interrupts are enabled when the
|
||||||
* scheduler starts. */
|
scheduler starts. */
|
||||||
lStatus = XIntc_Start( &xInterruptControllerInstance, XIN_REAL_MODE );
|
lStatus = XIntc_Start( &xInterruptControllerInstance, XIN_REAL_MODE );
|
||||||
|
|
||||||
if( lStatus == XST_SUCCESS )
|
if( lStatus == XST_SUCCESS )
|
||||||
|
@ -461,3 +456,5 @@ static int32_t prvInitialiseInterruptController( void )
|
||||||
return lStatus;
|
return lStatus;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
#include <microblaze_exceptions_g.h>
|
#include <microblaze_exceptions_g.h>
|
||||||
|
|
||||||
/* The Xilinx library defined exception entry point stacks a number of
|
/* The Xilinx library defined exception entry point stacks a number of
|
||||||
* registers. These definitions are offsets from the stack pointer to the various
|
registers. These definitions are offsets from the stack pointer to the various
|
||||||
* stacked register values. */
|
stacked register values. */
|
||||||
#define portexR3_STACK_OFFSET 4
|
#define portexR3_STACK_OFFSET 4
|
||||||
#define portexR4_STACK_OFFSET 5
|
#define portexR4_STACK_OFFSET 5
|
||||||
#define portexR5_STACK_OFFSET 6
|
#define portexR5_STACK_OFFSET 6
|
||||||
|
@ -52,69 +52,69 @@
|
||||||
#define portexR19_STACK_OFFSET -1
|
#define portexR19_STACK_OFFSET -1
|
||||||
|
|
||||||
/* This is defined to equal the size, in bytes, of the stack frame generated by
|
/* This is defined to equal the size, in bytes, of the stack frame generated by
|
||||||
* the Xilinx standard library exception entry point. It is required to determine
|
the Xilinx standard library exception entry point. It is required to determine
|
||||||
* the stack pointer value prior to the exception being entered. */
|
the stack pointer value prior to the exception being entered. */
|
||||||
#define portexASM_HANDLER_STACK_FRAME_SIZE 84UL
|
#define portexASM_HANDLER_STACK_FRAME_SIZE 84UL
|
||||||
|
|
||||||
/* The number of bytes a MicroBlaze instruction consumes. */
|
/* The number of bytes a MicroBlaze instruction consumes. */
|
||||||
#define portexINSTRUCTION_SIZE 4
|
#define portexINSTRUCTION_SIZE 4
|
||||||
|
|
||||||
/* Exclude this entire file if the MicroBlaze is not configured to handle
|
/* Exclude this entire file if the MicroBlaze is not configured to handle
|
||||||
* exceptions, or the application defined configuration constant
|
exceptions, or the application defined configuration constant
|
||||||
* configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
||||||
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
||||||
|
|
||||||
/* This variable is set in the exception entry code, before
|
/* This variable is set in the exception entry code, before
|
||||||
* vPortExceptionHandler is called. */
|
vPortExceptionHandler is called. */
|
||||||
uint32_t * pulStackPointerOnFunctionEntry = NULL;
|
uint32_t *pulStackPointerOnFunctionEntry = NULL;
|
||||||
|
|
||||||
/* This is the structure that is filled with the MicroBlaze context as it
|
/* This is the structure that is filled with the MicroBlaze context as it
|
||||||
* existed immediately prior to the exception occurrence. A pointer to this
|
existed immediately prior to the exception occurrence. A pointer to this
|
||||||
* structure is passed into the vApplicationExceptionRegisterDump() callback
|
structure is passed into the vApplicationExceptionRegisterDump() callback
|
||||||
* function, if one is defined. */
|
function, if one is defined. */
|
||||||
static xPortRegisterDump xRegisterDump;
|
static xPortRegisterDump xRegisterDump;
|
||||||
|
|
||||||
/* This is the FreeRTOS exception handler that is installed for all exception
|
/* This is the FreeRTOS exception handler that is installed for all exception
|
||||||
* types. It is called from vPortExceptionHanlderEntry() - which is itself defined
|
types. It is called from vPortExceptionHanlderEntry() - which is itself defined
|
||||||
* in portasm.S. */
|
in portasm.S. */
|
||||||
void vPortExceptionHandler( void * pvExceptionID );
|
void vPortExceptionHandler( void *pvExceptionID );
|
||||||
extern void vPortExceptionHandlerEntry( void * pvExceptionID );
|
extern void vPortExceptionHandlerEntry( void *pvExceptionID );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* vApplicationExceptionRegisterDump() is a callback function that the
|
/* vApplicationExceptionRegisterDump() is a callback function that the
|
||||||
* application can optionally define to receive a populated xPortRegisterDump
|
application can optionally define to receive a populated xPortRegisterDump
|
||||||
* structure. If the application chooses not to define a version of
|
structure. If the application chooses not to define a version of
|
||||||
* vApplicationExceptionRegisterDump() then this weekly defined default
|
vApplicationExceptionRegisterDump() then this weekly defined default
|
||||||
* implementation will be called instead. */
|
implementation will be called instead. */
|
||||||
extern void vApplicationExceptionRegisterDump( xPortRegisterDump * xRegisterDump ) __attribute__( ( weak ) );
|
extern void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump ) __attribute__((weak));
|
||||||
void vApplicationExceptionRegisterDump( xPortRegisterDump * xRegisterDump )
|
void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )
|
||||||
{
|
{
|
||||||
( void ) xRegisterDump;
|
( void ) xRegisterDump;
|
||||||
|
|
||||||
for( ; ; )
|
for( ;; )
|
||||||
{
|
{
|
||||||
portNOP();
|
portNOP();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortExceptionHandler( void * pvExceptionID )
|
void vPortExceptionHandler( void *pvExceptionID )
|
||||||
{
|
{
|
||||||
extern void * pxCurrentTCB;
|
extern void *pxCurrentTCB;
|
||||||
|
|
||||||
/* Fill an xPortRegisterDump structure with the MicroBlaze context as it
|
/* Fill an xPortRegisterDump structure with the MicroBlaze context as it
|
||||||
* was immediately before the exception occurrence. */
|
was immediately before the exception occurrence. */
|
||||||
|
|
||||||
/* First fill in the name and handle of the task that was in the Running
|
/* First fill in the name and handle of the task that was in the Running
|
||||||
* state when the exception occurred. */
|
state when the exception occurred. */
|
||||||
xRegisterDump.xCurrentTaskHandle = pxCurrentTCB;
|
xRegisterDump.xCurrentTaskHandle = pxCurrentTCB;
|
||||||
xRegisterDump.pcCurrentTaskName = pcTaskGetName( NULL );
|
xRegisterDump.pcCurrentTaskName = pcTaskGetName( NULL );
|
||||||
|
|
||||||
configASSERT( pulStackPointerOnFunctionEntry );
|
configASSERT( pulStackPointerOnFunctionEntry );
|
||||||
|
|
||||||
/* Obtain the values of registers that were stacked prior to this function
|
/* Obtain the values of registers that were stacked prior to this function
|
||||||
* being called, and may have changed since they were stacked. */
|
being called, and may have changed since they were stacked. */
|
||||||
xRegisterDump.ulR3 = pulStackPointerOnFunctionEntry[ portexR3_STACK_OFFSET ];
|
xRegisterDump.ulR3 = pulStackPointerOnFunctionEntry[ portexR3_STACK_OFFSET ];
|
||||||
xRegisterDump.ulR4 = pulStackPointerOnFunctionEntry[ portexR4_STACK_OFFSET ];
|
xRegisterDump.ulR4 = pulStackPointerOnFunctionEntry[ portexR4_STACK_OFFSET ];
|
||||||
xRegisterDump.ulR5 = pulStackPointerOnFunctionEntry[ portexR5_STACK_OFFSET ];
|
xRegisterDump.ulR5 = pulStackPointerOnFunctionEntry[ portexR5_STACK_OFFSET ];
|
||||||
|
@ -154,11 +154,11 @@
|
||||||
xRegisterDump.ulEDR = mfedr();
|
xRegisterDump.ulEDR = mfedr();
|
||||||
|
|
||||||
/* Move the saved program counter back to the instruction that was executed
|
/* Move the saved program counter back to the instruction that was executed
|
||||||
* when the exception occurred. This is only valid for certain types of
|
when the exception occurred. This is only valid for certain types of
|
||||||
* exception. */
|
exception. */
|
||||||
xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_exceptions - portexINSTRUCTION_SIZE;
|
xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_exceptions - portexINSTRUCTION_SIZE;
|
||||||
|
|
||||||
#if ( XPAR_MICROBLAZE_USE_FPU != 0 )
|
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
|
||||||
{
|
{
|
||||||
xRegisterDump.ulFSR = mffsr();
|
xRegisterDump.ulFSR = mffsr();
|
||||||
}
|
}
|
||||||
|
@ -169,63 +169,65 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Also fill in a string that describes what type of exception this is.
|
/* Also fill in a string that describes what type of exception this is.
|
||||||
* The string uses the same ID names as defined in the MicroBlaze standard
|
The string uses the same ID names as defined in the MicroBlaze standard
|
||||||
* library exception header files. */
|
library exception header files. */
|
||||||
switch( ( uint32_t ) pvExceptionID )
|
switch( ( uint32_t ) pvExceptionID )
|
||||||
{
|
{
|
||||||
case XEXC_ID_FSL:
|
case XEXC_ID_FSL :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_FSL";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_FSL";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEXC_ID_UNALIGNED_ACCESS:
|
case XEXC_ID_UNALIGNED_ACCESS :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_UNALIGNED_ACCESS";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_UNALIGNED_ACCESS";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEXC_ID_ILLEGAL_OPCODE:
|
case XEXC_ID_ILLEGAL_OPCODE :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_ILLEGAL_OPCODE";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_ILLEGAL_OPCODE";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEXC_ID_M_AXI_I_EXCEPTION:
|
case XEXC_ID_M_AXI_I_EXCEPTION :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_M_AXI_I_EXCEPTION or XEXC_ID_IPLB_EXCEPTION";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_M_AXI_I_EXCEPTION or XEXC_ID_IPLB_EXCEPTION";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEXC_ID_M_AXI_D_EXCEPTION:
|
case XEXC_ID_M_AXI_D_EXCEPTION :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_M_AXI_D_EXCEPTION or XEXC_ID_DPLB_EXCEPTION";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_M_AXI_D_EXCEPTION or XEXC_ID_DPLB_EXCEPTION";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEXC_ID_DIV_BY_ZERO:
|
case XEXC_ID_DIV_BY_ZERO :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_DIV_BY_ZERO";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_DIV_BY_ZERO";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEXC_ID_STACK_VIOLATION:
|
case XEXC_ID_STACK_VIOLATION :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_STACK_VIOLATION or XEXC_ID_MMU";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_STACK_VIOLATION or XEXC_ID_MMU";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if ( XPAR_MICROBLAZE_USE_FPU != 0 )
|
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
|
||||||
case XEXC_ID_FPU:
|
|
||||||
|
case XEXC_ID_FPU :
|
||||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_FPU see ulFSR value";
|
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_FPU see ulFSR value";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#endif /* XPAR_MICROBLAZE_USE_FPU */
|
#endif /* XPAR_MICROBLAZE_USE_FPU */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vApplicationExceptionRegisterDump() is a callback function that the
|
/* vApplicationExceptionRegisterDump() is a callback function that the
|
||||||
* application can optionally define to receive the populated xPortRegisterDump
|
application can optionally define to receive the populated xPortRegisterDump
|
||||||
* structure. If the application chooses not to define a version of
|
structure. If the application chooses not to define a version of
|
||||||
* vApplicationExceptionRegisterDump() then the weekly defined default
|
vApplicationExceptionRegisterDump() then the weekly defined default
|
||||||
* implementation within this file will be called instead. */
|
implementation within this file will be called instead. */
|
||||||
vApplicationExceptionRegisterDump( &xRegisterDump );
|
vApplicationExceptionRegisterDump( &xRegisterDump );
|
||||||
|
|
||||||
/* Must not attempt to leave this function! */
|
/* Must not attempt to leave this function! */
|
||||||
for( ; ; )
|
for( ;; )
|
||||||
{
|
{
|
||||||
portNOP();
|
portNOP();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortExceptionsInstallHandlers( void )
|
void vPortExceptionsInstallHandlers( void )
|
||||||
{
|
{
|
||||||
static uint32_t ulHandlersAlreadyInstalled = pdFALSE;
|
static uint32_t ulHandlersAlreadyInstalled = pdFALSE;
|
||||||
|
|
||||||
if( ulHandlersAlreadyInstalled == pdFALSE )
|
if( ulHandlersAlreadyInstalled == pdFALSE )
|
||||||
{
|
{
|
||||||
|
@ -269,9 +271,12 @@
|
||||||
|
|
||||||
microblaze_enable_exceptions();
|
microblaze_enable_exceptions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exclude the entire file if the MicroBlaze is not configured to handle
|
/* Exclude the entire file if the MicroBlaze is not configured to handle
|
||||||
* exceptions, or the application defined configuration item
|
exceptions, or the application defined configuration item
|
||||||
* configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
||||||
#endif /* ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) */
|
#endif /* ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,15 +26,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* BSP includes. */
|
/* BSP includes. */
|
||||||
#include <mb_interface.h>
|
#include <mb_interface.h>
|
||||||
#include <xparameters.h>
|
#include <xparameters.h>
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -47,50 +47,48 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
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
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Interrupt control macros and functions. */
|
/* Interrupt control macros and functions. */
|
||||||
void microblaze_disable_interrupts( void );
|
void microblaze_disable_interrupts( void );
|
||||||
void microblaze_enable_interrupts( void );
|
void microblaze_enable_interrupts( void );
|
||||||
#define portDISABLE_INTERRUPTS() microblaze_disable_interrupts()
|
#define portDISABLE_INTERRUPTS() microblaze_disable_interrupts()
|
||||||
#define portENABLE_INTERRUPTS() microblaze_enable_interrupts()
|
#define portENABLE_INTERRUPTS() microblaze_enable_interrupts()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section macros. */
|
/* Critical section macros. */
|
||||||
void vPortEnterCritical( void );
|
void vPortEnterCritical( void );
|
||||||
void vPortExitCritical( void );
|
void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() { \
|
||||||
{ \
|
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
microblaze_disable_interrupts(); \
|
microblaze_disable_interrupts(); \
|
||||||
uxCriticalNesting++; \
|
uxCriticalNesting++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() { \
|
||||||
{ \
|
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
/* Interrupts are disabled, so we can */ \
|
/* Interrupts are disabled, so we can */ \
|
||||||
/* access the variable directly. */ \
|
/* access the variable directly. */ \
|
||||||
|
@ -98,7 +96,7 @@
|
||||||
if( uxCriticalNesting == 0 ) \
|
if( uxCriticalNesting == 0 ) \
|
||||||
{ \
|
{ \
|
||||||
/* The nesting has unwound and we \
|
/* The nesting has unwound and we \
|
||||||
* can enable interrupts again. */ \
|
can enable interrupts again. */ \
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
@ -106,66 +104,65 @@
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The yield macro maps directly to the vPortYield() function. */
|
/* The yield macro maps directly to the vPortYield() function. */
|
||||||
void vPortYield( void );
|
void vPortYield( void );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
|
|
||||||
/* portYIELD_FROM_ISR() does not directly call vTaskSwitchContext(), but instead
|
/* portYIELD_FROM_ISR() does not directly call vTaskSwitchContext(), but instead
|
||||||
* sets a flag to say that a yield has been requested. The interrupt exit code
|
sets a flag to say that a yield has been requested. The interrupt exit code
|
||||||
* then checks this flag, and calls vTaskSwitchContext() before restoring a task
|
then checks this flag, and calls vTaskSwitchContext() before restoring a task
|
||||||
* context, if the flag is not false. This is done to prevent multiple calls to
|
context, if the flag is not false. This is done to prevent multiple calls to
|
||||||
* vTaskSwitchContext() being made from a single interrupt, as a single interrupt
|
vTaskSwitchContext() being made from a single interrupt, as a single interrupt
|
||||||
* can result in multiple peripherals being serviced. */
|
can result in multiple peripherals being serviced. */
|
||||||
extern volatile uint32_t ulTaskSwitchRequested;
|
extern volatile uint32_t ulTaskSwitchRequested;
|
||||||
#define portYIELD_FROM_ISR( x ) if( ( x ) != pdFALSE ) ulTaskSwitchRequested = 1
|
#define portYIELD_FROM_ISR( x ) if( ( x ) != pdFALSE ) ulTaskSwitchRequested = 1
|
||||||
|
|
||||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
#if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
/* Generic helper function. */
|
/* Generic helper function. */
|
||||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
{
|
{
|
||||||
uint8_t ucReturn;
|
uint8_t ucReturn;
|
||||||
|
|
||||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) );
|
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) );
|
||||||
|
|
||||||
return ucReturn;
|
return ucReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if ( configMAX_PRIORITIES > 32 )
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#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() asm volatile ( "NOP" )
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The following structure is used by the FreeRTOS exception handler. It is
|
/* The following structure is used by the FreeRTOS exception handler. It is
|
||||||
* filled with the MicroBlaze context as it was at the time the exception occurred.
|
filled with the MicroBlaze context as it was at the time the exception occurred.
|
||||||
* This is done as an aid to debugging exception occurrences. */
|
This is done as an aid to debugging exception occurrences. */
|
||||||
typedef struct PORT_REGISTER_DUMP
|
typedef struct PORT_REGISTER_DUMP
|
||||||
{
|
{
|
||||||
/* The following structure members hold the values of the MicroBlaze
|
/* The following structure members hold the values of the MicroBlaze
|
||||||
* registers at the time the exception was raised. */
|
registers at the time the exception was raised. */
|
||||||
uint32_t ulR1_SP;
|
uint32_t ulR1_SP;
|
||||||
uint32_t ulR2_small_data_area;
|
uint32_t ulR2_small_data_area;
|
||||||
uint32_t ulR3;
|
uint32_t ulR3;
|
||||||
|
@ -205,19 +202,20 @@
|
||||||
uint32_t ulEDR;
|
uint32_t ulEDR;
|
||||||
|
|
||||||
/* A human readable description of the exception cause. The strings used
|
/* A human readable description of the exception cause. The strings used
|
||||||
* are the same as the #define constant names found in the
|
are the same as the #define constant names found in the
|
||||||
* microblaze_exceptions_i.h header file */
|
microblaze_exceptions_i.h header file */
|
||||||
int8_t * pcExceptionCause;
|
int8_t *pcExceptionCause;
|
||||||
|
|
||||||
/* The human readable name of the task that was running at the time the
|
/* The human readable name of the task that was running at the time the
|
||||||
* exception occurred. This is the name that was given to the task when the
|
exception occurred. This is the name that was given to the task when the
|
||||||
* task was created using the FreeRTOS xTaskCreate() API function. */
|
task was created using the FreeRTOS xTaskCreate() API function. */
|
||||||
char * pcCurrentTaskName;
|
char *pcCurrentTaskName;
|
||||||
|
|
||||||
/* The handle of the task that was running a the time the exception
|
/* The handle of the task that was running a the time the exception
|
||||||
* occurred. */
|
occurred. */
|
||||||
void * xCurrentTaskHandle;
|
void * xCurrentTaskHandle;
|
||||||
} xPortRegisterDump;
|
|
||||||
|
} xPortRegisterDump;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -255,9 +253,7 @@
|
||||||
* pdPASS is returned if the function executes successfully. Any other value
|
* pdPASS is returned if the function executes successfully. Any other value
|
||||||
* being returned indicates that the function did not execute correctly.
|
* being returned indicates that the function did not execute correctly.
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID,
|
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );
|
||||||
XInterruptHandler pxHandler,
|
|
||||||
void * pvCallBackRef );
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -278,7 +274,7 @@
|
||||||
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void vPortEnableInterrupt( uint8_t ucInterruptID );
|
void vPortEnableInterrupt( uint8_t ucInterruptID );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disables the interrupt, within the interrupt controller, for the peripheral
|
* Disables the interrupt, within the interrupt controller, for the peripheral
|
||||||
|
@ -298,7 +294,7 @@
|
||||||
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void vPortDisableInterrupt( uint8_t ucInterruptID );
|
void vPortDisableInterrupt( uint8_t ucInterruptID );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is an application defined callback function used to install the tick
|
* This is an application defined callback function used to install the tick
|
||||||
|
@ -310,7 +306,7 @@
|
||||||
* The name of the interrupt handler that should be installed is vPortTickISR(),
|
* The name of the interrupt handler that should be installed is vPortTickISR(),
|
||||||
* which the function below declares as an extern.
|
* which the function below declares as an extern.
|
||||||
*/
|
*/
|
||||||
void vApplicationSetupTimerInterrupt( void );
|
void vApplicationSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is an application defined callback function used to clear whichever
|
* This is an application defined callback function used to clear whichever
|
||||||
|
@ -323,7 +319,7 @@
|
||||||
* implementation should not require modification provided the example definition
|
* implementation should not require modification provided the example definition
|
||||||
* of vApplicationSetupTimerInterrupt() is also not modified.
|
* of vApplicationSetupTimerInterrupt() is also not modified.
|
||||||
*/
|
*/
|
||||||
void vApplicationClearTimerInterrupt( void );
|
void vApplicationClearTimerInterrupt( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vPortExceptionsInstallHandlers() is only available when the MicroBlaze
|
* vPortExceptionsInstallHandlers() is only available when the MicroBlaze
|
||||||
|
@ -346,7 +342,7 @@
|
||||||
* See the description of vApplicationExceptionRegisterDump() for information
|
* See the description of vApplicationExceptionRegisterDump() for information
|
||||||
* on the processing performed by the FreeRTOS exception handler.
|
* on the processing performed by the FreeRTOS exception handler.
|
||||||
*/
|
*/
|
||||||
void vPortExceptionsInstallHandlers( void );
|
void vPortExceptionsInstallHandlers( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The FreeRTOS exception handler fills an xPortRegisterDump structure (defined
|
* The FreeRTOS exception handler fills an xPortRegisterDump structure (defined
|
||||||
|
@ -362,11 +358,12 @@
|
||||||
* register dump information. For example, an implementation could be provided
|
* register dump information. For example, an implementation could be provided
|
||||||
* that wrote the register dump data to a display, or a UART port.
|
* that wrote the register dump data to a display, or a UART port.
|
||||||
*/
|
*/
|
||||||
void vApplicationExceptionRegisterDump( xPortRegisterDump * xRegisterDump );
|
void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump );
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the NIOS2 port.
|
* Implementation of functions defined in portable.h for the NIOS2 port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Standard Includes. */
|
/* Standard Includes. */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -55,26 +55,23 @@ static void prvSetupTimerInterrupt( void );
|
||||||
/*
|
/*
|
||||||
* Call back for the alarm function.
|
* Call back for the alarm function.
|
||||||
*/
|
*/
|
||||||
void vPortSysTickHandler( void * context,
|
void vPortSysTickHandler( void * context, alt_u32 id );
|
||||||
alt_u32 id );
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvReadGp( uint32_t * ulValue )
|
static void prvReadGp( uint32_t *ulValue )
|
||||||
{
|
{
|
||||||
asm ( "stw gp, (%0)" ::"r" ( ulValue ) );
|
asm( "stw gp, (%0)" :: "r"(ulValue) );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 )
|
|
||||||
{
|
{
|
||||||
StackType_t * pxFramePointer = pxTopOfStack - 1;
|
StackType_t *pxFramePointer = pxTopOfStack - 1;
|
||||||
StackType_t xGlobalPointer;
|
StackType_t xGlobalPointer;
|
||||||
|
|
||||||
prvReadGp( &xGlobalPointer );
|
prvReadGp( &xGlobalPointer );
|
||||||
|
|
||||||
|
@ -113,7 +110,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
* here already. */
|
here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
@ -128,7 +125,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the NIOS2 port will require this function as there
|
/* It is unlikely that the NIOS2 port will require this function as there
|
||||||
* is nothing to return to. */
|
is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -139,10 +136,10 @@ void vPortEndScheduler( void )
|
||||||
void prvSetupTimerInterrupt( void )
|
void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
/* Try to register the interrupt handler. */
|
/* Try to register the interrupt handler. */
|
||||||
if( -EINVAL == alt_irq_register( SYS_CLK_IRQ, 0x0, vPortSysTickHandler ) )
|
if ( -EINVAL == alt_irq_register( SYS_CLK_IRQ, 0x0, vPortSysTickHandler ) )
|
||||||
{
|
{
|
||||||
/* Failed to install the Interrupt Handler. */
|
/* Failed to install the Interrupt Handler. */
|
||||||
asm ( "break" );
|
asm( "break" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -158,8 +155,7 @@ void prvSetupTimerInterrupt( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortSysTickHandler( void * context,
|
void vPortSysTickHandler( void * context, alt_u32 id )
|
||||||
alt_u32 id )
|
|
||||||
{
|
{
|
||||||
/* Increment the kernel tick. */
|
/* Increment the kernel tick. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
|
@ -178,14 +174,12 @@ void vPortSysTickHandler( void * context,
|
||||||
* kernel has its scheduler started so that contexts are saved and switched
|
* kernel has its scheduler started so that contexts are saved and switched
|
||||||
* correctly.
|
* correctly.
|
||||||
*/
|
*/
|
||||||
int alt_irq_register( alt_u32 id,
|
int alt_irq_register( alt_u32 id, void* context, void (*handler)(void*, alt_u32) )
|
||||||
void * context,
|
|
||||||
void ( * handler )( void *, alt_u32 ) )
|
|
||||||
{
|
{
|
||||||
int rc = -EINVAL;
|
int rc = -EINVAL;
|
||||||
alt_irq_context status;
|
alt_irq_context status;
|
||||||
|
|
||||||
if( id < ALT_NIRQ )
|
if (id < ALT_NIRQ)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* interrupts are disabled while the handler tables are updated to ensure
|
* interrupts are disabled while the handler tables are updated to ensure
|
||||||
|
@ -193,12 +187,12 @@ int alt_irq_register( alt_u32 id,
|
||||||
* state.
|
* state.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
status = alt_irq_disable_all();
|
status = alt_irq_disable_all ();
|
||||||
|
|
||||||
alt_irq[ id ].handler = handler;
|
alt_irq[id].handler = handler;
|
||||||
alt_irq[ id ].context = context;
|
alt_irq[id].context = context;
|
||||||
|
|
||||||
rc = ( handler ) ? alt_irq_enable( id ) : alt_irq_disable( id );
|
rc = (handler) ? alt_irq_enable (id): alt_irq_disable (id);
|
||||||
|
|
||||||
/* alt_irq_enable_all(status); This line is removed to prevent the interrupt from being immediately enabled. */
|
/* alt_irq_enable_all(status); This line is removed to prevent the interrupt from being immediately enabled. */
|
||||||
}
|
}
|
||||||
|
@ -206,3 +200,4 @@ int alt_irq_register( alt_u32 id,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sys/alt_irq.h"
|
#include "sys/alt_irq.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -45,64 +45,65 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
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
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#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 portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#define portNOP() asm volatile ( "NOP" )
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
#define portCRITICAL_NESTING_IN_TCB 1
|
#define portCRITICAL_NESTING_IN_TCB 1
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
extern void vTaskSwitchContext( void );
|
extern void vTaskSwitchContext( void );
|
||||||
#define portYIELD() asm volatile ( "trap" );
|
#define portYIELD() asm volatile ( "trap" );
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vTaskSwitchContext()
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vTaskSwitchContext()
|
||||||
|
|
||||||
|
|
||||||
/* Include the port_asm.S file where the Context saving/restoring is defined. */
|
/* Include the port_asm.S file where the Context saving/restoring is defined. */
|
||||||
__asm__ ( "\n\t.globl save_context");
|
__asm__( "\n\t.globl save_context" );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
extern void vTaskEnterCritical( void );
|
extern void vTaskEnterCritical( void );
|
||||||
extern void vTaskExitCritical( void );
|
extern void vTaskExitCritical( void );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() alt_irq_disable_all()
|
#define portDISABLE_INTERRUPTS() alt_irq_disable_all()
|
||||||
#define portENABLE_INTERRUPTS() alt_irq_enable_all( 0x01 );
|
#define portENABLE_INTERRUPTS() alt_irq_enable_all( 0x01 );
|
||||||
#define portENTER_CRITICAL() vTaskEnterCritical()
|
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vTaskExitCritical()
|
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* When switching out a task, if the task tag contains a buffer address then
|
/* When switching out a task, if the task tag contains a buffer address then
|
||||||
* save the flop context into the buffer. */
|
save the flop context into the buffer. */
|
||||||
#define traceTASK_SWITCHED_OUT() \
|
#define traceTASK_SWITCHED_OUT() \
|
||||||
if( pxCurrentTCB->pxTaskTag != NULL ) \
|
if( pxCurrentTCB->pxTaskTag != NULL ) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -35,10 +35,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When switching in a task, if the task tag contains a buffer address then
|
/* When switching in a task, if the task tag contains a buffer address then
|
||||||
* load the flop context from the buffer. */
|
load the flop context from the buffer. */
|
||||||
#define traceTASK_SWITCHED_IN() \
|
#define traceTASK_SWITCHED_IN() \
|
||||||
if( pxCurrentTCB->pxTaskTag != NULL ) \
|
if( pxCurrentTCB->pxTaskTag != NULL ) \
|
||||||
{ \
|
{ \
|
||||||
extern void vPortRestoreFPURegisters( void * ); \
|
extern void vPortRestoreFPURegisters( void * ); \
|
||||||
vPortRestoreFPURegisters( ( void * ) ( pxCurrentTCB->pxTaskTag ) ); \
|
vPortRestoreFPURegisters( ( void * ) ( pxCurrentTCB->pxTaskTag ) ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the PPC405 port.
|
* Implementation of functions defined in portable.h for the PPC405 port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
|
@ -96,9 +96,7 @@ static XIntc xInterruptController;
|
||||||
*
|
*
|
||||||
* See the header file portable.h.
|
* See the header file portable.h.
|
||||||
*/
|
*/
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
TaskFunction_t pxCode,
|
|
||||||
void * pvParameters )
|
|
||||||
{
|
{
|
||||||
/* Place a known value at the bottom of the stack for debugging. */
|
/* Place a known value at the bottom of the stack for debugging. */
|
||||||
*pxTopOfStack = 0xDEADBEEF;
|
*pxTopOfStack = 0xDEADBEEF;
|
||||||
|
@ -121,7 +119,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
|
||||||
/* R1 is the stack pointer so is omitted. */
|
/* R1 is the stack pointer so is omitted. */
|
||||||
|
|
||||||
*pxTopOfStack = 0x10000001UL; /* R0. */
|
*pxTopOfStack = 0x10000001UL;; /* R0. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x00000000UL; /* USPRG0. */
|
*pxTopOfStack = 0x00000000UL; /* USPRG0. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -135,11 +133,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode; /* SRR0. */
|
*pxTopOfStack = ( StackType_t ) pxCode; /* SRR0. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portINITIAL_MSR; /* SRR1. */
|
*pxTopOfStack = portINITIAL_MSR;/* SRR1. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) vPortEndScheduler; /* Next LR. */
|
*pxTopOfStack = ( StackType_t ) vPortEndScheduler;/* Next LR. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x00000000UL; /* Backchain. */
|
*pxTopOfStack = 0x00000000UL;/* Backchain. */
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
|
@ -159,9 +157,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented. */
|
/* Not implemented. */
|
||||||
for( ; ; )
|
for( ;; );
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -170,7 +166,7 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
const uint32_t ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );
|
const uint32_t ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );
|
||||||
|
|
||||||
XTime_PITClearInterrupt();
|
XTime_PITClearInterrupt();
|
||||||
XTime_FITClearInterrupt();
|
XTime_FITClearInterrupt();
|
||||||
|
@ -186,18 +182,18 @@ static void prvSetupTimerInterrupt( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortISRHandler( void * pvNullDoNotUse )
|
void vPortISRHandler( void *pvNullDoNotUse )
|
||||||
{
|
{
|
||||||
uint32_t ulInterruptStatus, ulInterruptMask = 1UL;
|
uint32_t ulInterruptStatus, ulInterruptMask = 1UL;
|
||||||
BaseType_t xInterruptNumber;
|
BaseType_t xInterruptNumber;
|
||||||
XIntc_Config * pxInterruptController;
|
XIntc_Config *pxInterruptController;
|
||||||
XIntc_VectorTableEntry * pxTable;
|
XIntc_VectorTableEntry *pxTable;
|
||||||
|
|
||||||
/* Just to remove compiler warning. */
|
/* Just to remove compiler warning. */
|
||||||
( void ) pvNullDoNotUse;
|
( void ) pvNullDoNotUse;
|
||||||
|
|
||||||
/* Get the configuration by using the device ID - in this case it is
|
/* Get the configuration by using the device ID - in this case it is
|
||||||
* assumed that only one interrupt controller is being used. */
|
assumed that only one interrupt controller is being used. */
|
||||||
pxInterruptController = &XIntc_ConfigTable[ XPAR_XPS_INTC_0_DEVICE_ID ];
|
pxInterruptController = &XIntc_ConfigTable[ XPAR_XPS_INTC_0_DEVICE_ID ];
|
||||||
|
|
||||||
/* Which interrupts are pending? */
|
/* Which interrupts are pending? */
|
||||||
|
@ -230,31 +226,29 @@ void vPortISRHandler( void * pvNullDoNotUse )
|
||||||
|
|
||||||
void vPortSetupInterruptController( void )
|
void vPortSetupInterruptController( void )
|
||||||
{
|
{
|
||||||
extern void vPortISRWrapper( void );
|
extern void vPortISRWrapper( void );
|
||||||
|
|
||||||
/* Perform all library calls necessary to initialise the exception table
|
/* Perform all library calls necessary to initialise the exception table
|
||||||
* and interrupt controller. This assumes only one interrupt controller is in
|
and interrupt controller. This assumes only one interrupt controller is in
|
||||||
* use. */
|
use. */
|
||||||
XExc_mDisableExceptions( XEXC_NON_CRITICAL );
|
XExc_mDisableExceptions( XEXC_NON_CRITICAL );
|
||||||
XExc_Init();
|
XExc_Init();
|
||||||
|
|
||||||
/* The library functions save the context - we then jump to a wrapper to
|
/* The library functions save the context - we then jump to a wrapper to
|
||||||
* save the stack into the TCB. The wrapper then calls the handler defined
|
save the stack into the TCB. The wrapper then calls the handler defined
|
||||||
* above. */
|
above. */
|
||||||
XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, ( XExceptionHandler ) vPortISRWrapper, NULL );
|
XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, ( XExceptionHandler ) vPortISRWrapper, NULL );
|
||||||
XIntc_Initialize( &xInterruptController, XPAR_XPS_INTC_0_DEVICE_ID );
|
XIntc_Initialize( &xInterruptController, XPAR_XPS_INTC_0_DEVICE_ID );
|
||||||
XIntc_Start( &xInterruptController, XIN_REAL_MODE );
|
XIntc_Start( &xInterruptController, XIN_REAL_MODE );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID,
|
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )
|
||||||
XInterruptHandler pxHandler,
|
|
||||||
void * pvCallBackRef )
|
|
||||||
{
|
{
|
||||||
BaseType_t xReturn = pdFAIL;
|
BaseType_t xReturn = pdFAIL;
|
||||||
|
|
||||||
/* This function is defined here so the scope of xInterruptController can
|
/* This function is defined here so the scope of xInterruptController can
|
||||||
* remain within this file. */
|
remain within this file. */
|
||||||
|
|
||||||
if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) )
|
if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,13 +26,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#include "xexception_l.h"
|
#include "xexception_l.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -45,75 +45,74 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* This port uses the critical nesting count from the TCB rather than
|
/* This port uses the critical nesting count from the TCB rather than
|
||||||
* maintaining a separate value and then saving this value in the task stack. */
|
maintaining a separate value and then saving this value in the task stack. */
|
||||||
#define portCRITICAL_NESTING_IN_TCB 1
|
#define portCRITICAL_NESTING_IN_TCB 1
|
||||||
|
|
||||||
/* Interrupt control macros. */
|
/* Interrupt control macros. */
|
||||||
#define portDISABLE_INTERRUPTS() XExc_mDisableExceptions( XEXC_NON_CRITICAL );
|
#define portDISABLE_INTERRUPTS() XExc_mDisableExceptions( XEXC_NON_CRITICAL );
|
||||||
#define portENABLE_INTERRUPTS() XExc_mEnableExceptions( XEXC_NON_CRITICAL );
|
#define portENABLE_INTERRUPTS() XExc_mEnableExceptions( XEXC_NON_CRITICAL );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section macros. */
|
/* Critical section macros. */
|
||||||
void vTaskEnterCritical( void );
|
void vTaskEnterCritical( void );
|
||||||
void vTaskExitCritical( void );
|
void vTaskExitCritical( void );
|
||||||
#define portENTER_CRITICAL() vTaskEnterCritical()
|
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vTaskExitCritical()
|
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
void vPortYield( void );
|
void vPortYield( void );
|
||||||
#define portYIELD() asm volatile ( "SC \n\t NOP" )
|
#define portYIELD() asm volatile ( "SC \n\t NOP" )
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#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() asm volatile ( "NOP" )
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
|
|
||||||
/* There are 32 * 32bit floating point regieters, plus the FPSCR to save. */
|
/* There are 32 * 32bit floating point regieters, plus the FPSCR to save. */
|
||||||
#define portNO_FLOP_REGISTERS_TO_SAVE ( 32 + 1 )
|
#define portNO_FLOP_REGISTERS_TO_SAVE ( 32 + 1 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
/* Port specific interrupt handling functions. */
|
/* Port specific interrupt handling functions. */
|
||||||
void vPortSetupInterruptController( void );
|
void vPortSetupInterruptController( void );
|
||||||
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID,
|
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );
|
||||||
XInterruptHandler pxHandler,
|
|
||||||
void * pvCallBackRef );
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* When switching out a task, if the task tag contains a buffer address then
|
/* When switching out a task, if the task tag contains a buffer address then
|
||||||
* save the flop context into the buffer. */
|
save the flop context into the buffer. */
|
||||||
#define traceTASK_SWITCHED_OUT() \
|
#define traceTASK_SWITCHED_OUT() \
|
||||||
if( pxCurrentTCB->pxTaskTag != NULL ) \
|
if( pxCurrentTCB->pxTaskTag != NULL ) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -35,10 +35,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When switching in a task, if the task tag contains a buffer address then
|
/* When switching in a task, if the task tag contains a buffer address then
|
||||||
* load the flop context from the buffer. */
|
load the flop context from the buffer. */
|
||||||
#define traceTASK_SWITCHED_IN() \
|
#define traceTASK_SWITCHED_IN() \
|
||||||
if( pxCurrentTCB->pxTaskTag != NULL ) \
|
if( pxCurrentTCB->pxTaskTag != NULL ) \
|
||||||
{ \
|
{ \
|
||||||
extern void vPortRestoreFPURegisters( void * ); \
|
extern void vPortRestoreFPURegisters( void * ); \
|
||||||
vPortRestoreFPURegisters( ( void * ) ( pxCurrentTCB->pxTaskTag ) ); \
|
vPortRestoreFPURegisters( ( void * ) ( pxCurrentTCB->pxTaskTag ) ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the PPC440 port.
|
* Implementation of functions defined in portable.h for the PPC440 port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
|
@ -96,9 +96,7 @@ static XIntc xInterruptController;
|
||||||
*
|
*
|
||||||
* See the header file portable.h.
|
* See the header file portable.h.
|
||||||
*/
|
*/
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
TaskFunction_t pxCode,
|
|
||||||
void * pvParameters )
|
|
||||||
{
|
{
|
||||||
/* Place a known value at the bottom of the stack for debugging. */
|
/* Place a known value at the bottom of the stack for debugging. */
|
||||||
*pxTopOfStack = 0xDEADBEEF;
|
*pxTopOfStack = 0xDEADBEEF;
|
||||||
|
@ -121,7 +119,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
|
||||||
/* R1 is the stack pointer so is omitted. */
|
/* R1 is the stack pointer so is omitted. */
|
||||||
|
|
||||||
*pxTopOfStack = 0x10000001UL; /* R0. */
|
*pxTopOfStack = 0x10000001UL;; /* R0. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x00000000UL; /* USPRG0. */
|
*pxTopOfStack = 0x00000000UL; /* USPRG0. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
@ -135,11 +133,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode; /* SRR0. */
|
*pxTopOfStack = ( StackType_t ) pxCode; /* SRR0. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portINITIAL_MSR; /* SRR1. */
|
*pxTopOfStack = portINITIAL_MSR;/* SRR1. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) vPortEndScheduler; /* Next LR. */
|
*pxTopOfStack = ( StackType_t ) vPortEndScheduler;/* Next LR. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = 0x00000000UL; /* Backchain. */
|
*pxTopOfStack = 0x00000000UL;/* Backchain. */
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
|
@ -159,9 +157,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented. */
|
/* Not implemented. */
|
||||||
for( ; ; )
|
for( ;; );
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -170,7 +166,7 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
const uint32_t ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );
|
const uint32_t ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL );
|
||||||
|
|
||||||
XTime_DECClearInterrupt();
|
XTime_DECClearInterrupt();
|
||||||
XTime_FITClearInterrupt();
|
XTime_FITClearInterrupt();
|
||||||
|
@ -186,18 +182,18 @@ static void prvSetupTimerInterrupt( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortISRHandler( void * pvNullDoNotUse )
|
void vPortISRHandler( void *pvNullDoNotUse )
|
||||||
{
|
{
|
||||||
uint32_t ulInterruptStatus, ulInterruptMask = 1UL;
|
uint32_t ulInterruptStatus, ulInterruptMask = 1UL;
|
||||||
BaseType_t xInterruptNumber;
|
BaseType_t xInterruptNumber;
|
||||||
XIntc_Config * pxInterruptController;
|
XIntc_Config *pxInterruptController;
|
||||||
XIntc_VectorTableEntry * pxTable;
|
XIntc_VectorTableEntry *pxTable;
|
||||||
|
|
||||||
/* Just to remove compiler warning. */
|
/* Just to remove compiler warning. */
|
||||||
( void ) pvNullDoNotUse;
|
( void ) pvNullDoNotUse;
|
||||||
|
|
||||||
/* Get the configuration by using the device ID - in this case it is
|
/* Get the configuration by using the device ID - in this case it is
|
||||||
* assumed that only one interrupt controller is being used. */
|
assumed that only one interrupt controller is being used. */
|
||||||
pxInterruptController = &XIntc_ConfigTable[ XPAR_XPS_INTC_0_DEVICE_ID ];
|
pxInterruptController = &XIntc_ConfigTable[ XPAR_XPS_INTC_0_DEVICE_ID ];
|
||||||
|
|
||||||
/* Which interrupts are pending? */
|
/* Which interrupts are pending? */
|
||||||
|
@ -230,31 +226,29 @@ void vPortISRHandler( void * pvNullDoNotUse )
|
||||||
|
|
||||||
void vPortSetupInterruptController( void )
|
void vPortSetupInterruptController( void )
|
||||||
{
|
{
|
||||||
extern void vPortISRWrapper( void );
|
extern void vPortISRWrapper( void );
|
||||||
|
|
||||||
/* Perform all library calls necessary to initialise the exception table
|
/* Perform all library calls necessary to initialise the exception table
|
||||||
* and interrupt controller. This assumes only one interrupt controller is in
|
and interrupt controller. This assumes only one interrupt controller is in
|
||||||
* use. */
|
use. */
|
||||||
XExc_mDisableExceptions( XEXC_NON_CRITICAL );
|
XExc_mDisableExceptions( XEXC_NON_CRITICAL );
|
||||||
XExc_Init();
|
XExc_Init();
|
||||||
|
|
||||||
/* The library functions save the context - we then jump to a wrapper to
|
/* The library functions save the context - we then jump to a wrapper to
|
||||||
* save the stack into the TCB. The wrapper then calls the handler defined
|
save the stack into the TCB. The wrapper then calls the handler defined
|
||||||
* above. */
|
above. */
|
||||||
XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, ( XExceptionHandler ) vPortISRWrapper, NULL );
|
XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, ( XExceptionHandler ) vPortISRWrapper, NULL );
|
||||||
XIntc_Initialize( &xInterruptController, XPAR_XPS_INTC_0_DEVICE_ID );
|
XIntc_Initialize( &xInterruptController, XPAR_XPS_INTC_0_DEVICE_ID );
|
||||||
XIntc_Start( &xInterruptController, XIN_REAL_MODE );
|
XIntc_Start( &xInterruptController, XIN_REAL_MODE );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID,
|
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )
|
||||||
XInterruptHandler pxHandler,
|
|
||||||
void * pvCallBackRef )
|
|
||||||
{
|
{
|
||||||
BaseType_t xReturn = pdFAIL;
|
BaseType_t xReturn = pdFAIL;
|
||||||
|
|
||||||
/* This function is defined here so the scope of xInterruptController can
|
/* This function is defined here so the scope of xInterruptController can
|
||||||
* remain within this file. */
|
remain within this file. */
|
||||||
|
|
||||||
if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) )
|
if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,13 +26,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#include "xexception_l.h"
|
#include "xexception_l.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -45,75 +45,74 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* This port uses the critical nesting count from the TCB rather than
|
/* This port uses the critical nesting count from the TCB rather than
|
||||||
* maintaining a separate value and then saving this value in the task stack. */
|
maintaining a separate value and then saving this value in the task stack. */
|
||||||
#define portCRITICAL_NESTING_IN_TCB 1
|
#define portCRITICAL_NESTING_IN_TCB 1
|
||||||
|
|
||||||
/* Interrupt control macros. */
|
/* Interrupt control macros. */
|
||||||
#define portDISABLE_INTERRUPTS() XExc_mDisableExceptions( XEXC_NON_CRITICAL );
|
#define portDISABLE_INTERRUPTS() XExc_mDisableExceptions( XEXC_NON_CRITICAL );
|
||||||
#define portENABLE_INTERRUPTS() XExc_mEnableExceptions( XEXC_NON_CRITICAL );
|
#define portENABLE_INTERRUPTS() XExc_mEnableExceptions( XEXC_NON_CRITICAL );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section macros. */
|
/* Critical section macros. */
|
||||||
void vTaskEnterCritical( void );
|
void vTaskEnterCritical( void );
|
||||||
void vTaskExitCritical( void );
|
void vTaskExitCritical( void );
|
||||||
#define portENTER_CRITICAL() vTaskEnterCritical()
|
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vTaskExitCritical()
|
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
void vPortYield( void );
|
void vPortYield( void );
|
||||||
#define portYIELD() asm volatile ( "SC \n\t NOP" )
|
#define portYIELD() asm volatile ( "SC \n\t NOP" )
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#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() asm volatile ( "NOP" )
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
|
|
||||||
/* There are 32 * 32bit floating point regieters, plus the FPSCR to save. */
|
/* There are 32 * 32bit floating point regieters, plus the FPSCR to save. */
|
||||||
#define portNO_FLOP_REGISTERS_TO_SAVE ( 32 + 1 )
|
#define portNO_FLOP_REGISTERS_TO_SAVE ( 32 + 1 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
/* Port specific interrupt handling functions. */
|
/* Port specific interrupt handling functions. */
|
||||||
void vPortSetupInterruptController( void );
|
void vPortSetupInterruptController( void );
|
||||||
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID,
|
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );
|
||||||
XInterruptHandler pxHandler,
|
|
||||||
void * pvCallBackRef );
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
* the Software without restriction, including without limitation the rights to
|
* the Software without restriction, including without limitation the rights to
|
||||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
* the Software, and t
|
* the Software, and t
|
||||||
*
|
|
||||||
* o permit persons to whom the Software is furnished to do so,
|
o permit persons to whom the Software is furnished to do so,
|
||||||
* subject to the following conditions:
|
* subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
@ -74,36 +74,36 @@
|
||||||
|
|
||||||
/* Save additional registers found on the Pulpino. */
|
/* Save additional registers found on the Pulpino. */
|
||||||
.macro portasmSAVE_ADDITIONAL_REGISTERS
|
.macro portasmSAVE_ADDITIONAL_REGISTERS
|
||||||
addi sp, sp, -( portasmADDITIONAL_CONTEXT_SIZE * portWORD_SIZE ) /* Make room for the additional registers. */
|
addi sp, sp, -(portasmADDITIONAL_CONTEXT_SIZE * portWORD_SIZE) /* Make room for the additional registers. */
|
||||||
csrr t0, lpstart0 /* Load additional registers into accessible temporary registers. */
|
csrr t0, lpstart0 /* Load additional registers into accessible temporary registers. */
|
||||||
csrr t1, lpend0
|
csrr t1, lpend0
|
||||||
csrr t2, lpcount0
|
csrr t2, lpcount0
|
||||||
csrr t3, lpstart1
|
csrr t3, lpstart1
|
||||||
csrr t4, lpend1
|
csrr t4, lpend1
|
||||||
csrr t5, lpcount1
|
csrr t5, lpcount1
|
||||||
sw t0, 1 * portWORD_SIZE( sp )
|
sw t0, 1 * portWORD_SIZE( sp )
|
||||||
sw t1, 2 * portWORD_SIZE( sp )
|
sw t1, 2 * portWORD_SIZE( sp )
|
||||||
sw t2, 3 * portWORD_SIZE( sp )
|
sw t2, 3 * portWORD_SIZE( sp )
|
||||||
sw t3, 4 * portWORD_SIZE( sp )
|
sw t3, 4 * portWORD_SIZE( sp )
|
||||||
sw t4, 5 * portWORD_SIZE( sp )
|
sw t4, 5 * portWORD_SIZE( sp )
|
||||||
sw t5, 6 * portWORD_SIZE( sp )
|
sw t5, 6 * portWORD_SIZE( sp )
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/* Restore the additional registers found on the Pulpino. */
|
/* Restore the additional registers found on the Pulpino. */
|
||||||
.macro portasmRESTORE_ADDITIONAL_REGISTERS
|
.macro portasmRESTORE_ADDITIONAL_REGISTERS
|
||||||
lw t0, 1 * portWORD_SIZE( sp ) /* Load additional registers into accessible temporary registers. */
|
lw t0, 1 * portWORD_SIZE( sp ) /* Load additional registers into accessible temporary registers. */
|
||||||
lw t1, 2 * portWORD_SIZE( sp )
|
lw t1, 2 * portWORD_SIZE( sp )
|
||||||
lw t2, 3 * portWORD_SIZE( sp )
|
lw t2, 3 * portWORD_SIZE( sp )
|
||||||
lw t3, 4 * portWORD_SIZE( sp )
|
lw t3, 4 * portWORD_SIZE( sp )
|
||||||
lw t4, 5 * portWORD_SIZE( sp )
|
lw t4, 5 * portWORD_SIZE( sp )
|
||||||
lw t5, 6 * portWORD_SIZE( sp )
|
lw t5, 6 * portWORD_SIZE( sp )
|
||||||
csrw lpstart0, t0
|
csrw lpstart0, t0
|
||||||
csrw lpend0, t1
|
csrw lpend0, t1
|
||||||
csrw lpcount0, t2
|
csrw lpcount0, t2
|
||||||
csrw lpstart1, t3
|
csrw lpstart1, t3
|
||||||
csrw lpend1, t4
|
csrw lpend1, t4
|
||||||
csrw lpcount1, t5
|
csrw lpcount1, t5
|
||||||
addi sp, sp, ( portasmADDITIONAL_CONTEXT_SIZE * portWORD_SIZE ) /* Remove space added for additional registers. */
|
addi sp, sp, (portasmADDITIONAL_CONTEXT_SIZE * portWORD_SIZE )/* Remove space added for additional registers. */
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */
|
#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */
|
||||||
|
|
|
@ -58,11 +58,11 @@
|
||||||
#define portasmADDITIONAL_CONTEXT_SIZE 0 /* Must be even number on 32-bit cores. */
|
#define portasmADDITIONAL_CONTEXT_SIZE 0 /* Must be even number on 32-bit cores. */
|
||||||
|
|
||||||
.macro portasmSAVE_ADDITIONAL_REGISTERS
|
.macro portasmSAVE_ADDITIONAL_REGISTERS
|
||||||
/* No additional registers to save, so this macro does nothing. */
|
/* No additional registers to save, so this macro does nothing. */
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro portasmRESTORE_ADDITIONAL_REGISTERS
|
.macro portasmRESTORE_ADDITIONAL_REGISTERS
|
||||||
/* No additional registers to restore, so this macro does nothing. */
|
/* No additional registers to restore, so this macro does nothing. */
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */
|
#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the RISC-V RV32 port.
|
* Implementation of functions defined in portable.h for the RISC-V RV32 port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
@ -38,20 +38,20 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
#ifdef configCLINT_BASE_ADDRESS
|
#ifdef configCLINT_BASE_ADDRESS
|
||||||
#warning The configCLINT_BASE_ADDRESS constant has been deprecated. configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS are currently being derived from the (possibly 0) configCLINT_BASE_ADDRESS setting. Please update to define configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS dirctly in place of configCLINT_BASE_ADDRESS. See https: /*www.freertos.org/Using-FreeRTOS-on-RISC-V.html */
|
#warning The configCLINT_BASE_ADDRESS constant has been deprecated. configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS are currently being derived from the (possibly 0) configCLINT_BASE_ADDRESS setting. Please update to define configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS dirctly in place of configCLINT_BASE_ADDRESS. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configMTIME_BASE_ADDRESS
|
#ifndef configMTIME_BASE_ADDRESS
|
||||||
#warning configMTIME_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtime register then set configMTIME_BASE_ADDRESS to the mapped address. Otherwise set configMTIME_BASE_ADDRESS to 0. See https: /*www.freertos.org/Using-FreeRTOS-on-RISC-V.html */
|
#warning configMTIME_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtime register then set configMTIME_BASE_ADDRESS to the mapped address. Otherwise set configMTIME_BASE_ADDRESS to 0. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configMTIMECMP_BASE_ADDRESS
|
#ifndef configMTIMECMP_BASE_ADDRESS
|
||||||
#warning configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtimecmp register then set configMTIMECMP_BASE_ADDRESS to the mapped address. Otherwise set configMTIMECMP_BASE_ADDRESS to 0. See https: /*www.freertos.org/Using-FreeRTOS-on-RISC-V.html */
|
#warning configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtimecmp register then set configMTIMECMP_BASE_ADDRESS to the mapped address. Otherwise set configMTIMECMP_BASE_ADDRESS to 0. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Let the user override the pre-loading of the initial LR with the address of
|
/* Let the user override the pre-loading of the initial LR with the address of
|
||||||
* prvTaskExitError() in case it messes up unwinding of the stack in the
|
prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||||
* debugger. */
|
debugger. */
|
||||||
#ifdef configTASK_RETURN_ADDRESS
|
#ifdef configTASK_RETURN_ADDRESS
|
||||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||||
#else
|
#else
|
||||||
|
@ -59,19 +59,19 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The stack used by interrupt service routines. Set configISR_STACK_SIZE_WORDS
|
/* The stack used by interrupt service routines. Set configISR_STACK_SIZE_WORDS
|
||||||
* to use a statically allocated array as the interrupt stack. Alternative leave
|
to use a statically allocated array as the interrupt stack. Alternative leave
|
||||||
* configISR_STACK_SIZE_WORDS undefined and update the linker script so that a
|
configISR_STACK_SIZE_WORDS undefined and update the linker script so that a
|
||||||
* linker variable names __freertos_irq_stack_top has the same value as the top
|
linker variable names __freertos_irq_stack_top has the same value as the top
|
||||||
* of the stack used by main. Using the linker script method will repurpose the
|
of the stack used by main. Using the linker script method will repurpose the
|
||||||
* stack that was used by main before the scheduler was started for use as the
|
stack that was used by main before the scheduler was started for use as the
|
||||||
* interrupt stack after the scheduler has started. */
|
interrupt stack after the scheduler has started. */
|
||||||
#ifdef configISR_STACK_SIZE_WORDS
|
#ifdef configISR_STACK_SIZE_WORDS
|
||||||
static __attribute__( ( aligned( 16 ) ) ) StackType_t xISRStack[ configISR_STACK_SIZE_WORDS ] = { 0 };
|
static __attribute__ ((aligned(16))) StackType_t xISRStack[ configISR_STACK_SIZE_WORDS ] = { 0 };
|
||||||
const StackType_t xISRStackTop = ( StackType_t ) &( xISRStack[ configISR_STACK_SIZE_WORDS & ~portBYTE_ALIGNMENT_MASK ] );
|
const StackType_t xISRStackTop = ( StackType_t ) &( xISRStack[ configISR_STACK_SIZE_WORDS & ~portBYTE_ALIGNMENT_MASK ] );
|
||||||
|
|
||||||
/* Don't use 0xa5 as the stack fill bytes as that is used by the kernerl for
|
/* Don't use 0xa5 as the stack fill bytes as that is used by the kernerl for
|
||||||
* the task stacks, and so will legitimately appear in many positions within
|
the task stacks, and so will legitimately appear in many positions within
|
||||||
* the ISR stack. */
|
the ISR stack. */
|
||||||
#define portISR_STACK_FILL_BYTE 0xee
|
#define portISR_STACK_FILL_BYTE 0xee
|
||||||
#else
|
#else
|
||||||
extern const uint32_t __freertos_irq_stack_top[];
|
extern const uint32_t __freertos_irq_stack_top[];
|
||||||
|
@ -83,42 +83,40 @@
|
||||||
* file is weak to allow application writers to change the timer used to
|
* file is weak to allow application writers to change the timer used to
|
||||||
* generate the tick interrupt.
|
* generate the tick interrupt.
|
||||||
*/
|
*/
|
||||||
void vPortSetupTimerInterrupt( void ) __attribute__( ( weak ) );
|
void vPortSetupTimerInterrupt( void ) __attribute__(( weak ));
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Used to program the machine timer compare register. */
|
/* Used to program the machine timer compare register. */
|
||||||
uint64_t ullNextTime = 0ULL;
|
uint64_t ullNextTime = 0ULL;
|
||||||
const uint64_t * pullNextTime = &ullNextTime;
|
const uint64_t *pullNextTime = &ullNextTime;
|
||||||
const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */
|
const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */
|
||||||
uint32_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS;
|
uint32_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS;
|
||||||
volatile uint64_t * pullMachineTimerCompareRegister = NULL;
|
volatile uint64_t * pullMachineTimerCompareRegister = NULL;
|
||||||
|
|
||||||
/* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task
|
/* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task
|
||||||
* stack checking. A problem in the ISR stack will trigger an assert, not call the
|
stack checking. A problem in the ISR stack will trigger an assert, not call the
|
||||||
* stack overflow hook function (because the stack overflow hook is specific to a
|
stack overflow hook function (because the stack overflow hook is specific to a
|
||||||
* task stack, not the ISR stack). */
|
task stack, not the ISR stack). */
|
||||||
#if defined( configISR_STACK_SIZE_WORDS ) && ( configCHECK_FOR_STACK_OVERFLOW > 2 )
|
#if defined( configISR_STACK_SIZE_WORDS ) && ( configCHECK_FOR_STACK_OVERFLOW > 2 )
|
||||||
#warning This path not tested, or even compiled yet.
|
#warning This path not tested, or even compiled yet.
|
||||||
|
|
||||||
static const uint8_t ucExpectedStackBytes[] =
|
static const uint8_t ucExpectedStackBytes[] = {
|
||||||
{
|
|
||||||
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \
|
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \
|
||||||
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \
|
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \
|
||||||
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \
|
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \
|
||||||
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \
|
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \
|
||||||
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE
|
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE }; \
|
||||||
}; \
|
|
||||||
|
|
||||||
#define portCHECK_ISR_STACK() configASSERT( ( memcmp( ( void * ) xISRStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) == 0 ) )
|
#define portCHECK_ISR_STACK() configASSERT( ( memcmp( ( void * ) xISRStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) == 0 ) )
|
||||||
#else /* if defined( configISR_STACK_SIZE_WORDS ) && ( configCHECK_FOR_STACK_OVERFLOW > 2 ) */
|
#else
|
||||||
/* Define the function away. */
|
/* Define the function away. */
|
||||||
#define portCHECK_ISR_STACK()
|
#define portCHECK_ISR_STACK()
|
||||||
#endif /* configCHECK_FOR_STACK_OVERFLOW > 2 */
|
#endif /* configCHECK_FOR_STACK_OVERFLOW > 2 */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 )
|
#if( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 )
|
||||||
|
|
||||||
void vPortSetupTimerInterrupt( void )
|
void vPortSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
|
@ -127,8 +125,7 @@ volatile uint64_t * pullMachineTimerCompareRegister = NULL;
|
||||||
volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configMTIME_BASE_ADDRESS );
|
volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configMTIME_BASE_ADDRESS );
|
||||||
volatile uint32_t ulHartId;
|
volatile uint32_t ulHartId;
|
||||||
|
|
||||||
__asm volatile ( "csrr %0, mhartid" : "=r" ( ulHartId ) );
|
__asm volatile( "csrr %0, mhartid" : "=r"( ulHartId ) );
|
||||||
|
|
||||||
pullMachineTimerCompareRegister = ( volatile uint64_t * ) ( ullMachineTimerCompareRegisterBase + ( ulHartId * sizeof( uint64_t ) ) );
|
pullMachineTimerCompareRegister = ( volatile uint64_t * ) ( ullMachineTimerCompareRegisterBase + ( ulHartId * sizeof( uint64_t ) ) );
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -152,20 +149,20 @@ volatile uint64_t * pullMachineTimerCompareRegister = NULL;
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void xPortStartFirstTask( void );
|
extern void xPortStartFirstTask( void );
|
||||||
|
|
||||||
#if ( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint32_t mtvec = 0;
|
volatile uint32_t mtvec = 0;
|
||||||
|
|
||||||
/* Check the least significant two bits of mtvec are 00 - indicating
|
/* Check the least significant two bits of mtvec are 00 - indicating
|
||||||
* single vector mode. */
|
single vector mode. */
|
||||||
__asm volatile ( "csrr %0, mtvec" : "=r" ( mtvec ) );
|
__asm volatile( "csrr %0, mtvec" : "=r"( mtvec ) );
|
||||||
configASSERT( ( mtvec & 0x03UL ) == 0 );
|
configASSERT( ( mtvec & 0x03UL ) == 0 );
|
||||||
|
|
||||||
/* Check alignment of the interrupt stack - which is the same as the
|
/* Check alignment of the interrupt stack - which is the same as the
|
||||||
* stack that was being used by main() prior to the scheduler being
|
stack that was being used by main() prior to the scheduler being
|
||||||
* started. */
|
started. */
|
||||||
configASSERT( ( xISRStackTop & portBYTE_ALIGNMENT_MASK ) == 0 );
|
configASSERT( ( xISRStackTop & portBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
|
|
||||||
#ifdef configISR_STACK_SIZE_WORDS
|
#ifdef configISR_STACK_SIZE_WORDS
|
||||||
|
@ -177,28 +174,28 @@ BaseType_t xPortStartScheduler( void )
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/* If there is a CLINT then it is ok to use the default implementation
|
/* If there is a CLINT then it is ok to use the default implementation
|
||||||
* in this file, otherwise vPortSetupTimerInterrupt() must be implemented to
|
in this file, otherwise vPortSetupTimerInterrupt() must be implemented to
|
||||||
* configure whichever clock is to be used to generate the tick interrupt. */
|
configure whichever clock is to be used to generate the tick interrupt. */
|
||||||
vPortSetupTimerInterrupt();
|
vPortSetupTimerInterrupt();
|
||||||
|
|
||||||
#if ( ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) )
|
#if( ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) )
|
||||||
{
|
{
|
||||||
/* Enable mtime and external interrupts. 1<<7 for timer interrupt, 1<<11
|
/* Enable mtime and external interrupts. 1<<7 for timer interrupt, 1<<11
|
||||||
* for external interrupt. _RB_ What happens here when mtime is not present as
|
for external interrupt. _RB_ What happens here when mtime is not present as
|
||||||
* with pulpino? */
|
with pulpino? */
|
||||||
__asm volatile ( "csrs mie, %0" ::"r" ( 0x880 ) );
|
__asm volatile( "csrs mie, %0" :: "r"(0x880) );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
/* Enable external interrupts. */
|
/* Enable external interrupts. */
|
||||||
__asm volatile ( "csrs mie, %0" ::"r" ( 0x800 ) );
|
__asm volatile( "csrs mie, %0" :: "r"(0x800) );
|
||||||
}
|
}
|
||||||
#endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) */
|
#endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) */
|
||||||
|
|
||||||
xPortStartFirstTask();
|
xPortStartFirstTask();
|
||||||
|
|
||||||
/* Should not get here as after calling xPortStartFirstTask() only tasks
|
/* Should not get here as after calling xPortStartFirstTask() only tasks
|
||||||
* should be executing. */
|
should be executing. */
|
||||||
return pdFAIL;
|
return pdFAIL;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -206,7 +203,10 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented. */
|
/* Not implemented. */
|
||||||
for( ; ; )
|
for( ;; );
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,11 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -44,144 +44,143 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#if __riscv_xlen == 64
|
#if __riscv_xlen == 64
|
||||||
#define portSTACK_TYPE uint64_t
|
#define portSTACK_TYPE uint64_t
|
||||||
#define portBASE_TYPE int64_t
|
#define portBASE_TYPE int64_t
|
||||||
#define portUBASE_TYPE uint64_t
|
#define portUBASE_TYPE uint64_t
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffffffffffUL
|
||||||
#define portPOINTER_SIZE_TYPE uint64_t
|
#define portPOINTER_SIZE_TYPE uint64_t
|
||||||
#elif __riscv_xlen == 32
|
#elif __riscv_xlen == 32
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE int32_t
|
#define portBASE_TYPE int32_t
|
||||||
#define portUBASE_TYPE uint32_t
|
#define portUBASE_TYPE uint32_t
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#else /* if __riscv_xlen == 64 */
|
#else
|
||||||
#error Assembler did not define __riscv_xlen
|
#error Assembler did not define __riscv_xlen
|
||||||
#endif /* if __riscv_xlen == 64 */
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef portBASE_TYPE BaseType_t;
|
typedef portBASE_TYPE BaseType_t;
|
||||||
typedef portUBASE_TYPE UBaseType_t;
|
typedef portUBASE_TYPE UBaseType_t;
|
||||||
typedef portUBASE_TYPE TickType_t;
|
typedef portUBASE_TYPE TickType_t;
|
||||||
|
|
||||||
/* Legacy type definitions. */
|
/* Legacy type definitions. */
|
||||||
#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
|
||||||
|
|
||||||
/* 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
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#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 )
|
||||||
#ifdef __riscv64
|
#ifdef __riscv64
|
||||||
#error This is the RV32 port that has not yet been adapted for 64.
|
#error This is the RV32 port that has not yet been adapted for 64.
|
||||||
#define portBYTE_ALIGNMENT 16
|
#define portBYTE_ALIGNMENT 16
|
||||||
#else
|
#else
|
||||||
#define portBYTE_ALIGNMENT 16
|
#define portBYTE_ALIGNMENT 16
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
extern void vTaskSwitchContext( void );
|
extern void vTaskSwitchContext( void );
|
||||||
#define portYIELD() __asm volatile ( "ecall" );
|
#define portYIELD() __asm volatile( "ecall" );
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vTaskSwitchContext()
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vTaskSwitchContext()
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
#define portCRITICAL_NESTING_IN_TCB 1
|
#define portCRITICAL_NESTING_IN_TCB 1
|
||||||
extern void vTaskEnterCritical( void );
|
extern void vTaskEnterCritical( void );
|
||||||
extern void vTaskExitCritical( void );
|
extern void vTaskExitCritical( void );
|
||||||
|
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
|
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile ( "csrc mstatus, 8" )
|
#define portDISABLE_INTERRUPTS() __asm volatile( "csrc mstatus, 8" )
|
||||||
#define portENABLE_INTERRUPTS() __asm volatile ( "csrs mstatus, 8" )
|
#define portENABLE_INTERRUPTS() __asm volatile( "csrs mstatus, 8" )
|
||||||
#define portENTER_CRITICAL() vTaskEnterCritical()
|
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vTaskExitCritical()
|
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
#if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if ( configMAX_PRIORITIES > 32 )
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - __builtin_clz( uxReadyPriorities ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - __builtin_clz( uxReadyPriorities ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
* not necessary for to use this port. They are defined so the common demo files
|
not necessary for to use this port. They are defined so the common demo files
|
||||||
* (which build with all the ports) will build. */
|
(which build with all the ports) will build. */
|
||||||
#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 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portNOP() __asm volatile ( " nop " )
|
#define portNOP() __asm volatile ( " nop " )
|
||||||
|
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
|
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
#define portFORCE_INLINE inline __attribute__(( always_inline))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* configCLINT_BASE_ADDRESS is a legacy definition that was replaced by the
|
/* configCLINT_BASE_ADDRESS is a legacy definition that was replaced by the
|
||||||
* configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS definitions. For
|
configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS definitions. For
|
||||||
* backward compatibility derive the newer definitions from the old if the old
|
backward compatibility derive the newer definitions from the old if the old
|
||||||
* definition is found. */
|
definition is found. */
|
||||||
#if defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS ) && ( configCLINT_BASE_ADDRESS == 0 )
|
#if defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS ) && ( configCLINT_BASE_ADDRESS == 0 )
|
||||||
|
/* Legacy case where configCLINT_BASE_ADDRESS was defined as 0 to indicate
|
||||||
/* Legacy case where configCLINT_BASE_ADDRESS was defined as 0 to indicate
|
there was no CLINT. Equivalent now is to set the MTIME and MTIMECMP
|
||||||
* there was no CLINT. Equivalent now is to set the MTIME and MTIMECMP
|
addresses to 0. */
|
||||||
* addresses to 0. */
|
|
||||||
#define configMTIME_BASE_ADDRESS ( 0 )
|
#define configMTIME_BASE_ADDRESS ( 0 )
|
||||||
#define configMTIMECMP_BASE_ADDRESS ( 0 )
|
#define configMTIMECMP_BASE_ADDRESS ( 0 )
|
||||||
#elif defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS )
|
#elif defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS )
|
||||||
|
/* Legacy case where configCLINT_BASE_ADDRESS was set to the base address of
|
||||||
/* Legacy case where configCLINT_BASE_ADDRESS was set to the base address of
|
the CLINT. Equivalent now is to derive the MTIME and MTIMECMP addresses
|
||||||
* the CLINT. Equivalent now is to derive the MTIME and MTIMECMP addresses
|
from the CLINT address. */
|
||||||
* from the CLINT address. */
|
|
||||||
#define configMTIME_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0xBFF8UL )
|
#define configMTIME_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0xBFF8UL )
|
||||||
#define configMTIMECMP_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0x4000UL )
|
#define configMTIMECMP_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0x4000UL )
|
||||||
#elif !defined( configMTIME_BASE_ADDRESS ) || !defined( configMTIMECMP_BASE_ADDRESS )
|
#elif !defined( configMTIME_BASE_ADDRESS ) || !defined( configMTIMECMP_BASE_ADDRESS )
|
||||||
#error configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. Set them to zero if there is no MTIME (machine time) clock. See https: /*www.freertos.org/Using-FreeRTOS-on-RISC-V.html */
|
#error configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. Set them to zero if there is no MTIME (machine time) clock. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html
|
||||||
#endif /* if defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS ) && ( configCLINT_BASE_ADDRESS == 0 ) */
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Variables used by scheduler */
|
/* Variables used by scheduler */
|
||||||
.extern _pxCurrentTCB
|
.extern _pxCurrentTCB
|
||||||
.extern _usCriticalNesting
|
.extern _usCriticalNesting
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -37,43 +37,43 @@
|
||||||
*/
|
*/
|
||||||
.macro portSAVE_CONTEXT
|
.macro portSAVE_CONTEXT
|
||||||
|
|
||||||
SEL RB0
|
SEL RB0
|
||||||
|
|
||||||
/* Save AX Register to stack. */
|
/* Save AX Register to stack. */
|
||||||
PUSH AX
|
PUSH AX
|
||||||
PUSH HL
|
PUSH HL
|
||||||
/* Save CS register. */
|
/* Save CS register. */
|
||||||
MOV A, CS
|
MOV A, CS
|
||||||
XCH A, X
|
XCH A, X
|
||||||
/* Save ES register. */
|
/* Save ES register. */
|
||||||
MOV A, ES
|
MOV A, ES
|
||||||
PUSH AX
|
PUSH AX
|
||||||
/* Save the remaining general purpose registers from bank 0. */
|
/* Save the remaining general purpose registers from bank 0. */
|
||||||
PUSH DE
|
PUSH DE
|
||||||
PUSH BC
|
PUSH BC
|
||||||
/* Save the other register banks - only necessary in the GCC port. */
|
/* Save the other register banks - only necessary in the GCC port. */
|
||||||
SEL RB1
|
SEL RB1
|
||||||
PUSH AX
|
PUSH AX
|
||||||
PUSH BC
|
PUSH BC
|
||||||
PUSH DE
|
PUSH DE
|
||||||
PUSH HL
|
PUSH HL
|
||||||
SEL RB2
|
SEL RB2
|
||||||
PUSH AX
|
PUSH AX
|
||||||
PUSH BC
|
PUSH BC
|
||||||
PUSH DE
|
PUSH DE
|
||||||
PUSH HL
|
PUSH HL
|
||||||
/* Registers in bank 3 are for ISR use only so don't need saving. */
|
/* Registers in bank 3 are for ISR use only so don't need saving. */
|
||||||
SEL RB0
|
SEL RB0
|
||||||
/* Save the usCriticalNesting value. */
|
/* Save the usCriticalNesting value. */
|
||||||
MOVW AX, !_usCriticalNesting
|
MOVW AX, !_usCriticalNesting
|
||||||
PUSH AX
|
PUSH AX
|
||||||
/* Save the Stack pointer. */
|
/* Save the Stack pointer. */
|
||||||
MOVW AX, !_pxCurrentTCB
|
MOVW AX, !_pxCurrentTCB
|
||||||
MOVW HL, AX
|
MOVW HL, AX
|
||||||
MOVW AX, SP
|
MOVW AX, SP
|
||||||
MOVW[ HL ], AX
|
MOVW [HL], AX
|
||||||
/* Switch stack pointers. */
|
/* Switch stack pointers. */
|
||||||
movw sp, # _stack /* Set stack pointer */
|
movw sp,#_stack /* Set stack pointer */
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
@ -84,43 +84,43 @@ movw sp, # _stack /* Set stack pointer */
|
||||||
* general purpose registers and the CS and ES (only in far memory mode)
|
* general purpose registers and the CS and ES (only in far memory mode)
|
||||||
* of the selected task from the task stack
|
* of the selected task from the task stack
|
||||||
*/
|
*/
|
||||||
.macro portRESTORE_CONTEXT MACRO
|
.macro portRESTORE_CONTEXT MACRO
|
||||||
SEL RB0
|
SEL RB0
|
||||||
/* Restore the Stack pointer. */
|
/* Restore the Stack pointer. */
|
||||||
MOVW AX, !_pxCurrentTCB
|
MOVW AX, !_pxCurrentTCB
|
||||||
MOVW HL, AX
|
MOVW HL, AX
|
||||||
MOVW AX, [ HL ]
|
MOVW AX, [HL]
|
||||||
MOVW SP, AX
|
MOVW SP, AX
|
||||||
/* Restore usCriticalNesting value. */
|
/* Restore usCriticalNesting value. */
|
||||||
POP AX
|
POP AX
|
||||||
MOVW !_usCriticalNesting, AX
|
MOVW !_usCriticalNesting, AX
|
||||||
|
/* Restore the alternative register banks - only necessary in the GCC
|
||||||
/* Restore the alternative register banks - only necessary in the GCC
|
port. Register bank 3 is dedicated for interrupts use so is not saved or
|
||||||
* port. Register bank 3 is dedicated for interrupts use so is not saved or
|
restored. */
|
||||||
* restored. */
|
SEL RB2
|
||||||
SEL RB2
|
POP HL
|
||||||
POP HL
|
POP DE
|
||||||
POP DE
|
POP BC
|
||||||
POP BC
|
POP AX
|
||||||
POP AX
|
SEL RB1
|
||||||
SEL RB1
|
POP HL
|
||||||
POP HL
|
POP DE
|
||||||
POP DE
|
POP BC
|
||||||
POP BC
|
POP AX
|
||||||
POP AX
|
SEL RB0
|
||||||
SEL RB0
|
/* Restore the necessary general purpose registers. */
|
||||||
/* Restore the necessary general purpose registers. */
|
POP BC
|
||||||
POP BC
|
POP DE
|
||||||
POP DE
|
/* Restore the ES register. */
|
||||||
/* Restore the ES register. */
|
POP AX
|
||||||
POP AX
|
MOV ES, A
|
||||||
MOV ES, A
|
/* Restore the CS register. */
|
||||||
/* Restore the CS register. */
|
XCH A, X
|
||||||
XCH A, X
|
MOV CS, A
|
||||||
MOV CS, A
|
/* Restore general purpose register HL. */
|
||||||
/* Restore general purpose register HL. */
|
POP HL
|
||||||
POP HL
|
/* Restore AX. */
|
||||||
/* Restore AX. */
|
POP AX
|
||||||
POP AX
|
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/* The critical nesting value is initialised to a non zero value to ensure
|
/* The critical nesting value is initialised to a non zero value to ensure
|
||||||
* interrupts don't accidentally become enabled before the scheduler is started. */
|
interrupts don't accidentally become enabled before the scheduler is started. */
|
||||||
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
|
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
|
||||||
|
|
||||||
/* Initial PSW value allocated to a newly created task.
|
/* Initial PSW value allocated to a newly created task.
|
||||||
|
@ -47,13 +47,13 @@
|
||||||
#define portPSW ( 0xc6UL )
|
#define portPSW ( 0xc6UL )
|
||||||
|
|
||||||
/* Each task maintains a count of the critical section nesting depth. Each time
|
/* Each task maintains a count of the critical section nesting depth. Each time
|
||||||
* a critical section is entered the count is incremented. Each time a critical
|
a critical section is entered the count is incremented. Each time a critical
|
||||||
* section is exited the count is decremented - with interrupts only being
|
section is exited the count is decremented - with interrupts only being
|
||||||
* re-enabled if the count is zero.
|
re-enabled if the count is zero.
|
||||||
*
|
|
||||||
* usCriticalNesting will get set to zero when the scheduler starts, but must
|
usCriticalNesting will get set to zero when the scheduler starts, but must
|
||||||
* not be initialised to zero as that could cause problems during the startup
|
not be initialised to zero as that could cause problems during the startup
|
||||||
* sequence. */
|
sequence. */
|
||||||
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -61,7 +61,7 @@ volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
/*
|
/*
|
||||||
* Sets up the periodic ISR used for the RTOS tick.
|
* Sets up the periodic ISR used for the RTOS tick.
|
||||||
*/
|
*/
|
||||||
__attribute__( ( weak ) ) void vApplicationSetupTimerInterrupt( void );
|
__attribute__((weak)) void vApplicationSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Starts the scheduler by loading the context of the first task to run.
|
* Starts the scheduler by loading the context of the first task to run.
|
||||||
|
@ -77,16 +77,14 @@ extern void vPortStartFirstTask( void );
|
||||||
*
|
*
|
||||||
* See the header file portable.h.
|
* See the header file portable.h.
|
||||||
*/
|
*/
|
||||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||||
TaskFunction_t pxCode,
|
|
||||||
void * pvParameters )
|
|
||||||
{
|
{
|
||||||
uint32_t * pulLocal;
|
uint32_t *pulLocal;
|
||||||
|
|
||||||
/* Stack type and pointers to the stack type are both 2 bytes. */
|
/* Stack type and pointers to the stack type are both 2 bytes. */
|
||||||
|
|
||||||
/* Parameters are passed in on the stack, and written using a 32bit value
|
/* Parameters are passed in on the stack, and written using a 32bit value
|
||||||
* hence a space is left for the second two bytes. */
|
hence a space is left for the second two bytes. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Write in the parameter value. */
|
/* Write in the parameter value. */
|
||||||
|
@ -95,14 +93,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The return address, leaving space for the first two bytes of the
|
/* The return address, leaving space for the first two bytes of the
|
||||||
* 32-bit value. */
|
32-bit value. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
pulLocal = ( uint32_t * ) pxTopOfStack;
|
pulLocal = ( uint32_t * ) pxTopOfStack;
|
||||||
*pulLocal = ( uint32_t ) 0;
|
*pulLocal = ( uint32_t ) 0;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The start address / PSW value is also written in as a 32bit value,
|
/* The start address / PSW value is also written in as a 32bit value,
|
||||||
* so leave a space for the second two bytes. */
|
so leave a space for the second two bytes. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Task function start address combined with the PSW. */
|
/* Task function start address combined with the PSW. */
|
||||||
|
@ -123,16 +121,16 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The remaining general purpose registers bank 0 (DE and BC) and the other
|
/* The remaining general purpose registers bank 0 (DE and BC) and the other
|
||||||
* two register banks...register bank 3 is dedicated for use by interrupts so
|
two register banks...register bank 3 is dedicated for use by interrupts so
|
||||||
* is not saved as part of the task context. */
|
is not saved as part of the task context. */
|
||||||
pxTopOfStack -= 10;
|
pxTopOfStack -= 10;
|
||||||
|
|
||||||
/* Finally the critical section nesting count is set to zero when the task
|
/* Finally the critical section nesting count is set to zero when the task
|
||||||
* first starts. */
|
first starts. */
|
||||||
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
/* Return a pointer to the top of the stack that has beene generated so it
|
/* Return a pointer to the top of the stack that has beene generated so it
|
||||||
* can be stored in the task control block for the task. */
|
can be stored in the task control block for the task. */
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -140,7 +138,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
portBASE_TYPE xPortStartScheduler( void )
|
portBASE_TYPE xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
||||||
* this function is called. */
|
this function is called. */
|
||||||
vApplicationSetupTimerInterrupt();
|
vApplicationSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Restore the context of the first task that is going to run. */
|
/* Restore the context of the first task that is going to run. */
|
||||||
|
@ -157,10 +155,10 @@ void vPortEndScheduler( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__attribute__( ( weak ) ) void vApplicationSetupTimerInterrupt( void )
|
__attribute__((weak)) void vApplicationSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
const uint16_t usClockHz = 15000UL; /* Internal clock. */
|
const uint16_t usClockHz = 15000UL; /* Internal clock. */
|
||||||
const uint16_t usCompareMatch = ( usClockHz / configTICK_RATE_HZ ) + 1UL;
|
const uint16_t usCompareMatch = ( usClockHz / configTICK_RATE_HZ ) + 1UL;
|
||||||
|
|
||||||
/* Use the internal 15K clock. */
|
/* Use the internal 15K clock. */
|
||||||
OSMC = ( unsigned char ) 0x16;
|
OSMC = ( unsigned char ) 0x16;
|
||||||
|
@ -185,7 +183,7 @@ __attribute__( ( weak ) ) void vApplicationSetupTimerInterrupt( void )
|
||||||
/* Enable INTIT interrupt. */
|
/* Enable INTIT interrupt. */
|
||||||
ITMK = ( unsigned char ) 0;
|
ITMK = ( unsigned char ) 0;
|
||||||
}
|
}
|
||||||
#endif /* ifdef RTCEN */
|
#endif
|
||||||
|
|
||||||
#ifdef TMKAEN
|
#ifdef TMKAEN
|
||||||
{
|
{
|
||||||
|
@ -207,6 +205,7 @@ __attribute__( ( weak ) ) void vApplicationSetupTimerInterrupt( void )
|
||||||
/* Enable INTIT interrupt. */
|
/* Enable INTIT interrupt. */
|
||||||
TMKAMK = ( unsigned char ) 0;
|
TMKAMK = ( unsigned char ) 0;
|
||||||
}
|
}
|
||||||
#endif /* ifdef TMKAEN */
|
#endif
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef short BaseType_t;
|
typedef short BaseType_t;
|
||||||
typedef unsigned short UBaseType_t;
|
typedef unsigned short UBaseType_t;
|
||||||
|
|
||||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
|
@ -71,8 +71,8 @@ typedef unsigned short UBaseType_t;
|
||||||
#define portNO_CRITICAL_SECTION_NESTING ( ( unsigned short ) 0 )
|
#define portNO_CRITICAL_SECTION_NESTING ( ( unsigned short ) 0 )
|
||||||
|
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint16_t usCriticalNesting; \
|
extern volatile uint16_t usCriticalNesting; \
|
||||||
\
|
\
|
||||||
portDISABLE_INTERRUPTS(); \
|
portDISABLE_INTERRUPTS(); \
|
||||||
\
|
\
|
||||||
|
@ -80,11 +80,11 @@ typedef unsigned short UBaseType_t;
|
||||||
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
||||||
/* times portENTER_CRITICAL() has been called. */ \
|
/* times portENTER_CRITICAL() has been called. */ \
|
||||||
usCriticalNesting++; \
|
usCriticalNesting++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint16_t usCriticalNesting; \
|
extern volatile uint16_t usCriticalNesting; \
|
||||||
\
|
\
|
||||||
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -98,7 +98,7 @@ typedef unsigned short UBaseType_t;
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
@ -114,7 +114,8 @@ typedef unsigned short UBaseType_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the SH2A port.
|
* Implementation of functions defined in portable.h for the SH2A port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Standard C includes. */
|
/* Standard C includes. */
|
||||||
#include "limits.h"
|
#include "limits.h"
|
||||||
|
@ -45,11 +45,11 @@
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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
|
||||||
|
@ -64,15 +64,15 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* These macros allow a critical section to be added around the call to
|
/* These macros allow a critical section to be added around the call to
|
||||||
* xTaskIncrementTick(), which is only ever called from interrupts at the kernel
|
xTaskIncrementTick(), which is only ever called from interrupts at the kernel
|
||||||
* priority - ie a known priority. Therefore these local macros are a slight
|
priority - ie a known priority. Therefore these local macros are a slight
|
||||||
* optimisation compared to calling the global SET/CLEAR_INTERRUPT_MASK macros,
|
optimisation compared to calling the global SET/CLEAR_INTERRUPT_MASK macros,
|
||||||
* which would require the old IPL to be read first and stored in a local variable. */
|
which would require the old IPL to be read first and stored in a local variable. */
|
||||||
#define portDISABLE_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0"::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
|
#define portDISABLE_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0" ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) )
|
||||||
#define portENABLE_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0"::"i" ( configKERNEL_INTERRUPT_PRIORITY ) )
|
#define portENABLE_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0" ::"i"(configKERNEL_INTERRUPT_PRIORITY) )
|
||||||
|
|
||||||
/* 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
|
||||||
|
|
||||||
|
@ -82,19 +82,19 @@
|
||||||
* Function to start the first task executing - written in asm code as direct
|
* Function to start the first task executing - written in asm code as direct
|
||||||
* access to registers is required.
|
* access to registers is required.
|
||||||
*/
|
*/
|
||||||
static void prvStartFirstTask( void ) __attribute__( ( naked ) );
|
static void prvStartFirstTask( void ) __attribute__((naked));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Software interrupt handler. Performs the actual context switch (saving and
|
* Software interrupt handler. Performs the actual context switch (saving and
|
||||||
* restoring of registers). Written in asm code as direct register access is
|
* restoring of registers). Written in asm code as direct register access is
|
||||||
* required.
|
* required.
|
||||||
*/
|
*/
|
||||||
void vPortSoftwareInterruptISR( void ) __attribute__( ( naked ) );
|
void vPortSoftwareInterruptISR( void ) __attribute__((naked));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The tick interrupt handler.
|
* The tick interrupt handler.
|
||||||
*/
|
*/
|
||||||
void vPortTickISR( void ) __attribute__( ( interrupt ) );
|
void vPortTickISR( void ) __attribute__((interrupt));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets up the periodic ISR used for the RTOS tick using the CMT.
|
* Sets up the periodic ISR used for the RTOS tick using the CMT.
|
||||||
|
@ -104,9 +104,8 @@ void vPortTickISR( void ) __attribute__( ( interrupt ) );
|
||||||
*/
|
*/
|
||||||
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 */
|
||||||
|
|
||||||
|
@ -122,42 +121,40 @@ static void prvSetupTimerInterrupt( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Used in the context save and restore code. */
|
/* Used in the context save and restore code. */
|
||||||
extern void * pxCurrentTCB;
|
extern void *pxCurrentTCB;
|
||||||
|
|
||||||
/* Calculate how many clock increments make up a single tick period. */
|
/* Calculate how many clock increments make up a single tick period. */
|
||||||
static const uint32_t ulMatchValueForOneTick = ( ( configPERIPHERAL_CLOCK_HZ / portCLOCK_DIVISOR ) / configTICK_RATE_HZ );
|
static const uint32_t ulMatchValueForOneTick = ( ( configPERIPHERAL_CLOCK_HZ / portCLOCK_DIVISOR ) / configTICK_RATE_HZ );
|
||||||
|
|
||||||
#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--;
|
||||||
|
@ -172,8 +169,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--;
|
||||||
|
@ -206,13 +203,13 @@ 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--;
|
||||||
|
@ -230,10 +227,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. */
|
||||||
|
@ -250,11 +247,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();
|
||||||
|
|
||||||
/* Should not get here. */
|
/* Should not get here. */
|
||||||
|
@ -265,7 +262,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
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 );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -274,37 +271,34 @@ static void prvStartFirstTask( void )
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
|
|
||||||
/* 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 \n"\
|
"SETPSW U \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"MOV.L #_pxCurrentTCB, R15 \n" \
|
||||||
"MOV.L [R15], R15 \n"\
|
"MOV.L [R15], R15 \n" \
|
||||||
"MOV.L [R15], R0 \n"\
|
"MOV.L [R15], R0 \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator low 32 bits. */
|
/* Accumulator low 32 bits. */
|
||||||
"MVTACLO R15 \n"\
|
"MVTACLO R15 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator high 32 bits. */
|
/* Accumulator high 32 bits. */
|
||||||
"MVTACHI R15 \n"\
|
"MVTACHI R15 \n" \
|
||||||
|
|
||||||
/* R1 to R15 - R0 is not included as it is the SP. */
|
/* R1 to R15 - R0 is not included as it is the SP. */
|
||||||
"POPM R1-R15 \n"\
|
"POPM R1-R15 \n" \
|
||||||
|
|
||||||
/* This pops the remaining registers. */
|
/* This pops the remaining registers. */
|
||||||
"RTE \n"\
|
"RTE \n" \
|
||||||
"NOP \n"\
|
"NOP \n" \
|
||||||
"NOP \n"
|
"NOP \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -315,82 +309,78 @@ void vPortSoftwareInterruptISR( void )
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
/* Re-enable interrupts. */
|
/* Re-enable interrupts. */
|
||||||
"SETPSW I \n"\
|
"SETPSW I \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"PUSH.L R15 \n" \
|
||||||
|
|
||||||
/* Read the user stack pointer. */
|
/* Read the user stack pointer. */
|
||||||
"MVFC USP, R15 \n"\
|
"MVFC USP, R15 \n" \
|
||||||
|
|
||||||
/* Move the address down to the data being moved. */
|
/* Move the address down to the data being moved. */
|
||||||
"SUB #12, R15 \n"\
|
"SUB #12, R15 \n" \
|
||||||
"MVTC R15, USP \n"\
|
"MVTC R15, USP \n" \
|
||||||
|
|
||||||
/* Copy the data across, R15, then PC, then PSW. */
|
/* Copy the data across, R15, then PC, then PSW. */
|
||||||
"MOV.L [ R0 ], [ R15 ] \n"\
|
"MOV.L [ R0 ], [ R15 ] \n" \
|
||||||
"MOV.L 4[ R0 ], 4[ R15 ] \n"\
|
"MOV.L 4[ R0 ], 4[ R15 ] \n" \
|
||||||
"MOV.L 8[ R0 ], 8[ R15 ] \n"\
|
"MOV.L 8[ R0 ], 8[ R15 ] \n" \
|
||||||
|
|
||||||
/* Move the interrupt stack pointer to its new correct position. */
|
/* Move the interrupt stack pointer to its new correct position. */
|
||||||
"ADD #12, R0 \n"\
|
"ADD #12, R0 \n" \
|
||||||
|
|
||||||
/* 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 \n"\
|
"SETPSW U \n" \
|
||||||
|
|
||||||
/* 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 \n"\
|
"PUSHM R1-R14 \n" \
|
||||||
|
|
||||||
/* Save the accumulator. */
|
/* Save the accumulator. */
|
||||||
"MVFACHI R15 \n"\
|
"MVFACHI R15 \n" \
|
||||||
"PUSH.L R15 \n"\
|
"PUSH.L R15 \n" \
|
||||||
|
|
||||||
/* Middle word. */
|
/* Middle word. */
|
||||||
"MVFACMI R15 \n"\
|
"MVFACMI R15 \n" \
|
||||||
|
|
||||||
/* Shifted left as it is restored to the low order word. */
|
/* Shifted left as it is restored to the low order word. */
|
||||||
"SHLL #16, R15 \n"\
|
"SHLL #16, R15 \n" \
|
||||||
"PUSH.L R15 \n"\
|
"PUSH.L R15 \n" \
|
||||||
|
|
||||||
/* Save the stack pointer to the TCB. */
|
/* Save the stack pointer to the TCB. */
|
||||||
"MOV.L #_pxCurrentTCB, R15 \n"\
|
"MOV.L #_pxCurrentTCB, R15 \n" \
|
||||||
"MOV.L [ R15 ], R15 \n"\
|
"MOV.L [ R15 ], R15 \n" \
|
||||||
"MOV.L R0, [ R15 ] \n"\
|
"MOV.L R0, [ R15 ] \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 %0 \n"\
|
"MVTIPL %0 \n" \
|
||||||
|
|
||||||
/* Select the next task to run. */
|
/* Select the next task to run. */
|
||||||
"BSR.A _vTaskSwitchContext \n"\
|
"BSR.A _vTaskSwitchContext \n" \
|
||||||
|
|
||||||
/* 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 %1 \n"\
|
"MVTIPL %1 \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"MOV.L #_pxCurrentTCB,R15 \n" \
|
||||||
"MOV.L [ R15 ], R15 \n"\
|
"MOV.L [ R15 ], R15 \n" \
|
||||||
"MOV.L [ R15 ], R0 \n"\
|
"MOV.L [ R15 ], R0 \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"POP R15 \n" \
|
||||||
"MVTACLO R15 \n"\
|
"MVTACLO R15 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
"MVTACHI R15 \n"\
|
"MVTACHI R15 \n" \
|
||||||
"POPM R1-R15 \n"\
|
"POPM R1-R15 \n" \
|
||||||
"RTE \n"\
|
"RTE \n" \
|
||||||
"NOP \n"\
|
"NOP \n" \
|
||||||
"NOP "
|
"NOP "
|
||||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ), "i" ( configKERNEL_INTERRUPT_PRIORITY )
|
:: "i"(configMAX_SYSCALL_INTERRUPT_PRIORITY), "i"(configKERNEL_INTERRUPT_PRIORITY)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -398,10 +388,10 @@ void vPortSoftwareInterruptISR( void )
|
||||||
void vPortTickISR( void )
|
void vPortTickISR( void )
|
||||||
{
|
{
|
||||||
/* Re-enabled interrupts. */
|
/* Re-enabled interrupts. */
|
||||||
__asm volatile ( "SETPSW I");
|
__asm volatile( "SETPSW I" );
|
||||||
|
|
||||||
/* Increment the tick, and perform any processing the new tick value
|
/* Increment the tick, and perform any processing the new tick value
|
||||||
* necessitates. Ensure IPL is at the max syscall value first. */
|
necessitates. Ensure IPL is at the max syscall value first. */
|
||||||
portDISABLE_INTERRUPTS_FROM_KERNEL_ISR();
|
portDISABLE_INTERRUPTS_FROM_KERNEL_ISR();
|
||||||
{
|
{
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
|
@ -417,7 +407,7 @@ void vPortTickISR( 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
|
||||||
|
@ -428,8 +418,8 @@ uint32_t ulPortGetIPL( void )
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
"MVFC PSW, R1 \n"\
|
"MVFC PSW, R1 \n" \
|
||||||
"SHLR #24, R1 \n"\
|
"SHLR #24, R1 \n" \
|
||||||
"RTS "
|
"RTS "
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -442,13 +432,13 @@ void vPortSetIPL( uint32_t ulNewIPL )
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
"PUSH R5 \n"\
|
"PUSH R5 \n" \
|
||||||
"MVFC PSW, R5 \n"\
|
"MVFC PSW, R5 \n" \
|
||||||
"SHLL #24, R1 \n"\
|
"SHLL #24, R1 \n" \
|
||||||
"AND #-0F000001H, R5 \n"\
|
"AND #-0F000001H, R5 \n" \
|
||||||
"OR R1, R5 \n"\
|
"OR R1, R5 \n" \
|
||||||
"MVTC R5, PSW \n"\
|
"MVTC R5, PSW \n" \
|
||||||
"POP R5 \n"\
|
"POP R5 \n" \
|
||||||
"RTS "
|
"RTS "
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -488,11 +478,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... */
|
||||||
_IEN( _CMT0_CMI0 ) = 1;
|
_IEN( _CMT0_CMI0 ) = 1;
|
||||||
|
@ -513,11 +503,11 @@ 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 )
|
||||||
{
|
{
|
||||||
__asm volatile ( "WAIT" );
|
__asm volatile( "WAIT" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allow the application to define some post sleep processing. */
|
/* Allow the application to define some post sleep processing. */
|
||||||
|
@ -543,46 +533,43 @@ 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. */
|
||||||
__asm volatile ( "CLRPSW i" );
|
__asm volatile( "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. */
|
||||||
CMT.CMSTR0.BIT.STR0 = 1;
|
CMT.CMSTR0.BIT.STR0 = 1;
|
||||||
__asm volatile ( "SETPSW i" );
|
__asm volatile( "SETPSW i" );
|
||||||
}
|
}
|
||||||
else if( eSleepAction == eNoTasksWaitingTimeout )
|
else if( eSleepAction == eNoTasksWaitingTimeout )
|
||||||
{
|
{
|
||||||
|
@ -596,7 +583,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. */
|
||||||
|
@ -616,7 +603,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;
|
||||||
|
|
||||||
|
@ -625,15 +612,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. */
|
||||||
|
@ -644,44 +630,45 @@ 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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,11 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -44,100 +44,101 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
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
|
||||||
#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() __asm volatile ( "NOP" )
|
#define portNOP() __asm volatile( "NOP" )
|
||||||
|
|
||||||
/* Save clobbered register, set ITU SWINR (at address 0x872E0), read the value
|
/* Save clobbered register, set ITU SWINR (at address 0x872E0), read the value
|
||||||
* back to ensure it is set before continuing, then restore the clobbered
|
back to ensure it is set before continuing, then restore the clobbered
|
||||||
* register. */
|
register. */
|
||||||
#define portYIELD() \
|
#define portYIELD() \
|
||||||
__asm volatile \
|
__asm volatile \
|
||||||
( \
|
( \
|
||||||
"MOV.L #0x872E0, r5 \n\t"\
|
"MOV.L #0x872E0, r5 \n\t" \
|
||||||
"MOV.B #1, [r5] \n\t"\
|
"MOV.B #1, [r5] \n\t" \
|
||||||
"MOV.L [r5], r5 \n\t"\
|
"MOV.L [r5], r5 \n\t" \
|
||||||
::: "r5" \
|
::: "r5" \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR( x ) if( x != pdFALSE ) { portYIELD(); }
|
#define portYIELD_FROM_ISR( x ) if( x != pdFALSE ) { portYIELD(); }
|
||||||
|
|
||||||
/* 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() __asm volatile ( "MVTIPL #0")
|
#define portENABLE_INTERRUPTS() __asm volatile ( "MVTIPL #0" )
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( ulPortGetIPL() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( ulPortGetIPL() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
|
||||||
#define portDISABLE_INTERRUPTS() if( ulPortGetIPL() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __asm volatile ( "MVTIPL %0"::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
|
#define portDISABLE_INTERRUPTS() if( ulPortGetIPL() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __asm volatile ( "MVTIPL %0" ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) )
|
||||||
#else
|
#else
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile ( "MVTIPL %0"::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
|
#define portDISABLE_INTERRUPTS() __asm volatile ( "MVTIPL %0" ::"i"(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... */
|
||||||
uint32_t ulPortGetIPL( void ) __attribute__( ( naked ) );
|
uint32_t ulPortGetIPL( void ) __attribute__((naked));
|
||||||
void vPortSetIPL( uint32_t ulNewIPL ) __attribute__( ( naked ) );
|
void vPortSetIPL( uint32_t ulNewIPL ) __attribute__((naked));
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortGetIPL(); portDISABLE_INTERRUPTS()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortGetIPL(); portDISABLE_INTERRUPTS()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) vPortSetIPL( uxSavedInterruptStatus )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) vPortSetIPL( uxSavedInterruptStatus )
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
/* Tickless idle/low power functionality. */
|
||||||
#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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the SH2A port.
|
* Implementation of functions defined in portable.h for the SH2A port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
@ -42,17 +42,17 @@
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
/* These macros allow a critical section to be added around the call to
|
/* These macros allow a critical section to be added around the call to
|
||||||
* xTaskIncrementTick(), which is only ever called from interrupts at the kernel
|
xTaskIncrementTick(), which is only ever called from interrupts at the kernel
|
||||||
* priority - ie a known priority. Therefore these local macros are a slight
|
priority - ie a known priority. Therefore these local macros are a slight
|
||||||
* optimisation compared to calling the global SET/CLEAR_INTERRUPT_MASK macros,
|
optimisation compared to calling the global SET/CLEAR_INTERRUPT_MASK macros,
|
||||||
* which would require the old IPL to be read first and stored in a local variable. */
|
which would require the old IPL to be read first and stored in a local variable. */
|
||||||
#define portDISABLE_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0"::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
|
#define portDISABLE_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0" ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) )
|
||||||
#define portENABLE_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0"::"i" ( configKERNEL_INTERRUPT_PRIORITY ) )
|
#define portENABLE_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0" ::"i"(configKERNEL_INTERRUPT_PRIORITY) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -60,32 +60,30 @@
|
||||||
* Function to start the first task executing - written in asm code as direct
|
* Function to start the first task executing - written in asm code as direct
|
||||||
* access to registers is required.
|
* access to registers is required.
|
||||||
*/
|
*/
|
||||||
static void prvStartFirstTask( void ) __attribute__( ( naked ) );
|
static void prvStartFirstTask( void ) __attribute__((naked));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Software interrupt handler. Performs the actual context switch (saving and
|
* Software interrupt handler. Performs the actual context switch (saving and
|
||||||
* restoring of registers). Written in asm code as direct register access is
|
* restoring of registers). Written in asm code as direct register access is
|
||||||
* required.
|
* required.
|
||||||
*/
|
*/
|
||||||
void vSoftwareInterruptISR( void ) __attribute__( ( naked ) );
|
void vSoftwareInterruptISR( void ) __attribute__((naked));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The tick interrupt handler.
|
* The tick interrupt handler.
|
||||||
*/
|
*/
|
||||||
void vTickISR( void ) __attribute__( ( interrupt ) );
|
void vTickISR( void ) __attribute__((interrupt));
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
extern void * pxCurrentTCB;
|
extern void *pxCurrentTCB;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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. */
|
||||||
|
|
||||||
|
@ -96,8 +94,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--;
|
||||||
|
@ -130,11 +128,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--;
|
||||||
|
@ -150,14 +148,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. */
|
||||||
|
@ -181,7 +179,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
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 );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -190,41 +188,38 @@ static void prvStartFirstTask( void )
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
|
|
||||||
/* 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 \n"\
|
"SETPSW U \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"MOV.L #_pxCurrentTCB, R15 \n" \
|
||||||
"MOV.L [R15], R15 \n"\
|
"MOV.L [R15], R15 \n" \
|
||||||
"MOV.L [R15], R0 \n"\
|
"MOV.L [R15], R0 \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator low 32 bits. */
|
/* Accumulator low 32 bits. */
|
||||||
"MVTACLO R15 \n"\
|
"MVTACLO R15 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator high 32 bits. */
|
/* Accumulator high 32 bits. */
|
||||||
"MVTACHI R15 \n"\
|
"MVTACHI R15 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Floating point status word. */
|
/* Floating point status word. */
|
||||||
"MVTC R15, FPSW \n"\
|
"MVTC R15, FPSW \n" \
|
||||||
|
|
||||||
/* R1 to R15 - R0 is not included as it is the SP. */
|
/* R1 to R15 - R0 is not included as it is the SP. */
|
||||||
"POPM R1-R15 \n"\
|
"POPM R1-R15 \n" \
|
||||||
|
|
||||||
/* This pops the remaining registers. */
|
/* This pops the remaining registers. */
|
||||||
"RTE \n"\
|
"RTE \n" \
|
||||||
"NOP \n"\
|
"NOP \n" \
|
||||||
"NOP \n"
|
"NOP \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -235,86 +230,82 @@ void vSoftwareInterruptISR( void )
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
/* Re-enable interrupts. */
|
/* Re-enable interrupts. */
|
||||||
"SETPSW I \n"\
|
"SETPSW I \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"PUSH.L R15 \n" \
|
||||||
|
|
||||||
/* Read the user stack pointer. */
|
/* Read the user stack pointer. */
|
||||||
"MVFC USP, R15 \n"\
|
"MVFC USP, R15 \n" \
|
||||||
|
|
||||||
/* Move the address down to the data being moved. */
|
/* Move the address down to the data being moved. */
|
||||||
"SUB #12, R15 \n"\
|
"SUB #12, R15 \n" \
|
||||||
"MVTC R15, USP \n"\
|
"MVTC R15, USP \n" \
|
||||||
|
|
||||||
/* Copy the data across, R15, then PC, then PSW. */
|
/* Copy the data across, R15, then PC, then PSW. */
|
||||||
"MOV.L [ R0 ], [ R15 ] \n"\
|
"MOV.L [ R0 ], [ R15 ] \n" \
|
||||||
"MOV.L 4[ R0 ], 4[ R15 ] \n"\
|
"MOV.L 4[ R0 ], 4[ R15 ] \n" \
|
||||||
"MOV.L 8[ R0 ], 8[ R15 ] \n"\
|
"MOV.L 8[ R0 ], 8[ R15 ] \n" \
|
||||||
|
|
||||||
/* Move the interrupt stack pointer to its new correct position. */
|
/* Move the interrupt stack pointer to its new correct position. */
|
||||||
"ADD #12, R0 \n"\
|
"ADD #12, R0 \n" \
|
||||||
|
|
||||||
/* 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 \n"\
|
"SETPSW U \n" \
|
||||||
|
|
||||||
/* 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 \n"\
|
"PUSHM R1-R14 \n" \
|
||||||
|
|
||||||
/* Save the FPSW and accumulator. */
|
/* Save the FPSW and accumulator. */
|
||||||
"MVFC FPSW, R15 \n"\
|
"MVFC FPSW, R15 \n" \
|
||||||
"PUSH.L R15 \n"\
|
"PUSH.L R15 \n" \
|
||||||
"MVFACHI R15 \n"\
|
"MVFACHI R15 \n" \
|
||||||
"PUSH.L R15 \n"\
|
"PUSH.L R15 \n" \
|
||||||
|
|
||||||
/* Middle word. */
|
/* Middle word. */
|
||||||
"MVFACMI R15 \n"\
|
"MVFACMI R15 \n" \
|
||||||
|
|
||||||
/* Shifted left as it is restored to the low order word. */
|
/* Shifted left as it is restored to the low order word. */
|
||||||
"SHLL #16, R15 \n"\
|
"SHLL #16, R15 \n" \
|
||||||
"PUSH.L R15 \n"\
|
"PUSH.L R15 \n" \
|
||||||
|
|
||||||
/* Save the stack pointer to the TCB. */
|
/* Save the stack pointer to the TCB. */
|
||||||
"MOV.L #_pxCurrentTCB, R15 \n"\
|
"MOV.L #_pxCurrentTCB, R15 \n" \
|
||||||
"MOV.L [ R15 ], R15 \n"\
|
"MOV.L [ R15 ], R15 \n" \
|
||||||
"MOV.L R0, [ R15 ] \n"\
|
"MOV.L R0, [ R15 ] \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 %0 \n"\
|
"MVTIPL %0 \n" \
|
||||||
|
|
||||||
/* Select the next task to run. */
|
/* Select the next task to run. */
|
||||||
"BSR.A _vTaskSwitchContext \n"\
|
"BSR.A _vTaskSwitchContext \n" \
|
||||||
|
|
||||||
/* 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 %1 \n"\
|
"MVTIPL %1 \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"MOV.L #_pxCurrentTCB,R15 \n" \
|
||||||
"MOV.L [ R15 ], R15 \n"\
|
"MOV.L [ R15 ], R15 \n" \
|
||||||
"MOV.L [ R15 ], R0 \n"\
|
"MOV.L [ R15 ], R0 \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"POP R15 \n" \
|
||||||
"MVTACLO R15 \n"\
|
"MVTACLO R15 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
"MVTACHI R15 \n"\
|
"MVTACHI R15 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
"MVTC R15, FPSW \n"\
|
"MVTC R15, FPSW \n" \
|
||||||
"POPM R1-R15 \n"\
|
"POPM R1-R15 \n" \
|
||||||
"RTE \n"\
|
"RTE \n" \
|
||||||
"NOP \n"\
|
"NOP \n" \
|
||||||
"NOP "
|
"NOP "
|
||||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ), "i" ( configKERNEL_INTERRUPT_PRIORITY )
|
:: "i"(configMAX_SYSCALL_INTERRUPT_PRIORITY), "i"(configKERNEL_INTERRUPT_PRIORITY)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -322,10 +313,10 @@ void vSoftwareInterruptISR( void )
|
||||||
void vTickISR( void )
|
void vTickISR( void )
|
||||||
{
|
{
|
||||||
/* Re-enabled interrupts. */
|
/* Re-enabled interrupts. */
|
||||||
__asm volatile ( "SETPSW I");
|
__asm volatile( "SETPSW I" );
|
||||||
|
|
||||||
/* Increment the tick, and perform any processing the new tick value
|
/* Increment the tick, and perform any processing the new tick value
|
||||||
* necessitates. Ensure IPL is at the max syscall value first. */
|
necessitates. Ensure IPL is at the max syscall value first. */
|
||||||
portDISABLE_INTERRUPTS_FROM_KERNEL_ISR();
|
portDISABLE_INTERRUPTS_FROM_KERNEL_ISR();
|
||||||
{
|
{
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
|
@ -341,8 +332,8 @@ uint32_t ulPortGetIPL( void )
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
"MVFC PSW, R1 \n"\
|
"MVFC PSW, R1 \n" \
|
||||||
"SHLR #24, R1 \n"\
|
"SHLR #24, R1 \n" \
|
||||||
"RTS "
|
"RTS "
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -355,13 +346,13 @@ void vPortSetIPL( uint32_t ulNewIPL )
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
"PUSH R5 \n"\
|
"PUSH R5 \n" \
|
||||||
"MVFC PSW, R5 \n"\
|
"MVFC PSW, R5 \n" \
|
||||||
"SHLL #24, R1 \n"\
|
"SHLL #24, R1 \n" \
|
||||||
"AND #-0F000001H, R5 \n"\
|
"AND #-0F000001H, R5 \n" \
|
||||||
"OR R1, R5 \n"\
|
"OR R1, R5 \n" \
|
||||||
"MVTC R5, PSW \n"\
|
"MVTC R5, PSW \n" \
|
||||||
"POP R5 \n"\
|
"POP R5 \n" \
|
||||||
"RTS "
|
"RTS "
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,11 +27,11 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -44,94 +44,95 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 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 ( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
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
|
||||||
#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() __asm volatile ( "NOP" )
|
#define portNOP() __asm volatile( "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. */
|
||||||
#define portYIELD() \
|
#define portYIELD() \
|
||||||
__asm volatile \
|
__asm volatile \
|
||||||
( \
|
( \
|
||||||
"PUSH.L R10 \n"\
|
"PUSH.L R10 \n" \
|
||||||
"MOV.L #0x872E0, R10 \n"\
|
"MOV.L #0x872E0, R10 \n" \
|
||||||
"MOV.B #0x1, [R10] \n"\
|
"MOV.B #0x1, [R10] \n" \
|
||||||
"MOV.L [R10], R10 \n"\
|
"MOV.L [R10], R10 \n" \
|
||||||
"POP R10 \n"\
|
"POP R10 \n" \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR( x ) if( x != pdFALSE ) portYIELD()
|
#define portYIELD_FROM_ISR( x ) if( x != pdFALSE ) portYIELD()
|
||||||
|
|
||||||
/* 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() __asm volatile ( "MVTIPL #0")
|
#define portENABLE_INTERRUPTS() __asm volatile ( "MVTIPL #0" )
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( ulPortGetIPL() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( ulPortGetIPL() <= configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
|
||||||
#define portDISABLE_INTERRUPTS() if( ulPortGetIPL() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __asm volatile ( "MVTIPL %0"::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
|
#define portDISABLE_INTERRUPTS() if( ulPortGetIPL() < configMAX_SYSCALL_INTERRUPT_PRIORITY ) __asm volatile ( "MVTIPL %0" ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) )
|
||||||
#else
|
#else
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile ( "MVTIPL %0"::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
|
#define portDISABLE_INTERRUPTS() __asm volatile ( "MVTIPL %0" ::"i"(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... */
|
||||||
uint32_t ulPortGetIPL( void ) __attribute__( ( naked ) );
|
uint32_t ulPortGetIPL( void ) __attribute__((naked));
|
||||||
void vPortSetIPL( uint32_t ulNewIPL ) __attribute__( ( naked ) );
|
void vPortSetIPL( uint32_t ulNewIPL ) __attribute__((naked));
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortGetIPL(); portDISABLE_INTERRUPTS()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortGetIPL(); portDISABLE_INTERRUPTS()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) vPortSetIPL( uxSavedInterruptStatus )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) vPortSetIPL( 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 )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the SH2A port.
|
* Implementation of functions defined in portable.h for the SH2A port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
@ -42,17 +42,17 @@
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* 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 )
|
||||||
|
|
||||||
/* These macros allow a critical section to be added around the call to
|
/* These macros allow a critical section to be added around the call to
|
||||||
* xTaskIncrementTick(), which is only ever called from interrupts at the kernel
|
xTaskIncrementTick(), which is only ever called from interrupts at the kernel
|
||||||
* priority - ie a known priority. Therefore these local macros are a slight
|
priority - ie a known priority. Therefore these local macros are a slight
|
||||||
* optimisation compared to calling the global SET/CLEAR_INTERRUPT_MASK macros,
|
optimisation compared to calling the global SET/CLEAR_INTERRUPT_MASK macros,
|
||||||
* which would require the old IPL to be read first and stored in a local variable. */
|
which would require the old IPL to be read first and stored in a local variable. */
|
||||||
#define portMASK_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) )
|
#define portMASK_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0" ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) )
|
||||||
#define portUNMASK_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0" ::"i" ( configKERNEL_INTERRUPT_PRIORITY ) )
|
#define portUNMASK_INTERRUPTS_FROM_KERNEL_ISR() __asm volatile ( "MVTIPL %0" ::"i"(configKERNEL_INTERRUPT_PRIORITY) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -60,32 +60,30 @@
|
||||||
* Function to start the first task executing - written in asm code as direct
|
* Function to start the first task executing - written in asm code as direct
|
||||||
* access to registers is required.
|
* access to registers is required.
|
||||||
*/
|
*/
|
||||||
static void prvStartFirstTask( void ) __attribute__( ( naked ) );
|
static void prvStartFirstTask( void ) __attribute__((naked));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Software interrupt handler. Performs the actual context switch (saving and
|
* Software interrupt handler. Performs the actual context switch (saving and
|
||||||
* restoring of registers). Written in asm code as direct register access is
|
* restoring of registers). Written in asm code as direct register access is
|
||||||
* required.
|
* required.
|
||||||
*/
|
*/
|
||||||
void vSoftwareInterruptISR( void ) __attribute__( ( naked ) );
|
void vSoftwareInterruptISR( void ) __attribute__((naked));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The tick interrupt handler.
|
* The tick interrupt handler.
|
||||||
*/
|
*/
|
||||||
void vTickISR( void ) __attribute__( ( interrupt ) );
|
void vTickISR( void ) __attribute__((interrupt));
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
extern void * pxCurrentTCB;
|
extern void *pxCurrentTCB;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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. */
|
||||||
|
|
||||||
|
@ -96,8 +94,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--;
|
||||||
|
@ -130,11 +128,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--;
|
||||||
|
@ -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. */
|
||||||
|
@ -189,7 +187,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
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 );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -198,57 +196,54 @@ static void prvStartFirstTask( void )
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
|
|
||||||
/* 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 \n"\
|
"SETPSW U \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"MOV.L #_pxCurrentTCB, R15 \n" \
|
||||||
"MOV.L [R15], R15 \n"\
|
"MOV.L [R15], R15 \n" \
|
||||||
"MOV.L [R15], R0 \n"\
|
"MOV.L [R15], R0 \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator low 32 bits. */
|
/* Accumulator low 32 bits. */
|
||||||
"MVTACLO R15, A0 \n"\
|
"MVTACLO R15, A0 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator high 32 bits. */
|
/* Accumulator high 32 bits. */
|
||||||
"MVTACHI R15, A0 \n"\
|
"MVTACHI R15, A0 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator guard. */
|
/* Accumulator guard. */
|
||||||
"MVTACGU R15, A0 \n"\
|
"MVTACGU R15, A0 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator low 32 bits. */
|
/* Accumulator low 32 bits. */
|
||||||
"MVTACLO R15, A1 \n"\
|
"MVTACLO R15, A1 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator high 32 bits. */
|
/* Accumulator high 32 bits. */
|
||||||
"MVTACHI R15, A1 \n"\
|
"MVTACHI R15, A1 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator guard. */
|
/* Accumulator guard. */
|
||||||
"MVTACGU R15, A1 \n"\
|
"MVTACGU R15, A1 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Floating point status word. */
|
/* Floating point status word. */
|
||||||
"MVTC R15, FPSW \n"\
|
"MVTC R15, FPSW \n" \
|
||||||
|
|
||||||
/* R1 to R15 - R0 is not included as it is the SP. */
|
/* R1 to R15 - R0 is not included as it is the SP. */
|
||||||
"POPM R1-R15 \n"\
|
"POPM R1-R15 \n" \
|
||||||
|
|
||||||
/* This pops the remaining registers. */
|
/* This pops the remaining registers. */
|
||||||
"RTE \n"\
|
"RTE \n" \
|
||||||
"NOP \n"\
|
"NOP \n" \
|
||||||
"NOP \n"
|
"NOP \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -259,111 +254,107 @@ void vSoftwareInterruptISR( void )
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
/* Re-enable interrupts. */
|
/* Re-enable interrupts. */
|
||||||
"SETPSW I \n"\
|
"SETPSW I \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"PUSH.L R15 \n" \
|
||||||
|
|
||||||
/* Read the user stack pointer. */
|
/* Read the user stack pointer. */
|
||||||
"MVFC USP, R15 \n"\
|
"MVFC USP, R15 \n" \
|
||||||
|
|
||||||
/* Move the address down to the data being moved. */
|
/* Move the address down to the data being moved. */
|
||||||
"SUB #12, R15 \n"\
|
"SUB #12, R15 \n" \
|
||||||
"MVTC R15, USP \n"\
|
"MVTC R15, USP \n" \
|
||||||
|
|
||||||
/* Copy the data across, R15, then PC, then PSW. */
|
/* Copy the data across, R15, then PC, then PSW. */
|
||||||
"MOV.L [ R0 ], [ R15 ] \n"\
|
"MOV.L [ R0 ], [ R15 ] \n" \
|
||||||
"MOV.L 4[ R0 ], 4[ R15 ] \n"\
|
"MOV.L 4[ R0 ], 4[ R15 ] \n" \
|
||||||
"MOV.L 8[ R0 ], 8[ R15 ] \n"\
|
"MOV.L 8[ R0 ], 8[ R15 ] \n" \
|
||||||
|
|
||||||
/* Move the interrupt stack pointer to its new correct position. */
|
/* Move the interrupt stack pointer to its new correct position. */
|
||||||
"ADD #12, R0 \n"\
|
"ADD #12, R0 \n" \
|
||||||
|
|
||||||
/* 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 \n"\
|
"SETPSW U \n" \
|
||||||
|
|
||||||
/* 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 \n"\
|
"PUSHM R1-R14 \n" \
|
||||||
|
|
||||||
/* Save the FPSW and accumulator. */
|
/* Save the FPSW and accumulator. */
|
||||||
"MVFC FPSW, R15 \n"\
|
"MVFC FPSW, R15 \n" \
|
||||||
"PUSH.L R15 \n"\
|
"PUSH.L R15 \n" \
|
||||||
"MVFACGU #0, A1, R15 \n"\
|
"MVFACGU #0, A1, R15 \n" \
|
||||||
"PUSH.L R15 \n"\
|
"PUSH.L R15 \n" \
|
||||||
"MVFACHI #0, A1, R15 \n"\
|
"MVFACHI #0, A1, R15 \n" \
|
||||||
"PUSH.L R15 \n"\
|
"PUSH.L R15 \n" \
|
||||||
/* Low order word. */
|
/* Low order word. */
|
||||||
"MVFACLO #0, A1, R15 \n"\
|
"MVFACLO #0, A1, R15 \n" \
|
||||||
"PUSH.L R15 \n"\
|
"PUSH.L R15 \n" \
|
||||||
"MVFACGU #0, A0, R15 \n"\
|
"MVFACGU #0, A0, R15 \n" \
|
||||||
"PUSH.L R15 \n"\
|
"PUSH.L R15 \n" \
|
||||||
"MVFACHI #0, A0, R15 \n"\
|
"MVFACHI #0, A0, R15 \n" \
|
||||||
"PUSH.L R15 \n"\
|
"PUSH.L R15 \n" \
|
||||||
/* Low order word. */
|
/* Low order word. */
|
||||||
"MVFACLO #0, A0, R15 \n"\
|
"MVFACLO #0, A0, R15 \n" \
|
||||||
"PUSH.L R15 \n"\
|
"PUSH.L R15 \n" \
|
||||||
|
|
||||||
/* Save the stack pointer to the TCB. */
|
/* Save the stack pointer to the TCB. */
|
||||||
"MOV.L #_pxCurrentTCB, R15 \n"\
|
"MOV.L #_pxCurrentTCB, R15 \n" \
|
||||||
"MOV.L [ R15 ], R15 \n"\
|
"MOV.L [ R15 ], R15 \n" \
|
||||||
"MOV.L R0, [ R15 ] \n"\
|
"MOV.L R0, [ R15 ] \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 %0 \n"\
|
"MVTIPL %0 \n" \
|
||||||
|
|
||||||
/* Select the next task to run. */
|
/* Select the next task to run. */
|
||||||
"BSR.A _vTaskSwitchContext \n"\
|
"BSR.A _vTaskSwitchContext \n" \
|
||||||
|
|
||||||
/* 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 %1 \n"\
|
"MVTIPL %1 \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"MOV.L #_pxCurrentTCB,R15 \n" \
|
||||||
"MOV.L [ R15 ], R15 \n"\
|
"MOV.L [ R15 ], R15 \n" \
|
||||||
"MOV.L [ R15 ], R0 \n"\
|
"MOV.L [ R15 ], R0 \n" \
|
||||||
|
|
||||||
|
|
||||||
/* 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 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator low 32 bits. */
|
/* Accumulator low 32 bits. */
|
||||||
"MVTACLO R15, A0 \n"\
|
"MVTACLO R15, A0 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator high 32 bits. */
|
/* Accumulator high 32 bits. */
|
||||||
"MVTACHI R15, A0 \n"\
|
"MVTACHI R15, A0 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator guard. */
|
/* Accumulator guard. */
|
||||||
"MVTACGU R15, A0 \n"\
|
"MVTACGU R15, A0 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator low 32 bits. */
|
/* Accumulator low 32 bits. */
|
||||||
"MVTACLO R15, A1 \n"\
|
"MVTACLO R15, A1 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator high 32 bits. */
|
/* Accumulator high 32 bits. */
|
||||||
"MVTACHI R15, A1 \n"\
|
"MVTACHI R15, A1 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
|
|
||||||
/* Accumulator guard. */
|
/* Accumulator guard. */
|
||||||
"MVTACGU R15, A1 \n"\
|
"MVTACGU R15, A1 \n" \
|
||||||
"POP R15 \n"\
|
"POP R15 \n" \
|
||||||
"MVTC R15, FPSW \n"\
|
"MVTC R15, FPSW \n" \
|
||||||
"POPM R1-R15 \n"\
|
"POPM R1-R15 \n" \
|
||||||
"RTE \n"\
|
"RTE \n" \
|
||||||
"NOP \n"\
|
"NOP \n" \
|
||||||
"NOP "
|
"NOP "
|
||||||
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ), "i" ( configKERNEL_INTERRUPT_PRIORITY )
|
:: "i"(configMAX_SYSCALL_INTERRUPT_PRIORITY), "i"(configKERNEL_INTERRUPT_PRIORITY)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -371,10 +362,10 @@ void vSoftwareInterruptISR( void )
|
||||||
void vTickISR( void )
|
void vTickISR( void )
|
||||||
{
|
{
|
||||||
/* Re-enabled interrupts. */
|
/* Re-enabled interrupts. */
|
||||||
__asm volatile ( "SETPSW I");
|
__asm volatile( "SETPSW I" );
|
||||||
|
|
||||||
/* Increment the tick, and perform any processing the new tick value
|
/* Increment the tick, and perform any processing the new tick value
|
||||||
* necessitates. Ensure IPL is at the max syscall value first. */
|
necessitates. Ensure IPL is at the max syscall value first. */
|
||||||
portMASK_INTERRUPTS_FROM_KERNEL_ISR();
|
portMASK_INTERRUPTS_FROM_KERNEL_ISR();
|
||||||
{
|
{
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
|
@ -390,8 +381,8 @@ uint32_t ulPortGetIPL( void )
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
"MVFC PSW, R1 \n"\
|
"MVFC PSW, R1 \n" \
|
||||||
"SHLR #24, R1 \n"\
|
"SHLR #24, R1 \n" \
|
||||||
"RTS "
|
"RTS "
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -404,13 +395,13 @@ void vPortSetIPL( uint32_t ulNewIPL )
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
"PUSH R5 \n"\
|
"PUSH R5 \n" \
|
||||||
"MVFC PSW, R5 \n"\
|
"MVFC PSW, R5 \n" \
|
||||||
"SHLL #24, R1 \n"\
|
"SHLL #24, R1 \n" \
|
||||||
"AND #-0F000001H, R5 \n"\
|
"AND #-0F000001H, R5 \n" \
|
||||||
"OR R1, R5 \n"\
|
"OR R1, R5 \n" \
|
||||||
"MVTC R5, PSW \n"\
|
"MVTC R5, PSW \n" \
|
||||||
"POP R5 \n"\
|
"POP R5 \n" \
|
||||||
"RTS "
|
"RTS "
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue