From b34df43001b316fdfc3b0111095cc4bfa9b215cc Mon Sep 17 00:00:00 2001 From: richardbarry Date: Wed, 1 Jun 2011 15:01:08 +0000 Subject: [PATCH] Updating MicroBlaze port - work in progress. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1442 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../RTOSDemoSource/FreeRTOSConfig.h | 4 + .../portable/GCC/MicroBlaze/port.c | 95 +++++++++++++++++-- .../portable/GCC/MicroBlaze/portmacro.h | 10 +- .../SDKProjects/RTOSDemoSource/main-blinky.c | 66 ++++--------- 4 files changed, 119 insertions(+), 56 deletions(-) diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOSConfig.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOSConfig.h index 154581022..b1d3b6718 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOSConfig.h +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOSConfig.h @@ -63,6 +63,8 @@ #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H +#include + /*----------------------------------------------------------- * Application specific definitions. * @@ -119,5 +121,7 @@ to exclude the API function. */ #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } +#define configINTERRUPT_CONTROLLER_TO_USE XPAR_INTC_SINGLE_DEVICE_ID + #endif /* FREERTOS_CONFIG_H */ diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/port.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/port.c index c34503cee..ed39d1d2c 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/port.c +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/port.c @@ -67,6 +67,7 @@ #include #include #include +#include /* Tasks are started with interrupts enabled. */ #define portINITIAL_MSR_STATE ( ( portSTACK_TYPE ) 0x02 ) @@ -83,6 +84,21 @@ to reach zero, so it is initialised to a high value. */ debugging. */ #define portISR_STACK_FILL_VALUE 0x55555555 +/*-----------------------------------------------------------*/ + +/* + * Initialise the interrupt controller instance. + */ +static portBASE_TYPE 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 + */ +extern void vApplicationSetupTimerInterrupt( 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 context. */ @@ -92,14 +108,9 @@ volatile unsigned portBASE_TYPE uxCriticalNesting = portINITIAL_NESTING_VALUE; separate stack for interrupts. */ unsigned long *pulISRStack; -/*-----------------------------------------------------------*/ +/* The instance of the interrupt controller used by this port. */ +static XIntc xInterruptControllerInstance; -/* - * 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 - */ -extern void vApplicationSetupTimerInterrupt( void ); /*-----------------------------------------------------------*/ /* @@ -313,10 +324,47 @@ static unsigned long ulInterruptMask; } /*-----------------------------------------------------------*/ +void vPortEnableInterrupt( unsigned char ucInterruptID ) +{ + XIntc_Enable( &xInterruptControllerInstance, ucInterruptID ); +} +/*-----------------------------------------------------------*/ + +void vPortDisableInterrupt( unsigned char ucInterruptID ) +{ + XIntc_Disable( &xInterruptControllerInstance, ucInterruptID ); +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef ) +{ +static portBASE_TYPE xInterruptControllerInitialised = pdFALSE; +portBASE_TYPE xReturn = XST_SUCCESS; + + if( xInterruptControllerInitialised != pdTRUE ) + { + xReturn = prvInitialiseInterruptController(); + xInterruptControllerInitialised = pdTRUE; + } + + if( xReturn == XST_SUCCESS ) + { + xReturn = XIntc_Connect( &xInterruptControllerInstance, ucInterruptID, pxHandler, pvCallBackRef ); + } + + if( xReturn == XST_SUCCESS ) + { + xReturn = pdPASS; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + /* * Handler for the timer interrupt. */ -void vTickISR( void *pvUnused, unsigned char ucUnused ) +void vTickISR( void *pvUnused ) { /* Ensure the unused parameter does not generate a compiler warning. */ ( void ) pvUnused; @@ -332,6 +380,37 @@ void vTickISR( void *pvUnused, unsigned char ucUnused ) } /*-----------------------------------------------------------*/ +static portBASE_TYPE prvInitialiseInterruptController( void ) +{ +portBASE_TYPE xStatus; + + xStatus = XIntc_Initialize( &xInterruptControllerInstance, configINTERRUPT_CONTROLLER_TO_USE ); + + if( xStatus == XST_SUCCESS ) + { + /* Initialise the exception table. */ + Xil_ExceptionInit(); + + /* Register the interrupt controller handle that uses the exception + table. */ + Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_INT, ( Xil_ExceptionHandler ) XIntc_DeviceInterruptHandler, NULL ); + + /* Service all pending interrupts each time the handler is entered. */ + XIntc_SetIntrSvcOption( xInterruptControllerInstance.BaseAddress, XIN_SVC_ALL_ISRS_OPTION ); + + /* Start the interrupt controller. Interrupts are enabled when the + scheduler starts. */ + xStatus = 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; + } + + configASSERT( ( xStatus == ( portBASE_TYPE ) XST_SUCCESS ) ) + + return xStatus; +} diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portmacro.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portmacro.h index f236ee98f..37aa3d607 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portmacro.h +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portmacro.h @@ -58,6 +58,9 @@ extern "C" { #endif +/* BSP includes. */ +#include "xbasic_types.h" + /*----------------------------------------------------------- * Port specific definitions. * @@ -86,11 +89,16 @@ extern "C" { #endif /*-----------------------------------------------------------*/ -/* Interrupt control macros. */ +/* Interrupt control macros and functions. */ void microblaze_disable_interrupts( void ); void microblaze_enable_interrupts( void ); #define portDISABLE_INTERRUPTS() microblaze_disable_interrupts() #define portENABLE_INTERRUPTS() microblaze_enable_interrupts() + +portBASE_TYPE xPortInstallInterruptHandler( unsigned char ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef ); +void vPortEnableInterrupt( unsigned char ucInterruptID ); +void vPortDisableInterrupt( unsigned char ucInterruptID ); + /*-----------------------------------------------------------*/ /* Critical section macros. */ diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/main-blinky.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/main-blinky.c index 724a0ccb2..2401a10ad 100644 --- a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/main-blinky.c +++ b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/main-blinky.c @@ -114,8 +114,8 @@ /* BSP includes. */ #include "xenv_standalone.h" #include "xtmrctr.h" -#include "xintc.h" #include "xil_exception.h" +#include "microblaze_exceptions_g.h" /* Priorities at which the tasks are created. */ #define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) @@ -169,14 +169,13 @@ static volatile unsigned long ulGPIOState = 0UL; /*-----------------------------------------------------------*/ -static XTmrCtr axi_timer_0_Timer; -static XIntc intc; +static XTmrCtr xTimer0Instance; /*-----------------------------------------------------------*/ int main(void) { - /* Configure the NVIC, LED outputs and button inputs. */ + /* Configure the interrupt controller, LED outputs and button inputs. */ prvSetupHardware(); /* Create the queue. */ @@ -312,39 +311,9 @@ unsigned long ulReceivedValue; static void prvSetupHardware( void ) { -int iStatus; - #ifdef MICROBLAZE_EXCEPTIONS_ENABLED microblaze_enable_exceptions(); #endif - - iStatus = XIntc_Initialize( &intc, XPAR_MICROBLAZE_0_INTC_AXI_TIMER_0_INTERRUPT_INTR ); - - if( iStatus == XST_SUCCESS ) - { - /* Sanity check on the hardware build. */ - iStatus = XIntc_SelfTest( &intc ); - } - - if( iStatus == XST_SUCCESS ) - { - /* Initialise the exception table. */ - Xil_ExceptionInit(); - - /* Register the interrupt controller handle that uses the exception - table. */ - Xil_ExceptionRegisterHandler( XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XIntc_DeviceInterruptHandler, NULL ); - - /* Start the interrupt controller. Interrupts are enabled when the - scheduler starts. */ - iStatus = XIntc_Start( &intc, XIN_REAL_MODE ); - - /* Ensure the compiler does not generate warnings for the unused - iStatus valud if configASSERT() is not defined. */ - ( void ) iStatus; - } - - configASSERT( ( iStatus == XST_SUCCESS ) ) } /*-----------------------------------------------------------*/ @@ -409,38 +378,41 @@ unsigned long ulGetRunTimeCounterValue( void ) void vApplicationSetupTimerInterrupt( void ) { -int iStatus; +portBASE_TYPE xStatus; const unsigned char ucTimerCounterNumber = ( unsigned char ) 0U; const unsigned long ulCounterValue = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) + 1UL ); -extern void vTickISR( void *pvUnused, unsigned char ucUnused ); +extern void vTickISR( void *pvUnused ); /* Initialise the timer/counter. */ - iStatus = XTmrCtr_Initialize( &axi_timer_0_Timer, XPAR_AXI_TIMER_0_DEVICE_ID ); + xStatus = XTmrCtr_Initialize( &xTimer0Instance, XPAR_AXI_TIMER_0_DEVICE_ID ); + + if( xStatus == XST_SUCCESS ) + { + /* Install the tick interrupt handler as the timer ISR. */ + xStatus = xPortInstallInterruptHandler( XPAR_MICROBLAZE_0_INTC_AXI_TIMER_0_INTERRUPT_INTR, vTickISR, NULL ); + } - if( iStatus == XST_SUCCESS ) + if( xStatus == pdPASS ) { - /* Enable the interrupt for the timer counter. Note that interrupts - are globally disabled when this function is called. Interrupt - processing will not actually start until the first task is executing. */ - XIntc_Enable( &intc, XPAR_MICROBLAZE_0_INTC_AXI_TIMER_0_INTERRUPT_INTR ); + vPortEnableInterrupt( XPAR_MICROBLAZE_0_INTC_AXI_TIMER_0_INTERRUPT_INTR ); /* Configure the timer interrupt handler. */ - XTmrCtr_SetHandler( &axi_timer_0_Timer, ( void * ) vTickISR, NULL ); + XTmrCtr_SetHandler( &xTimer0Instance, ( void * ) vTickISR, NULL ); /* Set the correct period for the timer. */ - XTmrCtr_SetResetValue( &axi_timer_0_Timer, ucTimerCounterNumber, ulCounterValue ); + XTmrCtr_SetResetValue( &xTimer0Instance, ucTimerCounterNumber, ulCounterValue ); /* Enable the interrupts. Auto-reload mode is used to generate a periodic tick. Note that interrupts are disabled when this function is called, so interrupts will not start to be processed until the first task has started to run. */ - XTmrCtr_SetOptions( &axi_timer_0_Timer, ucTimerCounterNumber, ( XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION | XTC_DOWN_COUNT_OPTION ) ); + XTmrCtr_SetOptions( &xTimer0Instance, ucTimerCounterNumber, ( XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION | XTC_DOWN_COUNT_OPTION ) ); /* Start the timer. */ - XTmrCtr_Start( &axi_timer_0_Timer, ucTimerCounterNumber ); + XTmrCtr_Start( &xTimer0Instance, ucTimerCounterNumber ); } - configASSERT( ( iStatus == XST_SUCCESS ) ); + configASSERT( ( xStatus == pdPASS ) ); } -- 2.39.5