2 * FreeRTOS Kernel V10.2.1
\r
3 * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
\r
6 * this software and associated documentation files (the "Software"), to deal in
\r
7 * the Software without restriction, including without limitation the rights to
\r
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
\r
9 * the Software, and to permit persons to whom the Software is furnished to do so,
\r
10 * subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
22 * http://www.FreeRTOS.org
\r
23 * http://aws.amazon.com/freertos
\r
25 * 1 tab == 4 spaces!
\r
28 /******************************************************************************
\r
29 * This project provides three demo applications. A simple blinky style
\r
30 * project, a more comprehensive test and demo application, and an lwIP example.
\r
31 * The mainSELECTED_APPLICATION setting (defined in this file) is used to
\r
32 * select between the three. The simply blinky demo is implemented and
\r
33 * described in main_blinky.c. The more comprehensive test and demo application
\r
34 * is implemented and described in main_full.c. The lwIP example is implemented
\r
35 * and described in main_lwIP.c.
\r
37 * This file implements the code that is not demo specific, including the
\r
38 * hardware setup and FreeRTOS hook functions.
\r
40 * ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON
\r
41 * THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO
\r
42 * APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT!
\r
46 /* Standard includes. */
\r
50 /* Scheduler include files. */
\r
51 #include "FreeRTOS.h"
\r
54 /* Demo app includes. */
\r
55 #include "partest.h"
\r
57 /* Xilinx includes. */
\r
58 #include "xtmrctr.h"
\r
59 #include "xil_cache.h"
\r
61 /* mainSELECTED_APPLICATION is used to select between three demo applications,
\r
62 * as described at the top of this file.
\r
64 * When mainSELECTED_APPLICATION is set to 0 the simple blinky example will
\r
67 * When mainSELECTED_APPLICATION is set to 1 the comprehensive test and demo
\r
68 * application will be run.
\r
70 * When mainSELECTED_APPLICATION is set to 2 the lwIP example will be run.
\r
72 #define mainSELECTED_APPLICATION 0
\r
74 /*-----------------------------------------------------------*/
\r
77 * Configure the hardware as necessary to run this demo.
\r
79 static void prvSetupHardware( void );
\r
82 * See the comments at the top of this file and above the
\r
83 * mainSELECTED_APPLICATION definition.
\r
85 #if ( mainSELECTED_APPLICATION == 0 )
\r
86 extern void main_blinky( void );
\r
87 #elif ( mainSELECTED_APPLICATION == 1 )
\r
88 extern void main_full( void );
\r
89 #elif ( mainSELECTED_APPLICATION == 2 )
\r
90 extern void main_lwIP( void );
\r
92 #error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition.
\r
95 /* Prototypes for the standard FreeRTOS callback/hook functions implemented
\r
96 within this file. */
\r
97 void vApplicationMallocFailedHook( void );
\r
98 void vApplicationIdleHook( void );
\r
99 void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
\r
100 void vApplicationTickHook( void );
\r
102 /* The dual timer is used to generate the RTOS tick interrupt and as a time base
\r
103 for the run time stats. */
\r
104 static XTmrCtr xTickTimerInstance;
\r
106 /*-----------------------------------------------------------*/
\r
110 /* Configure the hardware ready to run the demo. */
\r
111 prvSetupHardware();
\r
113 /* The mainSELECTED_APPLICATION setting is described at the top
\r
115 #if( mainSELECTED_APPLICATION == 0 )
\r
119 #elif( mainSELECTED_APPLICATION == 1 )
\r
129 /* Don't expect to reach here. */
\r
132 /*-----------------------------------------------------------*/
\r
134 static void prvSetupHardware( void )
\r
136 microblaze_disable_interrupts();
\r
138 #if defined( XPAR_MICROBLAZE_USE_ICACHE ) && ( XPAR_MICROBLAZE_USE_ICACHE != 0 )
\r
140 Xil_ICacheInvalidate();
\r
141 Xil_ICacheEnable();
\r
145 #if defined( XPAR_MICROBLAZE_USE_DCACHE ) && ( XPAR_MICROBLAZE_USE_DCACHE != 0 )
\r
147 Xil_DCacheInvalidate();
\r
148 Xil_DCacheEnable();
\r
152 /* Initialise the LEDs. ParTest is a historic name which used to stand for
\r
153 PARallel port TEST. */
\r
154 vParTestInitialise();
\r
156 /*-----------------------------------------------------------*/
\r
158 void vApplicationMallocFailedHook( void )
\r
160 volatile uint32_t ulDummy = 0;
\r
162 /* Called if a call to pvPortMalloc() fails because there is insufficient
\r
163 free memory available in the FreeRTOS heap. pvPortMalloc() is called
\r
164 internally by FreeRTOS API functions that create tasks, queues, software
\r
165 timers, and semaphores. The size of the FreeRTOS heap is set by the
\r
166 configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. Force an
\r
167 assertion failure. */
\r
168 configASSERT( ulDummy != 0 );
\r
170 /*-----------------------------------------------------------*/
\r
172 void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
\r
174 ( void ) pcTaskName;
\r
177 /* Run time stack overflow checking is performed if
\r
178 configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
\r
179 function is called if a stack overflow is detected. Force an assertion
\r
181 configASSERT( ( char * ) pxTask == pcTaskName );
\r
183 /*-----------------------------------------------------------*/
\r
185 void vApplicationIdleHook( void )
\r
187 #if( mainSELECTED_APPLICATION == 1 )
\r
189 extern void vFullDemoIdleHook( void );
\r
191 /* When the full demo is build the idle hook is used to create some
\r
192 timers to flash LEDs. */
\r
193 vFullDemoIdleHook();
\r
197 /*-----------------------------------------------------------*/
\r
199 void vAssertCalled( const char * pcFile, unsigned long ulLine )
\r
201 volatile unsigned long ul = 0;
\r
206 taskENTER_CRITICAL();
\r
208 /* Set ul to a non-zero value using the debugger to step out of this
\r
215 taskEXIT_CRITICAL();
\r
217 /*-----------------------------------------------------------*/
\r
219 void vApplicationTickHook( void )
\r
221 #if( mainSELECTED_APPLICATION == 1 )
\r
223 extern void vFullDemoTickHook( void );
\r
225 /* When the full demo is build the tick hook is used to demonstrate
\r
226 functions being called from an interrupt and perform some tests. */
\r
227 vFullDemoTickHook();
\r
231 /*-----------------------------------------------------------*/
\r
233 /* This is an application defined callback function used to install the tick
\r
234 interrupt handler. It is provided as an application callback because the kernel
\r
235 will run on lots of different MicroBlaze and FPGA configurations - not all of
\r
236 which will have the same timer peripherals defined or available. This example
\r
237 uses the Dual Timer 0. If that is available on your hardware platform then this
\r
238 example callback implementation may not require modification. The name of the
\r
239 interrupt handler that must be installed is vPortTickISR(), which the function
\r
240 below declares as an extern. */
\r
241 void vApplicationSetupTimerInterrupt( void )
\r
243 portBASE_TYPE xStatus;
\r
244 const unsigned char ucTickTimerCounterNumber = ( unsigned char ) 0U;
\r
245 const unsigned char ucRunTimeStatsCounterNumber = ( unsigned char ) 1U;
\r
246 const unsigned long ulCounterValue = ( ( XPAR_TMRCTR_0_CLOCK_FREQ_HZ / configTICK_RATE_HZ ) - 1UL );
\r
247 extern void vPortTickISR( void *pvUnused );
\r
249 /* Initialise the timer/counter. */
\r
250 xStatus = XTmrCtr_Initialize( &xTickTimerInstance, XPAR_TMRCTR_0_DEVICE_ID );
\r
252 if( xStatus == XST_SUCCESS )
\r
254 /* Install the tick interrupt handler as the timer ISR.
\r
255 *NOTE* The xPortInstallInterruptHandler() API function must be used for
\r
257 xStatus = xPortInstallInterruptHandler( XPAR_INTC_0_TMRCTR_0_VEC_ID, vPortTickISR, NULL );
\r
260 if( xStatus == pdPASS )
\r
262 /* Enable the timer interrupt in the interrupt controller.
\r
263 *NOTE* The vPortEnableInterrupt() API function must be used for this
\r
265 vPortEnableInterrupt( XPAR_INTC_0_TMRCTR_0_VEC_ID );
\r
267 /* Configure the timer interrupt handler. This installs the handler
\r
268 directly, rather than through the Xilinx driver. This is done for
\r
270 XTmrCtr_SetHandler( &xTickTimerInstance, ( void * ) vPortTickISR, NULL );
\r
272 /* Set the correct period for the timer. */
\r
273 XTmrCtr_SetResetValue( &xTickTimerInstance, ucTickTimerCounterNumber, ulCounterValue );
\r
275 /* Enable the interrupts. Auto-reload mode is used to generate a
\r
276 periodic tick. Note that interrupts are disabled when this function is
\r
277 called, so interrupts will not start to be processed until the first
\r
278 task has started to run. */
\r
279 XTmrCtr_SetOptions( &xTickTimerInstance, ucTickTimerCounterNumber, ( XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION | XTC_DOWN_COUNT_OPTION ) );
\r
281 /* Start the timer. */
\r
282 XTmrCtr_Start( &xTickTimerInstance, ucTickTimerCounterNumber );
\r
287 /* The second timer is used as the time base for the run time stats.
\r
288 Auto-reload mode is used to ensure the timer does not stop. */
\r
289 XTmrCtr_SetOptions( &xTickTimerInstance, ucRunTimeStatsCounterNumber, XTC_AUTO_RELOAD_OPTION );
\r
291 /* Start the timer. */
\r
292 XTmrCtr_Start( &xTickTimerInstance, ucRunTimeStatsCounterNumber );
\r
295 /* Sanity check that the function executed as expected. */
\r
296 configASSERT( ( xStatus == pdPASS ) );
\r
298 /*-----------------------------------------------------------*/
\r
300 /* This is an application defined callback function used to clear whichever
\r
301 interrupt was installed by the the vApplicationSetupTimerInterrupt() callback
\r
302 function. It is provided as an application callback because the kernel will run
\r
303 on lots of different MicroBlaze and FPGA configurations - not all of which will
\r
304 have the same timer peripherals defined or available. This example uses the
\r
305 dual timer 0. If that is available on your hardware platform then this example
\r
306 callback implementation will not require modification provided the example
\r
307 definition of vApplicationSetupTimerInterrupt() is also not modified. */
\r
308 void vApplicationClearTimerInterrupt( void )
\r
310 unsigned long ulCSR;
\r
312 /* Clear the timer interrupt */
\r
313 ulCSR = XTmrCtr_GetControlStatusReg( XPAR_TMRCTR_0_BASEADDR, 0 );
\r
314 XTmrCtr_SetControlStatusReg( XPAR_TMRCTR_0_BASEADDR, 0, ulCSR );
\r
316 /*-----------------------------------------------------------*/
\r
318 void *malloc( size_t x )
\r
320 /* Just to check it never gets called as there is no heap defined (other
\r
321 than the FreeRTOS heap). */
\r
324 /*-----------------------------------------------------------*/
\r
326 uint32_t ulMainGetRunTimeCounterValue( void )
\r
328 static uint32_t ulOverflows = 0, ulLastTime = 0;
\r
329 uint32_t ulTimeNow, ulReturn;
\r
330 const uint32_t ulPrescale = 10, ulTCR2Offset = 24UL;
\r
332 ulTimeNow = * ( ( uint32_t * ) ( XPAR_TMRCTR_0_BASEADDR + ulTCR2Offset ) );
\r
334 if( ulTimeNow < ulLastTime )
\r
336 /* 32 as its a 32-bit number. */
\r
337 ulOverflows += ( 1UL << ( 32 - ulPrescale ) );
\r
339 ulLastTime = ulTimeNow;
\r
341 ulReturn = ( ulTimeNow >> ulPrescale ) + ulOverflows;
\r
345 /*-----------------------------------------------------------*/
\r