mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Updating MicroBlaze port - work in progress.
This commit is contained in:
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( iStatus == XST_SUCCESS )
|
if( xStatus == XST_SUCCESS )
|
||||||
{
|
{
|
||||||
/* Enable the interrupt for the timer counter. Note that interrupts
|
/* Install the tick interrupt handler as the timer ISR. */
|
||||||
are globally disabled when this function is called. Interrupt
|
xStatus = xPortInstallInterruptHandler( XPAR_MICROBLAZE_0_INTC_AXI_TIMER_0_INTERRUPT_INTR, vTickISR, NULL );
|
||||||
processing will not actually start until the first task is executing. */
|
}
|
||||||
XIntc_Enable( &intc, XPAR_MICROBLAZE_0_INTC_AXI_TIMER_0_INTERRUPT_INTR );
|
|
||||||
|
if( xStatus == pdPASS )
|
||||||
|
{
|
||||||
|
vPortEnableInterrupt( 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…
Reference in a new issue