*/\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
#warning What about branch distance in asm file.\r
#warning Does not support flop use in ISRs.\r
#warning Level interrupts must be cleared in their handling function.\r
-#warning Can this be made generic by defining the vector address register externally?\r
\r
/*\r
* See header file for description.\r
}\r
\r
pxTopOfStack--;\r
-#warning What about task exit error function?\r
+\r
/* Next the return address, which in this case is the start of the task. */\r
*pxTopOfStack = ( StackType_t ) pxCode;\r
pxTopOfStack--;\r
\r
/* Next all the registers other than the stack pointer. */\r
- *pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */\r
+ *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* 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
/* Start the timer that generates the tick ISR. */\r
configSETUP_TICK_INTERRUPT();\r
-#warning Install spurious handler\r
__enable_irq();\r
vPortRestoreTaskContext();\r
}\r
POP {R1}\r
STR R1, [R0]\r
\r
- ; Ensure the priority mask is correct for the critical nesting depth\r
-;_RB_ LDR R2, =portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS\r
- CMP R1, #0\r
- MOVEQ R4, #255\r
-;_RB_ LDRNE R4, =( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT )\r
- STR R4, [r2]\r
-\r
; Restore all system mode registers other than the SP (which is already\r
; being used)\r
POP {R0-R12, R14}\r
\r
- ; Return to the task code, loading CPSR on the way.\r
+ ; Return to the task code, loading CPSR on the way. CPSR has the interrupt\r
+ ; enable bit set appropriately for the task about to execute.\r
RFEIA sp!\r
\r
endm\r
SVC_MODE EQU 0x13\r
IRQ_MODE EQU 0x12\r
\r
-; AIC register definitions.\r
-AIC_IVR EQU 0xFFFFF010UL\r
-AIC_EOICR EQU 0xFFFFF038UL\r
-\r
SECTION .text:CODE:ROOT(2)\r
ARM\r
\r
\r
\r
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; AIC interrupt handler\r
+; IRQ interrupt handler used when individual priorities cannot be masked\r
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
FreeRTOS_IRQ_Handler\r
\r
\r
; Call the interrupt handler\r
PUSH {r0-r3, lr}\r
- LDR r1, =AIC_IVR\r
+ LDR r1, =configINTERRUPT_VECTOR_ADDRESS\r
LDR r0, [r1]\r
STR r1, [r1] ; Write to IVR in case protect mode is being used.\r
BLX r0\r
CPSID i\r
\r
; Write to the EOI register\r
- LDR r4, =AIC_EOICR\r
+ LDR r4, =configEOI_ADDRESS\r
STR r0, [r4]\r
\r
; Restore the old nesting count\r