Complete first pass commenting of the new MicroBlaze demo main-blinky.c and main-full.c files.

pull/4/head
Richard Barry 14 years ago
parent e46b2a304f
commit 07e3174ad7

@ -389,11 +389,16 @@ const unsigned char ucSetToOutput = 0U;
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* vApplicationMallocFailedHook() will only be called if
free memory available in the FreeRTOS heap. pvPortMalloc() is called configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
internally by FreeRTOS API functions that create tasks, queues, software function that will get called if a call to pvPortMalloc() fails.
timers, and semaphores. The size of the FreeRTOS heap is set by the pvPortMalloc() is called internally by the kernel whenever a task, queue or
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ semaphore is created. It is also called by various parts of the demo
application. If heap_1.c or heap_2.c are used, then the size of the heap
available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; ); for( ;; );
} }
@ -404,9 +409,13 @@ void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* vApplicationStackOverflowHook() will only be called if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook configCHECK_FOR_STACK_OVERFLOW is set to either 1 or 2. The handle and name
function is called if a stack overflow is detected. */ of the offending task will be passed into the hook function via its
parameters. However, when a stack has overflowed, it is possible that the
parameters will have been corrupted, in which case the pxCurrentTCB variable
can be inspected directly. */
taskDISABLE_INTERRUPTS();
for( ;; ); for( ;; );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -415,9 +424,18 @@ void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This function is called on each cycle of the idle task. In this case it /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
does nothing useful, other than report the amout of FreeRTOS heap that to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
remains unallocated. */ task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */
/* This implementation of vApplicationIdleHook() simply demonstrates how
the xPortGetFreeHeapSize() function can be used. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
if( xFreeHeapSpace > 100 ) if( xFreeHeapSpace > 100 )
@ -432,7 +450,11 @@ volatile size_t xFreeHeapSpace;
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* This simple blinky demo does not use the tick hook, but a tick hook is /* vApplicationTickHook() will only be called if configUSE_TICK_HOOK is set
to 1 in FreeRTOSConfig.h. It executes from an interrupt context so must
not use any FreeRTOS API functions that do not end in ...FromISR().
This simple blinky demo does not use the tick hook, but a tick hook is
required to be defined as the blinky and full demos share a required to be defined as the blinky and full demos share a
FreeRTOSConfig.h header file. */ FreeRTOSConfig.h header file. */
} }
@ -444,7 +466,7 @@ will run on lots of different MicroBlaze and FPGA configurations - not all of
which will have the same timer peripherals defined or available. This example which will have the same timer peripherals defined or available. This example
uses the AXI Timer 0. If that is available on your hardware platform then this uses the AXI Timer 0. If that is available on your hardware platform then this
example callback implementation should not require modification. The name of example callback implementation should not require modification. The name of
the interrupt handler that should be installed in vTickISR(), which the function the interrupt handler that should be installed is vTickISR(), which the function
below declares as an extern. */ below declares as an extern. */
void vApplicationSetupTimerInterrupt( void ) void vApplicationSetupTimerInterrupt( void )
{ {

@ -52,41 +52,43 @@
*/ */
/* **************************************************************************** /* ****************************************************************************
* This project includes a lot of demo and test tasks, and is therefore complex. * main-blinky.c is included when the "Blinky" build configuration is used.
* If you would prefer a much simpler project to get started with, then select * main-full.c is included when the "Full" build configuration is used.
* the 'Blinky' build configuration within the SDK Eclipse IDE. *
* main-full.c creates a lot of demo and test tasks and timers, and is
* therefore very comprehensive but also complex. If you would prefer a much
* simpler project to get started with, then select the 'Blinky' build
* configuration within the SDK Eclipse IDE. See the documentation page for
* this demo on the http://www.FreeRTOS.org web site for more information.
* **************************************************************************** * ****************************************************************************
* *
* main() creates all the demo application tasks, then starts the scheduler. * main() creates all the demo application tasks and timers, then starts the
* The web documentation provides more details of the standard demo application * scheduler. The web documentation provides more details of the standard demo
* tasks, which provide no particular functionality, but do provide a good * application tasks, which provide no particular functionality, but do provide
* example of how to use the FreeRTOS API. * a good example of how to use the FreeRTOS API.
* *
* In addition to the standard demo tasks, the following tasks and tests are * In addition to the standard demo tasks, the following tasks and tests are
* defined and/or created within this file: * defined and/or created within this file:
* *
* Webserver ("lwIP") task - TBD _RB_ * TCP/IP ("lwIP") task - TBD _RB_
* *
* "Reg test" tasks - These fill the registers with known values, then check * "Reg test" tasks - These test the task context switch mechanism by first
* that each register still contains its expected value. Each task uses * filling the MicroBlaze registers with known values, before checking that each
* different values. The tasks run with very low priority so get preempted * register maintains the value that was written to it as the tasks are switched
* very frequently. A check variable is incremented on each iteration of the * in and out. The two register test tasks do not use the same values, and
* test loop. A register containing an unexpected value is indicative of an * execute at a very low priority to ensure they are pre-empted regularly.
* error in the context switching mechanism and will result in a branch to a
* null loop - which in turn will prevent the check variable from incrementing
* any further and allow the check timer (described below) to determine that an
* error has occurred. The nature of the reg test tasks necessitates that they
* are written in assembly code.
* *
* "Check" timer - The check timer period is initially set to five seconds. * "Check" timer - The check timer period is initially set to five seconds.
* The check timer callback function checks that all the standard demo tasks are * The check timer callback function checks that all the standard demo tasks,
* functioning as expected, without error. If an error is discovered in any * and the register check tasks, are not only still execution, but are executing
* standard demo task, then the check timer period is shortened to 200ms. The * without reporting any errors. If the check timer discovers that a task has
* check timer callback function also toggles an LED each time it is called. * either stalled or reported an error, then it changes its own period from
* Therefore, if the LED toggles every five seconds, all the tasks are * the inital five seconds, to just 200ms. The check timer callback function
* functioning as expected, without any error conditions being detected. If the * also toggles an LED each time it is called. This provides a visual
* LED toggles every 200ms then an error has been discovered in at least one * indication of the system status: If the LED toggles every five seconds then
* task. * no issues have been discovered. If the LED toggles every 200ms then an issue
* has been discovered with at least one task. The last reported issue is
* latched into the pcStatusMessage variable.
* *
* This file also includes example implementations of the vApplicationTickHook(), * This file also includes example implementations of the vApplicationTickHook(),
* vApplicationIdleHook(), vApplicationStackOverflowHook(), * vApplicationIdleHook(), vApplicationStackOverflowHook(),
@ -122,7 +124,7 @@
#include "comtest_strings.h" #include "comtest_strings.h"
#include "TimerDemo.h" #include "TimerDemo.h"
/* Priorities at which the tasks are created. */ /* Priorities at which the various tasks are created. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -134,93 +136,67 @@
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* The WEB server uses string handling functions, which in turn use a bit more
stack than most of the other tasks. */
#define mainuIP_STACK_SIZE ( configMINIMAL_STACK_SIZE * 3 )
/* The LED toggled by the check task. */ /* The LED toggled by the check task. */
#define mainCHECK_LED ( 3 ) #define mainCHECK_LED ( 3 )
/* The rate at which mainCHECK_LED will toggle when all the tasks are running /* The rate at which mainCHECK_LED will toggle when all the tasks are running
without error. Controlled by the check task as described at the top of this without error. See the description of the check timer in the comments at the
file. */ top of this file. */
#define mainNO_ERROR_CHECK_TIMER_PERIOD ( 5000 / portTICK_RATE_MS ) #define mainNO_ERROR_CHECK_TIMER_PERIOD ( 5000 / portTICK_RATE_MS )
/* The rate at which mainCHECK_LED will toggle when an error has been reported /* The rate at which mainCHECK_LED will toggle when an error has been reported
by at least one task. Controlled by the check task as described at the top of by at least one task. See the description of the check timer in the comments at
this file. */ the top of this file. */
#define mainERROR_CHECK_TIMER_PERIOD ( 200 / portTICK_RATE_MS ) #define mainERROR_CHECK_TIMER_PERIOD ( 200 / portTICK_RATE_MS )
/* A block time of zero means "don't block". */ /* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( ( portTickType ) 0 ) #define mainDONT_BLOCK ( ( portTickType ) 0 )
/* The LED used by the comtest tasks. See the comtest.c file for more /* The LED used by the comtest tasks. See the comtest_strings.c file for more
information. In this case an invalid LED number is provided as all four information. In this case an invalid LED number is provided as all four
available LEDs are already in use. */ available LEDs (LEDs 0 to 3) are already in use. */
#define mainCOM_TEST_LED ( 4 ) #define mainCOM_TEST_LED ( 4 )
/* Baud rate used by the comtest tasks. This is actually fixed in the hardware /* Baud rate used by the comtest tasks. The baud rate used is actually fixed in
when the hardware was built, but the standard serial init function required a UARTLite IP when the hardware was built, but the standard serial init function
baud rate parameter. */ required a baud rate parameter to be provided - in this case it is just
ignored. */
#define mainCOM_TEST_BAUD_RATE ( XPAR_RS232_UART_1_BAUDRATE ) #define mainCOM_TEST_BAUD_RATE ( XPAR_RS232_UART_1_BAUDRATE )
/* The timer test task generates a lot of timers that all use a different
period that is a multiple of the mainTIMER_TEST_PERIOD definition. */
#define mainTIMER_TEST_PERIOD ( 20 ) #define mainTIMER_TEST_PERIOD ( 20 )
/* /*-----------------------------------------------------------*/
* vApplicationMallocFailedHook() will only be called if
* configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
* function that will execute if a call to pvPortMalloc() fails.
* pvPortMalloc() is called internally by the kernel whenever a task, queue or
* semaphore is created. It is also called by various parts of the demo
* application.
*/
void vApplicationMallocFailedHook( void );
/*
* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set to 1
* in FreeRTOSConfig.h. It is a hook function that is called on each iteration
* of the idle task. It is essential that code added to this hook function
* never attempts to block in any way (for example, call xQueueReceive() with
* a block time specified). If the application makes use of the vTaskDelete()
* API function (as this demo application does) then it is also important that
* vApplicationIdleHook() is permitted to return to its calling function because
* it is the responsibility of the idle task to clean up memory allocated by the
* kernel to any task that has since been deleted.
*/
void vApplicationIdleHook( void );
/*
* vApplicationStackOverflowHook() will only be called if
* configCHECK_FOR_STACK_OVERFLOW is set to a non-zero value. The handle and
* name of the offending task should be passed in the function parameters, but
* it is possible that the stack overflow will have corrupted these - in which
* case pxCurrentTCB can be inspected to find the same information.
*/
void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName );
/* /*
* The reg test tasks as described at the top of this file. * The register test tasks as described in the comments at the top of this file.
* The nature of the register test tasks means they have to be implemented in
* assembler.
*/ */
extern void vRegisterTest1( void *pvParameters ); extern void vRegisterTest1( void *pvParameters );
extern void vRegisterTest2( void *pvParameters ); extern void vRegisterTest2( void *pvParameters );
/* /*
* Defines the 'check' functionality as described at the top of this file. This * Defines the 'check' timer functionality as described at the top of this file.
* function is the callback function for the 'check' timer. * This function is the callback function associated with the 'check' timer.
*/ */
static void vCheckTimerCallback( xTimerHandle xTimer ); static void vCheckTimerCallback( xTimerHandle xTimer );
/*
* Configure the interrupt controller, LED outputs and button inputs.
*/
static void prvSetupHardware( void ); static void prvSetupHardware( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The status message that is displayed at the bottom of the "task stats" web /* The check timer callback function sets pcStatusMessage to a string that
page, which is served by the uIP task. This will report any errors picked up indicates the last reported error that it discovered. */
by the reg test task. */
static const char *pcStatusMessage = NULL; static const char *pcStatusMessage = NULL;
/* Structures that hold the state of the various peripherals used by this demo.
These are used by the Xilinx peripheral driver API functions. In this case,
only the timer/counter is used directly within this file. */
static XTmrCtr xTimer0Instance; static XTmrCtr xTimer0Instance;
/* The 'check' timer, as described at the top of this file. */ /* The 'check' timer, as described at the top of this file. */
@ -230,16 +206,18 @@ static xTimerHandle xCheckTimer = NULL;
int main( void ) int main( void )
{ {
/* ************************************************************************* /***************************************************************************
This project includes a lot of demo and test tasks, and is therefore complex. This project includes a lot of demo and test tasks and timers, and is
If you would prefer a much simpler project to get started with, then select therefore comprehensive, but complex. If you would prefer a much simpler
the 'Blinky' build configuration within the SDK Eclipse IDE. project to get started with, then select the 'Blinky' build configuration
within the SDK Eclipse IDE.
***************************************************************************/ ***************************************************************************/
/* Configure the interrupt controller, LED outputs and button inputs. */ /* Configure the interrupt controller, LED outputs and button inputs. */
prvSetupHardware(); prvSetupHardware();
/* Start the reg test tasks which test the context switching mechanism. */ /* Start the reg test tasks, as described in the comments at the top of this
file. */
xTaskCreate( vRegisterTest1, ( const signed char * const ) "RegTst1", configMINIMAL_STACK_SIZE, ( void * ) 0, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegisterTest1, ( const signed char * const ) "RegTst1", configMINIMAL_STACK_SIZE, ( void * ) 0, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegisterTest2, ( const signed char * const ) "RegTst2", configMINIMAL_STACK_SIZE, ( void * ) 0, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegisterTest2, ( const signed char * const ) "RegTst2", configMINIMAL_STACK_SIZE, ( void * ) 0, tskIDLE_PRIORITY, NULL );
@ -258,31 +236,34 @@ int main( void )
/* Note - the set of standard demo tasks contains two versions of /* Note - the set of standard demo tasks contains two versions of
vStartMathTasks.c. One is defined in flop.c, and uses double precision vStartMathTasks.c. One is defined in flop.c, and uses double precision
floating point numbers and variables. The other is defined in sp_flop.c floating point numbers and variables. The other is defined in sp_flop.c,
and uses single precision floating point numbers and variables. The and uses single precision floating point numbers and variables. The
MicroBlaze floating point unit only handles single precision floating. MicroBlaze floating point unit only handles single precision floating.
Therefore, to test the floating point unit, sp_flop.c should be included Therefore, to test the floating point hardware, sp_flop.c should be included
in this project. */ in this project. */
vStartMathTasks( mainFLOP_TASK_PRIORITY ); vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* The suicide tasks must be created last as they need to know how many /* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation in order to ascertain whether tasks were running prior to their creation. This then allows them to
or not the correct/expected number of tasks are running at any given time. */ ascertain whether or not the correct/expected number of tasks are running at
any given time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Create the 'check' timer - the timer that periodically calls the /* Create the 'check' timer - the timer that periodically calls the
check function as described at the top of this file. Note that, for check function as described in the comments at the top of this file. Note
the reasons stated in the comments above the call to that, for reasons stated in the comments within vApplicationIdleHook()
vStartTimerDemoTask(), that the check timer is not actually started (defined in this file), the check timer is not actually started until after
until after the scheduler has been started. */ the scheduler has been started. */
xCheckTimer = xTimerCreate( ( const signed char * ) "Check timer", mainNO_ERROR_CHECK_TIMER_PERIOD, pdTRUE, ( void * ) 0, vCheckTimerCallback ); xCheckTimer = xTimerCreate( ( const signed char * ) "Check timer", mainNO_ERROR_CHECK_TIMER_PERIOD, pdTRUE, ( void * ) 0, vCheckTimerCallback );
/* Start the tasks running. */ /* Start the scheduler running. From this point on, only tasks and
interrupts will be executing. */
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well we will never reach here as the scheduler will now be /* If all is well then the following line will never be reached. If
running. If we do reach here then it is likely that there was insufficient execution does reach here, then it is highly probably that the heap size
heap available for the idle task to be created. */ is too small for the idle and/or timer tasks to be created within
vTaskStartScheduler(). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; ); for( ;; );
} }
@ -296,14 +277,11 @@ static long lErrorAlreadyLatched = pdFALSE;
portTickType xExecutionRate = mainNO_ERROR_CHECK_TIMER_PERIOD; portTickType xExecutionRate = mainNO_ERROR_CHECK_TIMER_PERIOD;
/* This is the callback function used by the 'check' timer, as described /* This is the callback function used by the 'check' timer, as described
at the top of this file. */ in the comments at the top of this file. */
/* Check the standard demo tasks are running without error. */ /* Check the standard demo tasks are running without error. */
if( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
/* Increase the rate at which this task cycles, which will increase the
rate at which mainCHECK_LED flashes to give visual feedback that an error
has occurred. */
pcStatusMessage = "Error: GenQueue"; pcStatusMessage = "Error: GenQueue";
} }
else if( xAreQueuePeekTasksStillRunning() != pdTRUE ) else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
@ -361,6 +339,9 @@ portTickType xExecutionRate = mainNO_ERROR_CHECK_TIMER_PERIOD;
pcStatusMessage = "Error: RegTest2\r\n"; pcStatusMessage = "Error: RegTest2\r\n";
} }
/* Store a local copy of the current reg test loop counters. If these have
not incremented the next time this callback function is executed then the
reg test tasks have either stalled or discovered an error. */
ulLastRegTest1CycleCount = ulRegTest1CycleCount; ulLastRegTest1CycleCount = ulRegTest1CycleCount;
ulLastRegTest2CycleCount = ulRegTest2CycleCount; ulLastRegTest2CycleCount = ulRegTest2CycleCount;
@ -373,23 +354,39 @@ portTickType xExecutionRate = mainNO_ERROR_CHECK_TIMER_PERIOD;
{ {
if( lErrorAlreadyLatched == pdFALSE ) if( lErrorAlreadyLatched == pdFALSE )
{ {
/* Ensure the LED toggles at a faster rate if an error has occurred. /* An error has occurred, so change the period of the timer that
This is called from a timer callback so must not attempt to block. */ calls this callback function. This results in the LED toggling at
xTimerChangePeriod( xTimer, mainERROR_CHECK_TIMER_PERIOD, mainDONT_BLOCK ); a faster rate - giving the user visual feedback that something is not
as it should be. This function is called from the context of the
/* Update the xExecutionRate variable as the rate at which this timer service task so must ***not*** attempt to block while calling
this function. */
if( xTimerChangePeriod( xTimer, mainERROR_CHECK_TIMER_PERIOD, mainDONT_BLOCK ) == pdPASS )
{
/* If the command to change the timer period was sent to the
timer command queue successfully, then latch the fact that the
timer period has already been changed. This is just done to
prevent xTimerChangePeriod() being called on every execution of
this function once an error has been discovered. */
lErrorAlreadyLatched = pdTRUE;
}
/* Update the xExecutionRate variable too as the rate at which this
callback is executed has to be passed into the callback is executed has to be passed into the
xAreTimerDemoTasksStillRunning() function. */ xAreTimerDemoTasksStillRunning() function. */
xExecutionRate = mainERROR_CHECK_TIMER_PERIOD; xExecutionRate = mainERROR_CHECK_TIMER_PERIOD;
/* Just to ensure the timer period is not changed on each execution
of the callback. */
lErrorAlreadyLatched = pdTRUE;
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This is an application defined callback function used to install the tick
interrupt handler. It is provided as an application callback because the kernel
will run on lots of different MicroBlaze and FPGA configurations - not all of
which will have the same timer peripherals defined or available. This example
uses the AXI Timer 0. If that is available on your hardware platform then this
example callback implementation should not require modification. The name of
the interrupt handler that should be installed is vTickISR(), which the function
below declares as an extern. */
void vApplicationSetupTimerInterrupt( void ) void vApplicationSetupTimerInterrupt( void )
{ {
portBASE_TYPE xStatus; portBASE_TYPE xStatus;
@ -402,12 +399,17 @@ extern void vTickISR( void *pvUnused );
if( xStatus == XST_SUCCESS ) if( xStatus == XST_SUCCESS )
{ {
/* Install the tick interrupt handler as the timer ISR. */ /* Install the tick interrupt handler as the timer ISR.
*NOTE* The xPortInstallInterruptHandler() API function must be used for
this purpose. */
xStatus = xPortInstallInterruptHandler( XPAR_INTC_0_TMRCTR_0_VEC_ID, vTickISR, NULL ); xStatus = xPortInstallInterruptHandler( XPAR_INTC_0_TMRCTR_0_VEC_ID, vTickISR, NULL );
} }
if( xStatus == pdPASS ) if( xStatus == pdPASS )
{ {
/* Enable the timer interrupt in the interrupt controller.
*NOTE* The vPortEnableInterrupt() API function must be used for this
purpose. */
vPortEnableInterrupt( XPAR_INTC_0_TMRCTR_0_VEC_ID ); vPortEnableInterrupt( XPAR_INTC_0_TMRCTR_0_VEC_ID );
/* Configure the timer interrupt handler. */ /* Configure the timer interrupt handler. */
@ -426,10 +428,20 @@ extern void vTickISR( void *pvUnused );
XTmrCtr_Start( &xTimer0Instance, ucTimerCounterNumber ); XTmrCtr_Start( &xTimer0Instance, ucTimerCounterNumber );
} }
/* Sanity check that the function executed as expected. */
configASSERT( ( xStatus == pdPASS ) ); configASSERT( ( xStatus == pdPASS ) );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This is an application defined callback function used to clear whichever
interrupt was installed by the the vApplicationSetupTimerInterrupt() callback
function - in this case the interrupt generated by the AXI timer. It is
provided as an application callback because the kernel will run on lots of
different MicroBlaze and FPGA configurations - not all of which will have the
same timer peripherals defined or available. This example uses the AXI Timer 0.
If that is available on your hardware platform then this example callback
implementation should not require modification provided the example definition
of vApplicationSetupTimerInterrupt() is also not modified. */
void vApplicationClearTimerInterrupt( void ) void vApplicationClearTimerInterrupt( void )
{ {
unsigned long ulCSR; unsigned long ulCSR;
@ -440,33 +452,60 @@ unsigned long ulCSR;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This function is explained by the comments above its prototype at the top
of this file. */
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue or
semaphore is created. It is also called by various parts of the demo
application. If heap_1.c or heap_2.c are used, then the size of the heap
available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; ); for( ;; );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This function is explained by the comments above its prototype at the top
of this file. */
void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ) void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
{ {
/* vApplicationStackOverflowHook() will only be called if
configCHECK_FOR_STACK_OVERFLOW is set to either 1 or 2. The handle and name
of the offending task will be passed into the hook function via its
parameters. However, when a stack has overflowed, it is possible that the
parameters will have been corrupted, in which case the pxCurrentTCB variable
can be inspected directly. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; ); for( ;; );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This function is explained by the comments above its prototype at the top
of this file. */
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
static long lCheckTimerStarted = pdFALSE; static long lCheckTimerStarted = pdFALSE;
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */
/* If the check timer has not already been started, then start it now.
Normally, the xTimerStart() API function can be called immediately after the
timer is created - how this demo application includes the timer demo tasks.
The timer demo tasks, as part of their test function, deliberately fill up
the timer command queue - meaning the check timer cannot be started until
after the scheduler has been started - at which point the timer command
queue will have been drained. */
if( lCheckTimerStarted == pdFALSE ) if( lCheckTimerStarted == pdFALSE )
{ {
xTimerStart( xCheckTimer, mainDONT_BLOCK ); //_RB_ comment why this is done here. xTimerStart( xCheckTimer, mainDONT_BLOCK );
lCheckTimerStarted = pdTRUE; lCheckTimerStarted = pdTRUE;
} }
} }
@ -474,24 +513,35 @@ static long lCheckTimerStarted = pdFALSE;
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* vApplicationTickHook() will only be called if configUSE_TICK_HOOK is set
to 1 in FreeRTOSConfig.h. It executes from an interrupt context so must
not use any FreeRTOS API functions that do not end in ...FromISR(). */
/* Call the periodic timer test, which tests the timer API functions that /* Call the periodic timer test, which tests the timer API functions that
can be called from an ISR. */ can be called from an ISR. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
char *pcGetTaskStatusMessage( void ) void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )
{ {
/* Not bothered about a critical section here although technically because of /* If configINSTALL_EXCEPTION_HANDLERS is set to 1 in FreeRTOSConfig.h, then
the task priorities the pointer could change it will be atomic if not near the kernel will automatically install its own exception handlers before the
atomic and its not critical. */ kernel is started, if the application writer has not already caused them to
if( pcStatusMessage == NULL ) be installed by calling either of the vPortExceptionsInstallHandlers()
{ or xPortInstallInterruptHandler() API functions before that time. The
return "All tasks running without error"; kernels exception handler populates an xPortRegisterDump structure with
} the processor state at the point that the exception was triggered - and also
else includes a strings that say what the exception cause was and which task was
running at the time. The exception handler then passes the populated
xPortRegisterDump structure into vApplicationExceptionRegisterDump() to
allow the application writer to perform any debugging that may be necessary.
However, defining vApplicationExceptionRegisterDump() within the application
itself is optional. The kernel will use a default implementation if the
application writer chooses not to provide their own. */
for( ;; )
{ {
return ( char * ) pcStatusMessage; portNOP();
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -499,8 +549,12 @@ char *pcGetTaskStatusMessage( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
/* Configure the LED outputs. */
vParTestInitialise(); vParTestInitialise();
/* Tasks inherit the exception and cache configuration of the MicroBlaze
at the point that they are created. */
#if MICROBLAZE_EXCEPTIONS_ENABLED == 1 #if MICROBLAZE_EXCEPTIONS_ENABLED == 1
microblaze_enable_exceptions(); microblaze_enable_exceptions();
#endif #endif
@ -518,11 +572,3 @@ static void prvSetupHardware( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )
{
for( ;; )
{
portNOP();
}
}

Loading…
Cancel
Save