+++ /dev/null
-/*\r
- FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-/*\r
- * This file initialises three timers as follows:\r
- *\r
- * Timer 0 and Timer 1 provide the interrupts that are used with the IntQ\r
- * standard demo tasks, which test interrupt nesting and using queues from\r
- * interrupts. Both these interrupts operate below the maximum syscall\r
- * interrupt priority.\r
- *\r
- * Timer 2 is a much higher frequency timer that tests the nesting of interrupts\r
- * that execute above the maximum syscall interrupt priority.\r
- *\r
- * All the timers can nest with the tick interrupt - creating a maximum\r
- * interrupt nesting depth of 4.\r
- *\r
- * For convenience, the high frequency timer is also used to provide the time\r
- * base for the run time stats.\r
- */\r
-\r
-/* Scheduler includes. */\r
-#include "FreeRTOS.h"\r
-\r
-/* Demo includes. */\r
-#include "IntQueueTimer.h"\r
-#include "IntQueue.h"\r
-\r
-/* Xilinx includes. */\r
-#include "xttcps.h"\r
-#include "xscugic.h"\r
-\r
-/* The frequencies at which the first two timers expire are slightly offset to\r
-ensure they don't remain synchronised. The frequency of the interrupt that\r
-operates above the max syscall interrupt priority is 10 times faster so really\r
-hammers the interrupt entry and exit code. */\r
-#define tmrTIMERS_USED 3\r
-#define tmrTIMER_0_FREQUENCY ( 2000UL )\r
-#define tmrTIMER_1_FREQUENCY ( 2001UL )\r
-#define tmrTIMER_2_FREQUENCY ( 20000UL )\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * The single interrupt service routines that is used to service all three\r
- * timers.\r
- */\r
-static void prvTimerHandler( void *CallBackRef );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* Hardware constants. */\r
-static const BaseType_t xDeviceIDs[ tmrTIMERS_USED ] = { XPAR_XTTCPS_0_DEVICE_ID, XPAR_XTTCPS_1_DEVICE_ID, XPAR_XTTCPS_2_DEVICE_ID };\r
-static const BaseType_t xInterruptIDs[ tmrTIMERS_USED ] = { XPAR_XTTCPS_0_INTR, XPAR_XTTCPS_1_INTR, XPAR_XTTCPS_2_INTR };\r
-\r
-/* Timer configuration settings. */\r
-typedef struct\r
-{\r
- uint32_t OutputHz; /* Output frequency. */\r
- uint16_t Interval; /* Interval value. */\r
- uint8_t Prescaler; /* Prescaler value. */\r
- uint16_t Options; /* Option settings. */\r
-} TmrCntrSetup;\r
-\r
-static TmrCntrSetup xTimerSettings[ tmrTIMERS_USED ] =\r
-{\r
- { tmrTIMER_0_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE },\r
- { tmrTIMER_1_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE },\r
- { tmrTIMER_2_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE }\r
-};\r
-\r
-/* Lower priority number means higher logical priority, so\r
-configMAX_API_CALL_INTERRUPT_PRIORITY - 1 is above the maximum system call\r
-interrupt priority. */\r
-static const UBaseType_t uxInterruptPriorities[ tmrTIMERS_USED ] =\r
-{\r
- configMAX_API_CALL_INTERRUPT_PRIORITY + 1,\r
- configMAX_API_CALL_INTERRUPT_PRIORITY,\r
- configMAX_API_CALL_INTERRUPT_PRIORITY - 1\r
-};\r
-\r
-static XTtcPs xTimerInstances[ tmrTIMERS_USED ];\r
-\r
-/* Used to provide a means of ensuring the intended interrupt nesting depth is\r
-actually being reached. */\r
-extern uint32_t ulPortInterruptNesting;\r
-static uint32_t ulMaxRecordedNesting = 0;\r
-\r
-/* Used to ensure the high frequency timer is running at the expected\r
-frequency. */\r
-static volatile uint32_t ulHighFrequencyTimerCounts = 0;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void vInitialiseTimerForIntQueueTest( void )\r
-{\r
-BaseType_t xStatus;\r
-TmrCntrSetup *pxTimerSettings;\r
-extern XScuGic xInterruptController;\r
-BaseType_t xTimer;\r
-XTtcPs *pxTimerInstance;\r
-XTtcPs_Config *pxTimerConfiguration;\r
-const uint8_t ucRisingEdge = 3;\r
-\r
- for( xTimer = 0; xTimer < tmrTIMERS_USED; xTimer++ )\r
- {\r
- /* Look up the timer's configuration. */\r
- pxTimerInstance = &( xTimerInstances[ xTimer ] );\r
- pxTimerConfiguration = XTtcPs_LookupConfig( xDeviceIDs[ xTimer ] );\r
- configASSERT( pxTimerConfiguration );\r
-\r
- pxTimerSettings = &( xTimerSettings[ xTimer ] );\r
-\r
- /* Initialise the device. */\r
- xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress );\r
- if( xStatus != XST_SUCCESS )\r
- {\r
- /* Not sure how to do this before XTtcPs_CfgInitialize is called\r
- as pxTimerInstance is set within XTtcPs_CfgInitialize(). */\r
- XTtcPs_Stop( pxTimerInstance );\r
- xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress );\r
- configASSERT( xStatus == XST_SUCCESS );\r
- }\r
-\r
- /* Set the options. */\r
- XTtcPs_SetOptions( pxTimerInstance, pxTimerSettings->Options );\r
-\r
- /* The timer frequency is preset in the pxTimerSettings structure.\r
- Derive the values for the other structure members. */\r
- XTtcPs_CalcIntervalFromFreq( pxTimerInstance, pxTimerSettings->OutputHz, &( pxTimerSettings->Interval ), &( pxTimerSettings->Prescaler ) );\r
-\r
- /* Set the interval and prescale. */\r
- XTtcPs_SetInterval( pxTimerInstance, pxTimerSettings->Interval );\r
- XTtcPs_SetPrescaler( pxTimerInstance, pxTimerSettings->Prescaler );\r
-\r
- /* The priority must be the lowest possible. */\r
- XScuGic_SetPriorityTriggerType( &xInterruptController, xInterruptIDs[ xTimer ], uxInterruptPriorities[ xTimer ] << portPRIORITY_SHIFT, ucRisingEdge );\r
-\r
- /* Connect to the interrupt controller. */\r
- xStatus = XScuGic_Connect( &xInterruptController, xInterruptIDs[ xTimer ], ( Xil_InterruptHandler ) prvTimerHandler, ( void * ) pxTimerInstance );\r
- configASSERT( xStatus == XST_SUCCESS);\r
-\r
- /* Enable the interrupt in the GIC. */\r
- XScuGic_Enable( &xInterruptController, xInterruptIDs[ xTimer ] );\r
-\r
- /* Enable the interrupts in the timer. */\r
- XTtcPs_EnableInterrupts( pxTimerInstance, XTTCPS_IXR_INTERVAL_MASK );\r
-\r
- /* Start the timer. */\r
- XTtcPs_Start( pxTimerInstance );\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvTimerHandler( void *pvCallBackRef )\r
-{\r
-uint32_t ulInterruptStatus;\r
-XTtcPs *pxTimer = ( XTtcPs * ) pvCallBackRef;\r
-BaseType_t xYieldRequired;\r
-\r
- /* Read the interrupt status, then write it back to clear the interrupt. */\r
- ulInterruptStatus = XTtcPs_GetInterruptStatus( pxTimer );\r
- XTtcPs_ClearInterruptStatus( pxTimer, ulInterruptStatus );\r
-\r
- /* Only one interrupt event type is expected. */\r
- configASSERT( ( XTTCPS_IXR_INTERVAL_MASK & ulInterruptStatus ) != 0 );\r
-\r
- /* Check the device ID to know which IntQueue demo to call. */\r
- if( pxTimer->Config.DeviceId == xDeviceIDs[ 0 ] )\r
- {\r
- xYieldRequired = xFirstTimerHandler();\r
- }\r
- else if( pxTimer->Config.DeviceId == xDeviceIDs[ 1 ] )\r
- {\r
- xYieldRequired = xSecondTimerHandler();\r
- }\r
- else\r
- {\r
- /* Used to check the timer is running at the expected frequency. */\r
- ulHighFrequencyTimerCounts++;\r
-\r
- /* Latch the highest interrupt nesting count detected. */\r
- if( ulPortInterruptNesting > ulMaxRecordedNesting )\r
- {\r
- ulMaxRecordedNesting = ulPortInterruptNesting;\r
- }\r
-\r
- xYieldRequired = pdFALSE;\r
- }\r
-\r
- /* If xYieldRequired is not pdFALSE then calling either xFirstTimerHandler()\r
- or xSecondTimerHandler() resulted in a task leaving the blocked state and\r
- the task that left the blocked state had a priority higher than the currently\r
- running task (the task this interrupt interrupted) - so a context switch\r
- should be performed so the interrupt returns directly to the higher priority\r
- task. xYieldRequired is tested inside the following macro. */\r
- portYIELD_FROM_ISR( xYieldRequired );\r
-}\r
-\r