Updating MicroBlaze port - work in progress.

pull/4/head
Richard Barry 14 years ago
parent 328a8b586f
commit 67039f6065

@ -63,6 +63,8 @@
#ifndef FREERTOS_CONFIG_H #ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H
#include <xparameters.h>
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Application specific definitions. * Application specific definitions.
* *
@ -119,5 +121,7 @@ to exclude the API function. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
#define configINTERRUPT_CONTROLLER_TO_USE XPAR_INTC_SINGLE_DEVICE_ID
#endif /* FREERTOS_CONFIG_H */ #endif /* FREERTOS_CONFIG_H */

@ -67,6 +67,7 @@
#include <xintc.h> #include <xintc.h>
#include <xintc_i.h> #include <xintc_i.h>
#include <xtmrctr.h> #include <xtmrctr.h>
#include <xil_exception.h>
/* Tasks are started with interrupts enabled. */ /* Tasks are started with interrupts enabled. */
#define portINITIAL_MSR_STATE ( ( portSTACK_TYPE ) 0x02 ) #define portINITIAL_MSR_STATE ( ( portSTACK_TYPE ) 0x02 )
@ -83,6 +84,21 @@ to reach zero, so it is initialised to a high value. */
debugging. */ debugging. */
#define portISR_STACK_FILL_VALUE 0x55555555 #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 /* 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 it's own count, so this variable is saved as part of the task
context. */ context. */
@ -92,14 +108,9 @@ volatile unsigned portBASE_TYPE uxCriticalNesting = portINITIAL_NESTING_VALUE;
separate stack for interrupts. */ separate stack for interrupts. */
unsigned long *pulISRStack; 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. * 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. */ /* Ensure the unused parameter does not generate a compiler warning. */
( void ) pvUnused; ( 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;
}

@ -58,6 +58,9 @@
extern "C" { extern "C" {
#endif #endif
/* BSP includes. */
#include "xbasic_types.h"
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Port specific definitions. * Port specific definitions.
* *
@ -86,11 +89,16 @@ extern "C" {
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Interrupt control macros. */ /* Interrupt control macros and functions. */
void microblaze_disable_interrupts( void ); void microblaze_disable_interrupts( void );
void microblaze_enable_interrupts( void ); void microblaze_enable_interrupts( void );
#define portDISABLE_INTERRUPTS() microblaze_disable_interrupts() #define portDISABLE_INTERRUPTS() microblaze_disable_interrupts()
#define portENABLE_INTERRUPTS() microblaze_enable_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. */ /* Critical section macros. */

@ -114,8 +114,8 @@
/* BSP includes. */ /* BSP includes. */
#include "xenv_standalone.h" #include "xenv_standalone.h"
#include "xtmrctr.h" #include "xtmrctr.h"
#include "xintc.h"
#include "xil_exception.h" #include "xil_exception.h"
#include "microblaze_exceptions_g.h"
/* Priorities at which the tasks are created. */ /* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #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 XTmrCtr xTimer0Instance;
static XIntc intc;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main(void) int main(void)
{ {
/* Configure the NVIC, LED outputs and button inputs. */ /* Configure the interrupt controller, LED outputs and button inputs. */
prvSetupHardware(); prvSetupHardware();
/* Create the queue. */ /* Create the queue. */
@ -312,39 +311,9 @@ unsigned long ulReceivedValue;
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
int iStatus;
#ifdef MICROBLAZE_EXCEPTIONS_ENABLED #ifdef MICROBLAZE_EXCEPTIONS_ENABLED
microblaze_enable_exceptions(); microblaze_enable_exceptions();
#endif #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 ) void vApplicationSetupTimerInterrupt( void )
{ {
int iStatus; portBASE_TYPE xStatus;
const unsigned char ucTimerCounterNumber = ( unsigned char ) 0U; const unsigned char ucTimerCounterNumber = ( unsigned char ) 0U;
const unsigned long ulCounterValue = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) + 1UL ); 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. */ /* 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 vPortEnableInterrupt( XPAR_MICROBLAZE_0_INTC_AXI_TIMER_0_INTERRUPT_INTR );
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 );
/* Configure the timer interrupt handler. */ /* 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. */ /* 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 /* Enable the interrupts. Auto-reload mode is used to generate a
periodic tick. Note that interrupts are disabled when this function is periodic tick. Note that interrupts are disabled when this function is
called, so interrupts will not start to be processed until the first called, so interrupts will not start to be processed until the first
task has started to run. */ 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. */ /* Start the timer. */
XTmrCtr_Start( &axi_timer_0_Timer, ucTimerCounterNumber ); XTmrCtr_Start( &xTimer0Instance, ucTimerCounterNumber );
} }
configASSERT( ( iStatus == XST_SUCCESS ) ); configASSERT( ( xStatus == pdPASS ) );
} }

Loading…
Cancel
Save