/*\r
- FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.\r
+ FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\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
+ >>! 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
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
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )\r
#endif\r
\r
+/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in\r
+portmacro.h. */\r
#ifndef configCLEAR_TICK_INTERRUPT\r
#define configCLEAR_TICK_INTERRUPT()\r
#endif\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
{ \\r
portCPU_IRQ_DISABLE(); \\r
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \\r
- __asm( "DSB \n" \\r
- "ISB \n" ); \\r
+ __asm volatile ( "DSB \n" \\r
+ "ISB \n" ); \\r
portCPU_IRQ_ENABLE(); \\r
}\r
\r
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )\r
#define portBIT_0_SET ( ( uint8_t ) 0x01 )\r
\r
+/* Let the user override the pre-loading of the initial LR with the address of\r
+prvTaskExitError() in case is messes up unwinding of the stack in the\r
+debugger. */\r
+#ifdef configTASK_RETURN_ADDRESS\r
+ #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS\r
+#else\r
+ #define portTASK_RETURN_ADDRESS prvTaskExitError\r
+#endif\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\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
pxTopOfStack--;\r
\r
/* Next all the registers other than the stack pointer. */\r
- *pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */\r
+ *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* R14 */\r
pxTopOfStack--;\r
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */\r
pxTopOfStack--;\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( ulPortInterruptNesting == ~0UL );\r
+ portDISABLE_INTERRUPTS();\r
+ for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
BaseType_t xPortStartScheduler( void )\r
{\r
uint32_t ulAPSR;\r
\r
/* Will only get here if xTaskStartScheduler() was called with the CPU in\r
a non-privileged mode or the binary point register was not set to its lowest\r
- possible value. */\r
+ possible value. prvTaskExitError() is referenced to prevent a compiler\r
+ warning about it being defined but not referenced in the case that the user\r
+ defines their own exit address. */\r
+ ( void ) prvTaskExitError;\r
return 0;\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
necessary to turn off interrupts in the CPU itself while the ICCPMR is being\r
updated. */\r
portCPU_IRQ_DISABLE();\r
- portICCPMR_PRIORITY_MASK_REGISTER = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );\r
- __asm( "dsb \n"\r
- "isb \n" );\r
+ portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );\r
+ __asm volatile ( "dsb \n"\r
+ "isb \n" );\r
portCPU_IRQ_ENABLE();\r
\r
/* Increment the RTOS tick. */\r
ulPortTaskHasFPUContext = pdTRUE;\r
\r
/* Initialise the floating point status register. */\r
- __asm( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) );\r
+ __asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) );\r
}\r
/*-----------------------------------------------------------*/\r
\r
/* Interrupt in the CPU must be turned off while the ICCPMR is being\r
updated. */\r
portCPU_IRQ_DISABLE();\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
- __asm( "dsb \n"\r
- "isb \n" );\r
+ portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );\r
+ __asm volatile ( "dsb \n"\r
+ "isb \n" );\r
}\r
portCPU_IRQ_ENABLE();\r
\r
configMAX_SYSCALL_INTERRUPT_PRIORITY.\r
\r
FreeRTOS maintains separate thread and ISR API functions to ensure\r
- interrupt entry is as fast and simple as possible.\r
-\r
- The following links provide detailed information:\r
- http://www.freertos.org/RTOS-Cortex-M3-M4.html\r
- http://www.freertos.org/FAQHelp.html */\r
- configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );\r
+ interrupt entry is as fast and simple as possible. */\r
+ configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );\r
\r
/* Priority grouping: The interrupt controller (GIC) allows the bits\r
that define each interrupt's priority to be split between bits that\r