/*\r
- FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+ FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.\r
\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
\r
***************************************************************************\r
* *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that has become a de facto standard. *\r
* *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
+ * Help yourself get started quickly and support the FreeRTOS *\r
+ * project by purchasing a FreeRTOS tutorial book, reference *\r
+ * manual, or both from: http://www.FreeRTOS.org/Documentation *\r
* *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * Thank you! *\r
* *\r
***************************************************************************\r
\r
-\r
This file is part of the FreeRTOS distribution.\r
\r
FreeRTOS is free software; you can redistribute it and/or modify it under\r
the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ >>! NOTE: The modification to the GPL is included to allow you to distribute\r
+ >>! a combined work that includes FreeRTOS without being obliged to provide\r
+ >>! the source code for proprietary components outside of the FreeRTOS\r
+ >>! kernel.\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available from the following\r
+ link: http://www.freertos.org/a00114.html\r
\r
1 tab == 4 spaces!\r
\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong?" *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
+ license and Real Time Engineers Ltd. contact details.\r
\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
+ Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and middleware.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
*/\r
\r
/* Standard includes. */\r
*\r
*/\r
\r
-/*\r
-\r
-Changes from V4.1.1\r
-\r
- + The second set of tasks were created the wrong way around. This has been\r
- corrected.\r
-*/\r
-\r
-\r
#include <stdlib.h>\r
\r
/* Scheduler include files. */\r
unsigned long ulReceived;\r
xQueueHandle xActivatedQueue;\r
\r
+ /* Remove compiler warnings. */\r
+ ( void ) pvParameters;\r
+\r
/* Create the queues and add them to the queue set before resuming the Tx\r
task. */\r
prvSetupTest();\r
*/\r
static void prvDemonstrateTaskStateAndHandleGetFunctions( void );\r
\r
+/*\r
+ * A task to demonstrate the use of the xQueueSpacesAvailable() function.\r
+ */\r
+static void prvDemoQueueSpaceFunctions( void *pvParameters );\r
+\r
/*-----------------------------------------------------------*/\r
\r
/* The variable into which error messages are latched. */\r
vStartCountingSemaphoreTasks();\r
vStartDynamicPriorityTasks();\r
vStartQueueSetTasks();\r
- vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );\r
+ vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY ); \r
+ xTaskCreate( prvDemoQueueSpaceFunctions, ( signed char * ) "QSpace", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
\r
/* The suicide tasks must be created last as they need to know how many\r
tasks were running prior to their creation. This then allows them to \r
}\r
/*-----------------------------------------------------------*/\r
\r
+static void prvDemoQueueSpaceFunctions( void *pvParameters )\r
+{\r
+xQueueHandle xQueue = NULL;\r
+const unsigned portBASE_TYPE uxQueueLength = 10;\r
+unsigned portBASE_TYPE uxReturn, x;\r
+\r
+ /* Remove compiler warnings. */\r
+ ( void ) pvParameters;\r
+\r
+ /* Create the queue that will be used. Nothing is actually going to be\r
+ sent or received so the queue item size is set to 0. */\r
+ xQueue = xQueueCreate( uxQueueLength, 0 );\r
+ configASSERT( xQueue );\r
+\r
+ for( ;; )\r
+ {\r
+ for( x = 0; x < uxQueueLength; x++ )\r
+ {\r
+ /* Ask how many messages are available... */\r
+ uxReturn = uxQueueMessagesWaiting( xQueue );\r
+ \r
+ /* Check the number of messages being reported as being available\r
+ is as expected, and force an assert if not. */\r
+ if( uxReturn != x )\r
+ {\r
+ /* xQueue cannot be NULL so this is deliberately causing an\r
+ assert to be triggered as there is an error. */\r
+ configASSERT( xQueue == NULL );\r
+ }\r
+\r
+ /* Ask how many spaces remain in the queue... */\r
+ uxReturn = uxQueueSpacesAvailable( xQueue );\r
+ \r
+ /* Check the number of spaces being reported as being available\r
+ is as expected, and force an assert if not. */\r
+ if( uxReturn != ( uxQueueLength - x ) )\r
+ {\r
+ /* xQueue cannot be NULL so this is deliberately causing an\r
+ assert to be triggered as there is an error. */\r
+ configASSERT( xQueue == NULL );\r
+ }\r
+\r
+ /* Fill one more space in the queue. */\r
+ xQueueSendToBack( xQueue, NULL, 0 );\r
+ }\r
+\r
+ /* Perform the same check while the queue is full. */\r
+ uxReturn = uxQueueMessagesWaiting( xQueue );\r
+ if( uxReturn != uxQueueLength )\r
+ {\r
+ configASSERT( xQueue == NULL );\r
+ }\r
+\r
+ uxReturn = uxQueueSpacesAvailable( xQueue );\r
+ \r
+ if( uxReturn != 0 )\r
+ {\r
+ configASSERT( xQueue == NULL );\r
+ }\r
+\r
+ /* The queue is full, start again. */\r
+ xQueueReset( xQueue );\r
+ }\r
+}\r
+\r
\r
#define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue )\r
#endif\r
\r
+#ifndef traceMALLOC\r
+ #define traceMALLOC( pvAddress, uiSize )\r
+#endif\r
+\r
+#ifndef traceFREE\r
+ #define traceFREE( pvAddress, uiSize )\r
+#endif\r
+\r
#ifndef configGENERATE_RUN_TIME_STATS\r
#define configGENERATE_RUN_TIME_STATS 0\r
#endif\r
*/\r
static void vPortStartFirstTask( void ) __attribute__ (( naked ));\r
\r
+/*\r
+ * Used to catch tasks that attempt to return from their implementing function.\r
+ */\r
+static void prvTaskExitError( void );\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\r
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */\r
pxTopOfStack--;\r
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */\r
- pxTopOfStack -= 6; /* LR, R12, R3..R1 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) prvTaskExitError; /* LR */\r
+ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */\r
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */\r
pxTopOfStack -= 8; /* R11..R4. */\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
+static void prvTaskExitError( void )\r
+{\r
+ /* A function that implements a task must not exit or attempt to return to\r
+ its caller as there is nothing to return to. If a task wants to exit it \r
+ should instead call vTaskDelete( NULL ).\r
+ \r
+ Artificially force an assert() to be triggered if configASSERT() is \r
+ defined, then stop here so application writers can catch the error. */\r
+ configASSERT( uxCriticalNesting == ~0UL );\r
+ portDISABLE_INTERRUPTS(); \r
+ for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
void vPortSVCHandler( void )\r
{\r
__asm volatile (\r
" msr PRIMASK, r0 \n"\r
" bx lr "\r
);\r
+ \r
+ /* Just to avoid compiler warning. */\r
+ ( void ) ulMask;\r
}\r
/*-----------------------------------------------------------*/\r
\r
*/\r
extern void vPortStartFirstTask( void );\r
\r
+/*\r
+ * Used to catch tasks that attempt to return from their implementing function.\r
+ */\r
+static void prvTaskExitError( void );\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\r
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */\r
pxTopOfStack--;\r
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */\r
- pxTopOfStack -= 6; /* LR, R12, R3..R1 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) prvTaskExitError; /* LR */\r
+ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */\r
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */\r
pxTopOfStack -= 8; /* R11..R4. */\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
+static void prvTaskExitError( void )\r
+{\r
+ /* A function that implements a task must not exit or attempt to return to\r
+ its caller as there is nothing to return to. If a task wants to exit it \r
+ should instead call vTaskDelete( NULL ).\r
+ \r
+ Artificially force an assert() to be triggered if configASSERT() is \r
+ defined, then stop here so application writers can catch the error. */\r
+ configASSERT( uxCriticalNesting == ~0UL );\r
+ portDISABLE_INTERRUPTS(); \r
+ for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
/*\r
* See header file for description.\r
*/\r
*/\r
static void prvPortStartFirstTask( void );\r
\r
+/*\r
+ * Used to catch tasks that attempt to return from their implementing function.\r
+ */\r
+static void prvTaskExitError( void );\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\r
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */\r
pxTopOfStack--;\r
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */\r
- pxTopOfStack -= 6; /* LR, R12, R3..R1 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) prvTaskExitError; /* LR */\r
+ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */\r
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */\r
pxTopOfStack -= 8; /* R11..R4. */\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
+static void prvTaskExitError( void )\r
+{\r
+ /* A function that implements a task must not exit or attempt to return to\r
+ its caller as there is nothing to return to. If a task wants to exit it \r
+ should instead call vTaskDelete( NULL ).\r
+ \r
+ Artificially force an assert() to be triggered if configASSERT() is \r
+ defined, then stop here so application writers can catch the error. */\r
+ configASSERT( uxCriticalNesting == ~0UL );\r
+ portDISABLE_INTERRUPTS(); \r
+ for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
__asm void vPortSVCHandler( void )\r
{\r
extern pxCurrentTCB;\r
uxTaskGetSystemState() function. Note the formatting functions are provided\r
for convenience only, and are NOT considered part of the kernel. */\r
#include <stdio.h>\r
-#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) */\r
+#endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */\r
\r
/* Sanity check the configuration. */\r
#if configUSE_TICKLESS_IDLE != 0\r
\r
if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
{\r
- xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
+ if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
+ {\r
+ xYieldRequired = pdTRUE;\r
+ }\r
+\r
( void ) uxListRemove( &( pxTCB->xGenericListItem ) );\r
prvAddTaskToReadyList( pxTCB );\r
}\r
before or during the call to xPortStartScheduler(). The stacks of\r
the created tasks contain a status word with interrupts switched on\r
so interrupts will automatically get re-enabled when the first task\r
- starts to run.\r
-\r
- STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE\r
- DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */\r
+ starts to run. */\r
portDISABLE_INTERRUPTS();\r
\r
+ #if ( configUSE_NEWLIB_REENTRANT == 1 )\r
+ {\r
+ /* Switch Newlib's _impure_ptr variable to point to the _reent\r
+ structure specific to the task that will run first. */\r
+ _impure_ptr = &( pxCurrentTCB->xNewLib_reent );\r
+ }\r
+ #endif /* configUSE_NEWLIB_REENTRANT */\r
+\r
xSchedulerRunning = pdTRUE;\r
xTickCount = ( portTickType ) 0U;\r
\r
{\r
tskTCB *pxTCB;\r
portBASE_TYPE xAlreadyYielded = pdFALSE;\r
-portBASE_TYPE xYieldRequired = pdFALSE;\r
\r
/* If uxSchedulerSuspended is zero then this function does not match a\r
previous call to vTaskSuspendAll(). */\r
the current task then we should yield. */\r
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
{\r
- xYieldRequired = pdTRUE;\r
+ xYieldPending = pdTRUE;\r
}\r
}\r
\r
{\r
if( xTaskIncrementTick() != pdFALSE )\r
{\r
- xYieldRequired = pdTRUE;\r
+ xYieldPending = pdTRUE;\r
}\r
--uxPendedTicks;\r
}\r
}\r
\r
- if( ( xYieldRequired == pdTRUE ) || ( xYieldPending == pdTRUE ) )\r
+ if( xYieldPending == pdTRUE )\r
{\r
xAlreadyYielded = pdTRUE;\r
- xYieldPending = pdFALSE;\r
portYIELD_WITHIN_API();\r
}\r
}\r
portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) );\r
#else\r
*pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();\r
- #endif \r
+ #endif\r
}\r
}\r
#else\r
}\r
}\r
#endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */\r
+ \r
+ #if ( configUSE_TICK_HOOK == 1 )\r
+ {\r
+ /* Guard against the tick hook being called when the pended tick\r
+ count is being unwound (when the scheduler is being unlocked). */\r
+ if( uxPendedTicks == ( unsigned portBASE_TYPE ) 0U )\r
+ {\r
+ vApplicationTickHook();\r
+ }\r
+ }\r
+ #endif /* configUSE_TICK_HOOK */ \r
}\r
else\r
{\r
#endif\r
}\r
\r
- #if ( configUSE_TICK_HOOK == 1 )\r
+ #if ( configUSE_PREEMPTION == 1 )\r
{\r
- /* Guard against the tick hook being called when the missed tick\r
- count is being unwound (when the scheduler is being unlocked). */\r
- if( uxPendedTicks == ( unsigned portBASE_TYPE ) 0U )\r
+ if( xYieldPending != pdFALSE )\r
{\r
- vApplicationTickHook();\r
+ xSwitchRequired = pdTRUE;\r
}\r
}\r
- #endif /* configUSE_TICK_HOOK */\r
+ #endif /* configUSE_PREEMPTION */\r
\r
return xSwitchRequired;\r
}\r
}\r
else\r
{\r
+ xYieldPending = pdFALSE;\r
traceTASK_SWITCHED_OUT();\r
\r
#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
the calling task to know if it should force a context\r
switch now. */\r
xReturn = pdTRUE;\r
+\r
+ /* Mark that a yield is pending in case the user is not using the\r
+ "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */\r
+ xYieldPending = pdTRUE;\r
}\r
else\r
{\r
case tmrCOMMAND_CHANGE_PERIOD :\r
pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue;\r
configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );\r
+\r
+ /* The new period does not really have a reference, and can be\r
+ longer or shorter than the old one. The command time is \r
+ therefore set to the current time, and as the period cannot be\r
+ zero the next expiry time can only be in the future, meaning\r
+ (unlike for the xTimerStart() case above) there is no fail case\r
+ that needs to be handled here. */\r
( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );\r
break;\r
\r