/*\r
- FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd. \r
+ FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
\r
- ***************************************************************************\r
- * *\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
- * 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
- * Thank you! *\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
\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
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
\r
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available from the following\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
link: http://www.freertos.org/a00114.html\r
\r
- 1 tab == 4 spaces!\r
-\r
***************************************************************************\r
* *\r
- * Having a problem? Start by reading the FAQ "My application does *\r
- * not run, what could be wrong?" *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
* *\r
- * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
* *\r
***************************************************************************\r
\r
- http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
- license and Real Time Engineers Ltd. contact details.\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
+\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
+\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
\r
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
\r
- http://www.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
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
\r
http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
engineered and independently SIL3 certified version for use in safety and\r
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )\r
#endif\r
\r
+#ifndef configCLEAR_TICK_INTERRUPT\r
+ #define configCLEAR_TICK_INTERRUPT()\r
+#endif\r
+\r
/* The number of bits to shift for an interrupt priority is dependent on the\r
number of bits implemented by the interrupt controller. */\r
#if configUNIQUE_INTERRUPT_PRIORITIES == 16\r
\r
/* A critical section is exited when the critical section nesting count reaches\r
this value. */\r
-#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 )\r
+#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )\r
\r
/* In all GICs 255 can be written to the priority mask register to unmask all\r
(but the lowest) interrupt priority. */\r
-#define portUNMASK_VALUE ( 0xFF )\r
+#define portUNMASK_VALUE ( 0xFFUL )\r
\r
/* Tasks are not created with a floating point context, but can be given a\r
floating point context after they have been created. A variable is stored as\r
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task\r
does not have an FPU context, or any other value if the task does have an FPU\r
context. */\r
-#define portNO_FLOATING_POINT_CONTEXT ( ( portSTACK_TYPE ) 0 )\r
+#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )\r
\r
/* Interrupt controller access addresses. */\r
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )\r
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )\r
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )\r
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )\r
-#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile unsigned long * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )\r
+#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )\r
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )\r
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )\r
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )\r
-#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile unsigned long * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )\r
-#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile unsigned char * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )\r
+#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )\r
+#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )\r
\r
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary\r
point is zero. */\r
-#define portBINARY_POINT_BITS ( ( unsigned char ) 0x03 )\r
+#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )\r
\r
/* Constants required to setup the initial task context. */\r
-#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */\r
-#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )\r
-#define portINTERRUPT_ENABLE_BIT ( 0x80UL )\r
+#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */\r
+#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )\r
#define portTHUMB_MODE_ADDRESS ( 0x01UL )\r
\r
/* Masks all bits in the APSR other than the mode bits. */\r
*/\r
extern void vPortRestoreTaskContext( 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
/* A variable is used to keep track of the critical section nesting. This\r
a non zero value to ensure interrupts don't inadvertently become unmasked before\r
the scheduler starts. As it is stored as part of the task context it will\r
automatically be set to 0 when the first task is started. */\r
-volatile unsigned long ulCriticalNesting = 9999UL;\r
+volatile uint32_t ulCriticalNesting = 9999UL;\r
\r
/* Used to pass constants into the ASM code. The address at which variables are\r
placed is the constant value so indirect loads in the asm code are not\r
required. */\r
-unsigned long ulICCIAR __attribute__( ( at( portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ) ) );\r
-unsigned long ulICCEOIR __attribute__( ( at( portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ) ) );\r
-unsigned long ulICCPMR __attribute__( ( at( portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ) ) );\r
-unsigned long ulAsmAPIPriorityMask __attribute__( ( at( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) );\r
+uint32_t ulICCIAR __attribute__( ( at( portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ) ) );\r
+uint32_t ulICCEOIR __attribute__( ( at( portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ) ) );\r
+uint32_t ulICCPMR __attribute__( ( at( portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ) ) );\r
+uint32_t ulAsmAPIPriorityMask __attribute__( ( at( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) );\r
\r
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then\r
a floating point context must be saved and restored for the task. */\r
-unsigned long ulPortTaskHasFPUContext = pdFALSE;\r
+uint32_t ulPortTaskHasFPUContext = pdFALSE;\r
\r
/* Set to 1 to pend a context switch from an ISR. */\r
-unsigned long ulPortYieldRequired = pdFALSE;\r
+uint32_t ulPortYieldRequired = pdFALSE;\r
\r
/* Counts the interrupt nesting depth. A context switch is only performed if\r
if the nesting depth is 0. */\r
-unsigned long ulPortInterruptNesting = 0UL;\r
+uint32_t ulPortInterruptNesting = 0UL;\r
\r
/*-----------------------------------------------------------*/\r
\r
/*\r
* See header file for description.\r
*/\r
-portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
+StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )\r
{\r
/* Setup the initial stack of the task. The stack is set exactly as\r
expected by the portRESTORE_CONTEXT() macro.\r
pxTopOfStack--;\r
*pxTopOfStack = NULL;\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;\r
+ *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;\r
\r
- if( ( ( unsigned long ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL )\r
+ if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL )\r
{\r
/* The task will start in THUMB mode. */\r
*pxTopOfStack |= portTHUMB_MODE_BIT;\r
pxTopOfStack--;\r
\r
/* Next the return address, which in this case is the start of the task. */\r
- *pxTopOfStack = ( portSTACK_TYPE ) pxCode;\r
+ *pxTopOfStack = ( StackType_t ) pxCode;\r
pxTopOfStack--;\r
\r
/* Next all the registers other than the stack pointer. */\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x00000000; /* R14 */\r
+ *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* R14 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */\r
+ *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */\r
+ *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */\r
+ *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */\r
+ *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */\r
+ *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */\r
+ *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */\r
+ *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */\r
+ *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */\r
+ *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */\r
+ *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */\r
+ *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */\r
+ *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */\r
pxTopOfStack--;\r
- *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */\r
+ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */\r
pxTopOfStack--;\r
\r
/* The task will start with a critical nesting count of 0 as interrupts are\r
}\r
/*-----------------------------------------------------------*/\r
\r
-portBASE_TYPE xPortStartScheduler( void )\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( ulPortInterruptNesting == ~0UL );\r
+ portDISABLE_INTERRUPTS();\r
+ for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+BaseType_t xPortStartScheduler( void )\r
{\r
-unsigned long ulAPSR;\r
+uint32_t ulAPSR;\r
\r
/* Only continue if the CPU is not in User mode. The CPU must be in a\r
Privileged mode for the scheduler to start. */\r
setting. See the comments in vPortValidateInterruptPriority() below for\r
more information. */\r
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );\r
- \r
+\r
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )\r
- { \r
+ {\r
/* Start the timer that generates the tick ISR. */\r
configSETUP_TICK_INTERRUPT();\r
\r
\r
void vPortEndScheduler( void )\r
{\r
- /* It is unlikely that the ARM port will require this function as there\r
- is nothing to return to. */\r
+ /* Not implemented in ports where there is nothing to return to.\r
+ Artificially force an assert. */\r
+ configASSERT( ulCriticalNesting == 1000UL );\r
}\r
/*-----------------------------------------------------------*/\r
\r
directly. Increment ulCriticalNesting to keep a count of how many times\r
portENTER_CRITICAL() has been called. */\r
ulCriticalNesting++;\r
+\r
+ /* This is not the interrupt safe version of the enter critical function so\r
+ assert() if it is being called from an interrupt context. Only API\r
+ functions that end in "FromISR" can be used in an interrupt. Only assert if\r
+ the critical nesting count is 1 to protect against recursive calls if the\r
+ assert function also uses a critical section. */\r
+ if( ulCriticalNesting == 1 )\r
+ {\r
+ configASSERT( ulPortInterruptNesting == 0 );\r
+ }\r
}\r
/*-----------------------------------------------------------*/\r
\r
handler runs at the lowest priority, so interrupts cannot already be masked,\r
so there is no need to save and restore the current mask value. */\r
__disable_irq();\r
- portICCPMR_PRIORITY_MASK_REGISTER = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );\r
+ portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );\r
__asm( "DSB \n"\r
"ISB \n" );\r
__enable_irq();\r
\r
/* Ensure all interrupt priorities are active again. */\r
portCLEAR_INTERRUPT_MASK();\r
+ configCLEAR_TICK_INTERRUPT();\r
}\r
/*-----------------------------------------------------------*/\r
\r
void vPortTaskUsesFPU( void )\r
{\r
-unsigned long ulInitialFPSCR = 0;\r
+uint32_t ulInitialFPSCR = 0;\r
\r
/* A task is registering the fact that it needs an FPU context. Set the\r
FPU flag (which is saved as part of the task context). */\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void vPortClearInterruptMask( unsigned long ulNewMaskValue )\r
+void vPortClearInterruptMask( uint32_t ulNewMaskValue )\r
{\r
if( ulNewMaskValue == pdFALSE )\r
{\r
}\r
/*-----------------------------------------------------------*/\r
\r
-unsigned long ulPortSetInterruptMask( void )\r
+uint32_t ulPortSetInterruptMask( void )\r
{\r
-unsigned long ulReturn;\r
+uint32_t ulReturn;\r
\r
__disable_irq();\r
- if( portICCPMR_PRIORITY_MASK_REGISTER == ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )\r
+ if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )\r
{\r
/* Interrupts were already masked. */\r
ulReturn = pdTRUE;\r
else\r
{\r
ulReturn = pdFALSE;\r
- portICCPMR_PRIORITY_MASK_REGISTER = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );\r
+ portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );\r
__asm( "DSB \n"\r
"ISB \n" );\r
}\r