From: rtel Date: Mon, 3 Feb 2014 17:39:45 +0000 (+0000) Subject: Finish the Zynq demo. X-Git-Tag: V8.0.0~30 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6918563766d74d4739c41212dcb3c04f423b6693;p=freertos Finish the Zynq demo. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2188 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.cproject b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.cproject index bf4326f6c..3b5e4b445 100644 --- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.cproject +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.cproject @@ -32,8 +32,9 @@ diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.project b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.project index 4431c9a66..dc088d707 100644 --- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.project +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.project @@ -25,40 +25,58 @@ - src/FreeRTOS-Plus-CLI + src/FreeRTOS_Source 2 - FREERTOS_ROOT/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI + FREERTOS_ROOT/FreeRTOS/Source - src/FreeRTOS_Source + src/Full_Demo/FreeRTOS-Plus-CLI 2 - FREERTOS_ROOT/FreeRTOS/Source + FREERTOS_ROOT/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI - src/Sample-CLI-commands.c + src/Full_Demo/Sample-CLI-commands.c 1 FREERTOS_ROOT/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c - src/Standard_Demo_Tasks + src/Full_Demo/Standard_Demo_Tasks 2 FREERTOS_ROOT/FreeRTOS/Demo/Common - src/UARTCommandConsole.c + src/Full_Demo/UARTCommandConsole.c 1 FREERTOS_ROOT/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c - src/Standard_Demo_Tasks/IntQueue.c + src/Full_Demo/Standard_Demo_Tasks/IntQueue.c 1 FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal/IntQueue.c - 1390227891704 - src/Standard_Demo_Tasks + 1390074074500 + src/FreeRTOS_Source/portable + 9 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-MemMang + + + + 1390074074500 + src/FreeRTOS_Source/portable + 9 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-GCC + + + + 0 + src/Full_Demo/Standard_Demo_Tasks 9 org.eclipse.ui.ide.multiFilter @@ -66,8 +84,8 @@ - 1390227891720 - src/Standard_Demo_Tasks + 0 + src/Full_Demo/Standard_Demo_Tasks 9 org.eclipse.ui.ide.multiFilter @@ -75,26 +93,26 @@ - 1390074074500 - src/FreeRTOS_Source/portable + 1390074123406 + src/FreeRTOS_Source/portable/GCC 9 org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-MemMang + 1.0-name-matches-false-false-ARM_CA9 - 1390074074500 - src/FreeRTOS_Source/portable - 9 + 1390074099015 + src/FreeRTOS_Source/portable/MemMang + 5 org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-GCC + 1.0-name-matches-false-false-heap_4.c - 1390228639904 - src/Standard_Demo_Tasks/Minimal + 0 + src/Full_Demo/Standard_Demo_Tasks/Minimal 6 org.eclipse.ui.ide.multiFilter @@ -102,8 +120,8 @@ - 1390228639904 - src/Standard_Demo_Tasks/Minimal + 0 + src/Full_Demo/Standard_Demo_Tasks/Minimal 6 org.eclipse.ui.ide.multiFilter @@ -111,8 +129,8 @@ - 1390228639904 - src/Standard_Demo_Tasks/Minimal + 0 + src/Full_Demo/Standard_Demo_Tasks/Minimal 6 org.eclipse.ui.ide.multiFilter @@ -120,8 +138,8 @@ - 1390228639904 - src/Standard_Demo_Tasks/Minimal + 0 + src/Full_Demo/Standard_Demo_Tasks/Minimal 6 org.eclipse.ui.ide.multiFilter @@ -129,8 +147,8 @@ - 1390228639904 - src/Standard_Demo_Tasks/Minimal + 0 + src/Full_Demo/Standard_Demo_Tasks/Minimal 6 org.eclipse.ui.ide.multiFilter @@ -138,30 +156,21 @@ - 1390227918703 - src/Standard_Demo_Tasks/include + 0 + src/Full_Demo/Standard_Demo_Tasks/Minimal 6 org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-alt*.* + 1.0-name-matches-false-false-copy*.* - 1390074123406 - src/FreeRTOS_Source/portable/GCC - 9 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-ARM_CA9 - - - - 1390074099015 - src/FreeRTOS_Source/portable/MemMang - 5 + 0 + src/Full_Demo/Standard_Demo_Tasks/include + 6 org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-heap_4.c + 1.0-name-matches-false-false-alt*.* diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Blinky_Demo/main_blinky.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Blinky_Demo/main_blinky.c new file mode 100644 index 000000000..4837cbc47 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Blinky_Demo/main_blinky.c @@ -0,0 +1,232 @@ +/* + FreeRTOS V8.0.0:rc2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + 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 from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + 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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and 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! +*/ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky style + * project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the simply blinky style version. + * + * NOTE 2: This file only contains the source code that is specific to the + * basic demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware are defined in main.c. + ****************************************************************************** + * + * main_blinky() creates one queue, and two tasks. It then starts the + * scheduler. + * + * The Queue Send Task: + * The queue send task is implemented by the prvQueueSendTask() function in + * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly + * block for 200 milliseconds, before sending the value 100 to the queue that + * was created within main_blinky(). Once the value is sent, the task loops + * back around to block for another 200 milliseconds...and so on. + * + * The Queue Receive Task: + * The queue receive task is implemented by the prvQueueReceiveTask() function + * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly + * blocks on attempts to read data from the queue that was created within + * main_blinky(). When data is received, the task checks the value of the + * data, and if the value equals the expected 100, toggles an LED. The 'block + * time' parameter passed to the queue receive function specifies that the + * task should be held in the Blocked state indefinitely to wait for data to + * be available on the queue. The queue receive task will only leave the + * Blocked state when the queue send task writes to the queue. As the queue + * send task writes to the queue every 200 milliseconds, the queue receive + * task leaves the Blocked state every 200 milliseconds, and therefore toggles + * the LED every 200 milliseconds. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Standard demo includes. */ +#include "partest.h" + +/* Priorities at which the tasks are created. */ +#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* The rate at which data is sent to the queue. The 200ms value is converted +to ticks using the portTICK_RATE_MS constant. */ +#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_RATE_MS ) + +/* The number of items the queue can hold. This is 1 as the receive task +will remove items as they are added, meaning the send task should always find +the queue empty. */ +#define mainQUEUE_LENGTH ( 1 ) + +/* The LED toggled by the Rx task. */ +#define mainTASK_LED ( 0 ) + +/*-----------------------------------------------------------*/ + +/* + * The tasks as described in the comments at the top of this file. + */ +static void prvQueueReceiveTask( void *pvParameters ); +static void prvQueueSendTask( void *pvParameters ); + +/* + * Called by main() to create the simply blinky style application if + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. + */ +void main_blinky( void ); + +/*-----------------------------------------------------------*/ + +/* The queue used by both tasks. */ +static xQueueHandle xQueue = NULL; + +/*-----------------------------------------------------------*/ + +void main_blinky( void ) +{ + /* Create the queue. */ + xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) ); + + if( xQueue != NULL ) + { + /* Start the two tasks as described in the comments at the top of this + file. */ + xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ + "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ + configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ + NULL, /* The parameter passed to the task - not used in this case. */ + mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ + NULL ); /* The task handle is not required, so NULL is passed. */ + + xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); + + /* Start the tasks and timer running. */ + vTaskStartScheduler(); + } + + /* If all is well, the scheduler will now be running, and the following + line will never be reached. If the following line does execute, then + there was either insufficient FreeRTOS heap memory available for the idle + and/or timer tasks to be created, or vTaskStartScheduler() was called from + User mode. See the memory management section on the FreeRTOS web site for + more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The + mode from which main() is called is set in the C start up code and must be + a privileged mode (not user mode). */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +static void prvQueueSendTask( void *pvParameters ) +{ +portTickType xNextWakeTime; +const unsigned long ulValueToSend = 100UL; + + /* Remove compiler warning about unused parameter. */ + ( void ) pvParameters; + + /* Initialise xNextWakeTime - this only needs to be done once. */ + xNextWakeTime = xTaskGetTickCount(); + + for( ;; ) + { + /* Place this task in the blocked state until it is time to run again. */ + vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); + + /* Send to the queue - causing the queue receive task to unblock and + toggle the LED. 0 is used as the block time so the sending operation + will not block - it shouldn't need to block as the queue should always + be empty at this point in the code. */ + xQueueSend( xQueue, &ulValueToSend, 0U ); + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueReceiveTask( void *pvParameters ) +{ +unsigned long ulReceivedValue; +const unsigned long ulExpectedValue = 100UL; + + /* Remove compiler warning about unused parameter. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Wait until something arrives in the queue - this task will block + indefinitely provided INCLUDE_vTaskSuspend is set to 1 in + FreeRTOSConfig.h. */ + xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); + + /* To get here something must have been received from the queue, but + is it the expected value? If it is, toggle the LED. */ + if( ulReceivedValue == ulExpectedValue ) + { + vParTestToggleLED( mainTASK_LED ); + ulReceivedValue = 0U; + } + } +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOSConfig.h index 9130dc805..b37a4e40f 100644 --- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOSConfig.h @@ -115,7 +115,7 @@ #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 1 -#define configMAX_PRIORITIES ( 5 ) +#define configMAX_PRIORITIES ( 7 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 160 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 51200 ) ) #define configMAX_TASK_NAME_LEN ( 10 ) @@ -151,7 +151,7 @@ to exclude the API function. */ #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_eTaskGetState 1 -#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTimerPendFunctionCall 1 /* This demo makes use of one or more example stats formatting functions. These format the raw data provided by the uxTaskGetSystemState() function in to human diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOS_tick_config.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOS_tick_config.c index 0134d31d7..fb2796f19 100644 --- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOS_tick_config.c +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOS_tick_config.c @@ -150,11 +150,12 @@ const XScuGic_VectorTableEntry *pxVectorEntry; /* The ID of the interrupt is obtained by bitwise anding the ICCIAR value with 0x3FF. */ ulInterruptID = ulICCIAR & 0x3FFUL; - configASSERT( ulInterruptID < XSCUGIC_MAX_NUM_INTR_INPUTS ); - - /* Call the function installed in the array of installed handler functions. */ - pxVectorEntry = &( pxVectorTable[ ulInterruptID ] ); - pxVectorEntry->Handler( pxVectorEntry->CallBackRef ); + if( ulInterruptID < XSCUGIC_MAX_NUM_INTR_INPUTS ) + { + /* Call the function installed in the array of installed handler functions. */ + pxVectorEntry = &( pxVectorTable[ ulInterruptID ] ); + pxVectorEntry->Handler( pxVectorEntry->CallBackRef ); + } } diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/IntQueueTimer.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/IntQueueTimer.c new file mode 100644 index 000000000..d41e7f1d7 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/IntQueueTimer.c @@ -0,0 +1,262 @@ +/* + FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + 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 from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + 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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and 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! +*/ + +/* + * This file initialises three timers as follows: + * + * Timer 0 and Timer 1 provide the interrupts that are used with the IntQ + * standard demo tasks, which test interrupt nesting and using queues from + * interrupts. Both these interrupts operate below the maximum syscall + * interrupt priority. + * + * Timer 2 is a much higher frequency timer that tests the nesting of interrupts + * that execute above the maximum syscall interrupt priority. + * + * All the timers can nest with the tick interrupt - creating a maximum + * interrupt nesting depth of 4. + * + * For convenience, the high frequency timer is also used to provide the time + * base for the run time stats. + */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" + +/* Demo includes. */ +#include "IntQueueTimer.h" +#include "IntQueue.h" + +/* Xilinx includes. */ +#include "xttcps.h" +#include "xscugic.h" + +/* The frequencies at which the first two timers expire are slightly offset to +ensure they don't remain synchronised. The frequency of the interrupt that +operates above the max syscall interrupt priority is 10 times faster so really +hammers the interrupt entry and exit code. */ +#define tmrTIMERS_USED 3 +#define tmrTIMER_0_FREQUENCY ( 2000UL ) +#define tmrTIMER_1_FREQUENCY ( 2001UL ) +#define tmrTIMER_2_FREQUENCY ( 20000UL ) + +/*-----------------------------------------------------------*/ + +/* + * The single interrupt service routines that is used to service all three + * timers. + */ +static void prvTimerHandler( void *CallBackRef ); + +/*-----------------------------------------------------------*/ + +/* Hardware constants. */ +static const BaseType_t xDeviceIDs[ tmrTIMERS_USED ] = { XPAR_XTTCPS_0_DEVICE_ID, XPAR_XTTCPS_1_DEVICE_ID, XPAR_XTTCPS_2_DEVICE_ID }; +static const BaseType_t xInterruptIDs[ tmrTIMERS_USED ] = { XPAR_XTTCPS_0_INTR, XPAR_XTTCPS_1_INTR, XPAR_XTTCPS_2_INTR }; + +/* Timer configuration settings. */ +typedef struct +{ + uint32_t OutputHz; /* Output frequency. */ + uint16_t Interval; /* Interval value. */ + uint8_t Prescaler; /* Prescaler value. */ + uint16_t Options; /* Option settings. */ +} TmrCntrSetup; + +static TmrCntrSetup xTimerSettings[ tmrTIMERS_USED ] = +{ + { tmrTIMER_0_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE }, + { tmrTIMER_1_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE }, + { tmrTIMER_2_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE } +}; + +/* Lower priority number means higher logical priority, so +configMAX_API_CALL_INTERRUPT_PRIORITY - 1 is above the maximum system call +interrupt priority. */ +static const UBaseType_t uxInterruptPriorities[ tmrTIMERS_USED ] = +{ + configMAX_API_CALL_INTERRUPT_PRIORITY + 1, + configMAX_API_CALL_INTERRUPT_PRIORITY, + configMAX_API_CALL_INTERRUPT_PRIORITY - 1 +}; + +static XTtcPs xTimerInstances[ tmrTIMERS_USED ]; + +/* Used to provide a means of ensuring the intended interrupt nesting depth is +actually being reached. */ +extern uint32_t ulPortInterruptNesting; +static uint32_t ulMaxRecordedNesting = 0; + +/* For convenience the high frequency timer increments a variable that is then +used as the time base for the run time stats. */ +volatile uint32_t ulHighFrequencyTimerCounts = 0; + +/*-----------------------------------------------------------*/ + +void vInitialiseTimerForIntQueueTest( void ) +{ +BaseType_t xStatus; +TmrCntrSetup *pxTimerSettings; +extern XScuGic xInterruptController; +BaseType_t xTimer; +XTtcPs *pxTimerInstance; +XTtcPs_Config *pxTimerConfiguration; +const uint8_t ucRisingEdge = 3; + + for( xTimer = 0; xTimer < tmrTIMERS_USED; xTimer++ ) + { + /* Look up the timer's configuration. */ + pxTimerInstance = &( xTimerInstances[ xTimer ] ); + pxTimerConfiguration = XTtcPs_LookupConfig( xDeviceIDs[ xTimer ] ); + configASSERT( pxTimerConfiguration ); + + pxTimerSettings = &( xTimerSettings[ xTimer ] ); + + /* Initialise the device. */ + xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress ); + if( xStatus != XST_SUCCESS ) + { + /* Not sure how to do this before XTtcPs_CfgInitialize is called + as pxTimerInstance is set within XTtcPs_CfgInitialize(). */ + XTtcPs_Stop( pxTimerInstance ); + xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress ); + configASSERT( xStatus == XST_SUCCESS ); + } + + /* Set the options. */ + XTtcPs_SetOptions( pxTimerInstance, pxTimerSettings->Options ); + + /* The timer frequency is preset in the pxTimerSettings structure. + Derive the values for the other structure members. */ + XTtcPs_CalcIntervalFromFreq( pxTimerInstance, pxTimerSettings->OutputHz, &( pxTimerSettings->Interval ), &( pxTimerSettings->Prescaler ) ); + + /* Set the interval and prescale. */ + XTtcPs_SetInterval( pxTimerInstance, pxTimerSettings->Interval ); + XTtcPs_SetPrescaler( pxTimerInstance, pxTimerSettings->Prescaler ); + + /* The priority must be the lowest possible. */ + XScuGic_SetPriorityTriggerType( &xInterruptController, xInterruptIDs[ xTimer ], uxInterruptPriorities[ xTimer ] << portPRIORITY_SHIFT, ucRisingEdge ); + + /* Connect to the interrupt controller. */ + xStatus = XScuGic_Connect( &xInterruptController, xInterruptIDs[ xTimer ], ( Xil_InterruptHandler ) prvTimerHandler, ( void * ) pxTimerInstance ); + configASSERT( xStatus == XST_SUCCESS); + + /* Enable the interrupt in the GIC. */ + XScuGic_Enable( &xInterruptController, xInterruptIDs[ xTimer ] ); + + /* Enable the interrupts in the timer. */ + XTtcPs_EnableInterrupts( pxTimerInstance, XTTCPS_IXR_INTERVAL_MASK ); + + /* Start the timer. */ + XTtcPs_Start( pxTimerInstance ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTimerHandler( void *pvCallBackRef ) +{ +uint32_t ulInterruptStatus; +XTtcPs *pxTimer = ( XTtcPs * ) pvCallBackRef; +BaseType_t xYieldRequired; + + /* Read the interrupt status, then write it back to clear the interrupt. */ + ulInterruptStatus = XTtcPs_GetInterruptStatus( pxTimer ); + XTtcPs_ClearInterruptStatus( pxTimer, ulInterruptStatus ); + + /* Only one interrupt event type is expected. */ + configASSERT( ( XTTCPS_IXR_INTERVAL_MASK & ulInterruptStatus ) != 0 ); + + /* Check the device ID to know which IntQueue demo to call. */ + if( pxTimer->Config.DeviceId == xDeviceIDs[ 0 ] ) + { + xYieldRequired = xFirstTimerHandler(); + } + else if( pxTimer->Config.DeviceId == xDeviceIDs[ 1 ] ) + { + xYieldRequired = xSecondTimerHandler(); + } + else + { + /* The high frequency timer is also used to generate the time base for + the run time state. */ + ulHighFrequencyTimerCounts++; + + /* Latch the highest interrupt nesting count detected. */ + if( ulPortInterruptNesting > ulMaxRecordedNesting ) + { + ulMaxRecordedNesting = ulPortInterruptNesting; + } + + xYieldRequired = pdFALSE; + } + + /* If xYieldRequired is not pdFALSE then calling either xFirstTimerHandler() + or xSecondTimerHandler() resulted in a task leaving the blocked state and + the task that left the blocked state had a priority higher than the currently + running task (the task this interrupt interrupted) - so a context switch + should be performed so the interrupt returns directly to the higher priority + task. xYieldRequired is tested inside the following macro. */ + portYIELD_FROM_ISR( xYieldRequired ); +} + diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/IntQueueTimer.h b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/IntQueueTimer.h new file mode 100644 index 000000000..874334606 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/IntQueueTimer.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + 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 from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + 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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and 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! +*/ + +#ifndef INT_QUEUE_TIMER_H +#define INT_QUEUE_TIMER_H + +void vInitialiseTimerForIntQueueTest( void ); +portBASE_TYPE xTimer0Handler( void ); +portBASE_TYPE xTimer1Handler( void ); + +#endif + diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/main_full.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/main_full.c new file mode 100644 index 000000000..18e359506 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/main_full.c @@ -0,0 +1,448 @@ +/* + FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + 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 from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + 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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and 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! +*/ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky style + * project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the comprehensive test and demo version. + * + * NOTE 2: This file only contains the source code that is specific to the + * full demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware, are defined in main.c. + * + * NOTE 3: The full demo includes a test that checks the floating point context + * is maintained correctly across task switches. The standard GCC libraries can + * use floating point registers and made this test fail (unless the tasks that + * use the library are given a floating point context as described on the + * documentation page for this demo). printf-stdarg.c is included in this + * project to prevent the standard GCC libraries being linked into the project. + * + ****************************************************************************** + * + * main_full() creates all the demo application tasks and software timers, then + * starts the scheduler. The web documentation provides more details of the + * standard demo application tasks, which provide no particular functionality, + * but do provide a good example of how to use the FreeRTOS API. + * + * In addition to the standard demo tasks, the following tasks and tests are + * defined and/or created within this file: + * + * FreeRTOS+CLI command console. The command console is access through the + * UART to USB connector on the ZC702 Zynq development board (marked J2). For + * reasons of robustness testing the UART driver is deliberately written to be + * inefficient and should not be used as a template for a production driver. + * Type "help" to see a list of registered commands. The FreeRTOS+CLI license + * is different to the FreeRTOS license, see http://www.FreeRTOS.org/cli for + * license and usage details. The default baud rate is 115200. + * + * "Reg test" tasks - These fill both the core and floating point registers with + * known values, then check that each register maintains its expected value for + * the lifetime of the task. Each task uses a different set of values. The reg + * test tasks execute with a very low priority, so get preempted very + * frequently. A register containing an unexpected value is indicative of an + * error in the context switching mechanism. + * + * "Check" task - The check task period is initially set to three seconds. The + * task checks that all the standard demo tasks, and the register check tasks, + * are not only still executing, but are executing without reporting any errors. + * If the check task discovers that a task has either stalled, or reported an + * error, then it changes its own execution period from the initial three + * seconds, to just 200ms. The check task also toggles an LED each time it is + * called. This provides a visual indication of the system status: If the LED + * toggles every three seconds, then no issues have been discovered. If the LED + * toggles every 200ms, then an issue has been discovered with at least one + * task. + */ + +/* Standard includes. */ +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "semphr.h" + +/* Standard demo application includes. */ +#include "flop.h" +#include "semtest.h" +#include "dynamic.h" +#include "BlockQ.h" +#include "blocktim.h" +#include "countsem.h" +#include "GenQTest.h" +#include "recmutex.h" +#include "death.h" +#include "partest.h" +#include "comtest2.h" +#include "serial.h" +#include "TimerDemo.h" +#include "QueueOverwrite.h" +#include "IntQueue.h" + +/* Priorities for the demo application tasks. */ +#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL ) +#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL ) +#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL ) +#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY ) +#define mainUART_COMMAND_CONSOLE_STACK_SIZE ( configMINIMAL_STACK_SIZE * 3UL ) +#define mainCOM_TEST_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY ) + +/* The priority used by the UART command console task. */ +#define mainUART_COMMAND_CONSOLE_TASK_PRIORITY ( configMAX_PRIORITIES - 2 ) + +/* The LED used by the check timer. */ +#define mainCHECK_LED ( 0 ) + +/* A block time of zero simply means "don't block". */ +#define mainDONT_BLOCK ( 0UL ) + +/* The period after which the check timer will expire, in ms, provided no errors +have been reported by any of the standard demo tasks. ms are converted to the +equivalent in ticks using the portTICK_PERIOD_MS constant. */ +#define mainNO_ERROR_CHECK_TASK_PERIOD ( 3000UL / portTICK_PERIOD_MS ) + +/* The period at which the check timer will expire, in ms, if an error has been +reported in one of the standard demo tasks. ms are converted to the equivalent +in ticks using the portTICK_PERIOD_MS constant. */ +#define mainERROR_CHECK_TASK_PERIOD ( 200UL / portTICK_PERIOD_MS ) + +/* Parameters that are passed into the register check tasks solely for the +purpose of ensuring parameters are passed into tasks correctly. */ +#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 ) +#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 ) + +/* The base period used by the timer test tasks. */ +#define mainTIMER_TEST_PERIOD ( 50 ) + +/*-----------------------------------------------------------*/ + +/* + * Called by main() to run the full demo (as opposed to the blinky demo) when + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. + */ +void main_full( void ); + +/* + * The check task, as described at the top of this file. + */ +static void prvCheckTask( void *pvParameters ); + +/* + * Register check tasks, and the tasks used to write over and check the contents + * of the FPU registers, as described at the top of this file. The nature of + * these files necessitates that they are written in an assembly file, but the + * entry points are kept in the C file for the convenience of checking the task + * parameter. + */ +static void prvRegTestTaskEntry1( void *pvParameters ); +extern void vRegTest1Implementation( void ); +static void prvRegTestTaskEntry2( void *pvParameters ); +extern void vRegTest2Implementation( void ); + +/* + * Register commands that can be used with FreeRTOS+CLI. The commands are + * defined in CLI-Commands.c and File-Related-CLI-Command.c respectively. + */ +extern void vRegisterSampleCLICommands( void ); + +/* + * The task that manages the FreeRTOS+CLI input and output. + */ +extern void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriority ); + +/*-----------------------------------------------------------*/ + +/* The following two variables are used to communicate the status of the +register check tasks to the check task. If the variables keep incrementing, +then the register check tasks has not discovered any errors. If a variable +stops incrementing, then an error has been found. */ +volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; + +/*-----------------------------------------------------------*/ + +void main_full( void ) +{ + /* Start all the other standard demo/test tasks. They have not particular + functionality, but do demonstrate how to use the FreeRTOS API and test the + kernel port. */ + vStartInterruptQueueTasks(); + vStartDynamicPriorityTasks(); + vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); + vCreateBlockTimeTasks(); + vStartCountingSemaphoreTasks(); + vStartGenericQueueTasks( tskIDLE_PRIORITY ); + vStartRecursiveMutexTasks(); + vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); + vStartMathTasks( mainFLOP_TASK_PRIORITY ); + vStartTimerDemoTask( mainTIMER_TEST_PERIOD ); + vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY ); + + /* Start the tasks that implements the command console on the UART, as + described above. */ + vUARTCommandConsoleStart( mainUART_COMMAND_CONSOLE_STACK_SIZE, mainUART_COMMAND_CONSOLE_TASK_PRIORITY ); + + /* Register the standard CLI commands. */ + vRegisterSampleCLICommands(); + + /* Create the register check tasks, as described at the top of this file */ + xTaskCreate( prvRegTestTaskEntry1, "Reg1", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_1_PARAMETER, tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvRegTestTaskEntry2, "Reg2", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL ); + + /* Create the task that performs the 'check' functionality, as described at + the top of this file. */ + xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); + + /* The set of tasks created by the following function call have to be + created last as they keep account of the number of tasks they expect to see + running. */ + vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); + + /* Start the scheduler. */ + vTaskStartScheduler(); + + /* If all is well, the scheduler will now be running, and the following + line will never be reached. If the following line does execute, then + there was either insufficient FreeRTOS heap memory available for the idle + and/or timer tasks to be created, or vTaskStartScheduler() was called from + User mode. See the memory management section on the FreeRTOS web site for + more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The + mode from which main() is called is set in the C start up code and must be + a privileged mode (not user mode). */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +static void prvCheckTask( void *pvParameters ) +{ +portTickType xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD; +portTickType xLastExecutionTime; +static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; +unsigned long ulErrorFound = pdFALSE; + + /* Just to stop compiler warnings. */ + ( void ) pvParameters; + + /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() + works correctly. */ + xLastExecutionTime = xTaskGetTickCount(); + + /* Cycle for ever, delaying then checking all the other tasks are still + operating without error. The onboard LED is toggled on each iteration. + If an error is detected then the delay period is decreased from + mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the + effect of increasing the rate at which the onboard LED toggles, and in so + doing gives visual feedback of the system status. */ + for( ;; ) + { + /* Delay until it is time to execute again. */ + vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod ); + + /* Check all the demo tasks (other than the flash tasks) to ensure + that they are all still running, and that none have detected an error. */ + if( xAreIntQueueTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xAreMathsTaskStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xAreBlockingQueuesStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xIsCreateTaskStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xAreSemaphoreTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xAreTimerDemoTasksStillRunning( ( portTickType ) mainNO_ERROR_CHECK_TASK_PERIOD ) != pdPASS ) + { + ulErrorFound = pdTRUE; + } + + if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xIsQueueOverwriteTaskStillRunning() != pdPASS ) + { + ulErrorFound = pdTRUE; + } + + /* Check that the register test 1 task is still running. */ + if( ulLastRegTest1Value == ulRegTest1LoopCounter ) + { + ulErrorFound = pdTRUE; + } + ulLastRegTest1Value = ulRegTest1LoopCounter; + + /* Check that the register test 2 task is still running. */ + if( ulLastRegTest2Value == ulRegTest2LoopCounter ) + { + ulErrorFound = pdTRUE; + } + ulLastRegTest2Value = ulRegTest2LoopCounter; + + /* Toggle the check LED to give an indication of the system status. If + the LED toggles every mainNO_ERROR_CHECK_TASK_PERIOD milliseconds then + everything is ok. A faster toggle indicates an error. */ + vParTestToggleLED( mainCHECK_LED ); + + if( ulErrorFound != pdFALSE ) + { + /* An error has been detected in one of the tasks - flash the LED + at a higher frequency to give visible feedback that something has + gone wrong (it might just be that the loop back connector required + by the comtest tasks has not been fitted). */ + xDelayPeriod = mainERROR_CHECK_TASK_PERIOD; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvRegTestTaskEntry1( void *pvParameters ) +{ + /* Although the regtest task is written in assembler, its entry point is + written in C for convenience of checking the task parameter is being passed + in correctly. */ + if( pvParameters == mainREG_TEST_TASK_1_PARAMETER ) + { + /* The reg test task also tests the floating point registers. Tasks + that use the floating point unit must call vPortTaskUsesFPU() before + any floating point instructions are executed. */ + vPortTaskUsesFPU(); + + /* Start the part of the test that is written in assembler. */ + vRegTest1Implementation(); + } + + /* The following line will only execute if the task parameter is found to + be incorrect. The check timer will detect that the regtest loop counter is + not being incremented and flag an error. */ + vTaskDelete( NULL ); +} +/*-----------------------------------------------------------*/ + +static void prvRegTestTaskEntry2( void *pvParameters ) +{ + /* Although the regtest task is written in assembler, its entry point is + written in C for convenience of checking the task parameter is being passed + in correctly. */ + if( pvParameters == mainREG_TEST_TASK_2_PARAMETER ) + { + /* The reg test task also tests the floating point registers. Tasks + that use the floating point unit must call vPortTaskUsesFPU() before + any floating point instructions are executed. */ + vPortTaskUsesFPU(); + + /* Start the part of the test that is written in assembler. */ + vRegTest2Implementation(); + } + + /* The following line will only execute if the task parameter is found to + be incorrect. The check timer will detect that the regtest loop counter is + not being incremented and flag an error. */ + vTaskDelete( NULL ); +} +/*-----------------------------------------------------------*/ + + + + diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/reg_test.S b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/reg_test.S new file mode 100644 index 000000000..694113edc --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/reg_test.S @@ -0,0 +1,656 @@ +/* + FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd. + + FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT + http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + 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. See the GNU General Public License for more + details. You should have received a copy of the GNU General Public License + and the FreeRTOS license exception along with FreeRTOS; if not itcan be + viewed here: http://www.freertos.org/a00114.html and also obtained by + writing to Real Time Engineers Ltd., contact details for whom are available + on the FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, and our new + fully thread aware and reentrant UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems, who sell the code with commercial support, + indemnification and middleware, under the OpenRTOS brand. + + 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. +*/ + + .global vRegTest1Implementation + .global vRegTest2Implementation + .extern ulRegTest1LoopCounter + .extern ulRegTest2LoopCounter + + .text + .arm + + /* This function is explained in the comments at the top of main-full.c. */ +vRegTest1Implementation: + + /* Fill each general purpose register with a known value. */ + mov r0, #0xFF + mov r1, #0x11 + mov r2, #0x22 + mov r3, #0x33 + mov r4, #0x44 + mov r5, #0x55 + mov r6, #0x66 + mov r7, #0x77 + mov r8, #0x88 + mov r9, #0x99 + mov r10, #0xAA + mov r11, #0xBB + mov r12, #0xCC + mov r14, #0xEE + + /* Fill each FPU register with a known value. */ + vmov d0, r0, r1 + vmov d1, r2, r3 + vmov d2, r4, r5 + vmov d3, r6, r7 + vmov d4, r8, r9 + vmov d5, r10, r11 + vmov d6, r0, r1 + vmov d7, r2, r3 + vmov d8, r4, r5 + vmov d9, r6, r7 + vmov d10, r8, r9 + vmov d11, r10, r11 + vmov d12, r0, r1 + vmov d13, r2, r3 + vmov d14, r4, r5 + vmov d15, r6, r7 + + vmov d16, r0, r1 + vmov d17, r2, r3 + vmov d18, r4, r5 + vmov d19, r6, r7 + vmov d20, r8, r9 + vmov d21, r10, r11 + vmov d22, r0, r1 + vmov d23, r2, r3 + vmov d24, r4, r5 + vmov d25, r6, r7 + vmov d26, r8, r9 + vmov d27, r10, r11 + vmov d28, r0, r1 + vmov d29, r2, r3 + vmov d30, r4, r5 + vmov d31, r6, r7 + + /* Loop, checking each itteration that each register still contains the + expected value. */ +reg1_loop: + /* Yield to increase test coverage */ + svc 0 + + /* Check all the VFP registers still contain the values set above. + First save registers that are clobbered by the test. */ + push { r0-r1 } + + vmov r0, r1, d0 + cmp r0, #0xFF + bne reg1_error_loopf + cmp r1, #0x11 + bne reg1_error_loopf + vmov r0, r1, d1 + cmp r0, #0x22 + bne reg1_error_loopf + cmp r1, #0x33 + bne reg1_error_loopf + vmov r0, r1, d2 + cmp r0, #0x44 + bne reg1_error_loopf + cmp r1, #0x55 + bne reg1_error_loopf + vmov r0, r1, d3 + cmp r0, #0x66 + bne reg1_error_loopf + cmp r1, #0x77 + bne reg1_error_loopf + vmov r0, r1, d4 + cmp r0, #0x88 + bne reg1_error_loopf + cmp r1, #0x99 + bne reg1_error_loopf + vmov r0, r1, d5 + cmp r0, #0xAA + bne reg1_error_loopf + cmp r1, #0xBB + bne reg1_error_loopf + vmov r0, r1, d6 + cmp r0, #0xFF + bne reg1_error_loopf + cmp r1, #0x11 + bne reg1_error_loopf + vmov r0, r1, d7 + cmp r0, #0x22 + bne reg1_error_loopf + cmp r1, #0x33 + bne reg1_error_loopf + vmov r0, r1, d8 + cmp r0, #0x44 + bne reg1_error_loopf + cmp r1, #0x55 + bne reg1_error_loopf + vmov r0, r1, d9 + cmp r0, #0x66 + bne reg1_error_loopf + cmp r1, #0x77 + bne reg1_error_loopf + vmov r0, r1, d10 + cmp r0, #0x88 + bne reg1_error_loopf + cmp r1, #0x99 + bne reg1_error_loopf + vmov r0, r1, d11 + cmp r0, #0xAA + bne reg1_error_loopf + cmp r1, #0xBB + bne reg1_error_loopf + vmov r0, r1, d12 + cmp r0, #0xFF + bne reg1_error_loopf + cmp r1, #0x11 + bne reg1_error_loopf + vmov r0, r1, d13 + cmp r0, #0x22 + bne reg1_error_loopf + cmp r1, #0x33 + bne reg1_error_loopf + vmov r0, r1, d14 + cmp r0, #0x44 + bne reg1_error_loopf + cmp r1, #0x55 + bne reg1_error_loopf + vmov r0, r1, d15 + cmp r0, #0x66 + bne reg1_error_loopf + cmp r1, #0x77 + bne reg1_error_loopf + + vmov r0, r1, d16 + cmp r0, #0xFF + bne reg1_error_loopf + cmp r1, #0x11 + bne reg1_error_loopf + vmov r0, r1, d17 + cmp r0, #0x22 + bne reg1_error_loopf + cmp r1, #0x33 + bne reg1_error_loopf + vmov r0, r1, d18 + cmp r0, #0x44 + bne reg1_error_loopf + cmp r1, #0x55 + bne reg1_error_loopf + vmov r0, r1, d19 + cmp r0, #0x66 + bne reg1_error_loopf + cmp r1, #0x77 + bne reg1_error_loopf + vmov r0, r1, d20 + cmp r0, #0x88 + bne reg1_error_loopf + cmp r1, #0x99 + bne reg1_error_loopf + vmov r0, r1, d21 + cmp r0, #0xAA + bne reg1_error_loopf + cmp r1, #0xBB + bne reg1_error_loopf + vmov r0, r1, d22 + cmp r0, #0xFF + bne reg1_error_loopf + cmp r1, #0x11 + bne reg1_error_loopf + vmov r0, r1, d23 + cmp r0, #0x22 + bne reg1_error_loopf + cmp r1, #0x33 + bne reg1_error_loopf + vmov r0, r1, d24 + cmp r0, #0x44 + bne reg1_error_loopf + cmp r1, #0x55 + bne reg1_error_loopf + vmov r0, r1, d25 + cmp r0, #0x66 + bne reg1_error_loopf + cmp r1, #0x77 + bne reg1_error_loopf + vmov r0, r1, d26 + cmp r0, #0x88 + bne reg1_error_loopf + cmp r1, #0x99 + bne reg1_error_loopf + vmov r0, r1, d27 + cmp r0, #0xAA + bne reg1_error_loopf + cmp r1, #0xBB + bne reg1_error_loopf + vmov r0, r1, d28 + cmp r0, #0xFF + bne reg1_error_loopf + cmp r1, #0x11 + bne reg1_error_loopf + vmov r0, r1, d29 + cmp r0, #0x22 + bne reg1_error_loopf + cmp r1, #0x33 + bne reg1_error_loopf + vmov r0, r1, d30 + cmp r0, #0x44 + bne reg1_error_loopf + cmp r1, #0x55 + bne reg1_error_loopf + vmov r0, r1, d31 + cmp r0, #0x66 + bne reg1_error_loopf + cmp r1, #0x77 + bne reg1_error_loopf + + /* Restore the registers that were clobbered by the test. */ + pop {r0-r1} + + /* VFP register test passed. Jump to the core register test. */ + b reg1_loopf_pass + +reg1_error_loopf: + /* If this line is hit then a VFP register value was found to be + incorrect. */ + b reg1_error_loopf + +reg1_loopf_pass: + + /* Test each general purpose register to check that it still contains the + expected known value, jumping to reg1_error_loop if any register contains + an unexpected value. */ + cmp r0, #0xFF + bne reg1_error_loop + cmp r1, #0x11 + bne reg1_error_loop + cmp r2, #0x22 + bne reg1_error_loop + cmp r3, #0x33 + bne reg1_error_loop + cmp r4, #0x44 + bne reg1_error_loop + cmp r5, #0x55 + bne reg1_error_loop + cmp r6, #0x66 + bne reg1_error_loop + cmp r7, #0x77 + bne reg1_error_loop + cmp r8, #0x88 + bne reg1_error_loop + cmp r9, #0x99 + bne reg1_error_loop + cmp r10, #0xAA + bne reg1_error_loop + cmp r11, #0xBB + bne reg1_error_loop + cmp r12, #0xCC + bne reg1_error_loop + cmp r14, #0xEE + bne reg1_error_loop + + /* Everything passed, increment the loop counter. */ + push { r0-r1 } + ldr r0, =ulRegTest1LoopCounter + ldr r1, [r0] + adds r1, r1, #1 + str r1, [r0] + pop { r0-r1 } + + /* Start again. */ + b reg1_loop + +reg1_error_loop: + /* If this line is hit then there was an error in a core register value. + The loop ensures the loop counter stops incrementing. */ + b reg1_error_loop + nop + +/*-----------------------------------------------------------*/ + +vRegTest2Implementation: + + /* Put a known value in each register. */ + mov r0, #0xFF000000 + mov r1, #0x11000000 + mov r2, #0x22000000 + mov r3, #0x33000000 + mov r4, #0x44000000 + mov r5, #0x55000000 + mov r6, #0x66000000 + mov r7, #0x77000000 + mov r8, #0x88000000 + mov r9, #0x99000000 + mov r10, #0xAA000000 + mov r11, #0xBB000000 + mov r12, #0xCC000000 + mov r14, #0xEE000000 + + /* Likewise the floating point registers */ + vmov d0, r0, r1 + vmov d1, r2, r3 + vmov d2, r4, r5 + vmov d3, r6, r7 + vmov d4, r8, r9 + vmov d5, r10, r11 + vmov d6, r0, r1 + vmov d7, r2, r3 + vmov d8, r4, r5 + vmov d9, r6, r7 + vmov d10, r8, r9 + vmov d11, r10, r11 + vmov d12, r0, r1 + vmov d13, r2, r3 + vmov d14, r4, r5 + vmov d15, r6, r7 + + vmov d16, r0, r1 + vmov d17, r2, r3 + vmov d18, r4, r5 + vmov d19, r6, r7 + vmov d20, r8, r9 + vmov d21, r10, r11 + vmov d22, r0, r1 + vmov d23, r2, r3 + vmov d24, r4, r5 + vmov d25, r6, r7 + vmov d26, r8, r9 + vmov d27, r10, r11 + vmov d28, r0, r1 + vmov d29, r2, r3 + vmov d30, r4, r5 + vmov d31, r6, r7 + + /* Loop, checking each itteration that each register still contains the + expected value. */ +reg2_loop: + /* Check all the VFP registers still contain the values set above. + First save registers that are clobbered by the test. */ + push { r0-r1 } + + vmov r0, r1, d0 + cmp r0, #0xFF000000 + bne reg2_error_loopf + cmp r1, #0x11000000 + bne reg2_error_loopf + vmov r0, r1, d1 + cmp r0, #0x22000000 + bne reg2_error_loopf + cmp r1, #0x33000000 + bne reg2_error_loopf + vmov r0, r1, d2 + cmp r0, #0x44000000 + bne reg2_error_loopf + cmp r1, #0x55000000 + bne reg2_error_loopf + vmov r0, r1, d3 + cmp r0, #0x66000000 + bne reg2_error_loopf + cmp r1, #0x77000000 + bne reg2_error_loopf + vmov r0, r1, d4 + cmp r0, #0x88000000 + bne reg2_error_loopf + cmp r1, #0x99000000 + bne reg2_error_loopf + vmov r0, r1, d5 + cmp r0, #0xAA000000 + bne reg2_error_loopf + cmp r1, #0xBB000000 + bne reg2_error_loopf + vmov r0, r1, d6 + cmp r0, #0xFF000000 + bne reg2_error_loopf + cmp r1, #0x11000000 + bne reg2_error_loopf + vmov r0, r1, d7 + cmp r0, #0x22000000 + bne reg2_error_loopf + cmp r1, #0x33000000 + bne reg2_error_loopf + vmov r0, r1, d8 + cmp r0, #0x44000000 + bne reg2_error_loopf + cmp r1, #0x55000000 + bne reg2_error_loopf + vmov r0, r1, d9 + cmp r0, #0x66000000 + bne reg2_error_loopf + cmp r1, #0x77000000 + bne reg2_error_loopf + vmov r0, r1, d10 + cmp r0, #0x88000000 + bne reg2_error_loopf + cmp r1, #0x99000000 + bne reg2_error_loopf + vmov r0, r1, d11 + cmp r0, #0xAA000000 + bne reg2_error_loopf + cmp r1, #0xBB000000 + bne reg2_error_loopf + vmov r0, r1, d12 + cmp r0, #0xFF000000 + bne reg2_error_loopf + cmp r1, #0x11000000 + bne reg2_error_loopf + vmov r0, r1, d13 + cmp r0, #0x22000000 + bne reg2_error_loopf + cmp r1, #0x33000000 + bne reg2_error_loopf + vmov r0, r1, d14 + cmp r0, #0x44000000 + bne reg2_error_loopf + cmp r1, #0x55000000 + bne reg2_error_loopf + vmov r0, r1, d15 + cmp r0, #0x66000000 + bne reg2_error_loopf + cmp r1, #0x77000000 + bne reg2_error_loopf + + vmov r0, r1, d16 + cmp r0, #0xFF000000 + bne reg2_error_loopf + cmp r1, #0x11000000 + bne reg2_error_loopf + vmov r0, r1, d17 + cmp r0, #0x22000000 + bne reg2_error_loopf + cmp r1, #0x33000000 + bne reg2_error_loopf + vmov r0, r1, d18 + cmp r0, #0x44000000 + bne reg2_error_loopf + cmp r1, #0x55000000 + bne reg2_error_loopf + vmov r0, r1, d19 + cmp r0, #0x66000000 + bne reg2_error_loopf + cmp r1, #0x77000000 + bne reg2_error_loopf + vmov r0, r1, d20 + cmp r0, #0x88000000 + bne reg2_error_loopf + cmp r1, #0x99000000 + bne reg2_error_loopf + vmov r0, r1, d21 + cmp r0, #0xAA000000 + bne reg2_error_loopf + cmp r1, #0xBB000000 + bne reg2_error_loopf + vmov r0, r1, d22 + cmp r0, #0xFF000000 + bne reg2_error_loopf + cmp r1, #0x11000000 + bne reg2_error_loopf + vmov r0, r1, d23 + cmp r0, #0x22000000 + bne reg2_error_loopf + cmp r1, #0x33000000 + bne reg2_error_loopf + vmov r0, r1, d24 + cmp r0, #0x44000000 + bne reg2_error_loopf + cmp r1, #0x55000000 + bne reg2_error_loopf + vmov r0, r1, d25 + cmp r0, #0x66000000 + bne reg2_error_loopf + cmp r1, #0x77000000 + bne reg2_error_loopf + vmov r0, r1, d26 + cmp r0, #0x88000000 + bne reg2_error_loopf + cmp r1, #0x99000000 + bne reg2_error_loopf + vmov r0, r1, d27 + cmp r0, #0xAA000000 + bne reg2_error_loopf + cmp r1, #0xBB000000 + bne reg2_error_loopf + vmov r0, r1, d28 + cmp r0, #0xFF000000 + bne reg2_error_loopf + cmp r1, #0x11000000 + bne reg2_error_loopf + vmov r0, r1, d29 + cmp r0, #0x22000000 + bne reg2_error_loopf + cmp r1, #0x33000000 + bne reg2_error_loopf + vmov r0, r1, d30 + cmp r0, #0x44000000 + bne reg2_error_loopf + cmp r1, #0x55000000 + bne reg2_error_loopf + vmov r0, r1, d31 + cmp r0, #0x66000000 + bne reg2_error_loopf + cmp r1, #0x77000000 + bne reg2_error_loopf + + /* Restore the registers that were clobbered by the test. */ + pop {r0-r1} + + /* VFP register test passed. Jump to the core register test. */ + b reg2_loopf_pass + +reg2_error_loopf: + /* If this line is hit then a VFP register value was found to be + incorrect. */ + b reg2_error_loopf + +reg2_loopf_pass: + + cmp r0, #0xFF000000 + bne reg2_error_loop + cmp r1, #0x11000000 + bne reg2_error_loop + cmp r2, #0x22000000 + bne reg2_error_loop + cmp r3, #0x33000000 + bne reg2_error_loop + cmp r4, #0x44000000 + bne reg2_error_loop + cmp r5, #0x55000000 + bne reg2_error_loop + cmp r6, #0x66000000 + bne reg2_error_loop + cmp r7, #0x77000000 + bne reg2_error_loop + cmp r8, #0x88000000 + bne reg2_error_loop + cmp r9, #0x99000000 + bne reg2_error_loop + cmp r10, #0xAA000000 + bne reg2_error_loop + cmp r11, #0xBB000000 + bne reg2_error_loop + cmp r12, #0xCC000000 + bne reg2_error_loop + cmp r14, #0xEE000000 + bne reg2_error_loop + + /* Everything passed, increment the loop counter. */ + push { r0-r1 } + ldr r0, =ulRegTest2LoopCounter + ldr r1, [r0] + adds r1, r1, #1 + str r1, [r0] + pop { r0-r1 } + + /* Start again. */ + b reg2_loop + +reg2_error_loop: + /* If this line is hit then there was an error in a core register value. + The loop ensures the loop counter stops incrementing. */ + b reg2_error_loop + nop + + + .end + diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/serial.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/serial.c new file mode 100644 index 000000000..cf154578b --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/serial.c @@ -0,0 +1,316 @@ +/* + FreeRTOS V8.0.0:rc2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + 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 from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + 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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and 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! + */ + +/* + BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER. + + Note1: This driver is used specifically to provide an interface to the + FreeRTOS+CLI command interpreter. It is *not* intended to be a generic + serial port driver. Nor is it intended to be used as an example of an + efficient implementation. In particular, a queue is used to buffer + received characters, which is fine in this case as key presses arrive + slowly, but a DMA and/or RAM buffer should be used in place of the queue in + applications that expect higher throughput. + + Note2: This driver does not attempt to handle UART errors. +*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* Demo application includes. */ +#include "serial.h" + +/* Xilinx includes. */ +#include "xuartps.h" +#include "xscugic.h" +#include "xil_exception.h" + +/* The UART interrupts of interest when receiving. */ +#define serRECEIVE_INTERRUPT_MASK ( XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL | XUARTPS_IXR_TOUT ) + +/* The UART interrupts of interest when transmitting. */ +#define serTRANSMIT_IINTERRUPT_MASK ( XUARTPS_IXR_TXEMPTY ) + +/*-----------------------------------------------------------*/ + +/* The UART being used. */ +static XUartPs xUARTInstance; + +/* The interrupt controller, which is configred by the hardware setup routines +defined in main(). */ +extern XScuGic xInterruptController; + +/* The queue into which received key presses are placed. NOTE THE COMMENTS AT +THE TOP OF THIS FILE REGARDING THE USE OF QUEUES FOR THIS PURPOSE. */ +static QueueHandle_t xRxQueue = NULL; + +/* The semaphore used to indicate the end of a transmission. */ +static SemaphoreHandle_t xTxCompleteSemaphore = NULL; + +/*-----------------------------------------------------------*/ + +/* + * The UART interrupt handler is defined in this file to provide more control, + * but still uses parts of the Xilinx provided driver. + */ +void prvUART_Handler( void *pvNotUsed ); + +/*-----------------------------------------------------------*/ + +/* + * See the serial2.h header file. + */ +xComPortHandle xSerialPortInitMinimal( uint32_t ulWantedBaud, UBaseType_t uxQueueLength ) +{ +BaseType_t xStatus; +XUartPs_Config *pxConfig; + + /* Create the queue used to hold received characters. NOTE THE COMMENTS AT + THE TOP OF THIS FILE REGARDING THE QUEUE OF QUEUES FOR THIS PURPSOE. */ + xRxQueue = xQueueCreate( uxQueueLength, sizeof( char ) ); + configASSERT( xRxQueue ); + + /* Create the semaphore used to signal the end of a transmission, then take + the semaphore so it is in the correct state the first time + xSerialSendString() is called. A block time of zero is used when taking + the semaphore as it is guaranteed to be available (it was just created). */ + xTxCompleteSemaphore = xSemaphoreCreateMutex(); + configASSERT( xTxCompleteSemaphore ); + xSemaphoreTake( xTxCompleteSemaphore, 0 ); + + /* Look up the UART configuration then initialise the dirver. */ + pxConfig = XUartPs_LookupConfig( XPAR_XUARTPS_0_DEVICE_ID ); + + /* Initialise the driver. */ + xStatus = XUartPs_CfgInitialize( &xUARTInstance, pxConfig, XPAR_PS7_UART_1_BASEADDR ); + configASSERT( xStatus == XST_SUCCESS ); + + /* Misc. parameter configuration. */ + XUartPs_SetBaudRate( &xUARTInstance, ulWantedBaud ); + XUartPs_SetOperMode( &xUARTInstance, XUARTPS_OPER_MODE_NORMAL ); + + /* Install the interrupt service routine that is defined within this + file. */ + xStatus = XScuGic_Connect( &xInterruptController, XPAR_XUARTPS_1_INTR, (Xil_ExceptionHandler) prvUART_Handler, (void *) &xUARTInstance ); + configASSERT( xStatus == XST_SUCCESS ); + + /* Ensure interrupts start clear. */ + XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET, XUARTPS_IXR_MASK ); + + /* Enable the UART interrupt within the GIC. */ + XScuGic_Enable( &xInterruptController, XPAR_XUARTPS_1_INTR ); + + /* Enable the interrupts of interest in the UART. */ + XUartPs_SetInterruptMask( &xUARTInstance, XUARTPS_IXR_RXFULL | XUARTPS_IXR_RXOVR | XUARTPS_IXR_TOUT | XUARTPS_IXR_TXEMPTY ); + + /* Set the receive timeout. */ + XUartPs_SetRecvTimeout( &xUARTInstance, 8 ); + + return ( xComPortHandle ) 0; +} +/*-----------------------------------------------------------*/ + +BaseType_t xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime ) +{ +BaseType_t xReturn; + + /* Only a single port is supported. */ + ( void ) pxPort; + + /* Obtain a received character from the queue - entering the Blocked state + (so not consuming any processing time) to wait for a character if one is not + already available. */ + xReturn = xQueueReceive( xRxQueue, pcRxedChar, xBlockTime ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength ) +{ +const TickType_t xMaxWait = 200UL / portTICK_PERIOD_MS; + + /* Only a single port is supported. */ + ( void ) pxPort; + + /* Start the transmission. The interrupt service routine will complete the + transmission if necessary. */ + XUartPs_Send( &xUARTInstance, ( void * ) pcString, usStringLength ); + + /* Wait until the string has been transmitted before exiting this function, + otherwise there is a risk the calling function will overwrite the string + pointed to by the pcString parameter while it is still being transmitted. + The calling task will wait in the Blocked state (so not consuming any + processing time) until the mutex is available. */ + xSemaphoreTake( xTxCompleteSemaphore, xMaxWait ); +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime ) +{ + /* Only a single port is supported. */ + ( void ) pxPort; + + /* Send the character. */ + XUartPs_Send( &xUARTInstance, ( void * ) &cOutChar, sizeof( cOutChar ) ); + + /* Wait for the transmission to be complete so the mutex is left in the + correct state for the next time vSerialPutString() is called. */ + xSemaphoreTake( xTxCompleteSemaphore, xBlockTime ); + + return pdPASS; +} +/*-----------------------------------------------------------*/ + +void vSerialClose(xComPortHandle xPort) +{ + /* Not supported as not required by the demo application. */ + ( void ) xPort; +} +/*-----------------------------------------------------------*/ + +void prvUART_Handler( void *pvNotUsed ) +{ +extern unsigned int XUartPs_SendBuffer( XUartPs *InstancePtr ); +uint32_t ulActiveInterrupts, ulChannelStatusRegister; +BaseType_t xHigherPriorityTaskWoken = pdFALSE; +char cChar; + + configASSERT( pvNotUsed == &xUARTInstance ); + + /* Read the interrupt ID register to see which interrupt is active. */ + ulActiveInterrupts = XUartPs_ReadReg(XPAR_PS7_UART_1_BASEADDR, XUARTPS_IMR_OFFSET); + ulActiveInterrupts &= XUartPs_ReadReg(XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET); + + /* Are any receive events of interest active? */ + if( ( ulActiveInterrupts & serRECEIVE_INTERRUPT_MASK ) != 0 ) + { + /* Read the Channel Status Register to determine if there is any data in + the RX FIFO. */ + ulChannelStatusRegister = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_SR_OFFSET ); + + /* Move data from the Rx FIFO to the Rx queue. NOTE THE COMMENTS AT THE + TOP OF THIS FILE ABOUT USING QUEUES FOR THIS PURPSOE. */ + while( ( ulChannelStatusRegister & XUARTPS_SR_RXEMPTY ) == 0 ) + { + cChar = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_FIFO_OFFSET ); + + /* If writing to the queue unblocks a task, and the unblocked task + has a priority above the currently running task (the task that this + interrupt interrupted), then xHigherPriorityTaskWoken will be set + to pdTRUE inside the xQueueSendFromISR() function. + xHigherPriorityTaskWoken is then passed to portYIELD_FROM_ISR() at + the end of this interrupt handler to request a context switch so the + interrupt returns directly to the (higher priority) unblocked + task. */ + xQueueSendFromISR( xRxQueue, &cChar, &xHigherPriorityTaskWoken ); + ulChannelStatusRegister = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_SR_OFFSET ); + } + } + + /* Are any transmit events of interest active? */ + if( ( ulActiveInterrupts & serTRANSMIT_IINTERRUPT_MASK ) != 0 ) + { + if( xUARTInstance.SendBuffer.RemainingBytes == 0 ) + { + /* Give back the semaphore to indicate that the tranmission is + complete. If giving the semaphore unblocks a task, and the + unblocked task has a priority above the currently running task (the + task that this interrupt interrupted), then xHigherPriorityTaskWoken + will be set to pdTRUE inside the xSemaphoreGiveFromISR() function. + xHigherPriorityTaskWoken is then passed to portYIELD_FROM_ISR() at + the end of this interrupt handler to request a context switch so the + interrupt returns directly to the (higher priority) unblocked + task. */ + xSemaphoreGiveFromISR( xTxCompleteSemaphore, &xHigherPriorityTaskWoken ); + + /* No more data to transmit. */ + XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_IDR_OFFSET, XUARTPS_IXR_TXEMPTY ); + } + else + { + /* More data to send. */ + XUartPs_SendBuffer( &xUARTInstance ); + } + } + + /* portYIELD_FROM_ISR() will request a context switch if executing this + interrupt handler caused a task to leave the blocked state, and the task + that left the blocked state has a higher priority than the currently running + task (the task this interrupt interrupted). See the comment above the calls + to xSemaphoreGiveFromISR() and xQueueSendFromISR() within this function. */ + portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + + /* Clear the interrupt status. */ + XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET, ulActiveInterrupts ); +} + + + + + diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/IntQueueTimer.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/IntQueueTimer.c deleted file mode 100644 index 1a24a4cba..000000000 --- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/IntQueueTimer.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd. - All rights reserved - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - 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 from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - 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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and 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! -*/ - -/* - * This file initialises three timers as follows: - * - * Timer 0 and Timer 1 provide the interrupts that are used with the IntQ - * standard demo tasks, which test interrupt nesting and using queues from - * interrupts. Both these interrupts operate below the maximum syscall - * interrupt priority. - * - * Timer 2 is a much higher frequency timer that tests the nesting of interrupts - * that execute above the maximum syscall interrupt priority. - * - * All the timers can nest with the tick interrupt - creating a maximum - * interrupt nesting depth of 4. - * - * For convenience, the high frequency timer is also used to provide the time - * base for the run time stats. - */ - -/* Scheduler includes. */ -#include "FreeRTOS.h" - -/* Demo includes. */ -#include "IntQueueTimer.h" -#include "IntQueue.h" - -/* Xilinx includes. */ -#include "xttcps.h" -#include "xscugic.h" - -/* The frequencies at which the first two timers expire are slightly offset to -ensure they don't remain synchronised. The frequency of the interrupt that -operates above the max syscall interrupt priority is 10 times faster so really -hammers the interrupt entry and exit code. */ -#define tmrTIMERS_USED 3 -#define tmrTIMER_0_FREQUENCY ( 2000UL ) -#define tmrTIMER_1_FREQUENCY ( 2001UL ) -#define tmrTIMER_2_FREQUENCY ( 20000UL ) - -/*-----------------------------------------------------------*/ - -/* - * The single interrupt service routines that is used to service all three - * timers. - */ -static void prvTimerHandler( void *CallBackRef ); - -/*-----------------------------------------------------------*/ - -/* Hardware constants. */ -static const BaseType_t xDeviceIDs[ tmrTIMERS_USED ] = { XPAR_XTTCPS_0_DEVICE_ID, XPAR_XTTCPS_1_DEVICE_ID, XPAR_XTTCPS_2_DEVICE_ID }; -static const BaseType_t xInterruptIDs[ tmrTIMERS_USED ] = { XPAR_XTTCPS_0_INTR, XPAR_XTTCPS_1_INTR, XPAR_XTTCPS_2_INTR }; - -/* Timer configuration settings. */ -typedef struct -{ - uint32_t OutputHz; /* Output frequency. */ - uint16_t Interval; /* Interval value. */ - uint8_t Prescaler; /* Prescaler value. */ - uint16_t Options; /* Option settings. */ -} TmrCntrSetup; - -static TmrCntrSetup xTimerSettings[ tmrTIMERS_USED ] = -{ - { tmrTIMER_0_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE }, - { tmrTIMER_1_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE }, - { tmrTIMER_2_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE } -}; - -/* Lower priority number means higher logical priority, so -configMAX_API_CALL_INTERRUPT_PRIORITY - 1 is above the maximum system call -interrupt priority. */ -static const UBaseType_t uxInterruptPriorities[ tmrTIMERS_USED ] = -{ - configMAX_API_CALL_INTERRUPT_PRIORITY + 1, - configMAX_API_CALL_INTERRUPT_PRIORITY, - configMAX_API_CALL_INTERRUPT_PRIORITY - 1 -} -static XTtcPs xTimerInstances[ tmrTIMERS_USED ]; - -/* Used to provide a means of ensuring the intended interrupt nesting depth is -actually being reached. */ -extern uint32_t ulPortInterruptNesting; -static uint32_t ulMaxRecordedNesting = 0; - -/* For convenience the high frequency timer increments a variable that is then -used as the time base for the run time stats. */ -volatile uint32_t ulHighFrequencyTimerCounts = 0; - -/*-----------------------------------------------------------*/ - -void vInitialiseTimerForIntQueueTest( void ) -{ -BaseType_t xStatus; -TmrCntrSetup *pxTimerSettings; -extern XScuGic xInterruptController; -BaseType_t xTimer; -XTtcPs *pxTimerInstance; -XTtcPs_Config *pxTimerConfiguration; -const uint8_t ucRisingEdge = 3; - - for( xTimer = 0; xTimer < tmrTIMERS_USED; xTimer++ ) - { - /* Look up the timer's configuration. */ - pxTimerInstance = &( xTimerInstances[ xTimer ] ); - pxTimerConfiguration = XTtcPs_LookupConfig( xDeviceIDs[ xTimer ] ); - configASSERT( pxTimerConfiguration ); - - pxTimerSettings = &( xTimerSettings[ xTimer ] ); - - /* Initialise the device. */ - xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress ); - if( xStatus != XST_SUCCESS ) - { - /* Not sure how to do this before XTtcPs_CfgInitialize is called - as pxTimerInstance is set within XTtcPs_CfgInitialize(). */ - XTtcPs_Stop( pxTimerInstance ); - xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress ); - configASSERT( xStatus == XST_SUCCESS ); - } - - /* Set the options. */ - XTtcPs_SetOptions( pxTimerInstance, pxTimerSettings->Options ); - - /* The timer frequency is preset in the pxTimerSettings structure. - Derive the values for the other structure members. */ - XTtcPs_CalcIntervalFromFreq( pxTimerInstance, pxTimerSettings->OutputHz, &( pxTimerSettings->Interval ), &( pxTimerSettings->Prescaler ) ); - - /* Set the interval and prescale. */ - XTtcPs_SetInterval( pxTimerInstance, pxTimerSettings->Interval ); - XTtcPs_SetPrescaler( pxTimerInstance, pxTimerSettings->Prescaler ); - - /* The priority must be the lowest possible. */ - XScuGic_SetPriorityTriggerType( &xInterruptController, xInterruptIDs[ xTimer ], uxInterruptPriorities[ xTimer ] << portPRIORITY_SHIFT, ucRisingEdge ); - - /* Connect to the interrupt controller. */ - xStatus = XScuGic_Connect( &xInterruptController, xInterruptIDs[ xTimer ], ( Xil_InterruptHandler ) prvTimerHandler, ( void * ) pxTimerInstance ); - configASSERT( xStatus == XST_SUCCESS); - - /* Enable the interrupt in the GIC. */ - XScuGic_Enable( &xInterruptController, xInterruptIDs[ xTimer ] ); - - /* Enable the interrupts in the timer. */ - XTtcPs_EnableInterrupts( pxTimerInstance, XTTCPS_IXR_INTERVAL_MASK ); - - /* Start the timer. */ - XTtcPs_Start( pxTimerInstance ); - } -} -/*-----------------------------------------------------------*/ - -static void prvTimerHandler( void *pvCallBackRef ) -{ -uint32_t ulInterruptStatus; -XTtcPs *pxTimer = ( XTtcPs * ) pvCallBackRef; -BaseType_t xYieldRequired; - - /* Read the interrupt status, then write it back to clear the interrupt. */ - ulInterruptStatus = XTtcPs_GetInterruptStatus( pxTimer ); - XTtcPs_ClearInterruptStatus( pxTimer, ulInterruptStatus ); - - /* Only one interrupt event type is expected. */ - configASSERT( ( XTTCPS_IXR_INTERVAL_MASK & ulInterruptStatus ) != 0 ); - - /* Check the device ID to know which IntQueue demo to call. */ - if( pxTimer->Config.DeviceId == xDeviceIDs[ 0 ] ) - { - xYieldRequired = xFirstTimerHandler(); - } - else if( pxTimer->Config.DeviceId == xDeviceIDs[ 1 ] ) - { - xYieldRequired = xSecondTimerHandler(); - } - else - { - /* The high frequency timer is also used to generate the time base for - the run time state. */ - ulHighFrequencyTimerCounts++; - - /* Latch the highest interrupt nesting count detected. */ - if( ulPortInterruptNesting > ulMaxRecordedNesting ) - { - ulMaxRecordedNesting = ulPortInterruptNesting; - } - - xYieldRequired = pdFALSE; - } - - /* If xYieldRequired is not pdFALSE then calling either xFirstTimerHandler() - or xSecondTimerHandler() resulted in a task leaving the blocked state and - the task that left the blocked state had a priority higher than the currently - running task (the task this interrupt interrupted) - so a context switch - should be performed so the interrupt returns directly to the higher priority - task. xYieldRequired is tested inside the following macro. */ - portYIELD_FROM_ISR( xYieldRequired ); -} - diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/IntQueueTimer.h b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/IntQueueTimer.h deleted file mode 100644 index 874334606..000000000 --- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/IntQueueTimer.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd. - All rights reserved - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - 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 from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - 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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and 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! -*/ - -#ifndef INT_QUEUE_TIMER_H -#define INT_QUEUE_TIMER_H - -void vInitialiseTimerForIntQueueTest( void ); -portBASE_TYPE xTimer0Handler( void ); -portBASE_TYPE xTimer1Handler( void ); - -#endif - diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c index f2aff13ab..280f4404f 100644 --- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c @@ -74,6 +74,13 @@ * This file implements the code that is not demo specific, including the * hardware setup and FreeRTOS hook functions. * + * NOTE: The full demo includes a test that checks the floating point context + * is maintained correctly across task switches. The standard GCC libraries can + * use floating point registers and made this test fail (unless the tasks that + * use the library are given a floating point context as described on the + * documentation page for this demo). printf-stdarg.c is included in this + * project to prevent the standard GCC libraries being linked into the project. + * * 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! @@ -128,6 +135,10 @@ void vApplicationIdleHook( void ); void vApplicationStackOverflowHook( xTaskHandle pxTask, char *pcTaskName ); void vApplicationTickHook( void ); +/*-----------------------------------------------------------*/ + +/* The interrupt controller is initialised in this file, and made available to +other modules. */ XScuGic xInterruptController; /*-----------------------------------------------------------*/ @@ -149,6 +160,7 @@ int main( void ) } #endif + /* Don't expect to reach here. */ return 0; } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main_blinky.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main_blinky.c deleted file mode 100644 index 4837cbc47..000000000 --- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main_blinky.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - FreeRTOS V8.0.0:rc2 - Copyright (C) 2014 Real Time Engineers Ltd. - All rights reserved - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - 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 from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - 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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and 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! -*/ - -/****************************************************************************** - * NOTE 1: This project provides two demo applications. A simple blinky style - * project, and a more comprehensive test and demo application. The - * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select - * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY - * in main.c. This file implements the simply blinky style version. - * - * NOTE 2: This file only contains the source code that is specific to the - * basic demo. Generic functions, such FreeRTOS hook functions, and functions - * required to configure the hardware are defined in main.c. - ****************************************************************************** - * - * main_blinky() creates one queue, and two tasks. It then starts the - * scheduler. - * - * The Queue Send Task: - * The queue send task is implemented by the prvQueueSendTask() function in - * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly - * block for 200 milliseconds, before sending the value 100 to the queue that - * was created within main_blinky(). Once the value is sent, the task loops - * back around to block for another 200 milliseconds...and so on. - * - * The Queue Receive Task: - * The queue receive task is implemented by the prvQueueReceiveTask() function - * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly - * blocks on attempts to read data from the queue that was created within - * main_blinky(). When data is received, the task checks the value of the - * data, and if the value equals the expected 100, toggles an LED. The 'block - * time' parameter passed to the queue receive function specifies that the - * task should be held in the Blocked state indefinitely to wait for data to - * be available on the queue. The queue receive task will only leave the - * Blocked state when the queue send task writes to the queue. As the queue - * send task writes to the queue every 200 milliseconds, the queue receive - * task leaves the Blocked state every 200 milliseconds, and therefore toggles - * the LED every 200 milliseconds. - */ - -/* Kernel includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "semphr.h" - -/* Standard demo includes. */ -#include "partest.h" - -/* Priorities at which the tasks are created. */ -#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) -#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) - -/* The rate at which data is sent to the queue. The 200ms value is converted -to ticks using the portTICK_RATE_MS constant. */ -#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_RATE_MS ) - -/* The number of items the queue can hold. This is 1 as the receive task -will remove items as they are added, meaning the send task should always find -the queue empty. */ -#define mainQUEUE_LENGTH ( 1 ) - -/* The LED toggled by the Rx task. */ -#define mainTASK_LED ( 0 ) - -/*-----------------------------------------------------------*/ - -/* - * The tasks as described in the comments at the top of this file. - */ -static void prvQueueReceiveTask( void *pvParameters ); -static void prvQueueSendTask( void *pvParameters ); - -/* - * Called by main() to create the simply blinky style application if - * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. - */ -void main_blinky( void ); - -/*-----------------------------------------------------------*/ - -/* The queue used by both tasks. */ -static xQueueHandle xQueue = NULL; - -/*-----------------------------------------------------------*/ - -void main_blinky( void ) -{ - /* Create the queue. */ - xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) ); - - if( xQueue != NULL ) - { - /* Start the two tasks as described in the comments at the top of this - file. */ - xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ - "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ - configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ - NULL, /* The parameter passed to the task - not used in this case. */ - mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ - NULL ); /* The task handle is not required, so NULL is passed. */ - - xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); - - /* Start the tasks and timer running. */ - vTaskStartScheduler(); - } - - /* If all is well, the scheduler will now be running, and the following - line will never be reached. If the following line does execute, then - there was either insufficient FreeRTOS heap memory available for the idle - and/or timer tasks to be created, or vTaskStartScheduler() was called from - User mode. See the memory management section on the FreeRTOS web site for - more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The - mode from which main() is called is set in the C start up code and must be - a privileged mode (not user mode). */ - for( ;; ); -} -/*-----------------------------------------------------------*/ - -static void prvQueueSendTask( void *pvParameters ) -{ -portTickType xNextWakeTime; -const unsigned long ulValueToSend = 100UL; - - /* Remove compiler warning about unused parameter. */ - ( void ) pvParameters; - - /* Initialise xNextWakeTime - this only needs to be done once. */ - xNextWakeTime = xTaskGetTickCount(); - - for( ;; ) - { - /* Place this task in the blocked state until it is time to run again. */ - vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); - - /* Send to the queue - causing the queue receive task to unblock and - toggle the LED. 0 is used as the block time so the sending operation - will not block - it shouldn't need to block as the queue should always - be empty at this point in the code. */ - xQueueSend( xQueue, &ulValueToSend, 0U ); - } -} -/*-----------------------------------------------------------*/ - -static void prvQueueReceiveTask( void *pvParameters ) -{ -unsigned long ulReceivedValue; -const unsigned long ulExpectedValue = 100UL; - - /* Remove compiler warning about unused parameter. */ - ( void ) pvParameters; - - for( ;; ) - { - /* Wait until something arrives in the queue - this task will block - indefinitely provided INCLUDE_vTaskSuspend is set to 1 in - FreeRTOSConfig.h. */ - xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); - - /* To get here something must have been received from the queue, but - is it the expected value? If it is, toggle the LED. */ - if( ulReceivedValue == ulExpectedValue ) - { - vParTestToggleLED( mainTASK_LED ); - ulReceivedValue = 0U; - } - } -} -/*-----------------------------------------------------------*/ - diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main_full.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main_full.c deleted file mode 100644 index f6f632573..000000000 --- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main_full.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd. - All rights reserved - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - 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 from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - 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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and 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! -*/ - -/****************************************************************************** - * NOTE 1: This project provides two demo applications. A simple blinky style - * project, and a more comprehensive test and demo application. The - * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select - * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY - * in main.c. This file implements the comprehensive test and demo version. - * - * NOTE 2: This file only contains the source code that is specific to the - * full demo. Generic functions, such FreeRTOS hook functions, and functions - * required to configure the hardware, are defined in main.c. - * - ****************************************************************************** - * - * main_full() creates all the demo application tasks and software timers, then - * starts the scheduler. The web documentation provides more details of the - * standard demo application tasks, which provide no particular functionality, - * but do provide a good example of how to use the FreeRTOS API. - * - * In addition to the standard demo tasks, the following tasks and tests are - * defined and/or created within this file: - * - * FreeRTOS+CLI command console. The command console is access through UART2 - * using 115200 baud if mainINCLUDE_FAT_SL_DEMO is set to 1. For reasons of - * robustness testing the UART driver is deliberately written to be inefficient - * and should not be used as a template for a production driver. Type "help" to - * see a list of registered commands. The FreeRTOS+CLI license is different to - * the FreeRTOS license, see http://www.FreeRTOS.org/cli for license and usage - * details. - * - * FreeRTOS+FAT SL. FreeRTOS+FAT SL is demonstrated using a RAM disk if - * mainINCLUDE_FAT_SL_DEMO is set to 1. [At the time of writing] The - * functionality of the file system demo is identical to the functionality of - * the FreeRTOS Win32 simulator file system demo, with the command console being - * accessed via the UART (as described above) instead of a network terminal. - * The FreeRTOS+FAT SL license is different to the FreeRTOS license, see - * http://www.FreeRTOS.org/fat_sl for license and usage details, and a - * description of the file system demo functionality. - * - * "Reg test" tasks - These fill both the core and floating point registers with - * known values, then check that each register maintains its expected value for - * the lifetime of the task. Each task uses a different set of values. The reg - * test tasks execute with a very low priority, so get preempted very - * frequently. A register containing an unexpected value is indicative of an - * error in the context switching mechanism. - * - * "Check" task - The check task period is initially set to three seconds. The - * task checks that all the standard demo tasks, and the register check tasks, - * are not only still executing, but are executing without reporting any errors. - * If the check task discovers that a task has either stalled, or reported an - * error, then it changes its own execution period from the initial three - * seconds, to just 200ms. The check task also toggles an LED each time it is - * called. This provides a visual indication of the system status: If the LED - * toggles every three seconds, then no issues have been discovered. If the LED - * toggles every 200ms, then an issue has been discovered with at least one - * task. - */ - -/* Standard includes. */ -#include - -/* Kernel includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "timers.h" -#include "semphr.h" - -/* Standard demo application includes. */ -#include "flop.h" -#include "semtest.h" -#include "dynamic.h" -#include "BlockQ.h" -#include "blocktim.h" -#include "countsem.h" -#include "GenQTest.h" -#include "recmutex.h" -#include "death.h" -#include "partest.h" -#include "comtest2.h" -#include "serial.h" -#include "TimerDemo.h" -#include "QueueOverwrite.h" -#include "IntQueue.h" - -/* FreeRTOS+CLI and FreeRTOS+FAT SL includes. */ -//#include "UARTCommandConsole.h" - -/* Priorities for the demo application tasks. */ -#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL ) -#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL ) -#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL ) -#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY ) -#define mainUART_COMMAND_CONSOLE_STACK_SIZE ( configMINIMAL_STACK_SIZE * 3UL ) -#define mainCOM_TEST_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) -#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) -#define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY ) - -/* The priority used by the UART command console task. */ -#define mainUART_COMMAND_CONSOLE_TASK_PRIORITY ( configMAX_PRIORITIES - 2 ) - -/* The LED used by the check timer. */ -#define mainCHECK_LED ( 0 ) - -/* A block time of zero simply means "don't block". */ -#define mainDONT_BLOCK ( 0UL ) - -/* In this example the baud rate is hard coded and there is no LED for use by -the COM test tasks, so just set both to invalid values. */ -#define mainCOM_TEST_LED ( 100 ) -#define mainBAUD_RATE ( 0 ) - -/* The period after which the check timer will expire, in ms, provided no errors -have been reported by any of the standard demo tasks. ms are converted to the -equivalent in ticks using the portTICK_RATE_MS constant. */ -#define mainNO_ERROR_CHECK_TASK_PERIOD ( 3000UL / portTICK_RATE_MS ) - -/* The period at which the check timer will expire, in ms, if an error has been -reported in one of the standard demo tasks. ms are converted to the equivalent -in ticks using the portTICK_RATE_MS constant. */ -#define mainERROR_CHECK_TASK_PERIOD ( 200UL / portTICK_RATE_MS ) - -/* Parameters that are passed into the register check tasks solely for the -purpose of ensuring parameters are passed into tasks correctly. */ -#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 ) -#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 ) - -/* The base period used by the timer test tasks. */ -#define mainTIMER_TEST_PERIOD ( 50 ) - -/* The length of queues used to pass characters into and out of the UART -interrupt. Note the comments above about the UART driver being implemented in -this way to test the kernel robustness rather than to provide a template for an -efficient production driver. */ -#define mainUART_QUEUE_LENGTHS 10 - -/*-----------------------------------------------------------*/ - -/* - * Called by main() to run the full demo (as opposed to the blinky demo) when - * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. - */ -void main_full( void ); - -/* - * The check task, as described at the top of this file. - */ -static void prvCheckTask( void *pvParameters ); - -/* - * Register check tasks, and the tasks used to write over and check the contents - * of the FPU registers, as described at the top of this file. The nature of - * these files necessitates that they are written in an assembly file, but the - * entry points are kept in the C file for the convenience of checking the task - * parameter. - */ -static void prvRegTestTaskEntry1( void *pvParameters ); -extern void vRegTest1Implementation( void ); -static void prvRegTestTaskEntry2( void *pvParameters ); -extern void vRegTest2Implementation( void ); - -/* - * Register commands that can be used with FreeRTOS+CLI. The commands are - * defined in CLI-Commands.c and File-Related-CLI-Command.c respectively. - */ -extern void vRegisterSampleCLICommands( void ); - -/* - * The task that manages the FreeRTOS+CLI input and output. - */ -extern void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriority ); - -/*-----------------------------------------------------------*/ - -/* The following two variables are used to communicate the status of the -register check tasks to the check software timer. If the variables keep -incrementing, then the register check tasks has not discovered any errors. If -a variable stops incrementing, then an error has been found. */ -volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; - -/*-----------------------------------------------------------*/ - -void main_full( void ) -{ - /* Start all the other standard demo/test tasks. The have not particular - functionality, but do demonstrate how to use the FreeRTOS API and test the - kernel port. */ - vStartInterruptQueueTasks(); - vStartDynamicPriorityTasks(); - vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); - vCreateBlockTimeTasks(); - vStartCountingSemaphoreTasks(); - vStartGenericQueueTasks( tskIDLE_PRIORITY ); - vStartRecursiveMutexTasks(); - vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); - vStartMathTasks( mainFLOP_TASK_PRIORITY ); - vStartTimerDemoTask( mainTIMER_TEST_PERIOD ); - vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY ); - - /* Start the tasks that implements the command console on the UART, as - described above. */ - vUARTCommandConsoleStart( mainUART_COMMAND_CONSOLE_STACK_SIZE, mainUART_COMMAND_CONSOLE_TASK_PRIORITY ); - - /* Register the standard CLI commands. */ - vRegisterSampleCLICommands(); - - - /* Create the register check tasks, as described at the top of this - file */ - xTaskCreate( prvRegTestTaskEntry1, "Reg1", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_1_PARAMETER, tskIDLE_PRIORITY, NULL ); - xTaskCreate( prvRegTestTaskEntry2, "Reg2", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL ); - - /* Create the task that performs the 'check' functionality, as described at - the top of this file. */ - xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); - - /* The set of tasks created by the following function call have to be - created last as they keep account of the number of tasks they expect to see - running. */ - vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); - - /* Start the scheduler. */ - vTaskStartScheduler(); - - /* If all is well, the scheduler will now be running, and the following - line will never be reached. If the following line does execute, then - there was either insufficient FreeRTOS heap memory available for the idle - and/or timer tasks to be created, or vTaskStartScheduler() was called from - User mode. See the memory management section on the FreeRTOS web site for - more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The - mode from which main() is called is set in the C start up code and must be - a privileged mode (not user mode). */ - for( ;; ); -} -/*-----------------------------------------------------------*/ - -static void prvCheckTask( void *pvParameters ) -{ -portTickType xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD; -portTickType xLastExecutionTime; -static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; -unsigned long ulErrorFound = pdFALSE; - - /* Just to stop compiler warnings. */ - ( void ) pvParameters; - - /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() - works correctly. */ - xLastExecutionTime = xTaskGetTickCount(); - - /* Cycle for ever, delaying then checking all the other tasks are still - operating without error. The onboard LED is toggled on each iteration. - If an error is detected then the delay period is decreased from - mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the - effect of increasing the rate at which the onboard LED toggles, and in so - doing gives visual feedback of the system status. */ - for( ;; ) - { - /* Delay until it is time to execute again. */ - vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod ); - - /* Check all the demo tasks (other than the flash tasks) to ensure - that they are all still running, and that none have detected an error. */ - if( xAreIntQueueTasksStillRunning() != pdTRUE ) - { - ulErrorFound = pdTRUE; - } - - if( xAreMathsTaskStillRunning() != pdTRUE ) - { - ulErrorFound = pdTRUE; - } - - if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) - { - ulErrorFound = pdTRUE; - } - - if( xAreBlockingQueuesStillRunning() != pdTRUE ) - { - ulErrorFound = pdTRUE; - } - - if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) - { - ulErrorFound = pdTRUE; - } - - if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) - { - ulErrorFound = pdTRUE; - } - - if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) - { - ulErrorFound = pdTRUE; - } - - if( xIsCreateTaskStillRunning() != pdTRUE ) - { - ulErrorFound = pdTRUE; - } - - if( xAreSemaphoreTasksStillRunning() != pdTRUE ) - { - ulErrorFound = pdTRUE; - } - - if( xAreTimerDemoTasksStillRunning( ( portTickType ) mainNO_ERROR_CHECK_TASK_PERIOD ) != pdPASS ) - { - ulErrorFound = pdTRUE; - } - - if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) - { - ulErrorFound = pdTRUE; - } - - if( xIsQueueOverwriteTaskStillRunning() != pdPASS ) - { - ulErrorFound = pdTRUE; - } - - /* Check that the register test 1 task is still running. */ - if( ulLastRegTest1Value == ulRegTest1LoopCounter ) - { - ulErrorFound = pdTRUE; - } - ulLastRegTest1Value = ulRegTest1LoopCounter; - - /* Check that the register test 2 task is still running. */ - if( ulLastRegTest2Value == ulRegTest2LoopCounter ) - { - ulErrorFound = pdTRUE; - } - ulLastRegTest2Value = ulRegTest2LoopCounter; - - /* Toggle the check LED to give an indication of the system status. If - the LED toggles every mainNO_ERROR_CHECK_TASK_PERIOD milliseconds then - everything is ok. A faster toggle indicates an error. */ - vParTestToggleLED( mainCHECK_LED ); - - if( ulErrorFound != pdFALSE ) - { - /* An error has been detected in one of the tasks - flash the LED - at a higher frequency to give visible feedback that something has - gone wrong (it might just be that the loop back connector required - by the comtest tasks has not been fitted). */ - xDelayPeriod = mainERROR_CHECK_TASK_PERIOD; - } - } -} -/*-----------------------------------------------------------*/ - -static void prvRegTestTaskEntry1( void *pvParameters ) -{ - /* Although the regtest task is written in assembler, its entry point is - written in C for convenience of checking the task parameter is being passed - in correctly. */ - if( pvParameters == mainREG_TEST_TASK_1_PARAMETER ) - { - /* The reg test task also tests the floating point registers. Tasks - that use the floating point unit must call vPortTaskUsesFPU() before - any floating point instructions are executed. */ - vPortTaskUsesFPU(); - - /* Start the part of the test that is written in assembler. */ - vRegTest1Implementation(); - } - - /* The following line will only execute if the task parameter is found to - be incorrect. The check timer will detect that the regtest loop counter is - not being incremented and flag an error. */ - vTaskDelete( NULL ); -} -/*-----------------------------------------------------------*/ - -static void prvRegTestTaskEntry2( void *pvParameters ) -{ - /* Although the regtest task is written in assembler, its entry point is - written in C for convenience of checking the task parameter is being passed - in correctly. */ - if( pvParameters == mainREG_TEST_TASK_2_PARAMETER ) - { - /* The reg test task also tests the floating point registers. Tasks - that use the floating point unit must call vPortTaskUsesFPU() before - any floating point instructions are executed. */ - vPortTaskUsesFPU(); - - /* Start the part of the test that is written in assembler. */ - vRegTest2Implementation(); - } - - /* The following line will only execute if the task parameter is found to - be incorrect. The check timer will detect that the regtest loop counter is - not being incremented and flag an error. */ - vTaskDelete( NULL ); -} -/*-----------------------------------------------------------*/ - - - - diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/printf-stdarg.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/printf-stdarg.c new file mode 100644 index 000000000..b5ac41be7 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/printf-stdarg.c @@ -0,0 +1,293 @@ +/* + Copyright 2001, 2002 Georges Menie (www.menie.org) + stdarg version contributed by Christian Ettinger + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + putchar is the only external dependency for this file, + if you have a working putchar, leave it commented out. + If not, uncomment the define below and + replace outbyte(c) by your own function call. + +*/ + +#define putchar(c) c + +#include + +static void printchar(char **str, int c) +{ + //extern int putchar(int c); + + if (str) { + **str = (char)c; + ++(*str); + } + else + { + (void)putchar(c); + } +} + +#define PAD_RIGHT 1 +#define PAD_ZERO 2 + +static int prints(char **out, const char *string, int width, int pad) +{ + register int pc = 0, padchar = ' '; + + if (width > 0) { + register int len = 0; + register const char *ptr; + for (ptr = string; *ptr; ++ptr) ++len; + if (len >= width) width = 0; + else width -= len; + if (pad & PAD_ZERO) padchar = '0'; + } + if (!(pad & PAD_RIGHT)) { + for ( ; width > 0; --width) { + printchar (out, padchar); + ++pc; + } + } + for ( ; *string ; ++string) { + printchar (out, *string); + ++pc; + } + for ( ; width > 0; --width) { + printchar (out, padchar); + ++pc; + } + + return pc; +} + +/* the following should be enough for 32 bit int */ +#define PRINT_BUF_LEN 12 + +static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase) +{ + char print_buf[PRINT_BUF_LEN]; + register char *s; + register int t, neg = 0, pc = 0; + register unsigned int u = (unsigned int)i; + + if (i == 0) { + print_buf[0] = '0'; + print_buf[1] = '\0'; + return prints (out, print_buf, width, pad); + } + + if (sg && b == 10 && i < 0) { + neg = 1; + u = (unsigned int)-i; + } + + s = print_buf + PRINT_BUF_LEN-1; + *s = '\0'; + + while (u) { + t = (unsigned int)u % b; + if( t >= 10 ) + t += letbase - '0' - 10; + *--s = (char)(t + '0'); + u /= b; + } + + if (neg) { + if( width && (pad & PAD_ZERO) ) { + printchar (out, '-'); + ++pc; + --width; + } + else { + *--s = '-'; + } + } + + return pc + prints (out, s, width, pad); +} + +static int print( char **out, const char *format, va_list args ) +{ + register int width, pad; + register int pc = 0; + char scr[2]; + + for (; *format != 0; ++format) { + if (*format == '%') { + ++format; + width = pad = 0; + if (*format == '\0') break; + if (*format == '%') goto out; + if (*format == '-') { + ++format; + pad = PAD_RIGHT; + } + while (*format == '0') { + ++format; + pad |= PAD_ZERO; + } + for ( ; *format >= '0' && *format <= '9'; ++format) { + width *= 10; + width += *format - '0'; + } + if( *format == 's' ) { + register char *s = (char *)va_arg( args, int ); + pc += prints (out, s?s:"(null)", width, pad); + continue; + } + if( *format == 'd' ) { + pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a'); + continue; + } + if( *format == 'x' ) { + pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a'); + continue; + } + if( *format == 'X' ) { + pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A'); + continue; + } + if( *format == 'u' ) { + pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a'); + continue; + } + if( *format == 'c' ) { + /* char are converted to int then pushed on the stack */ + scr[0] = (char)va_arg( args, int ); + scr[1] = '\0'; + pc += prints (out, scr, width, pad); + continue; + } + } + else { + out: + printchar (out, *format); + ++pc; + } + } + if (out) **out = '\0'; + va_end( args ); + return pc; +} + +int printf(const char *format, ...) +{ + va_list args; + + va_start( args, format ); + return print( 0, format, args ); +} + +int sprintf(char *out, const char *format, ...) +{ + va_list args; + + va_start( args, format ); + return print( &out, format, args ); +} + + +int snprintf( char *buf, unsigned int count, const char *format, ... ) +{ + va_list args; + + ( void ) count; + + va_start( args, format ); + return print( &buf, format, args ); +} + + +#ifdef TEST_PRINTF +int main(void) +{ + char *ptr = "Hello world!"; + char *np = 0; + int i = 5; + unsigned int bs = sizeof(int)*8; + int mi; + char buf[80]; + + mi = (1 << (bs-1)) + 1; + printf("%s\n", ptr); + printf("printf test\n"); + printf("%s is null pointer\n", np); + printf("%d = 5\n", i); + printf("%d = - max int\n", mi); + printf("char %c = 'a'\n", 'a'); + printf("hex %x = ff\n", 0xff); + printf("hex %02x = 00\n", 0); + printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3); + printf("%d %s(s)%", 0, "message"); + printf("\n"); + printf("%d %s(s) with %%\n", 0, "message"); + sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf); + sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf); + sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf); + sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf); + sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf); + sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf); + sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf); + sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf); + + return 0; +} + +/* + * if you compile this file with + * gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c + * you will get a normal warning: + * printf.c:214: warning: spurious trailing `%' in format + * this line is testing an invalid % at the end of the format string. + * + * this should display (on 32bit int machine) : + * + * Hello world! + * printf test + * (null) is null pointer + * 5 = 5 + * -2147483647 = - max int + * char a = 'a' + * hex ff = ff + * hex 00 = 00 + * signed -3 = unsigned 4294967293 = hex fffffffd + * 0 message(s) + * 0 message(s) with % + * justif: "left " + * justif: " right" + * 3: 0003 zero padded + * 3: 3 left justif. + * 3: 3 right justif. + * -3: -003 zero padded + * -3: -3 left justif. + * -3: -3 right justif. + */ + +#endif + + +/* To keep linker happy. */ +int write( int i, char* c, int n) +{ + (void)i; + (void)n; + (void)c; + return 0; +} + diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/reg_test.S b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/reg_test.S deleted file mode 100644 index 694113edc..000000000 --- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/reg_test.S +++ /dev/null @@ -1,656 +0,0 @@ -/* - FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd. - - FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT - http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS tutorial books are available in pdf and paperback. * - * Complete, revised, and edited pdf reference manuals are also * - * available. * - * * - * Purchasing FreeRTOS documentation will not only help you, by * - * ensuring you get running as quickly as possible and with an * - * in-depth knowledge of how to use FreeRTOS, it will also help * - * the FreeRTOS project to continue with its mission of providing * - * professional grade, cross platform, de facto standard solutions * - * for microcontrollers - completely free of charge! * - * * - * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * - * * - * Thank you for using FreeRTOS, and thank you for your support! * - * * - *************************************************************************** - - - 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. See the GNU General Public License for more - details. You should have received a copy of the GNU General Public License - and the FreeRTOS license exception along with FreeRTOS; if not itcan be - viewed here: http://www.freertos.org/a00114.html and also obtained by - writing to Real Time Engineers Ltd., contact details for whom are available - on the FreeRTOS WEB site. - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, and our new - fully thread aware and reentrant UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems, who sell the code with commercial support, - indemnification and middleware, under the OpenRTOS brand. - - 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. -*/ - - .global vRegTest1Implementation - .global vRegTest2Implementation - .extern ulRegTest1LoopCounter - .extern ulRegTest2LoopCounter - - .text - .arm - - /* This function is explained in the comments at the top of main-full.c. */ -vRegTest1Implementation: - - /* Fill each general purpose register with a known value. */ - mov r0, #0xFF - mov r1, #0x11 - mov r2, #0x22 - mov r3, #0x33 - mov r4, #0x44 - mov r5, #0x55 - mov r6, #0x66 - mov r7, #0x77 - mov r8, #0x88 - mov r9, #0x99 - mov r10, #0xAA - mov r11, #0xBB - mov r12, #0xCC - mov r14, #0xEE - - /* Fill each FPU register with a known value. */ - vmov d0, r0, r1 - vmov d1, r2, r3 - vmov d2, r4, r5 - vmov d3, r6, r7 - vmov d4, r8, r9 - vmov d5, r10, r11 - vmov d6, r0, r1 - vmov d7, r2, r3 - vmov d8, r4, r5 - vmov d9, r6, r7 - vmov d10, r8, r9 - vmov d11, r10, r11 - vmov d12, r0, r1 - vmov d13, r2, r3 - vmov d14, r4, r5 - vmov d15, r6, r7 - - vmov d16, r0, r1 - vmov d17, r2, r3 - vmov d18, r4, r5 - vmov d19, r6, r7 - vmov d20, r8, r9 - vmov d21, r10, r11 - vmov d22, r0, r1 - vmov d23, r2, r3 - vmov d24, r4, r5 - vmov d25, r6, r7 - vmov d26, r8, r9 - vmov d27, r10, r11 - vmov d28, r0, r1 - vmov d29, r2, r3 - vmov d30, r4, r5 - vmov d31, r6, r7 - - /* Loop, checking each itteration that each register still contains the - expected value. */ -reg1_loop: - /* Yield to increase test coverage */ - svc 0 - - /* Check all the VFP registers still contain the values set above. - First save registers that are clobbered by the test. */ - push { r0-r1 } - - vmov r0, r1, d0 - cmp r0, #0xFF - bne reg1_error_loopf - cmp r1, #0x11 - bne reg1_error_loopf - vmov r0, r1, d1 - cmp r0, #0x22 - bne reg1_error_loopf - cmp r1, #0x33 - bne reg1_error_loopf - vmov r0, r1, d2 - cmp r0, #0x44 - bne reg1_error_loopf - cmp r1, #0x55 - bne reg1_error_loopf - vmov r0, r1, d3 - cmp r0, #0x66 - bne reg1_error_loopf - cmp r1, #0x77 - bne reg1_error_loopf - vmov r0, r1, d4 - cmp r0, #0x88 - bne reg1_error_loopf - cmp r1, #0x99 - bne reg1_error_loopf - vmov r0, r1, d5 - cmp r0, #0xAA - bne reg1_error_loopf - cmp r1, #0xBB - bne reg1_error_loopf - vmov r0, r1, d6 - cmp r0, #0xFF - bne reg1_error_loopf - cmp r1, #0x11 - bne reg1_error_loopf - vmov r0, r1, d7 - cmp r0, #0x22 - bne reg1_error_loopf - cmp r1, #0x33 - bne reg1_error_loopf - vmov r0, r1, d8 - cmp r0, #0x44 - bne reg1_error_loopf - cmp r1, #0x55 - bne reg1_error_loopf - vmov r0, r1, d9 - cmp r0, #0x66 - bne reg1_error_loopf - cmp r1, #0x77 - bne reg1_error_loopf - vmov r0, r1, d10 - cmp r0, #0x88 - bne reg1_error_loopf - cmp r1, #0x99 - bne reg1_error_loopf - vmov r0, r1, d11 - cmp r0, #0xAA - bne reg1_error_loopf - cmp r1, #0xBB - bne reg1_error_loopf - vmov r0, r1, d12 - cmp r0, #0xFF - bne reg1_error_loopf - cmp r1, #0x11 - bne reg1_error_loopf - vmov r0, r1, d13 - cmp r0, #0x22 - bne reg1_error_loopf - cmp r1, #0x33 - bne reg1_error_loopf - vmov r0, r1, d14 - cmp r0, #0x44 - bne reg1_error_loopf - cmp r1, #0x55 - bne reg1_error_loopf - vmov r0, r1, d15 - cmp r0, #0x66 - bne reg1_error_loopf - cmp r1, #0x77 - bne reg1_error_loopf - - vmov r0, r1, d16 - cmp r0, #0xFF - bne reg1_error_loopf - cmp r1, #0x11 - bne reg1_error_loopf - vmov r0, r1, d17 - cmp r0, #0x22 - bne reg1_error_loopf - cmp r1, #0x33 - bne reg1_error_loopf - vmov r0, r1, d18 - cmp r0, #0x44 - bne reg1_error_loopf - cmp r1, #0x55 - bne reg1_error_loopf - vmov r0, r1, d19 - cmp r0, #0x66 - bne reg1_error_loopf - cmp r1, #0x77 - bne reg1_error_loopf - vmov r0, r1, d20 - cmp r0, #0x88 - bne reg1_error_loopf - cmp r1, #0x99 - bne reg1_error_loopf - vmov r0, r1, d21 - cmp r0, #0xAA - bne reg1_error_loopf - cmp r1, #0xBB - bne reg1_error_loopf - vmov r0, r1, d22 - cmp r0, #0xFF - bne reg1_error_loopf - cmp r1, #0x11 - bne reg1_error_loopf - vmov r0, r1, d23 - cmp r0, #0x22 - bne reg1_error_loopf - cmp r1, #0x33 - bne reg1_error_loopf - vmov r0, r1, d24 - cmp r0, #0x44 - bne reg1_error_loopf - cmp r1, #0x55 - bne reg1_error_loopf - vmov r0, r1, d25 - cmp r0, #0x66 - bne reg1_error_loopf - cmp r1, #0x77 - bne reg1_error_loopf - vmov r0, r1, d26 - cmp r0, #0x88 - bne reg1_error_loopf - cmp r1, #0x99 - bne reg1_error_loopf - vmov r0, r1, d27 - cmp r0, #0xAA - bne reg1_error_loopf - cmp r1, #0xBB - bne reg1_error_loopf - vmov r0, r1, d28 - cmp r0, #0xFF - bne reg1_error_loopf - cmp r1, #0x11 - bne reg1_error_loopf - vmov r0, r1, d29 - cmp r0, #0x22 - bne reg1_error_loopf - cmp r1, #0x33 - bne reg1_error_loopf - vmov r0, r1, d30 - cmp r0, #0x44 - bne reg1_error_loopf - cmp r1, #0x55 - bne reg1_error_loopf - vmov r0, r1, d31 - cmp r0, #0x66 - bne reg1_error_loopf - cmp r1, #0x77 - bne reg1_error_loopf - - /* Restore the registers that were clobbered by the test. */ - pop {r0-r1} - - /* VFP register test passed. Jump to the core register test. */ - b reg1_loopf_pass - -reg1_error_loopf: - /* If this line is hit then a VFP register value was found to be - incorrect. */ - b reg1_error_loopf - -reg1_loopf_pass: - - /* Test each general purpose register to check that it still contains the - expected known value, jumping to reg1_error_loop if any register contains - an unexpected value. */ - cmp r0, #0xFF - bne reg1_error_loop - cmp r1, #0x11 - bne reg1_error_loop - cmp r2, #0x22 - bne reg1_error_loop - cmp r3, #0x33 - bne reg1_error_loop - cmp r4, #0x44 - bne reg1_error_loop - cmp r5, #0x55 - bne reg1_error_loop - cmp r6, #0x66 - bne reg1_error_loop - cmp r7, #0x77 - bne reg1_error_loop - cmp r8, #0x88 - bne reg1_error_loop - cmp r9, #0x99 - bne reg1_error_loop - cmp r10, #0xAA - bne reg1_error_loop - cmp r11, #0xBB - bne reg1_error_loop - cmp r12, #0xCC - bne reg1_error_loop - cmp r14, #0xEE - bne reg1_error_loop - - /* Everything passed, increment the loop counter. */ - push { r0-r1 } - ldr r0, =ulRegTest1LoopCounter - ldr r1, [r0] - adds r1, r1, #1 - str r1, [r0] - pop { r0-r1 } - - /* Start again. */ - b reg1_loop - -reg1_error_loop: - /* If this line is hit then there was an error in a core register value. - The loop ensures the loop counter stops incrementing. */ - b reg1_error_loop - nop - -/*-----------------------------------------------------------*/ - -vRegTest2Implementation: - - /* Put a known value in each register. */ - mov r0, #0xFF000000 - mov r1, #0x11000000 - mov r2, #0x22000000 - mov r3, #0x33000000 - mov r4, #0x44000000 - mov r5, #0x55000000 - mov r6, #0x66000000 - mov r7, #0x77000000 - mov r8, #0x88000000 - mov r9, #0x99000000 - mov r10, #0xAA000000 - mov r11, #0xBB000000 - mov r12, #0xCC000000 - mov r14, #0xEE000000 - - /* Likewise the floating point registers */ - vmov d0, r0, r1 - vmov d1, r2, r3 - vmov d2, r4, r5 - vmov d3, r6, r7 - vmov d4, r8, r9 - vmov d5, r10, r11 - vmov d6, r0, r1 - vmov d7, r2, r3 - vmov d8, r4, r5 - vmov d9, r6, r7 - vmov d10, r8, r9 - vmov d11, r10, r11 - vmov d12, r0, r1 - vmov d13, r2, r3 - vmov d14, r4, r5 - vmov d15, r6, r7 - - vmov d16, r0, r1 - vmov d17, r2, r3 - vmov d18, r4, r5 - vmov d19, r6, r7 - vmov d20, r8, r9 - vmov d21, r10, r11 - vmov d22, r0, r1 - vmov d23, r2, r3 - vmov d24, r4, r5 - vmov d25, r6, r7 - vmov d26, r8, r9 - vmov d27, r10, r11 - vmov d28, r0, r1 - vmov d29, r2, r3 - vmov d30, r4, r5 - vmov d31, r6, r7 - - /* Loop, checking each itteration that each register still contains the - expected value. */ -reg2_loop: - /* Check all the VFP registers still contain the values set above. - First save registers that are clobbered by the test. */ - push { r0-r1 } - - vmov r0, r1, d0 - cmp r0, #0xFF000000 - bne reg2_error_loopf - cmp r1, #0x11000000 - bne reg2_error_loopf - vmov r0, r1, d1 - cmp r0, #0x22000000 - bne reg2_error_loopf - cmp r1, #0x33000000 - bne reg2_error_loopf - vmov r0, r1, d2 - cmp r0, #0x44000000 - bne reg2_error_loopf - cmp r1, #0x55000000 - bne reg2_error_loopf - vmov r0, r1, d3 - cmp r0, #0x66000000 - bne reg2_error_loopf - cmp r1, #0x77000000 - bne reg2_error_loopf - vmov r0, r1, d4 - cmp r0, #0x88000000 - bne reg2_error_loopf - cmp r1, #0x99000000 - bne reg2_error_loopf - vmov r0, r1, d5 - cmp r0, #0xAA000000 - bne reg2_error_loopf - cmp r1, #0xBB000000 - bne reg2_error_loopf - vmov r0, r1, d6 - cmp r0, #0xFF000000 - bne reg2_error_loopf - cmp r1, #0x11000000 - bne reg2_error_loopf - vmov r0, r1, d7 - cmp r0, #0x22000000 - bne reg2_error_loopf - cmp r1, #0x33000000 - bne reg2_error_loopf - vmov r0, r1, d8 - cmp r0, #0x44000000 - bne reg2_error_loopf - cmp r1, #0x55000000 - bne reg2_error_loopf - vmov r0, r1, d9 - cmp r0, #0x66000000 - bne reg2_error_loopf - cmp r1, #0x77000000 - bne reg2_error_loopf - vmov r0, r1, d10 - cmp r0, #0x88000000 - bne reg2_error_loopf - cmp r1, #0x99000000 - bne reg2_error_loopf - vmov r0, r1, d11 - cmp r0, #0xAA000000 - bne reg2_error_loopf - cmp r1, #0xBB000000 - bne reg2_error_loopf - vmov r0, r1, d12 - cmp r0, #0xFF000000 - bne reg2_error_loopf - cmp r1, #0x11000000 - bne reg2_error_loopf - vmov r0, r1, d13 - cmp r0, #0x22000000 - bne reg2_error_loopf - cmp r1, #0x33000000 - bne reg2_error_loopf - vmov r0, r1, d14 - cmp r0, #0x44000000 - bne reg2_error_loopf - cmp r1, #0x55000000 - bne reg2_error_loopf - vmov r0, r1, d15 - cmp r0, #0x66000000 - bne reg2_error_loopf - cmp r1, #0x77000000 - bne reg2_error_loopf - - vmov r0, r1, d16 - cmp r0, #0xFF000000 - bne reg2_error_loopf - cmp r1, #0x11000000 - bne reg2_error_loopf - vmov r0, r1, d17 - cmp r0, #0x22000000 - bne reg2_error_loopf - cmp r1, #0x33000000 - bne reg2_error_loopf - vmov r0, r1, d18 - cmp r0, #0x44000000 - bne reg2_error_loopf - cmp r1, #0x55000000 - bne reg2_error_loopf - vmov r0, r1, d19 - cmp r0, #0x66000000 - bne reg2_error_loopf - cmp r1, #0x77000000 - bne reg2_error_loopf - vmov r0, r1, d20 - cmp r0, #0x88000000 - bne reg2_error_loopf - cmp r1, #0x99000000 - bne reg2_error_loopf - vmov r0, r1, d21 - cmp r0, #0xAA000000 - bne reg2_error_loopf - cmp r1, #0xBB000000 - bne reg2_error_loopf - vmov r0, r1, d22 - cmp r0, #0xFF000000 - bne reg2_error_loopf - cmp r1, #0x11000000 - bne reg2_error_loopf - vmov r0, r1, d23 - cmp r0, #0x22000000 - bne reg2_error_loopf - cmp r1, #0x33000000 - bne reg2_error_loopf - vmov r0, r1, d24 - cmp r0, #0x44000000 - bne reg2_error_loopf - cmp r1, #0x55000000 - bne reg2_error_loopf - vmov r0, r1, d25 - cmp r0, #0x66000000 - bne reg2_error_loopf - cmp r1, #0x77000000 - bne reg2_error_loopf - vmov r0, r1, d26 - cmp r0, #0x88000000 - bne reg2_error_loopf - cmp r1, #0x99000000 - bne reg2_error_loopf - vmov r0, r1, d27 - cmp r0, #0xAA000000 - bne reg2_error_loopf - cmp r1, #0xBB000000 - bne reg2_error_loopf - vmov r0, r1, d28 - cmp r0, #0xFF000000 - bne reg2_error_loopf - cmp r1, #0x11000000 - bne reg2_error_loopf - vmov r0, r1, d29 - cmp r0, #0x22000000 - bne reg2_error_loopf - cmp r1, #0x33000000 - bne reg2_error_loopf - vmov r0, r1, d30 - cmp r0, #0x44000000 - bne reg2_error_loopf - cmp r1, #0x55000000 - bne reg2_error_loopf - vmov r0, r1, d31 - cmp r0, #0x66000000 - bne reg2_error_loopf - cmp r1, #0x77000000 - bne reg2_error_loopf - - /* Restore the registers that were clobbered by the test. */ - pop {r0-r1} - - /* VFP register test passed. Jump to the core register test. */ - b reg2_loopf_pass - -reg2_error_loopf: - /* If this line is hit then a VFP register value was found to be - incorrect. */ - b reg2_error_loopf - -reg2_loopf_pass: - - cmp r0, #0xFF000000 - bne reg2_error_loop - cmp r1, #0x11000000 - bne reg2_error_loop - cmp r2, #0x22000000 - bne reg2_error_loop - cmp r3, #0x33000000 - bne reg2_error_loop - cmp r4, #0x44000000 - bne reg2_error_loop - cmp r5, #0x55000000 - bne reg2_error_loop - cmp r6, #0x66000000 - bne reg2_error_loop - cmp r7, #0x77000000 - bne reg2_error_loop - cmp r8, #0x88000000 - bne reg2_error_loop - cmp r9, #0x99000000 - bne reg2_error_loop - cmp r10, #0xAA000000 - bne reg2_error_loop - cmp r11, #0xBB000000 - bne reg2_error_loop - cmp r12, #0xCC000000 - bne reg2_error_loop - cmp r14, #0xEE000000 - bne reg2_error_loop - - /* Everything passed, increment the loop counter. */ - push { r0-r1 } - ldr r0, =ulRegTest2LoopCounter - ldr r1, [r0] - adds r1, r1, #1 - str r1, [r0] - pop { r0-r1 } - - /* Start again. */ - b reg2_loop - -reg2_error_loop: - /* If this line is hit then there was an error in a core register value. - The loop ensures the loop counter stops incrementing. */ - b reg2_error_loop - nop - - - .end - diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/serial.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/serial.c deleted file mode 100644 index cf154578b..000000000 --- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/serial.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - FreeRTOS V8.0.0:rc2 - Copyright (C) 2014 Real Time Engineers Ltd. - All rights reserved - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - 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 from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - 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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and 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! - */ - -/* - BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER. - - Note1: This driver is used specifically to provide an interface to the - FreeRTOS+CLI command interpreter. It is *not* intended to be a generic - serial port driver. Nor is it intended to be used as an example of an - efficient implementation. In particular, a queue is used to buffer - received characters, which is fine in this case as key presses arrive - slowly, but a DMA and/or RAM buffer should be used in place of the queue in - applications that expect higher throughput. - - Note2: This driver does not attempt to handle UART errors. -*/ - -/* Scheduler includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" -#include "semphr.h" - -/* Demo application includes. */ -#include "serial.h" - -/* Xilinx includes. */ -#include "xuartps.h" -#include "xscugic.h" -#include "xil_exception.h" - -/* The UART interrupts of interest when receiving. */ -#define serRECEIVE_INTERRUPT_MASK ( XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL | XUARTPS_IXR_TOUT ) - -/* The UART interrupts of interest when transmitting. */ -#define serTRANSMIT_IINTERRUPT_MASK ( XUARTPS_IXR_TXEMPTY ) - -/*-----------------------------------------------------------*/ - -/* The UART being used. */ -static XUartPs xUARTInstance; - -/* The interrupt controller, which is configred by the hardware setup routines -defined in main(). */ -extern XScuGic xInterruptController; - -/* The queue into which received key presses are placed. NOTE THE COMMENTS AT -THE TOP OF THIS FILE REGARDING THE USE OF QUEUES FOR THIS PURPOSE. */ -static QueueHandle_t xRxQueue = NULL; - -/* The semaphore used to indicate the end of a transmission. */ -static SemaphoreHandle_t xTxCompleteSemaphore = NULL; - -/*-----------------------------------------------------------*/ - -/* - * The UART interrupt handler is defined in this file to provide more control, - * but still uses parts of the Xilinx provided driver. - */ -void prvUART_Handler( void *pvNotUsed ); - -/*-----------------------------------------------------------*/ - -/* - * See the serial2.h header file. - */ -xComPortHandle xSerialPortInitMinimal( uint32_t ulWantedBaud, UBaseType_t uxQueueLength ) -{ -BaseType_t xStatus; -XUartPs_Config *pxConfig; - - /* Create the queue used to hold received characters. NOTE THE COMMENTS AT - THE TOP OF THIS FILE REGARDING THE QUEUE OF QUEUES FOR THIS PURPSOE. */ - xRxQueue = xQueueCreate( uxQueueLength, sizeof( char ) ); - configASSERT( xRxQueue ); - - /* Create the semaphore used to signal the end of a transmission, then take - the semaphore so it is in the correct state the first time - xSerialSendString() is called. A block time of zero is used when taking - the semaphore as it is guaranteed to be available (it was just created). */ - xTxCompleteSemaphore = xSemaphoreCreateMutex(); - configASSERT( xTxCompleteSemaphore ); - xSemaphoreTake( xTxCompleteSemaphore, 0 ); - - /* Look up the UART configuration then initialise the dirver. */ - pxConfig = XUartPs_LookupConfig( XPAR_XUARTPS_0_DEVICE_ID ); - - /* Initialise the driver. */ - xStatus = XUartPs_CfgInitialize( &xUARTInstance, pxConfig, XPAR_PS7_UART_1_BASEADDR ); - configASSERT( xStatus == XST_SUCCESS ); - - /* Misc. parameter configuration. */ - XUartPs_SetBaudRate( &xUARTInstance, ulWantedBaud ); - XUartPs_SetOperMode( &xUARTInstance, XUARTPS_OPER_MODE_NORMAL ); - - /* Install the interrupt service routine that is defined within this - file. */ - xStatus = XScuGic_Connect( &xInterruptController, XPAR_XUARTPS_1_INTR, (Xil_ExceptionHandler) prvUART_Handler, (void *) &xUARTInstance ); - configASSERT( xStatus == XST_SUCCESS ); - - /* Ensure interrupts start clear. */ - XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET, XUARTPS_IXR_MASK ); - - /* Enable the UART interrupt within the GIC. */ - XScuGic_Enable( &xInterruptController, XPAR_XUARTPS_1_INTR ); - - /* Enable the interrupts of interest in the UART. */ - XUartPs_SetInterruptMask( &xUARTInstance, XUARTPS_IXR_RXFULL | XUARTPS_IXR_RXOVR | XUARTPS_IXR_TOUT | XUARTPS_IXR_TXEMPTY ); - - /* Set the receive timeout. */ - XUartPs_SetRecvTimeout( &xUARTInstance, 8 ); - - return ( xComPortHandle ) 0; -} -/*-----------------------------------------------------------*/ - -BaseType_t xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime ) -{ -BaseType_t xReturn; - - /* Only a single port is supported. */ - ( void ) pxPort; - - /* Obtain a received character from the queue - entering the Blocked state - (so not consuming any processing time) to wait for a character if one is not - already available. */ - xReturn = xQueueReceive( xRxQueue, pcRxedChar, xBlockTime ); - return xReturn; -} -/*-----------------------------------------------------------*/ - -void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength ) -{ -const TickType_t xMaxWait = 200UL / portTICK_PERIOD_MS; - - /* Only a single port is supported. */ - ( void ) pxPort; - - /* Start the transmission. The interrupt service routine will complete the - transmission if necessary. */ - XUartPs_Send( &xUARTInstance, ( void * ) pcString, usStringLength ); - - /* Wait until the string has been transmitted before exiting this function, - otherwise there is a risk the calling function will overwrite the string - pointed to by the pcString parameter while it is still being transmitted. - The calling task will wait in the Blocked state (so not consuming any - processing time) until the mutex is available. */ - xSemaphoreTake( xTxCompleteSemaphore, xMaxWait ); -} -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime ) -{ - /* Only a single port is supported. */ - ( void ) pxPort; - - /* Send the character. */ - XUartPs_Send( &xUARTInstance, ( void * ) &cOutChar, sizeof( cOutChar ) ); - - /* Wait for the transmission to be complete so the mutex is left in the - correct state for the next time vSerialPutString() is called. */ - xSemaphoreTake( xTxCompleteSemaphore, xBlockTime ); - - return pdPASS; -} -/*-----------------------------------------------------------*/ - -void vSerialClose(xComPortHandle xPort) -{ - /* Not supported as not required by the demo application. */ - ( void ) xPort; -} -/*-----------------------------------------------------------*/ - -void prvUART_Handler( void *pvNotUsed ) -{ -extern unsigned int XUartPs_SendBuffer( XUartPs *InstancePtr ); -uint32_t ulActiveInterrupts, ulChannelStatusRegister; -BaseType_t xHigherPriorityTaskWoken = pdFALSE; -char cChar; - - configASSERT( pvNotUsed == &xUARTInstance ); - - /* Read the interrupt ID register to see which interrupt is active. */ - ulActiveInterrupts = XUartPs_ReadReg(XPAR_PS7_UART_1_BASEADDR, XUARTPS_IMR_OFFSET); - ulActiveInterrupts &= XUartPs_ReadReg(XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET); - - /* Are any receive events of interest active? */ - if( ( ulActiveInterrupts & serRECEIVE_INTERRUPT_MASK ) != 0 ) - { - /* Read the Channel Status Register to determine if there is any data in - the RX FIFO. */ - ulChannelStatusRegister = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_SR_OFFSET ); - - /* Move data from the Rx FIFO to the Rx queue. NOTE THE COMMENTS AT THE - TOP OF THIS FILE ABOUT USING QUEUES FOR THIS PURPSOE. */ - while( ( ulChannelStatusRegister & XUARTPS_SR_RXEMPTY ) == 0 ) - { - cChar = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_FIFO_OFFSET ); - - /* If writing to the queue unblocks a task, and the unblocked task - has a priority above the currently running task (the task that this - interrupt interrupted), then xHigherPriorityTaskWoken will be set - to pdTRUE inside the xQueueSendFromISR() function. - xHigherPriorityTaskWoken is then passed to portYIELD_FROM_ISR() at - the end of this interrupt handler to request a context switch so the - interrupt returns directly to the (higher priority) unblocked - task. */ - xQueueSendFromISR( xRxQueue, &cChar, &xHigherPriorityTaskWoken ); - ulChannelStatusRegister = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_SR_OFFSET ); - } - } - - /* Are any transmit events of interest active? */ - if( ( ulActiveInterrupts & serTRANSMIT_IINTERRUPT_MASK ) != 0 ) - { - if( xUARTInstance.SendBuffer.RemainingBytes == 0 ) - { - /* Give back the semaphore to indicate that the tranmission is - complete. If giving the semaphore unblocks a task, and the - unblocked task has a priority above the currently running task (the - task that this interrupt interrupted), then xHigherPriorityTaskWoken - will be set to pdTRUE inside the xSemaphoreGiveFromISR() function. - xHigherPriorityTaskWoken is then passed to portYIELD_FROM_ISR() at - the end of this interrupt handler to request a context switch so the - interrupt returns directly to the (higher priority) unblocked - task. */ - xSemaphoreGiveFromISR( xTxCompleteSemaphore, &xHigherPriorityTaskWoken ); - - /* No more data to transmit. */ - XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_IDR_OFFSET, XUARTPS_IXR_TXEMPTY ); - } - else - { - /* More data to send. */ - XUartPs_SendBuffer( &xUARTInstance ); - } - } - - /* portYIELD_FROM_ISR() will request a context switch if executing this - interrupt handler caused a task to leave the blocked state, and the task - that left the blocked state has a higher priority than the currently running - task (the task this interrupt interrupted). See the comment above the calls - to xSemaphoreGiveFromISR() and xQueueSendFromISR() within this function. */ - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); - - /* Clear the interrupt status. */ - XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET, ulActiveInterrupts ); -} - - - - -