mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Comment the new MicroBlaze port layer files.
This commit is contained in:
parent
0e12cd0768
commit
f90794f05a
|
@ -68,47 +68,55 @@
|
|||
#include <xil_exception.h>
|
||||
#include <microblaze_exceptions_g.h>
|
||||
|
||||
/* 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 reach zero, so it is initialised to a high value. */
|
||||
/* 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
|
||||
nesting variable is initialised to a non-zero value. */
|
||||
#define portINITIAL_NESTING_VALUE ( 0xff )
|
||||
|
||||
/* The bit within the MSR register that enabled/disables interrupts. */
|
||||
#define portMSR_IE ( 0x02U )
|
||||
|
||||
/* 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
|
||||
given to the FSR register when the initial context is set up for a task being
|
||||
created. */
|
||||
#define portINITIAL_FSR ( 0U )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the interrupt controller instance.
|
||||
*/
|
||||
static portBASE_TYPE prvInitialiseInterruptController( void );
|
||||
static long prvInitialiseInterruptController( void );
|
||||
|
||||
/*
|
||||
* Call an application provided callback to set up the periodic interrupt used
|
||||
* for the RTOS tick. Using an application callback allows the application
|
||||
* writer to decide
|
||||
/* Ensure the interrupt controller instance variable is initialised before it is
|
||||
* used, and that the initialisation only happens once.
|
||||
*/
|
||||
extern void vApplicationSetupTimerInterrupt( void );
|
||||
static long prvEnsureInterruptControllerIsInitialised( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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 its own count, so this variable is saved as part of the task
|
||||
context. */
|
||||
volatile unsigned portBASE_TYPE uxCriticalNesting = portINITIAL_NESTING_VALUE;
|
||||
|
||||
/* To limit the amount of stack required by each task, this port uses a
|
||||
separate stack for interrupts. */
|
||||
/* 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
|
||||
of the task stack. */
|
||||
unsigned long *pulISRStack;
|
||||
|
||||
/* If an interrupt requests a context switch then ulTaskSwitchRequested will
|
||||
get set to 1, which in turn will cause vTaskSwitchContext() to be called
|
||||
prior to a task context getting restored on exit from the interrupt. This
|
||||
mechanism is used as a single interrupt can cause multiple peripherals handlers
|
||||
to get called, and vTaskSwitchContext() should not get called in each handler. */
|
||||
/* If an interrupt requests a context switch, then ulTaskSwitchRequested will
|
||||
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
|
||||
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
|
||||
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
|
||||
vTaskSwitchContext() multiple times as each peripheral is serviced. */
|
||||
volatile unsigned long ulTaskSwitchRequested = 0UL;
|
||||
|
||||
/* The instance of the interrupt controller used by this port. */
|
||||
/* The instance of the interrupt controller used by this port. This is required
|
||||
by the Xilinx library API functions. */
|
||||
static XIntc xInterruptControllerInstance;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -117,7 +125,7 @@ static XIntc xInterruptControllerInstance;
|
|||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been made.
|
||||
*
|
||||
* See the header file portable.h.
|
||||
* See the portable.h header file.
|
||||
*/
|
||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||
{
|
||||
|
@ -127,16 +135,7 @@ const unsigned long ulR13 = ( unsigned long ) &_SDA_BASE_;
|
|||
|
||||
/* Place a few bytes of known values on the bottom of the stack.
|
||||
This is essential for the Microblaze port and these lines must
|
||||
not be omitted. The parameter value will overwrite the
|
||||
0x22222222 value during the function prologue. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x22222222;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x33333333;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The debugger will look at the previous stack frame. */
|
||||
not be omitted. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000000;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x00000000;
|
||||
|
@ -172,6 +171,8 @@ const unsigned long ulR13 = ( unsigned long ) &_SDA_BASE_;
|
|||
*pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4 - return values and temporaries. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;/* R5 contains the function call parameters. */
|
||||
|
||||
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6 - other parameters and temporaries. Used as the return address from vPortTaskEntryPoint. */
|
||||
pxTopOfStack--;
|
||||
|
@ -187,11 +188,17 @@ const unsigned long ulR13 = ( unsigned long ) &_SDA_BASE_;
|
|||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x0c; /* R12 - temporaries. */
|
||||
pxTopOfStack--;
|
||||
#else
|
||||
pxTopOfStack-= 8;
|
||||
#endif
|
||||
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) ulR13; /* R13 - read/write small data area. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* R14 - return address for interrupt. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) NULL; /* R15 - return address for subroutine. */
|
||||
|
||||
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R16 - return address for trap (debugger). */
|
||||
pxTopOfStack--;
|
||||
|
@ -199,7 +206,13 @@ const unsigned long ulR13 = ( unsigned long ) &_SDA_BASE_;
|
|||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R18 - reserved for assembler and compiler temporaries. */
|
||||
pxTopOfStack--;
|
||||
#else
|
||||
pxTopOfStack -= 4;
|
||||
#endif
|
||||
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R19 - must be saved across function calls. Callee-save. Seems to be interpreted as the frame pointer. */
|
||||
|
||||
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R20 - reserved for storing a pointer to the Global Offset Table (GOT) in Position Independent Code (PIC). Non-volatile in non-PIC code. Must be saved across function calls. Callee-save. Not used by FreeRTOS. */
|
||||
pxTopOfStack--;
|
||||
|
@ -225,9 +238,12 @@ const unsigned long ulR13 = ( unsigned long ) &_SDA_BASE_;
|
|||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x1f; /* R31 - must be saved across function calls. Callee-save. */
|
||||
pxTopOfStack--;
|
||||
#else
|
||||
pxTopOfStack -= 13;
|
||||
#endif
|
||||
|
||||
/* 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. */
|
||||
/* 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. */
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -238,12 +254,23 @@ extern void ( vPortStartFirstTask )( void );
|
|||
extern unsigned long _stack[];
|
||||
|
||||
/* 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
|
||||
interrupt handler because the kernel will run on lots of different
|
||||
MicroBlaze and FPGA configurations - not all of which will have the same
|
||||
timer peripherals defined or available. An example definition of
|
||||
vApplicationSetupTimerInterrupt() is provided in the official demo
|
||||
application that accompanies this port. */
|
||||
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 = ( unsigned long * ) _stack;
|
||||
|
||||
/* Ensure there is enough space for the functions called from the interrupt
|
||||
service routines to write back into the stack frame of the caller. */
|
||||
pulISRStack -= 2;
|
||||
|
||||
/* Restore the context of the first task that is going to run. From here
|
||||
on, the created tasks will be executing. */
|
||||
vPortStartFirstTask();
|
||||
|
@ -268,7 +295,7 @@ extern void VPortYieldASM( void );
|
|||
|
||||
/* 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
|
||||
each task maintains it's own interrupt status. */
|
||||
each task maintains its own interrupt status. */
|
||||
portENTER_CRITICAL();
|
||||
{
|
||||
/* Jump directly to the yield function to ensure there is no
|
||||
|
@ -282,43 +309,92 @@ extern void VPortYieldASM( void );
|
|||
|
||||
void vPortEnableInterrupt( unsigned char ucInterruptID )
|
||||
{
|
||||
long lReturn;
|
||||
|
||||
/* An API function is provided to enable an interrupt in the interrupt
|
||||
controller because the interrupt controller instance variable is private
|
||||
to this file. */
|
||||
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||
if( lReturn == pdPASS )
|
||||
{
|
||||
XIntc_Enable( &xInterruptControllerInstance, ucInterruptID );
|
||||
}
|
||||
|
||||
configASSERT( lReturn );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortDisableInterrupt( unsigned char ucInterruptID )
|
||||
{
|
||||
long lReturn;
|
||||
|
||||
/* An API function is provided to disable an interrupt in the interrupt
|
||||
controller because the interrupt controller instance variable is private
|
||||
to this file. */
|
||||
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||
|
||||
if( lReturn == pdPASS )
|
||||
{
|
||||
XIntc_Disable( &xInterruptControllerInstance, ucInterruptID );
|
||||
}
|
||||
|
||||
configASSERT( lReturn );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )
|
||||
{
|
||||
static portBASE_TYPE xInterruptControllerInitialised = pdFALSE;
|
||||
portBASE_TYPE xReturn = XST_SUCCESS;
|
||||
long lReturn;
|
||||
|
||||
if( xInterruptControllerInitialised != pdTRUE )
|
||||
/* An API function is provided to install an interrupt handler because the
|
||||
interrupt controller instance variable is private to this file. */
|
||||
|
||||
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||
|
||||
if( lReturn == pdPASS )
|
||||
{
|
||||
xReturn = prvInitialiseInterruptController();
|
||||
xInterruptControllerInitialised = pdTRUE;
|
||||
lReturn = XIntc_Connect( &xInterruptControllerInstance, ucInterruptID, pxHandler, pvCallBackRef );
|
||||
}
|
||||
|
||||
if( xReturn == XST_SUCCESS )
|
||||
if( lReturn == XST_SUCCESS )
|
||||
{
|
||||
xReturn = XIntc_Connect( &xInterruptControllerInstance, ucInterruptID, pxHandler, pvCallBackRef );
|
||||
lReturn = pdPASS;
|
||||
}
|
||||
|
||||
if( xReturn == XST_SUCCESS )
|
||||
configASSERT( lReturn == pdPASS );
|
||||
|
||||
return lReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static long prvEnsureInterruptControllerIsInitialised( void )
|
||||
{
|
||||
static long lInterruptControllerInitialised = pdFALSE;
|
||||
long lReturn;
|
||||
|
||||
/* Ensure the interrupt controller instance variable is initialised before
|
||||
it is used, and that the initialisation only happens once. */
|
||||
if( lInterruptControllerInitialised != pdTRUE )
|
||||
{
|
||||
xReturn = pdPASS;
|
||||
lReturn = prvInitialiseInterruptController();
|
||||
|
||||
if( lReturn == pdPASS )
|
||||
{
|
||||
lInterruptControllerInitialised = pdTRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lReturn = pdPASS;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
return lReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Handler for the timer interrupt.
|
||||
* Handler for the timer interrupt. This is the handler that the application
|
||||
* defined callback function vApplicationSetupTimerInterrupt() should install.
|
||||
*/
|
||||
void vTickISR( void *pvUnused )
|
||||
{
|
||||
|
@ -327,13 +403,20 @@ extern void vApplicationClearTimerInterrupt( void );
|
|||
/* Ensure the unused parameter does not generate a compiler warning. */
|
||||
( void ) pvUnused;
|
||||
|
||||
/* This port uses an application defined callback function to clear the tick
|
||||
interrupt because the kernel will run on lots of different MicroBlaze and
|
||||
FPGA configurations - not all of which will have the same timer peripherals
|
||||
defined or available. An example definition of
|
||||
vApplicationClearTimerInterrupt() is provided in the official demo
|
||||
application that accompanies this port. */
|
||||
vApplicationClearTimerInterrupt();
|
||||
|
||||
/* Increment the RTOS tick - this might cause a task to unblock. */
|
||||
vTaskIncrementTick();
|
||||
|
||||
/* If we are using the preemptive scheduler then we also need to determine
|
||||
if this tick should cause a context switch. */
|
||||
/* If the preemptive scheduler is being used then a context switch should be
|
||||
requested in case incrementing the tick unblocked a task, or a time slice
|
||||
should cause another task to enter the Running state. */
|
||||
#if configUSE_PREEMPTION == 1
|
||||
/* Force vTaskSwitchContext() to be called as the interrupt exits. */
|
||||
ulTaskSwitchRequested = 1;
|
||||
|
@ -341,13 +424,13 @@ extern void vApplicationClearTimerInterrupt( void );
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portBASE_TYPE prvInitialiseInterruptController( void )
|
||||
static long prvInitialiseInterruptController( void )
|
||||
{
|
||||
portBASE_TYPE xStatus;
|
||||
long lStatus;
|
||||
|
||||
xStatus = XIntc_Initialize( &xInterruptControllerInstance, configINTERRUPT_CONTROLLER_TO_USE );
|
||||
lStatus = XIntc_Initialize( &xInterruptControllerInstance, configINTERRUPT_CONTROLLER_TO_USE );
|
||||
|
||||
if( xStatus == XST_SUCCESS )
|
||||
if( lStatus == XST_SUCCESS )
|
||||
{
|
||||
/* Initialise the exception table. */
|
||||
Xil_ExceptionInit();
|
||||
|
@ -366,28 +449,21 @@ portBASE_TYPE xStatus;
|
|||
|
||||
/* Start the interrupt controller. Interrupts are enabled when the
|
||||
scheduler starts. */
|
||||
xStatus = XIntc_Start( &xInterruptControllerInstance, XIN_REAL_MODE );
|
||||
lStatus = XIntc_Start( &xInterruptControllerInstance, XIN_REAL_MODE );
|
||||
|
||||
/* Ensure the compiler does not generate warnings for the unused
|
||||
iStatus valud if configASSERT() is not defined. */
|
||||
( void ) xStatus;
|
||||
if( lStatus == XST_SUCCESS )
|
||||
{
|
||||
lStatus = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
lStatus = pdFAIL;
|
||||
}
|
||||
}
|
||||
|
||||
configASSERT( ( xStatus == ( portBASE_TYPE ) XST_SUCCESS ) )
|
||||
configASSERT( lStatus == pdPASS );
|
||||
|
||||
/*_RB_ Exception test code. */
|
||||
#if 0
|
||||
This does not cause the bralid address to be in the r17 register.
|
||||
__asm volatile (
|
||||
"bralid r15, 1234 \n"
|
||||
"or r0, r0, r0 \n"
|
||||
);
|
||||
#endif
|
||||
#if 0
|
||||
xStatus /= 0;
|
||||
#endif
|
||||
|
||||
return xStatus;
|
||||
return lStatus;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@
|
|||
#include <microblaze_exceptions_i.h>
|
||||
#include <microblaze_exceptions_g.h>
|
||||
|
||||
/* The Xilinx library defined exception entry point stacks a number of
|
||||
registers. These definitions are offsets from the stack pointer to the various
|
||||
stacked register values. */
|
||||
#define portexR3_STACK_OFFSET 4
|
||||
#define portexR4_STACK_OFFSET 5
|
||||
#define portexR5_STACK_OFFSET 6
|
||||
|
@ -74,24 +77,42 @@
|
|||
#define portexMSR_STACK_OFFSET 19
|
||||
#define portexR19_STACK_OFFSET -1
|
||||
|
||||
#define portexESR_DS_MASK 0x00001000UL
|
||||
|
||||
/* 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 stack pointer value prior to the exception being entered. */
|
||||
#define portexASM_HANDLER_STACK_FRAME_SIZE 84UL
|
||||
|
||||
/* Exclude the entire file if the MicroBlaze is not configured to handle
|
||||
exceptions, or the application defined configuration item
|
||||
/* The number of bytes a MicroBlaze instruction consumes. */
|
||||
#define portexINSTRUCTION_SIZE 4
|
||||
|
||||
/* Exclude this entire file if the MicroBlaze is not configured to handle
|
||||
exceptions, or the application defined configuration constant
|
||||
configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
||||
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
||||
|
||||
/* These are global volatiles to allow their inspection by a debugger. */
|
||||
/* These variables are set in the exception entry code, before
|
||||
vPortExceptionHandler is called. */
|
||||
unsigned long *pulStackPointerOnFunctionEntry = NULL, ulBTROnFunctionEntry = 0UL;
|
||||
|
||||
/* This is the structure that is filled with the MicroBlaze context as it
|
||||
existed immediately prior to the exception occurrence. A pointer to this
|
||||
structure is passed into the vApplicationExceptionRegisterDump() callback
|
||||
function, if one is defined. */
|
||||
static xPortRegisterDump xRegisterDump;
|
||||
|
||||
/* This is the FreeRTOS exception handler that is installed for all exception
|
||||
types. It is called from vPortExceptionHanlderEntry() - which is itself defined
|
||||
in portasm.S. */
|
||||
void vPortExceptionHandler( void *pvExceptionID );
|
||||
extern void vPortExceptionHandlerEntry( void *pvExceptionID );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* vApplicationExceptionRegisterDump() is a callback function that the
|
||||
application can optionally define to receive a populated xPortRegisterDump
|
||||
structure. If the application chooses not to define a version of
|
||||
vApplicationExceptionRegisterDump() then this weekly defined default
|
||||
implementation will be called instead. */
|
||||
extern void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump ) __attribute__((weak));
|
||||
void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )
|
||||
{
|
||||
|
@ -106,6 +127,11 @@ void vPortExceptionHandler( void *pvExceptionID )
|
|||
{
|
||||
extern void *pxCurrentTCB;
|
||||
|
||||
/* Fill an xPortRegisterDump structure with the MicroBlaze context as it
|
||||
was immediately before the exception occurrence. */
|
||||
|
||||
/* First fill in the name and handle of the task that was in the Running
|
||||
state when the exception occurred. */
|
||||
xRegisterDump.xCurrentTaskHandle = pxCurrentTCB;
|
||||
xRegisterDump.pcCurrentTaskName = pcTaskGetTaskName( NULL );
|
||||
|
||||
|
@ -126,6 +152,7 @@ extern void *pxCurrentTCB;
|
|||
xRegisterDump.ulR15_return_address_from_subroutine = pulStackPointerOnFunctionEntry[ portexR15_STACK_OFFSET ];
|
||||
xRegisterDump.ulR18 = pulStackPointerOnFunctionEntry[ portexR18_STACK_OFFSET ];
|
||||
xRegisterDump.ulR19 = pulStackPointerOnFunctionEntry[ portexR19_STACK_OFFSET ];
|
||||
xRegisterDump.ulMSR = pulStackPointerOnFunctionEntry[ portexMSR_STACK_OFFSET ];
|
||||
|
||||
/* Obtain the value of all other registers. */
|
||||
xRegisterDump.ulR2_small_data_area = mfgpr( R2 );
|
||||
|
@ -148,25 +175,14 @@ extern void *pxCurrentTCB;
|
|||
xRegisterDump.ulR31 = mfgpr( R31 );
|
||||
xRegisterDump.ulR1_SP = ( ( unsigned long ) pulStackPointerOnFunctionEntry ) + portexASM_HANDLER_STACK_FRAME_SIZE;
|
||||
xRegisterDump.ulBTR = ulBTROnFunctionEntry;
|
||||
xRegisterDump.ulMSR = pulStackPointerOnFunctionEntry[ portexMSR_STACK_OFFSET ];
|
||||
xRegisterDump.ulEAR = mfear();
|
||||
xRegisterDump.ulESR = mfesr();
|
||||
xRegisterDump.ulEDR = mfedr();
|
||||
|
||||
|
||||
#ifdef THIS_IS_PROBABLY_INCORRECT
|
||||
if( ( xRegisterDump.ulESR * portexESR_DS_MASK ) != 0UL )
|
||||
{
|
||||
xRegisterDump.ulPC = mfbtr();
|
||||
}
|
||||
else
|
||||
{
|
||||
xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_some_exceptions - 4;
|
||||
}
|
||||
#else
|
||||
xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_some_exceptions - 4;
|
||||
#endif
|
||||
|
||||
/* Move the saved program counter back to the instruction that was executed
|
||||
when the exception occurred. This is only valid for certain types of
|
||||
exception. */
|
||||
xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_some_exceptions - portexINSTRUCTION_SIZE;
|
||||
|
||||
#if XPAR_MICROBLAZE_0_USE_FPU == 1
|
||||
{
|
||||
|
@ -178,6 +194,9 @@ extern void *pxCurrentTCB;
|
|||
}
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
library exception header files. */
|
||||
switch( ( unsigned long ) pvExceptionID )
|
||||
{
|
||||
case XEXC_ID_FSL :
|
||||
|
@ -218,6 +237,11 @@ extern void *pxCurrentTCB;
|
|||
#endif /* XPAR_MICROBLAZE_0_USE_FPU */
|
||||
}
|
||||
|
||||
/* vApplicationExceptionRegisterDump() is a callback function that the
|
||||
application can optionally define to receive the populated xPortRegisterDump
|
||||
structure. If the application chooses not to define a version of
|
||||
vApplicationExceptionRegisterDump() then the weekly defined default
|
||||
implementation within this file will be called instead. */
|
||||
vApplicationExceptionRegisterDump( &xRegisterDump );
|
||||
|
||||
/* Must not attempt to leave this function! */
|
||||
|
|
|
@ -57,7 +57,10 @@
|
|||
licensing and training services.
|
||||
*/
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOSConfig.h"
|
||||
|
||||
/* Xilinx library includes. */
|
||||
#include "microblaze_exceptions_g.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
|
@ -250,7 +253,7 @@ back into the caller stack. */
|
|||
|
||||
/* This function is used to exit portRESTORE_CONTEXT() if the task being
|
||||
returned to last left the Running state by calling taskYIELD() (rather than
|
||||
being preempted by an interrupt. */
|
||||
being preempted by an interrupt). */
|
||||
.text
|
||||
.align 2
|
||||
exit_from_yield:
|
||||
|
@ -276,9 +279,7 @@ _interrupt_handler:
|
|||
/* Stack the return address. */
|
||||
swi r14, r1, portR14_OFFSET
|
||||
|
||||
/* Switch to the ISR stack. The pulISRStack value has already been set to
|
||||
leave space for the caller function to write back into the stack of this
|
||||
function. */
|
||||
/* Switch to the ISR stack. */
|
||||
lwi r1, r0, pulISRStack
|
||||
|
||||
/* The parameter to the interrupt handler. */
|
||||
|
|
|
@ -100,6 +100,8 @@ portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterr
|
|||
void vPortEnableInterrupt( unsigned char ucInterruptID );
|
||||
void vPortDisableInterrupt( unsigned char ucInterruptID );
|
||||
|
||||
void vApplicationSetupTimerInterrupt( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section macros. */
|
||||
|
|
Loading…
Reference in a new issue