]> git.sur5r.net Git - freertos/commitdiff
Continue work on RX600 port - work in progress - add the actual context switch function.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 18 Aug 2010 20:36:00 +0000 (20:36 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 18 Aug 2010 20:36:00 +0000 (20:36 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1049 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/portable/Renesas/RX600/port.c

index 2998d30cdf0e71ed5bc327bec271647bf9a00607..822a77c40679119154b4a2c9c23db065772bf408 100644 (file)
@@ -63,6 +63,7 @@
 #include "string.h"\r
 \r
 /* Hardware specifics. */\r
+#include <machine.h>\r
 #include "iodefine.h"\r
 \r
 /*-----------------------------------------------------------*/\r
@@ -78,7 +79,6 @@ flags set and IPL clear. */
 #define portINITIAL_PSW     ( ( portSTACK_TYPE ) 0x00030000 )\r
 #define portINITIAL_FPSW    ( ( portSTACK_TYPE ) 0x00000100 )\r
 \r
-\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
@@ -95,6 +95,10 @@ void vPortPendContextSwitch( void );
 \r
 static void prvStartFirstTask( void );\r
 \r
+static void prvYieldHandler( void );\r
+\r
+void vSoftwareInterruptISR( void );\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 extern void *pxCurrentTCB;\r
@@ -179,41 +183,14 @@ extern void vApplicationSetupTimerInterrupt( void );
                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
@@ -224,9 +201,9 @@ static void prvStartFirstTask( void )
 \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
@@ -241,5 +218,113 @@ static void prvStartFirstTask( void )
     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