X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=FreeRTOS%2FDemo%2FCORTEX_A9_Zynq_ZC702%2FRTOSDemo%2Fsrc%2Fmain.c;fp=FreeRTOS%2FDemo%2FCORTEX_A9_Zynq_ZC702%2FRTOSDemo%2Fsrc%2Fmain.c;h=e8c05249eb597b73684a47a1d8ff7dd26a0a2092;hb=4b6d6a375e02a47e688b19b2d71f30bcdad4df66;hp=0000000000000000000000000000000000000000;hpb=ad183844de6b1178bb547f3d2149a34fd02e5195;p=freertos diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c new file mode 100644 index 000000000..e8c05249e --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c @@ -0,0 +1,464 @@ +/* + FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/****************************************************************************** + * + * See http://www.freertos.org/RTOS-Xilinx-Zynq.html for instructions. + * + * This project provides three demo applications. A simple blinky style + * project, a more comprehensive test and demo application, and an lwIP example. + * The mainSELECTED_APPLICATION setting (defined in this file) is used to + * select between the three. The simply blinky demo is implemented and + * described in main_blinky.c. The more comprehensive test and demo application + * is implemented and described in main_full.c. The lwIP example is implemented + * and described in main_lwIP.c. + * + * This file implements the code that is not demo specific, including the + * hardware setup and FreeRTOS hook functions. + * + * !!! IMPORTANT NOTE !!! + * The GCC libraries that ship with the Xilinx SDK make use of the floating + * point registers. To avoid this causing corruption it is necessary to avoid + * their use. For this reason main.c contains very basic C implementations of + * the standard C library functions memset(), memcpy() and memcmp(), which are + * are used by FreeRTOS itself. Defining these functions in the project + * prevents the linker pulling them in from the library. Any other standard C + * library functions that are used by the application must likewise be defined + * in C. + * + * ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON + * THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO + * APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT! + * + */ + +/* Standard includes. */ +#include +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Standard demo includes. */ +#include "partest.h" +#include "TimerDemo.h" +#include "QueueOverwrite.h" +#include "EventGroupsDemo.h" +#include "TaskNotify.h" +#include "IntSemTest.h" + +/* Xilinx includes. */ +#include "platform.h" +#include "xparameters.h" +#include "xscutimer.h" +#include "xscugic.h" +#include "xil_exception.h" + +/* mainSELECTED_APPLICATION is used to select between three demo applications, + * as described at the top of this file. + * + * When mainSELECTED_APPLICATION is set to 0 the simple blinky example will + * be run. + * + * When mainSELECTED_APPLICATION is set to 1 the comprehensive test and demo + * application will be run. + * + * When mainSELECTED_APPLICATION is set to 2 the lwIP example will be run. + */ +#define mainSELECTED_APPLICATION 1 + +/*-----------------------------------------------------------*/ + +/* + * Configure the hardware as necessary to run this demo. + */ +static void prvSetupHardware( void ); + +/* + * See the comments at the top of this file and above the + * mainSELECTED_APPLICATION definition. + */ +#if ( mainSELECTED_APPLICATION == 0 ) + extern void main_blinky( void ); +#elif ( mainSELECTED_APPLICATION == 1 ) + extern void main_full( void ); +#elif ( mainSELECTED_APPLICATION == 2 ) + extern void main_lwIP( void ); +#else + #error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition. +#endif + +/* + * The Xilinx projects use a BSP that do not allow the start up code to be + * altered easily. Therefore the vector table used by FreeRTOS is defined in + * FreeRTOS_asm_vectors.S, which is part of this project. Switch to use the + * FreeRTOS vector table. + */ +extern void vPortInstallFreeRTOSVectorTable( void ); + +/* Prototypes for the standard FreeRTOS callback/hook functions implemented +within this file. */ +void vApplicationMallocFailedHook( void ); +void vApplicationIdleHook( void ); +void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); +void vApplicationTickHook( void ); + +/* The private watchdog is used as the timer that generates run time +stats. This frequency means it will overflow quite quickly. */ +XScuWdt xWatchDogInstance; + +/*-----------------------------------------------------------*/ + +/* The interrupt controller is initialised in this file, and made available to +other modules. */ +XScuGic xInterruptController; + +/*-----------------------------------------------------------*/ + +int main( void ) +{ + /* See http://www.freertos.org/RTOS-Xilinx-Zynq.html for instructions. */ + + /* Configure the hardware ready to run the demo. */ + prvSetupHardware(); + + /* The mainSELECTED_APPLICATION setting is described at the top of this + file. */ + #if( mainSELECTED_APPLICATION == 0 ) + { + main_blinky(); + } + #elif( mainSELECTED_APPLICATION == 1 ) + { + main_full(); + } + #else + { + main_lwIP(); + } + #endif + + /* Don't expect to reach here. */ + return 0; +} +/*-----------------------------------------------------------*/ + +static void prvSetupHardware( void ) +{ +BaseType_t xStatus; +XScuGic_Config *pxGICConfig; + + /* Ensure no interrupts execute while the scheduler is in an inconsistent + state. Interrupts are automatically enabled when the scheduler is + started. */ + portDISABLE_INTERRUPTS(); + + /* Obtain the configuration of the GIC. */ + pxGICConfig = XScuGic_LookupConfig( XPAR_SCUGIC_SINGLE_DEVICE_ID ); + + /* Sanity check the FreeRTOSConfig.h settings are correct for the + hardware. */ + configASSERT( pxGICConfig ); + configASSERT( pxGICConfig->CpuBaseAddress == ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ) ); + configASSERT( pxGICConfig->DistBaseAddress == configINTERRUPT_CONTROLLER_BASE_ADDRESS ); + + /* Install a default handler for each GIC interrupt. */ + xStatus = XScuGic_CfgInitialize( &xInterruptController, pxGICConfig, pxGICConfig->CpuBaseAddress ); + configASSERT( xStatus == XST_SUCCESS ); + ( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */ + + /* Initialise the LED port. */ + vParTestInitialise(); + + /* The Xilinx projects use a BSP that do not allow the start up code to be + altered easily. Therefore the vector table used by FreeRTOS is defined in + FreeRTOS_asm_vectors.S, which is part of this project. Switch to use the + FreeRTOS vector table. */ + vPortInstallFreeRTOSVectorTable(); +} +/*-----------------------------------------------------------*/ + +void vApplicationMallocFailedHook( void ) +{ + /* Called if a call to pvPortMalloc() fails because there is insufficient + free memory available in the FreeRTOS heap. pvPortMalloc() is called + internally by FreeRTOS API functions that create tasks, queues, software + timers, and semaphores. The size of the FreeRTOS heap is set by the + configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ + taskDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) +{ + ( void ) pcTaskName; + ( void ) pxTask; + + /* Run time stack overflow checking is performed if + configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook + function is called if a stack overflow is detected. */ + taskDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ +volatile size_t xFreeHeapSpace, xMinimumEverFreeHeapSpace; + + /* This is just a trivial example of an idle hook. It is called on each + cycle of the idle task. It must *NOT* attempt to block. In this case the + idle task just queries the amount of FreeRTOS heap that remains. See the + memory management section on the http://www.FreeRTOS.org web site for memory + management options. If there is a lot of heap memory free then the + configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up + RAM. */ + xFreeHeapSpace = xPortGetFreeHeapSize(); + xMinimumEverFreeHeapSpace = xPortGetMinimumEverFreeHeapSize(); + + /* Remove compiler warning about xFreeHeapSpace being set but never used. */ + ( void ) xFreeHeapSpace; + ( void ) xMinimumEverFreeHeapSpace; +} +/*-----------------------------------------------------------*/ + +void vAssertCalled( const char * pcFile, unsigned long ulLine ) +{ +volatile unsigned long ul = 0; + + ( void ) pcFile; + ( void ) ulLine; + + taskENTER_CRITICAL(); + { + /* Set ul to a non-zero value using the debugger to step out of this + function. */ + while( ul == 0 ) + { + portNOP(); + } + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +void vApplicationTickHook( void ) +{ + #if( mainSELECTED_APPLICATION == 1 ) + { + /* The full demo includes a software timer demo/test that requires + prodding periodically from the tick interrupt. */ + vTimerPeriodicISRTests(); + + /* Call the periodic queue overwrite from ISR demo. */ + vQueueOverwritePeriodicISRDemo(); + + /* Call the periodic event group from ISR demo. */ + vPeriodicEventGroupsProcessing(); + + /* Use task notifications from an interrupt. */ + xNotifyTaskFromISR(); + + /* Use mutexes from interrupts. */ + vInterruptSemaphorePeriodicTest(); + } + #endif +} +/*-----------------------------------------------------------*/ + +void *memcpy( void *pvDest, const void *pvSource, size_t xBytes ) +{ +/* The compiler used during development seems to err unless these volatiles are +included at -O3 optimisation. */ +volatile unsigned char *pcDest = ( volatile unsigned char * ) pvDest, *pcSource = ( volatile unsigned char * ) pvSource; +size_t x; + + /* Extremely crude standard library implementations in lieu of having a C + library. */ + if( pvDest != pvSource ) + { + for( x = 0; x < xBytes; x++ ) + { + pcDest[ x ] = pcSource[ x ]; + } + } + + return pvDest; +} +/*-----------------------------------------------------------*/ + +void *memset( void *pvDest, int iValue, size_t xBytes ) +{ +/* The compiler used during development seems to err unless these volatiles are +included at -O3 optimisation. */ +volatile unsigned char * volatile pcDest = ( volatile unsigned char * volatile ) pvDest; +volatile size_t x; + + /* Extremely crude standard library implementations in lieu of having a C + library. */ + for( x = 0; x < xBytes; x++ ) + { + pcDest[ x ] = ( unsigned char ) iValue; + } + + return pvDest; +} +/*-----------------------------------------------------------*/ + +int memcmp( const void *pvMem1, const void *pvMem2, size_t xBytes ) +{ +const volatile unsigned char *pucMem1 = pvMem1, *pucMem2 = pvMem2; +volatile size_t x; + + /* Extremely crude standard library implementations in lieu of having a C + library. */ + for( x = 0; x < xBytes; x++ ) + { + if( pucMem1[ x ] != pucMem2[ x ] ) + { + break; + } + } + + return xBytes - x; +} +/*-----------------------------------------------------------*/ + +void vInitialiseTimerForRunTimeStats( void ) +{ +XScuWdt_Config *pxWatchDogInstance; +uint32_t ulValue; +const uint32_t ulMaxDivisor = 0xff, ulDivisorShift = 0x08; + + pxWatchDogInstance = XScuWdt_LookupConfig( XPAR_SCUWDT_0_DEVICE_ID ); + XScuWdt_CfgInitialize( &xWatchDogInstance, pxWatchDogInstance, pxWatchDogInstance->BaseAddr ); + + ulValue = XScuWdt_GetControlReg( &xWatchDogInstance ); + ulValue |= ulMaxDivisor << ulDivisorShift; + XScuWdt_SetControlReg( &xWatchDogInstance, ulValue ); + + XScuWdt_LoadWdt( &xWatchDogInstance, UINT_MAX ); + XScuWdt_SetTimerMode( &xWatchDogInstance ); + XScuWdt_Start( &xWatchDogInstance ); +} +/*-----------------------------------------------------------*/ + +/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an +implementation of vApplicationGetIdleTaskMemory() to provide the memory that is +used by the Idle task. */ +void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) +{ +/* If the buffers to be provided to the Idle task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ +static StaticTask_t xIdleTaskTCB; +static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} +/*-----------------------------------------------------------*/ + +/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the +application must provide an implementation of vApplicationGetTimerTaskMemory() +to provide the memory that is used by the Timer service task. */ +void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) +{ +/* If the buffers to be provided to the Timer task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ +static StaticTask_t xTimerTaskTCB; +static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} + +