\r
/*-----------------------------------------------------------*/\r
\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
-\r
/*\r
* See header file for description.\r
*/\r
INCLUDE portASM.h\r
\r
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; SVC handler is used to start the scheduler and yield a task.\r
+; SVC handler is used to yield a task.\r
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
FreeRTOS_SWI_Handler\r
\r
portSAVE_CONTEXT\r
LDR R0, =vTaskSwitchContext\r
BLX R0\r
+ portRESTORE_CONTEXT\r
\r
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
+; vPortRestoreTaskContext is used to start the scheduler.\r
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
vPortRestoreTaskContext\r
+ ; Switch to system mode\r
+ CPS #SYS_MODE\r
portRESTORE_CONTEXT\r
\r
-\r
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
; IRQ interrupt handler used when individual priorities cannot be masked\r
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
AND r2, r2, #4\r
SUB sp, sp, r2\r
\r
- ; Call the interrupt handler\r
+ ; Obtain the address of the interrupt handler, then call it.\r
PUSH {r0-r3, lr}\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
+ STR r1, [r1] ; [SAMA5] Write to IVR in case protect mode is being used.\r
+ DSB\r
+ ISB\r
+ CPSIE i\r
BLX r0\r
POP {r0-r3, lr}\r
ADD sp, sp, r2\r
}\r
\r
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )\r
- #define portYIELD() __asm( "SWI 0" );\r
+ #define portYIELD() __asm( "SWI 0" ); __ISB()\r
\r
\r
/*-----------------------------------------------------------\r
\r
#define portENTER_CRITICAL() vPortEnterCritical();\r
#define portEXIT_CRITICAL() vPortExitCritical();\r
- #define portDISABLE_INTERRUPTS() __disable_irq() /* No priority mask register so global disable is used. */\r
+ #define portDISABLE_INTERRUPTS() __disable_irq(); __DSB(); __ISB() /* No priority mask register so global disable is used. */\r
#define portENABLE_INTERRUPTS() __enable_irq()\r
- #define portSET_INTERRUPT_MASK_FROM_ISR() __get_interrupt_state()\r
+ #define portSET_INTERRUPT_MASK_FROM_ISR() __get_interrupt_state(); __disable_irq() /* No priority mask register so global disable is used. */\r
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) __set_interrupt_state(x)\r
\r
/*-----------------------------------------------------------*/\r