*/\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