#include "string.h"\r
\r
/* Hardware specifics. */\r
+#include <machine.h>\r
#include "iodefine.h"\r
\r
/*-----------------------------------------------------------*/\r
#define portINITIAL_PSW ( ( portSTACK_TYPE ) 0x00030000 )\r
#define portINITIAL_FPSW ( ( portSTACK_TYPE ) 0x00000100 )\r
\r
-\r
/*-----------------------------------------------------------*/\r
\r
/*\r
\r
static void prvStartFirstTask( void );\r
\r
+static void prvYieldHandler( void );\r
+\r
+void vSoftwareInterruptISR( void );\r
+\r
/*-----------------------------------------------------------*/\r
\r
extern void *pxCurrentTCB;\r
prvStartFirstTask();\r
}\r
\r
+ /* Just to make sure the function is not optimised away. */\r
+ ( void ) vSoftwareInterruptISR();\r
+\r
/* Should not get here. */\r
return pdFAIL;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void vPortEndScheduler( void )\r
-{\r
- /* Not implemented as there is nothing to return to. */\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#pragma interrupt ( vTickISR( vect = _VECT( configTICK_VECTOR ), enable ) )\r
-void vTickISR( void )\r
-{\r
-static volatile unsigned long ul = 0;\r
-\r
- ul++;\r
- \r
- /* Clear the interrupt. */\r
-// vTaskIncrementTick();\r
- \r
- #if( configUSE_PREEMPTION == 1 )\r
-// taskYIELD();\r
- #endif\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#pragma interrupt ( vSoftwareInterruptISR( vect = _VECT( _ICU_SWINT ), enable ) )\r
-void vSoftwareInterruptISR( void )\r
-{\r
-static volatile unsigned long ul = 0;\r
-\r
- ul++;\r
-}\r
-\r
#pragma inline_asm prvStartFirstTask\r
static void prvStartFirstTask( void )\r
{\r
\r
/* Obtain the location of the stack associated with which ever task \r
pxCurrentTCB is currently pointing to. */\r
- MOV.L #_pxCurrentTCB,R15\r
- MOV.L [R15],R15\r
- MOV.L [R15],R0\r
+ MOV.L #_pxCurrentTCB, R15\r
+ MOV.L [R15], R15\r
+ MOV.L [R15], R0\r
\r
/* Restore the registers from the stack of the task pointed to by \r
pxCurrentTCB. */\r
NOP\r
NOP\r
}\r
+/*-----------------------------------------------------------*/\r
+\r
+#pragma interrupt ( vTickISR( vect = _VECT( configTICK_VECTOR ), enable ) )\r
+void vTickISR( void )\r
+{\r
+ /* Clear the interrupt. */\r
+ vTaskIncrementTick();\r
+ \r
+ #if( configUSE_PREEMPTION == 1 )\r
+ taskYIELD();\r
+ #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vSoftwareInterruptISR( void )\r
+{\r
+ prvYieldHandler();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#pragma inline_asm prvYieldHandler\r
+static void prvYieldHandler( void )\r
+{\r
+ /* Install as the software interrupt handler. */\r
+ .RVECTOR _VECT( _ICU_SWINT ), _vSoftwareInterruptISR\r
+\r
+ /* Re-enable interrupts. */\r
+ SETPSW I\r
+\r
+ /* Move the data that was automatically pushed onto the interrupt stack when\r
+ the interrupt occurred from the interrupt stack to the user stack. \r
+ \r
+ R15 is saved before it is used. */\r
+ PUSH.L R15\r
+ \r
+ /* Read the user stack pointer. */\r
+ MVFC USP, R15\r
+ \r
+ /* Move the address down to the data being moved. */\r
+ SUB #12, R15\r
+ MVTC R15, USP\r
+ \r
+ /* Copy the data accross. */\r
+ MOV.L [ R0 ], [ R15 ] ; R15\r
+ MOV.L 4[ R0 ], 4[ R15 ] ; PC\r
+ MOV.L 8[ R0 ], 8[ R15 ] ; PSW\r
+\r
+ /* Move the interrupt stack pointer to its new correct position. */\r
+ ADD #12, R0\r
+ \r
+ /* All the rest of the registers are saved directly to the user stack. */\r
+ SETPSW U\r
+\r
+ /* Save the rest of the registers (R15 has been saved already. */\r
+ PUSHM R1-R14 ; General purpose registers. \r
+ MVFC FPSW, R15 ; Floating point status word.\r
+ PUSH.L R15\r
+ MVFACHI R15 ; Accumulator\r
+ PUSH.L R15\r
+ MVFACMI R15 ; Accumulator\r
+ SHLL #16, R15\r
+ PUSH.L R15\r
+\r
+ /* Save the stack pointer to the TCB. */\r
+ MOV.L #_pxCurrentTCB, R15\r
+ MOV.L [ R15 ], R15\r
+ MOV.L R0, [ R15 ]\r
+ \r
+ /* Ensure the interrupt mask is set to the syscall priority while the kernel\r
+ structures are being accessed. */\r
+ MVTIPL #configMAX_SYSCALL_INTERRUPT_PRIORITY\r
+\r
+ /* Select the next task to run. */\r
+ BSR.A _vTaskSwitchContext\r
+\r
+ /* Reset the interrupt mask. */\r
+ MVTIPL #configKERNEL_INTERRUPT_PRIORITY\r
+\r
+ /* Load the stack pointer of the task that is now selected as the Running\r
+ state task from its TCB. */\r
+ MOV.L #_pxCurrentTCB,R15\r
+ MOV.L [ R15 ], R15\r
+ MOV.L [ R15 ], R0\r
+\r
+ /* Restore the context of the new task. The PSW (Program Status Word) and\r
+ PC will be popped by the RTE instruction. */\r
+ POP R15\r
+ MVTACLO R15\r
+ POP R15\r
+ MVTACHI R15\r
+ POP R15\r
+ MVTC R15,FPSW\r
+ POPM R1-R15\r
+ RTE\r
+ NOP\r
+ NOP\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortEndScheduler( void )\r
+{\r
+ /* Not implemented as there is nothing to return to. */\r
+ \r
+ /* The following line is just to prevent the symbol getting optimised away. */\r
+ ( void ) vTaskSwitchContext();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
\r
\r