#ifndef FREERTOS_CONFIG_H\r
#define FREERTOS_CONFIG_H\r
\r
+#include <xparameters.h>\r
+\r
/*-----------------------------------------------------------\r
* Application specific definitions.\r
*\r
\r
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } \r
\r
+#define configINTERRUPT_CONTROLLER_TO_USE XPAR_INTC_SINGLE_DEVICE_ID\r
+\r
#endif /* FREERTOS_CONFIG_H */\r
\r
#include <xintc.h>\r
#include <xintc_i.h>\r
#include <xtmrctr.h>\r
+#include <xil_exception.h>\r
\r
/* Tasks are started with interrupts enabled. */\r
#define portINITIAL_MSR_STATE ( ( portSTACK_TYPE ) 0x02 )\r
debugging. */\r
#define portISR_STACK_FILL_VALUE 0x55555555\r
\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Initialise the interrupt controller instance.\r
+ */\r
+static portBASE_TYPE 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
+ */\r
+extern void vApplicationSetupTimerInterrupt( void );\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
context. */\r
separate stack for interrupts. */\r
unsigned long *pulISRStack;\r
\r
-/*-----------------------------------------------------------*/\r
+/* The instance of the interrupt controller used by this port. */\r
+static XIntc xInterruptControllerInstance;\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
- */\r
-extern void vApplicationSetupTimerInterrupt( void );\r
/*-----------------------------------------------------------*/\r
\r
/* \r
}\r
/*-----------------------------------------------------------*/\r
\r
+void vPortEnableInterrupt( unsigned char ucInterruptID )\r
+{\r
+ XIntc_Enable( &xInterruptControllerInstance, ucInterruptID );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortDisableInterrupt( unsigned char ucInterruptID )\r
+{\r
+ XIntc_Disable( &xInterruptControllerInstance, ucInterruptID );\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
+\r
+ if( xInterruptControllerInitialised != pdTRUE )\r
+ {\r
+ xReturn = prvInitialiseInterruptController();\r
+ xInterruptControllerInitialised = pdTRUE;\r
+ }\r
+\r
+ if( xReturn == XST_SUCCESS )\r
+ {\r
+ xReturn = XIntc_Connect( &xInterruptControllerInstance, ucInterruptID, pxHandler, pvCallBackRef );\r
+ }\r
+\r
+ if( xReturn == XST_SUCCESS )\r
+ {\r
+ xReturn = pdPASS;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
/* \r
* Handler for the timer interrupt.\r
*/\r
-void vTickISR( void *pvUnused, unsigned char ucUnused )\r
+void vTickISR( void *pvUnused )\r
{\r
/* Ensure the unused parameter does not generate a compiler warning. */\r
( void ) pvUnused;\r
}\r
/*-----------------------------------------------------------*/\r
\r
+static portBASE_TYPE prvInitialiseInterruptController( void )\r
+{\r
+portBASE_TYPE xStatus;\r
+\r
+ xStatus = XIntc_Initialize( &xInterruptControllerInstance, configINTERRUPT_CONTROLLER_TO_USE );\r
+\r
+ if( xStatus == XST_SUCCESS )\r
+ {\r
+ /* Initialise the exception table. */\r
+ Xil_ExceptionInit();\r
+\r
+ /* Register the interrupt controller handle that uses the exception\r
+ table. */\r
+ Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_INT, ( Xil_ExceptionHandler ) XIntc_DeviceInterruptHandler, NULL );\r
+\r
+ /* Service all pending interrupts each time the handler is entered. */\r
+ XIntc_SetIntrSvcOption( xInterruptControllerInstance.BaseAddress, XIN_SVC_ALL_ISRS_OPTION );\r
+\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
+ }\r
+\r
+ configASSERT( ( xStatus == ( portBASE_TYPE ) XST_SUCCESS ) )\r
+\r
+ return xStatus;\r
+}\r
\r
\r
\r
extern "C" {\r
#endif\r
\r
+/* BSP includes. */\r
+#include "xbasic_types.h"\r
+\r
/*-----------------------------------------------------------\r
* Port specific definitions. \r
*\r
#endif\r
/*-----------------------------------------------------------*/ \r
\r
-/* Interrupt control macros. */\r
+/* Interrupt control macros and functions. */\r
void microblaze_disable_interrupts( void );\r
void microblaze_enable_interrupts( void );\r
#define portDISABLE_INTERRUPTS() microblaze_disable_interrupts()\r
#define portENABLE_INTERRUPTS() microblaze_enable_interrupts()\r
+\r
+portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );\r
+void vPortEnableInterrupt( unsigned char ucInterruptID );\r
+void vPortDisableInterrupt( unsigned char ucInterruptID );\r
+\r
/*-----------------------------------------------------------*/\r
\r
/* Critical section macros. */\r
/* BSP includes. */\r
#include "xenv_standalone.h"\r
#include "xtmrctr.h"\r
-#include "xintc.h"\r
#include "xil_exception.h"\r
+#include "microblaze_exceptions_g.h"\r
\r
/* Priorities at which the tasks are created. */\r
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
\r
/*-----------------------------------------------------------*/\r
\r
-static XTmrCtr axi_timer_0_Timer;\r
-static XIntc intc;\r
+static XTmrCtr xTimer0Instance;\r
\r
/*-----------------------------------------------------------*/\r
\r
int main(void)\r
{\r
- /* Configure the NVIC, LED outputs and button inputs. */\r
+ /* Configure the interrupt controller, LED outputs and button inputs. */\r
prvSetupHardware();\r
\r
/* Create the queue. */\r
\r
static void prvSetupHardware( void )\r
{\r
-int iStatus;\r
-\r
#ifdef MICROBLAZE_EXCEPTIONS_ENABLED\r
microblaze_enable_exceptions();\r
#endif\r
-\r
- iStatus = XIntc_Initialize( &intc, XPAR_MICROBLAZE_0_INTC_AXI_TIMER_0_INTERRUPT_INTR );\r
-\r
- if( iStatus == XST_SUCCESS )\r
- {\r
- /* Sanity check on the hardware build. */\r
- iStatus = XIntc_SelfTest( &intc );\r
- }\r
-\r
- if( iStatus == XST_SUCCESS )\r
- {\r
- /* Initialise the exception table. */\r
- Xil_ExceptionInit();\r
-\r
- /* Register the interrupt controller handle that uses the exception\r
- table. */\r
- Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XIntc_DeviceInterruptHandler, NULL );\r
-\r
- /* Start the interrupt controller. Interrupts are enabled when the\r
- scheduler starts. */\r
- iStatus = XIntc_Start( &intc, XIN_REAL_MODE );\r
-\r
- /* Ensure the compiler does not generate warnings for the unused
- iStatus valud if configASSERT() is not defined. */\r
- ( void ) iStatus;\r
- }\r
-\r
- configASSERT( ( iStatus == XST_SUCCESS ) )\r
}\r
/*-----------------------------------------------------------*/\r
\r
\r
void vApplicationSetupTimerInterrupt( void )\r
{\r
-int iStatus;\r
+portBASE_TYPE xStatus;\r
const unsigned char ucTimerCounterNumber = ( unsigned char ) 0U;\r
const unsigned long ulCounterValue = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) + 1UL );\r
-extern void vTickISR( void *pvUnused, unsigned char ucUnused );\r
+extern void vTickISR( void *pvUnused );\r
\r
/* Initialise the timer/counter. */\r
- iStatus = XTmrCtr_Initialize( &axi_timer_0_Timer, XPAR_AXI_TIMER_0_DEVICE_ID );\r
+ xStatus = XTmrCtr_Initialize( &xTimer0Instance, XPAR_AXI_TIMER_0_DEVICE_ID );\r
+\r
+ if( xStatus == XST_SUCCESS )\r
+ {\r
+ /* Install the tick interrupt handler as the timer ISR. */\r
+ xStatus = xPortInstallInterruptHandler( XPAR_MICROBLAZE_0_INTC_AXI_TIMER_0_INTERRUPT_INTR, vTickISR, NULL );\r
+ }\r
\r
- if( iStatus == XST_SUCCESS )\r
+ if( xStatus == pdPASS )\r
{\r
- /* Enable the interrupt for the timer counter. Note that interrupts\r
- are globally disabled when this function is called. Interrupt\r
- processing will not actually start until the first task is executing. */\r
- XIntc_Enable( &intc, XPAR_MICROBLAZE_0_INTC_AXI_TIMER_0_INTERRUPT_INTR );\r
+ vPortEnableInterrupt( XPAR_MICROBLAZE_0_INTC_AXI_TIMER_0_INTERRUPT_INTR );\r
\r
/* Configure the timer interrupt handler. */\r
- XTmrCtr_SetHandler( &axi_timer_0_Timer, ( void * ) vTickISR, NULL );\r
+ XTmrCtr_SetHandler( &xTimer0Instance, ( void * ) vTickISR, NULL );\r
\r
/* Set the correct period for the timer. */\r
- XTmrCtr_SetResetValue( &axi_timer_0_Timer, ucTimerCounterNumber, ulCounterValue );\r
+ XTmrCtr_SetResetValue( &xTimer0Instance, ucTimerCounterNumber, ulCounterValue );\r
\r
/* Enable the interrupts. Auto-reload mode is used to generate a\r
periodic tick. Note that interrupts are disabled when this function is\r
called, so interrupts will not start to be processed until the first\r
task has started to run. */\r
- XTmrCtr_SetOptions( &axi_timer_0_Timer, ucTimerCounterNumber, ( XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION | XTC_DOWN_COUNT_OPTION ) );\r
+ XTmrCtr_SetOptions( &xTimer0Instance, ucTimerCounterNumber, ( XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION | XTC_DOWN_COUNT_OPTION ) );\r
\r
/* Start the timer. */\r
- XTmrCtr_Start( &axi_timer_0_Timer, ucTimerCounterNumber );\r
+ XTmrCtr_Start( &xTimer0Instance, ucTimerCounterNumber );\r
}\r
\r
- configASSERT( ( iStatus == XST_SUCCESS ) );\r
+ configASSERT( ( xStatus == pdPASS ) );\r
}\r
\r
\r