]> git.sur5r.net Git - freertos/commitdiff
Comment the new MicroBlaze port layer files.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Thu, 30 Jun 2011 18:26:32 +0000 (18:26 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Thu, 30 Jun 2011 18:26:32 +0000 (18:26 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1480 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/port.c
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/port_exceptions.c
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portasm.S
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portmacro.h

index 25c9a286d6d1c1c8a7d4cdf829e2f5f78feb8653..63fdb467ac0dac4bbd8181f67151060c910f1047 100644 (file)
 #include <xil_exception.h>\r
 #include <microblaze_exceptions_g.h>\r
 \r
-/* Tasks are started with a critical section nesting of 0 - however prior\r
-to the scheduler being commenced we don't want the critical nesting level\r
-to reach zero, so it is initialised to a high value. */\r
+/* Tasks are started with a critical section nesting of 0 - however, prior to \r
+the scheduler being commenced interrupts should not be enabled, so the critical \r
+nesting variable is initialised to a non-zero value. */\r
 #define portINITIAL_NESTING_VALUE      ( 0xff )\r
 \r
 /* The bit within the MSR register that enabled/disables interrupts. */\r
 #define portMSR_IE                                     ( 0x02U )\r
 \r
+/* If the floating point unit is included in the MicroBlaze build, then the\r
+FSR register is saved as part of the task context.  portINITIAL_FSR is the value\r
+given to the FSR register when the initial context is set up for a task being\r
+created. */\r
 #define portINITIAL_FSR                                ( 0U )\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
  * Initialise the interrupt controller instance.\r
  */\r
-static portBASE_TYPE prvInitialiseInterruptController( void );\r
+static long prvInitialiseInterruptController( void );\r
 \r
-/*\r
- * Call an application provided callback to set up the periodic interrupt used\r
- * for the RTOS tick.  Using an application callback allows the application\r
- * writer to decide\r
+/* Ensure the interrupt controller instance variable is initialised before it is \r
+ * used, and that the initialisation only happens once. \r
  */\r
-extern void vApplicationSetupTimerInterrupt( void );\r
+static long prvEnsureInterruptControllerIsInitialised( void );\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* Counts the nesting depth of calls to portENTER_CRITICAL().  Each task \r
-maintains it's own count, so this variable is saved as part of the task\r
+maintains its own count, so this variable is saved as part of the task\r
 context. */\r
 volatile unsigned portBASE_TYPE uxCriticalNesting = portINITIAL_NESTING_VALUE;\r
 \r
-/* To limit the amount of stack required by each task, this port uses a\r
-separate stack for interrupts. */\r
+/* This port uses a separate stack for interrupts.  This prevents the stack of\r
+every task needing to be large enough to hold an entire interrupt stack on top\r
+of the task stack. */\r
 unsigned long *pulISRStack;\r
 \r
-/* If an interrupt requests a context switch then ulTaskSwitchRequested will\r
-get set to 1, which in turn will cause vTaskSwitchContext() to be called\r
-prior to a task context getting restored on exit from the interrupt.  This\r
-mechanism is used as a single interrupt can cause multiple peripherals handlers\r
-to get called, and vTaskSwitchContext() should not get called in each handler. */\r
+/* If an interrupt requests a context switch, then ulTaskSwitchRequested will\r
+get set to 1.  ulTaskSwitchRequested is inspected just before the main interrupt\r
+handler exits.  If, at that time, ulTaskSwitchRequested is set to 1, the kernel\r
+will call vTaskSwitchContext() to ensure the task that runs immediately after\r
+the interrupt exists is the highest priority task that is able to run.  This is \r
+an unusual mechanism, but is used for this port because a single interrupt can \r
+cause the servicing of multiple peripherals - and it is inefficient to call\r
+vTaskSwitchContext() multiple times as each peripheral is serviced. */\r
 volatile unsigned long ulTaskSwitchRequested = 0UL;\r
 \r
-/* The instance of the interrupt controller used by this port. */\r
+/* The instance of the interrupt controller used by this port.  This is required\r
+by the Xilinx library API functions. */\r
 static XIntc xInterruptControllerInstance;\r
 \r
 /*-----------------------------------------------------------*/\r
@@ -117,7 +125,7 @@ static XIntc xInterruptControllerInstance;
  * Initialise the stack of a task to look exactly as if a call to \r
  * portSAVE_CONTEXT had been made.\r
  * \r
- * See the header file portable.h.\r
+ * See the portable.h header file.\r
  */\r
 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
 {\r
@@ -127,16 +135,7 @@ const unsigned long ulR13 = ( unsigned long ) &_SDA_BASE_;
 \r
        /* Place a few bytes of known values on the bottom of the stack. \r
        This is essential for the Microblaze port and these lines must\r
-       not be omitted.  The parameter value will overwrite the \r
-       0x22222222 value during the function prologue. */\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x11111111;\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x22222222;\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x33333333;\r
-       pxTopOfStack--; \r
-\r
-       /* The debugger will look at the previous stack frame. */\r
+       not be omitted. */\r
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00000000;\r
        pxTopOfStack--;\r
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00000000;\r
@@ -172,62 +171,79 @@ const unsigned long ulR13 = ( unsigned long ) &_SDA_BASE_;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x04;        /* R4 - return values and temporaries. */\r
        pxTopOfStack--;\r
        *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;/* R5 contains the function call parameters. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x06;        /* R6 - other parameters and temporaries.  Used as the return address from vPortTaskEntryPoint. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x07;        /* R7 - other parameters and temporaries. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x08;        /* R8 - other parameters and temporaries. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x09;        /* R9 - other parameters and temporaries. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x0a;        /* R10 - other parameters and temporaries. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x0b;        /* R11 - temporaries. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x0c;        /* R12 - temporaries. */\r
-       pxTopOfStack--;\r
+\r
+       #ifdef portPRE_LOAD_STACK_FOR_DEBUGGING\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x06;        /* R6 - other parameters and temporaries.  Used as the return address from vPortTaskEntryPoint. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x07;        /* R7 - other parameters and temporaries. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x08;        /* R8 - other parameters and temporaries. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x09;        /* R9 - other parameters and temporaries. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x0a;        /* R10 - other parameters and temporaries. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x0b;        /* R11 - temporaries. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x0c;        /* R12 - temporaries. */\r
+               pxTopOfStack--;\r
+       #else\r
+               pxTopOfStack-= 8;\r
+       #endif\r
+       \r
        *pxTopOfStack = ( portSTACK_TYPE ) ulR13;       /* R13 - read/write small data area. */\r
        pxTopOfStack--;\r
        *pxTopOfStack = ( portSTACK_TYPE ) pxCode;      /* R14 - return address for interrupt. */\r
        pxTopOfStack--;\r
        *pxTopOfStack = ( portSTACK_TYPE ) NULL;        /* R15 - return address for subroutine. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x10;        /* R16 - return address for trap (debugger). */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x11;        /* R17 - return address for exceptions, if configured. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x12;        /* R18 - reserved for assembler and compiler temporaries. */\r
-       pxTopOfStack--;\r
+       \r
+       #ifdef portPRE_LOAD_STACK_FOR_DEBUGGING\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x10;        /* R16 - return address for trap (debugger). */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x11;        /* R17 - return address for exceptions, if configured. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x12;        /* R18 - reserved for assembler and compiler temporaries. */\r
+               pxTopOfStack--;\r
+       #else\r
+               pxTopOfStack -= 4;\r
+       #endif\r
+       \r
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00;        /* R19 - must be saved across function calls. Callee-save.  Seems to be interpreted as the frame pointer. */\r
-       pxTopOfStack--;\r
-       *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. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x15;        /* R21 - must be saved across function calls. Callee-save. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x16;        /* R22 - must be saved across function calls. Callee-save. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x17;        /* R23 - must be saved across function calls. Callee-save. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x18;        /* R24 - must be saved across function calls. Callee-save. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x19;        /* R25 - must be saved across function calls. Callee-save. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x1a;        /* R26 - must be saved across function calls. Callee-save. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x1b;        /* R27 - must be saved across function calls. Callee-save. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x1c;        /* R28 - must be saved across function calls. Callee-save. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x1d;        /* R29 - must be saved across function calls. Callee-save. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x1e;        /* R30 - must be saved across function calls. Callee-save. */\r
-       pxTopOfStack--;\r
-       *pxTopOfStack = ( portSTACK_TYPE ) 0x1f;        /* R31 - must be saved across function calls. Callee-save. */\r
-       pxTopOfStack--;\r
+       \r
+       #ifdef portPRE_LOAD_STACK_FOR_DEBUGGING \r
+               pxTopOfStack--;\r
+               *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. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x15;        /* R21 - must be saved across function calls. Callee-save. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x16;        /* R22 - must be saved across function calls. Callee-save. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x17;        /* R23 - must be saved across function calls. Callee-save. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x18;        /* R24 - must be saved across function calls. Callee-save. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x19;        /* R25 - must be saved across function calls. Callee-save. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x1a;        /* R26 - must be saved across function calls. Callee-save. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x1b;        /* R27 - must be saved across function calls. Callee-save. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x1c;        /* R28 - must be saved across function calls. Callee-save. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x1d;        /* R29 - must be saved across function calls. Callee-save. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x1e;        /* R30 - must be saved across function calls. Callee-save. */\r
+               pxTopOfStack--;\r
+               *pxTopOfStack = ( portSTACK_TYPE ) 0x1f;        /* R31 - must be saved across function calls. Callee-save. */\r
+               pxTopOfStack--;\r
+       #else\r
+               pxTopOfStack -= 13;\r
+       #endif\r
 \r
-       /* Return a pointer to the top of the stack we have generated so this can\r
-       be stored in the task control block for the task. */\r
+       /* Return a pointer to the top of the stack that has been generated so this \r
+       can     be stored in the task control block for the task. */\r
        return pxTopOfStack;\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -238,12 +254,23 @@ extern void ( vPortStartFirstTask )( void );
 extern unsigned long _stack[];\r
 \r
        /* Setup the hardware to generate the tick.  Interrupts are disabled when\r
-       this function is called. */\r
+       this function is called.  \r
+       \r
+       This port uses an application defined callback function to install the tick\r
+       interrupt handler because the kernel will run on lots of different \r
+       MicroBlaze and FPGA configurations - not all of which will have the same \r
+       timer peripherals defined or available.  An example definition of\r
+       vApplicationSetupTimerInterrupt() is provided in the official demo\r
+       application that accompanies this port. */\r
        vApplicationSetupTimerInterrupt();\r
 \r
-       /* Reuse the stack from main as the stack for the interrupts/exceptions. */\r
+       /* Reuse the stack from main() as the stack for the interrupts/exceptions. */\r
        pulISRStack = ( unsigned long * ) _stack;\r
 \r
+       /* Ensure there is enough space for the functions called from the interrupt\r
+       service routines to write back into the stack frame of the caller. */
+       pulISRStack -= 2;\r
+\r
        /* Restore the context of the first task that is going to run.  From here\r
        on, the created tasks will be executing. */\r
        vPortStartFirstTask();\r
@@ -268,7 +295,7 @@ extern void VPortYieldASM( void );
 \r
        /* Perform the context switch in a critical section to assure it is\r
        not interrupted by the tick ISR.  It is not a problem to do this as\r
-       each task maintains it's own interrupt status. */\r
+       each task maintains its own interrupt status. */\r
        portENTER_CRITICAL();\r
        {\r
                /* Jump directly to the yield function to ensure there is no\r
@@ -282,43 +309,92 @@ extern void VPortYieldASM( void );
 \r
 void vPortEnableInterrupt( unsigned char ucInterruptID )\r
 {\r
-       XIntc_Enable( &xInterruptControllerInstance, ucInterruptID );\r
+long lReturn;\r
+\r
+       /* An API function is provided to enable an interrupt in the interrupt\r
+       controller because the interrupt controller instance variable is private\r
+       to this file. */\r
+       lReturn = prvEnsureInterruptControllerIsInitialised();\r
+       if( lReturn == pdPASS )\r
+       {\r
+               XIntc_Enable( &xInterruptControllerInstance, ucInterruptID );\r
+       }\r
+       \r
+       configASSERT( lReturn );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 void vPortDisableInterrupt( unsigned char ucInterruptID )\r
 {\r
-       XIntc_Disable( &xInterruptControllerInstance, ucInterruptID );\r
+long lReturn;\r
+\r
+       /* An API function is provided to disable an interrupt in the interrupt\r
+       controller because the interrupt controller instance variable is private\r
+       to this file. */\r
+       lReturn = prvEnsureInterruptControllerIsInitialised();\r
+       \r
+       if( lReturn == pdPASS )\r
+       {\r
+               XIntc_Disable( &xInterruptControllerInstance, ucInterruptID );\r
+       }\r
+       \r
+       configASSERT( lReturn );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )\r
 {\r
-static portBASE_TYPE xInterruptControllerInitialised = pdFALSE;\r
-portBASE_TYPE xReturn = XST_SUCCESS;\r
+long lReturn;\r
 \r
-       if( xInterruptControllerInitialised != pdTRUE )\r
+       /* An API function is provided to install an interrupt handler because the \r
+       interrupt controller instance variable is private to this file. */\r
+\r
+       lReturn = prvEnsureInterruptControllerIsInitialised();\r
+       \r
+       if( lReturn == pdPASS )\r
        {\r
-               xReturn = prvInitialiseInterruptController();\r
-               xInterruptControllerInitialised = pdTRUE;\r
+               lReturn = XIntc_Connect( &xInterruptControllerInstance, ucInterruptID, pxHandler, pvCallBackRef );\r
        }\r
 \r
-       if( xReturn == XST_SUCCESS )\r
+       if( lReturn == XST_SUCCESS )\r
        {\r
-               xReturn = XIntc_Connect( &xInterruptControllerInstance, ucInterruptID, pxHandler, pvCallBackRef );\r
+               lReturn = pdPASS;\r
        }\r
+       \r
+       configASSERT( lReturn == pdPASS );\r
+\r
+       return lReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static long prvEnsureInterruptControllerIsInitialised( void )\r
+{\r
+static long lInterruptControllerInitialised = pdFALSE;\r
+long lReturn;\r
 \r
-       if( xReturn == XST_SUCCESS )\r
+       /* Ensure the interrupt controller instance variable is initialised before\r
+       it is used, and that the initialisation only happens once. */\r
+       if( lInterruptControllerInitialised != pdTRUE )\r
+       {\r
+               lReturn = prvInitialiseInterruptController();\r
+               \r
+               if( lReturn == pdPASS )\r
+               {\r
+                       lInterruptControllerInitialised = pdTRUE;\r
+               }\r
+       }\r
+       else\r
        {\r
-               xReturn = pdPASS;\r
+               lReturn = pdPASS;\r
        }\r
 \r
-       return xReturn;\r
+       return lReturn;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 /* \r
- * Handler for the timer interrupt.\r
+ * Handler for the timer interrupt.  This is the handler that the application\r
+ * defined callback function vApplicationSetupTimerInterrupt() should install.\r
  */\r
 void vTickISR( void *pvUnused )\r
 {\r
@@ -327,13 +403,20 @@ extern void vApplicationClearTimerInterrupt( void );
        /* Ensure the unused parameter does not generate a compiler warning. */\r
        ( void ) pvUnused;\r
 \r
+       /* This port uses an application defined callback function to clear the tick\r
+       interrupt because the kernel will run on lots of different MicroBlaze and \r
+       FPGA configurations - not all of which will have the same timer peripherals \r
+       defined or available.  An example definition of\r
+       vApplicationClearTimerInterrupt() is provided in the official demo\r
+       application that accompanies this port. */      \r
        vApplicationClearTimerInterrupt();\r
 \r
        /* Increment the RTOS tick - this might cause a task to unblock. */\r
        vTaskIncrementTick();\r
 \r
-       /* If we are using the preemptive scheduler then we also need to determine\r
-       if this tick should cause a context switch. */\r
+       /* If the preemptive scheduler is being used then a context switch should be\r
+       requested in case incrementing the tick unblocked a task, or a time slice\r
+       should cause another task to enter the Running state. */\r
        #if configUSE_PREEMPTION == 1\r
                /* Force vTaskSwitchContext() to be called as the interrupt exits. */\r
                ulTaskSwitchRequested = 1;\r
@@ -341,13 +424,13 @@ extern void vApplicationClearTimerInterrupt( void );
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-static portBASE_TYPE prvInitialiseInterruptController( void )\r
+static long prvInitialiseInterruptController( void )\r
 {\r
-portBASE_TYPE xStatus;\r
+long lStatus;\r
 \r
-       xStatus = XIntc_Initialize( &xInterruptControllerInstance, configINTERRUPT_CONTROLLER_TO_USE );\r
+       lStatus = XIntc_Initialize( &xInterruptControllerInstance, configINTERRUPT_CONTROLLER_TO_USE );\r
 \r
-       if( xStatus == XST_SUCCESS )\r
+       if( lStatus == XST_SUCCESS )\r
        {\r
                /* Initialise the exception table. */\r
                Xil_ExceptionInit();\r
@@ -366,28 +449,21 @@ portBASE_TYPE xStatus;
 \r
                /* Start the interrupt controller.  Interrupts are enabled when the\r
                scheduler starts. */\r
-               xStatus = XIntc_Start( &xInterruptControllerInstance, XIN_REAL_MODE );\r
-\r
-               /* Ensure the compiler does not generate warnings for the unused\r
-               iStatus valud if configASSERT() is not defined. */\r
-               ( void ) xStatus;\r
+               lStatus = XIntc_Start( &xInterruptControllerInstance, XIN_REAL_MODE );\r
+\r
+               if( lStatus == XST_SUCCESS )\r
+               {\r
+                       lStatus = pdPASS;\r
+               }\r
+               else\r
+               {\r
+                       lStatus = pdFAIL;\r
+               }\r
        }\r
 \r
-       configASSERT( ( xStatus == ( portBASE_TYPE ) XST_SUCCESS ) )\r
-\r
-/*_RB_ Exception test code. */\r
-#if 0\r
-This does not cause the bralid address to be in the r17 register.\r
-__asm volatile (\r
-                                       "bralid r15, 1234 \n"\r
-                                       "or r0, r0, r0 \n"\r
-                               );\r
-#endif\r
-#if 0\r
-       xStatus /= 0;\r
-#endif\r
-\r
-       return xStatus;\r
+       configASSERT( lStatus == pdPASS );\r
+\r
+       return lStatus;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
index f963afd49a446d84351a0c6a85cca3413d8a6913..fc570ac93158ad72d24b1dd1659b6a4088169a5f 100644 (file)
@@ -59,6 +59,9 @@
 #include <microblaze_exceptions_i.h>\r
 #include <microblaze_exceptions_g.h>\r
 \r
+/* The Xilinx library defined exception entry point stacks a number of\r
+registers.  These definitions are offsets from the stack pointer to the various\r
+stacked register values. */\r
 #define portexR3_STACK_OFFSET  4\r
 #define portexR4_STACK_OFFSET  5\r
 #define portexR5_STACK_OFFSET  6\r
 #define portexMSR_STACK_OFFSET 19\r
 #define portexR19_STACK_OFFSET  -1\r
 \r
-#define portexESR_DS_MASK              0x00001000UL\r
-\r
+/* This is defined to equal the size, in bytes, of the stack frame generated by\r
+the Xilinx standard library exception entry point.  It is required to determine\r
+the stack pointer value prior to the exception being entered. */\r
 #define portexASM_HANDLER_STACK_FRAME_SIZE 84UL\r
 \r
-/* Exclude the entire file if the MicroBlaze is not configured to handle\r
-exceptions, or the application defined configuration item \r
+/* The number of bytes a MicroBlaze instruction consumes. */\r
+#define portexINSTRUCTION_SIZE 4\r
+\r
+/* Exclude this entire file if the MicroBlaze is not configured to handle\r
+exceptions, or the application defined configuration constant\r
 configINSTALL_EXCEPTION_HANDLERS is not set to 1. */\r
 #if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )\r
 \r
-/* These are global volatiles to allow their inspection by a debugger. */\r
+/* These variables are set in the exception entry code, before \r
+vPortExceptionHandler is called. */\r
 unsigned long *pulStackPointerOnFunctionEntry = NULL, ulBTROnFunctionEntry = 0UL;\r
 \r
+/* This is the structure that is filled with the MicroBlaze context as it\r
+existed immediately prior to the exception occurrence.  A pointer to this\r
+structure is passed into the vApplicationExceptionRegisterDump() callback\r
+function, if one is defined. */\r
 static xPortRegisterDump xRegisterDump;\r
 \r
+/* This is the FreeRTOS exception handler that is installed for all exception\r
+types.  It is called from vPortExceptionHanlderEntry() - which is itself defined\r
+in portasm.S. */\r
 void vPortExceptionHandler( void *pvExceptionID );\r
 extern void vPortExceptionHandlerEntry( void *pvExceptionID );\r
 \r
 /*-----------------------------------------------------------*/\r
+\r
+/* vApplicationExceptionRegisterDump() is a callback function that the \r
+application can optionally define to receive a populated xPortRegisterDump\r
+structure.  If the application chooses not to define a version of \r
+vApplicationExceptionRegisterDump() then this weekly defined default \r
+implementation will be called instead. */\r
 extern void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump ) __attribute__((weak));\r
 void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )\r
 {\r
@@ -106,6 +127,11 @@ void vPortExceptionHandler( void *pvExceptionID )
 {\r
 extern void *pxCurrentTCB;\r
 \r
+       /* Fill an xPortRegisterDump structure with the MicroBlaze context as it\r
+       was immediately before the exception occurrence. */\r
+       \r
+       /* First fill in the name and handle of the task that was in the Running \r
+       state when the exception occurred. */\r
        xRegisterDump.xCurrentTaskHandle = pxCurrentTCB;\r
        xRegisterDump.pcCurrentTaskName = pcTaskGetTaskName( NULL );\r
 \r
@@ -126,7 +152,8 @@ extern void *pxCurrentTCB;
        xRegisterDump.ulR15_return_address_from_subroutine = pulStackPointerOnFunctionEntry[ portexR15_STACK_OFFSET ];\r
        xRegisterDump.ulR18 = pulStackPointerOnFunctionEntry[ portexR18_STACK_OFFSET ];\r
        xRegisterDump.ulR19 = pulStackPointerOnFunctionEntry[ portexR19_STACK_OFFSET ];\r
-\r
+       xRegisterDump.ulMSR = pulStackPointerOnFunctionEntry[ portexMSR_STACK_OFFSET ];\r
+       \r
        /* Obtain the value of all other registers. */\r
        xRegisterDump.ulR2_small_data_area = mfgpr( R2 );\r
        xRegisterDump.ulR13_read_write_small_data_area = mfgpr( R13 );\r
@@ -148,25 +175,14 @@ extern void *pxCurrentTCB;
        xRegisterDump.ulR31 = mfgpr( R31 );\r
        xRegisterDump.ulR1_SP = ( ( unsigned long ) pulStackPointerOnFunctionEntry ) + portexASM_HANDLER_STACK_FRAME_SIZE;\r
        xRegisterDump.ulBTR = ulBTROnFunctionEntry;\r
-       xRegisterDump.ulMSR = pulStackPointerOnFunctionEntry[ portexMSR_STACK_OFFSET ];\r
        xRegisterDump.ulEAR = mfear();\r
        xRegisterDump.ulESR = mfesr();\r
        xRegisterDump.ulEDR = mfedr();\r
-\r
-\r
-#ifdef THIS_IS_PROBABLY_INCORRECT\r
-       if( ( xRegisterDump.ulESR * portexESR_DS_MASK ) != 0UL )\r
-       {\r
-               xRegisterDump.ulPC = mfbtr();\r
-       }\r
-       else\r
-       {\r
-               xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_some_exceptions - 4;\r
-       }\r
-#else\r
-       xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_some_exceptions - 4;\r
-#endif\r
-\r
+       \r
+       /* Move the saved program counter back to the instruction that was executed\r
+       when the exception occurred.  This is only valid for certain types of\r
+       exception. */\r
+       xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_some_exceptions - portexINSTRUCTION_SIZE;\r
 \r
        #if XPAR_MICROBLAZE_0_USE_FPU == 1\r
        {\r
@@ -178,6 +194,9 @@ extern void *pxCurrentTCB;
        }\r
        #endif\r
 \r
+       /* Also fill in a string that describes what type of exception this is.\r
+       The string uses the same ID names as defined in the MicroBlaze standard\r
+       library exception header files. */\r
        switch( ( unsigned long ) pvExceptionID )\r
        {\r
                case XEXC_ID_FSL :\r
@@ -218,6 +237,11 @@ extern void *pxCurrentTCB;
                #endif /* XPAR_MICROBLAZE_0_USE_FPU */\r
        }\r
 \r
+       /* vApplicationExceptionRegisterDump() is a callback function that the \r
+       application can optionally define to receive the populated xPortRegisterDump\r
+       structure.  If the application chooses not to define a version of \r
+       vApplicationExceptionRegisterDump() then the weekly defined default \r
+       implementation within this file will be called instead. */\r
        vApplicationExceptionRegisterDump( &xRegisterDump );\r
 \r
        /* Must not attempt to leave this function! */\r
index 68908775545caa29439d128f2a09632bced079a4..674343690d2fc420973067ba51ae05a2e09c7fa8 100644 (file)
     licensing and training services.\r
 */\r
 \r
+/* FreeRTOS includes. */\r
 #include "FreeRTOSConfig.h"\r
+\r
+/* Xilinx library includes. */\r
 #include "microblaze_exceptions_g.h"\r
 #include "xparameters.h"\r
 \r
@@ -250,7 +253,7 @@ back into the caller stack. */
 \r
 /* This function is used to exit portRESTORE_CONTEXT() if the task being\r
 returned to last left the Running state by calling taskYIELD() (rather than\r
-being preempted by an interrupt. */\r
+being preempted by an interrupt). */\r
        .text\r
        .align  2\r
 exit_from_yield:\r
@@ -276,13 +279,11 @@ _interrupt_handler:
        /* Stack the return address. */\r
        swi r14, r1, portR14_OFFSET\r
 \r
-       /* Switch to the ISR stack.  The pulISRStack value has already been set to\r
-       leave space for the caller function to write back into the stack of this\r
-       function. */\r
+       /* Switch to the ISR stack. */\r
        lwi r1, r0, pulISRStack\r
 \r
        /* The parameter to the interrupt handler. */\r
-       ori     r5, r0, configINTERRUPT_CONTROLLER_TO_USE\r
+       ori r5, r0, configINTERRUPT_CONTROLLER_TO_USE\r
 \r
        /* Execute any pending interrupts. */\r
        bralid r15, XIntc_DeviceInterruptHandler\r
index c14bbc7bfc6a5347fd7862fab3c9be4d096a8e20..50d6353fd8123adbd98ef051cbf5848dc933a3f2 100644 (file)
@@ -100,6 +100,8 @@ portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterr
 void vPortEnableInterrupt( unsigned char ucInterruptID );\r
 void vPortDisableInterrupt( unsigned char ucInterruptID );\r
 \r
+void vApplicationSetupTimerInterrupt( void );\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* Critical section macros. */\r