2011-07-27 21:03:14 +08:00
/*
2013-11-28 18:48:33 +08:00
FreeRTOS V7 .6 .0 - Copyright ( C ) 2013 Real Time Engineers Ltd .
2013-10-15 03:56:47 +08:00
All rights reserved
2012-10-16 20:17:47 +08:00
2013-07-18 02:32:57 +08:00
VISIT http : //www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
2011-07-27 21:03:14 +08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
2013-07-18 02:32:57 +08:00
* FreeRTOS provides completely free yet professionally developed , *
* robust , strictly quality controlled , supported , and cross *
* platform software that has become a de facto standard . *
2011-07-27 21:03:14 +08:00
* *
2013-07-18 02:32:57 +08:00
* Help yourself get started quickly and support the FreeRTOS *
* project by purchasing a FreeRTOS tutorial book , reference *
* manual , or both from : http : //www.FreeRTOS.org/Documentation *
2011-07-27 21:03:14 +08:00
* *
2013-07-18 02:32:57 +08:00
* Thank you ! *
2011-07-27 21:03:14 +08:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
This file is part of the FreeRTOS distribution .
FreeRTOS is free software ; you can redistribute it and / or modify it under
the terms of the GNU General Public License ( version 2 ) as published by the
2013-07-18 02:32:57 +08:00
Free Software Foundation > > ! AND MODIFIED BY ! < < the FreeRTOS exception .
2013-02-20 02:36:58 +08:00
2013-07-18 02:32:57 +08:00
> > ! NOTE : The modification to the GPL is included to allow you to distribute
> > ! a combined work that includes FreeRTOS without being obliged to provide
> > ! the source code for proprietary components outside of the FreeRTOS
> > ! kernel .
2013-02-20 02:36:58 +08:00
FreeRTOS is distributed in the hope that it will be useful , but WITHOUT ANY
WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS
2013-07-18 02:32:57 +08:00
FOR A PARTICULAR PURPOSE . Full license text is available from the following
link : http : //www.freertos.org/a00114.html
2011-07-27 21:03:14 +08:00
1 tab = = 4 spaces !
2013-02-20 02:36:58 +08:00
2012-05-09 00:36:52 +08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Having a problem ? Start by reading the FAQ " My application does *
2012-10-16 20:17:47 +08:00
* not run , what could be wrong ? " *
2012-05-09 00:36:52 +08:00
* *
* http : //www.FreeRTOS.org/FAQHelp.html *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2011-07-27 21:03:14 +08:00
2013-07-18 02:32:57 +08:00
http : //www.FreeRTOS.org - Documentation, books, training, latest versions,
2013-02-20 02:36:58 +08:00
license and Real Time Engineers Ltd . contact details .
2012-05-09 00:36:52 +08:00
http : //www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
2013-07-18 02:32:57 +08:00
including FreeRTOS + Trace - an indispensable productivity tool , a DOS
compatible FAT file system , and our tiny thread aware UDP / IP stack .
http : //www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand . Low cost OpenRTOS
licenses offer ticketed support , indemnification and middleware .
http : //www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
2013-02-20 02:36:58 +08:00
mission critical applications that require provable dependability .
2013-07-18 02:32:57 +08:00
1 tab = = 4 spaces !
2011-07-27 21:03:14 +08:00
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable . h for the MicroBlaze port .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Scheduler includes. */
# include "FreeRTOS.h"
# include "task.h"
/* Standard includes. */
# include <string.h>
/* Hardware includes. */
# include <xintc_i.h>
# include <xil_exception.h>
# include <microblaze_exceptions_g.h>
2013-11-28 18:48:33 +08:00
/* 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
2011-07-27 21:03:14 +08:00
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 .
*/
2013-12-29 22:06:04 +08:00
static int32_t prvInitialiseInterruptController ( void ) ;
2011-07-27 21:03:14 +08:00
2013-11-28 18:48:33 +08:00
/* Ensure the interrupt controller instance variable is initialised before it is
* used , and that the initialisation only happens once .
2011-07-27 21:03:14 +08:00
*/
2013-12-29 22:06:04 +08:00
static int32_t prvEnsureInterruptControllerIsInitialised ( void ) ;
2011-07-27 21:03:14 +08:00
/*-----------------------------------------------------------*/
2013-11-28 18:48:33 +08:00
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
2011-07-27 21:03:14 +08:00
maintains its own count , so this variable is saved as part of the task
context . */
2013-12-29 22:06:04 +08:00
volatile UBaseType_t uxCriticalNesting = portINITIAL_NESTING_VALUE ;
2011-07-27 21:03:14 +08:00
/* 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 . */
2013-12-29 22:06:04 +08:00
uint32_t * pulISRStack ;
2011-07-27 21:03:14 +08:00
/* 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
2013-11-28 18:48:33 +08:00
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
2011-07-27 21:03:14 +08:00
cause the servicing of multiple peripherals - and it is inefficient to call
vTaskSwitchContext ( ) multiple times as each peripheral is serviced . */
2013-12-29 22:06:04 +08:00
volatile uint32_t ulTaskSwitchRequested = 0UL ;
2011-07-27 21:03:14 +08:00
/* The instance of the interrupt controller used by this port. This is required
by the Xilinx library API functions . */
static XIntc xInterruptControllerInstance ;
/*-----------------------------------------------------------*/
2013-11-28 18:48:33 +08:00
/*
* Initialise the stack of a task to look exactly as if a call to
2011-07-27 21:03:14 +08:00
* portSAVE_CONTEXT had been made .
2013-11-28 18:48:33 +08:00
*
2011-07-27 21:03:14 +08:00
* See the portable . h header file .
*/
2013-12-29 22:06:04 +08:00
StackType_t * pxPortInitialiseStack ( StackType_t * pxTopOfStack , pdTASK_CODE pxCode , void * pvParameters )
2011-07-27 21:03:14 +08:00
{
extern void * _SDA2_BASE_ , * _SDA_BASE_ ;
2013-12-29 22:06:04 +08:00
const uint32_t ulR2 = ( uint32_t ) & _SDA2_BASE_ ;
const uint32_t ulR13 = ( uint32_t ) & _SDA_BASE_ ;
2011-07-27 21:03:14 +08:00
2013-11-28 18:48:33 +08:00
/* Place a few bytes of known values on the bottom of the stack.
2011-07-27 21:03:14 +08:00
This is essential for the Microblaze port and these lines must
not be omitted . */
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x00000000 ;
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x00000000 ;
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x00000000 ;
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
# if XPAR_MICROBLAZE_0_USE_FPU == 1
/* The FSR value placed in the initial task context is just 0. */
* pxTopOfStack = portINITIAL_FSR ;
pxTopOfStack - - ;
# endif
/* The MSR value placed in the initial task context should have interrupts
disabled . Each task will enable interrupts automatically when it enters
the running state for the first time . */
* pxTopOfStack = mfmsr ( ) & ~ portMSR_IE ;
pxTopOfStack - - ;
/* First stack an initial value for the critical section nesting. This
is initialised to zero . */
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x00 ;
2013-11-28 18:48:33 +08:00
2011-07-27 21:03:14 +08:00
/* R0 is always zero. */
/* R1 is the SP. */
/* Place an initial value for all the general purpose registers. */
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) ulR2 ; /* R2 - read only small data area. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x03 ; /* R3 - return values and temporaries. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x04 ; /* R4 - return values and temporaries. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) pvParameters ; /* R5 contains the function call parameters. */
2011-07-27 21:03:14 +08:00
# ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x06 ; /* R6 - other parameters and temporaries. Used as the return address from vPortTaskEntryPoint. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x07 ; /* R7 - other parameters and temporaries. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x08 ; /* R8 - other parameters and temporaries. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x09 ; /* R9 - other parameters and temporaries. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x0a ; /* R10 - other parameters and temporaries. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x0b ; /* R11 - temporaries. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x0c ; /* R12 - temporaries. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
# else
pxTopOfStack - = 8 ;
# endif
2013-11-28 18:48:33 +08:00
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) ulR13 ; /* R13 - read/write small data area. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) pxCode ; /* R14 - return address for interrupt. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) NULL ; /* R15 - return address for subroutine. */
2013-11-28 18:48:33 +08:00
2011-07-27 21:03:14 +08:00
# ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x10 ; /* R16 - return address for trap (debugger). */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x11 ; /* R17 - return address for exceptions, if configured. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x12 ; /* R18 - reserved for assembler and compiler temporaries. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
# else
pxTopOfStack - = 4 ;
# endif
2013-11-28 18:48:33 +08:00
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x00 ; /* R19 - must be saved across function calls. Callee-save. Seems to be interpreted as the frame pointer. */
2013-11-28 18:48:33 +08:00
# ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 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. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x15 ; /* R21 - must be saved across function calls. Callee-save. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x16 ; /* R22 - must be saved across function calls. Callee-save. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x17 ; /* R23 - must be saved across function calls. Callee-save. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x18 ; /* R24 - must be saved across function calls. Callee-save. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x19 ; /* R25 - must be saved across function calls. Callee-save. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x1a ; /* R26 - must be saved across function calls. Callee-save. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x1b ; /* R27 - must be saved across function calls. Callee-save. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x1c ; /* R28 - must be saved across function calls. Callee-save. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x1d ; /* R29 - must be saved across function calls. Callee-save. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x1e ; /* R30 - must be saved across function calls. Callee-save. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
2013-12-29 22:06:04 +08:00
* pxTopOfStack = ( StackType_t ) 0x1f ; /* R31 - must be saved across function calls. Callee-save. */
2011-07-27 21:03:14 +08:00
pxTopOfStack - - ;
# else
pxTopOfStack - = 13 ;
# endif
2013-11-28 18:48:33 +08:00
/* Return a pointer to the top of the stack that has been generated so this
2011-07-27 21:03:14 +08:00
can be stored in the task control block for the task . */
return pxTopOfStack ;
}
/*-----------------------------------------------------------*/
2013-12-29 22:06:04 +08:00
BaseType_t xPortStartScheduler ( void )
2011-07-27 21:03:14 +08:00
{
extern void ( vPortStartFirstTask ) ( void ) ;
2013-12-29 22:06:04 +08:00
extern uint32_t _stack [ ] ;
2011-07-27 21:03:14 +08:00
/* Setup the hardware to generate the tick. Interrupts are disabled when
2013-11-28 18:48:33 +08:00
this function is called .
2011-07-27 21:03:14 +08:00
This port uses an application defined callback function to install the tick
2013-11-28 18:48:33 +08:00
interrupt handler because the kernel will run on lots of different
MicroBlaze and FPGA configurations - not all of which will have the same
2011-07-27 21:03:14 +08:00
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. */
2013-12-29 22:06:04 +08:00
pulISRStack = ( uint32_t * ) _stack ;
2011-07-27 21:03:14 +08:00
/* Ensure there is enough space for the functions called from the interrupt
2011-09-21 02:22:39 +08:00
service routines to write back into the stack frame of the caller . */
2011-07-27 21:03:14 +08:00
pulISRStack - = 2 ;
/* Restore the context of the first task that is going to run. From here
on , the created tasks will be executing . */
vPortStartFirstTask ( ) ;
/* Should not get here as the tasks are now running! */
return pdFALSE ;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler ( void )
{
2013-11-28 18:48:33 +08:00
/* Not implemented in ports where there is nothing to return to.
Artificially force an assert . */
configASSERT ( uxCriticalNesting = = 1000UL ) ;
2011-07-27 21:03:14 +08:00
}
/*-----------------------------------------------------------*/
/*
2013-11-28 18:48:33 +08:00
* Manual context switch called by portYIELD or taskYIELD .
2011-07-27 21:03:14 +08:00
*/
void vPortYield ( void )
{
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 its own interrupt status . */
portENTER_CRITICAL ( ) ;
{
/* Jump directly to the yield function to ensure there is no
compiler generated prologue code . */
asm volatile ( " bralid r14, VPortYieldASM \n \t " \
" or r0, r0, r0 \n \t " ) ;
}
portEXIT_CRITICAL ( ) ;
}
/*-----------------------------------------------------------*/
2013-12-29 22:06:04 +08:00
void vPortEnableInterrupt ( uint8_t ucInterruptID )
2011-07-27 21:03:14 +08:00
{
2013-12-29 22:06:04 +08:00
int32_t lReturn ;
2011-07-27 21:03:14 +08:00
/* 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 ) ;
}
2013-11-28 18:48:33 +08:00
2011-07-27 21:03:14 +08:00
configASSERT ( lReturn ) ;
}
/*-----------------------------------------------------------*/
2013-12-29 22:06:04 +08:00
void vPortDisableInterrupt ( uint8_t ucInterruptID )
2011-07-27 21:03:14 +08:00
{
2013-12-29 22:06:04 +08:00
int32_t lReturn ;
2011-07-27 21:03:14 +08:00
/* 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 ( ) ;
2013-11-28 18:48:33 +08:00
2011-07-27 21:03:14 +08:00
if ( lReturn = = pdPASS )
{
XIntc_Disable ( & xInterruptControllerInstance , ucInterruptID ) ;
}
2013-11-28 18:48:33 +08:00
2011-07-27 21:03:14 +08:00
configASSERT ( lReturn ) ;
}
/*-----------------------------------------------------------*/
2013-12-29 22:06:04 +08:00
BaseType_t xPortInstallInterruptHandler ( uint8_t ucInterruptID , XInterruptHandler pxHandler , void * pvCallBackRef )
2011-07-27 21:03:14 +08:00
{
2013-12-29 22:06:04 +08:00
int32_t lReturn ;
2011-07-27 21:03:14 +08:00
2013-11-28 18:48:33 +08:00
/* An API function is provided to install an interrupt handler because the
2011-07-27 21:03:14 +08:00
interrupt controller instance variable is private to this file . */
lReturn = prvEnsureInterruptControllerIsInitialised ( ) ;
2013-11-28 18:48:33 +08:00
2011-07-27 21:03:14 +08:00
if ( lReturn = = pdPASS )
{
lReturn = XIntc_Connect ( & xInterruptControllerInstance , ucInterruptID , pxHandler , pvCallBackRef ) ;
}
if ( lReturn = = XST_SUCCESS )
{
lReturn = pdPASS ;
}
2013-11-28 18:48:33 +08:00
2011-07-27 21:03:14 +08:00
configASSERT ( lReturn = = pdPASS ) ;
return lReturn ;
}
/*-----------------------------------------------------------*/
2013-12-29 22:06:04 +08:00
static int32_t prvEnsureInterruptControllerIsInitialised ( void )
2011-07-27 21:03:14 +08:00
{
2013-12-29 22:06:04 +08:00
static int32_t lInterruptControllerInitialised = pdFALSE ;
int32_t lReturn ;
2011-07-27 21:03:14 +08:00
/* Ensure the interrupt controller instance variable is initialised before
it is used , and that the initialisation only happens once . */
if ( lInterruptControllerInitialised ! = pdTRUE )
{
lReturn = prvInitialiseInterruptController ( ) ;
2013-11-28 18:48:33 +08:00
2011-07-27 21:03:14 +08:00
if ( lReturn = = pdPASS )
{
lInterruptControllerInitialised = pdTRUE ;
}
}
else
{
lReturn = pdPASS ;
}
return lReturn ;
}
/*-----------------------------------------------------------*/
2013-11-28 18:48:33 +08:00
/*
2011-07-27 21:03:14 +08:00
* Handler for the timer interrupt . This is the handler that the application
* defined callback function vApplicationSetupTimerInterrupt ( ) should install .
*/
void vPortTickISR ( void * pvUnused )
{
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
2013-11-28 18:48:33 +08:00
interrupt because the kernel will run on lots of different MicroBlaze and
FPGA configurations - not all of which will have the same timer peripherals
2011-07-27 21:03:14 +08:00
defined or available . An example definition of
vApplicationClearTimerInterrupt ( ) is provided in the official demo
2013-11-28 18:48:33 +08:00
application that accompanies this port . */
2011-07-27 21:03:14 +08:00
vApplicationClearTimerInterrupt ( ) ;
/* Increment the RTOS tick - this might cause a task to unblock. */
2013-06-06 23:46:40 +08:00
if ( xTaskIncrementTick ( ) ! = pdFALSE )
{
2011-07-27 21:03:14 +08:00
/* Force vTaskSwitchContext() to be called as the interrupt exits. */
ulTaskSwitchRequested = 1 ;
2013-06-06 23:46:40 +08:00
}
2011-07-27 21:03:14 +08:00
}
/*-----------------------------------------------------------*/
2013-12-29 22:06:04 +08:00
static int32_t prvInitialiseInterruptController ( void )
2011-07-27 21:03:14 +08:00
{
2013-12-29 22:06:04 +08:00
int32_t lStatus ;
2011-07-27 21:03:14 +08:00
lStatus = XIntc_Initialize ( & xInterruptControllerInstance , configINTERRUPT_CONTROLLER_TO_USE ) ;
if ( lStatus = = XST_SUCCESS )
{
/* Initialise the exception table. */
Xil_ExceptionInit ( ) ;
/* Service all pending interrupts each time the handler is entered. */
XIntc_SetIntrSvcOption ( xInterruptControllerInstance . BaseAddress , XIN_SVC_ALL_ISRS_OPTION ) ;
/* Install exception handlers if the MicroBlaze is configured to handle
exceptions , and the application defined constant
configINSTALL_EXCEPTION_HANDLERS is set to 1. */
# if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
{
vPortExceptionsInstallHandlers ( ) ;
}
# endif /* MICROBLAZE_EXCEPTIONS_ENABLED */
/* Start the interrupt controller. Interrupts are enabled when the
scheduler starts . */
lStatus = XIntc_Start ( & xInterruptControllerInstance , XIN_REAL_MODE ) ;
if ( lStatus = = XST_SUCCESS )
{
lStatus = pdPASS ;
}
else
{
lStatus = pdFAIL ;
}
}
configASSERT ( lStatus = = pdPASS ) ;
return lStatus ;
}
/*-----------------------------------------------------------*/