]> git.sur5r.net Git - freertos/commitdiff
Continue work on RX600 port - work in progress.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Fri, 13 Aug 2010 17:38:50 +0000 (17:38 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Fri, 13 Aug 2010 17:38:50 +0000 (17:38 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1044 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/portable/Renesas/RX600/port.c
Source/portable/Renesas/RX600/portmacro.h

index b7cf7ffe9fdd39996f281ff3a68025b4d51cdace..e41221f618c74a0736edaf83aea8c44c9370d840 100644 (file)
 \r
 /*-----------------------------------------------------------*/\r
 \r
-/* Dimensions the array into which the floating point context is saved.  \r
-Allocate enough space for FPR0 to FPR15, FPUL and FPSCR, each of which is 4\r
-bytes big.  If this number is changed then the 72 in portasm.src also needs\r
-changing. */\r
-#define portFLOP_REGISTERS_TO_STORE    ( 18 )\r
-#define portFLOP_STORAGE_SIZE          ( portFLOP_REGISTERS_TO_STORE * 4 )\r
-\r
 /* Tasks should start with interrupts enabled, therefore PSW is set with U,I,PM \r
 flags set and IPL clear. */\r
-#define portINITIAL_PSW      ( ( portSTACK_TYPE ) 0x00130000 )\r
+/* \r
+ U = 1 User stack pointer.\r
+ I = 1 Interrupts enabled.\r
+ PM = 0 Supervisor mode.\r
+ IPL = 0 All interrupt priorities enabled.\r
+*/\r
+#define portINITIAL_PSW      ( ( portSTACK_TYPE ) 0x00030000 )\r
 #define portINITIAL_FPSW     ( ( portSTACK_TYPE ) 0x00000100 )\r
 \r
 \r
@@ -89,6 +88,16 @@ void vPortYield( void );
  */\r
 void vPortStartFirstTask( void );\r
 \r
+void vPortPendContextSwitch( void );\r
+\r
+static void prvStartFirstTask( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+extern void *pxCurrentTCB;\r
+\r
+unsigned char ucIPLToRestore = 0;\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* \r
@@ -148,17 +157,17 @@ portBASE_TYPE xPortStartScheduler( void )
 {\r
 extern void vApplicationSetupTimerInterrupt( void );\r
 \r
-       /* Call an application function to set up the timer that will generate the\r
-       tick interrupt.  This way the application can decide which peripheral to \r
-       use.  A demo application is provided to show a suitable example. */\r
-       vApplicationSetupTimerInterrupt();\r
+       /* Use pxCurrentTCB just so it does not get optimised away. */\r
+       if( pxCurrentTCB != NULL )\r
+       {\r
+               /* Call an application function to set up the timer that will generate the\r
+               tick interrupt.  This way the application can decide which peripheral to \r
+               use.  A demo application is provided to show a suitable example. */\r
+               vApplicationSetupTimerInterrupt();\r
 \r
-       /* Start the first task.  This will only restore the standard registers and\r
-       not the flop registers.  This does not really matter though because the only\r
-       flop register that is initialised to a particular value is fpscr, and it is\r
-       only initialised to the current value, which will still be the current value\r
-       when the first task starts executing. */\r
-       //trapa( portSTART_SCHEDULER_TRAP_NO );\r
+               /* Start the first task. */\r
+               prvStartFirstTask();\r
+       }\r
 \r
        /* Should not get here. */\r
        return pdFAIL;\r
@@ -176,3 +185,68 @@ void vPortYield( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+#pragma interrupt (vTickISR(vect=configTICK_VECTOR,enable))\r
+void vTickISR( void )\r
+{\r
+       /* Restore previous IPL on exit. */\r
+       //set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY );\r
+       \r
+       /* Clear the interrupt. */\r
+       vTaskIncrementTick();\r
+       \r
+       #if( configUSE_PREEMPTION == 1 )\r
+               taskYIELD();\r
+       #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortSetInterruptMask( void )\r
+{\r
+unsigned char ucPreviousIPL;\r
+\r
+       /* Store the current IPL to ensure it is restored correctly later if it is\r
+       not currently 0.  This is a stack variable, so there should not be a race\r
+       condition even if there is an interrupt or context switch before the new\r
+       IPL value gets set. */\r
+       ucPreviousIPL = get_ipl();\r
+       \r
+       /* Set the mask up to the max syscall priority. */\r
+       set_ipl( configMAX_SYSCALL_INTERRUPT_PRIORITY );\r
+       \r
+       /* Now the mask is set there will not be a context switch, so the previous\r
+       and current IPL values can be compared.  This ensures against the IPL being\r
+       set back to zero too early when critical sections nest. */\r
+       if( ucPreviousIPL < configMAX_SYSCALL_INTERRUPT_PRIORITY )\r
+       {\r
+               ucIPLToRestore = ucPreviousIPL;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#pragma inline_asm prvStartFirstTask\r
+static void prvStartFirstTask( void )\r
+{\r
+       /* When starting the scheduler there is nothing that needs moving to the\r
+       interrupt stack because the function is not called from an interrupt.\r
+       Just ensure the current stack is the user stack. */\r
+       SETPSW      U\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
+\r
+       /* Restore the registers from the stack of the task pointed to by \r
+       pxCurrentTCB. */\r
+    POP                R15\r
+    MVTACLO    R15             /* Accumulator low 32 bits. */\r
+    POP                R15\r
+    MVTACHI    R15             /* Accumulator high 32 bits. */\r
+    POP                R15\r
+    MVTC       R15,FPSW        /* Floating point status word. */\r
+    POPM       R1-R15          /* R1 to R15 - R0 is not included as it is the SP. */\r
+    RTE                                        /* This pops the remaining registers. */\r
+    NOP\r
+    NOP\r
+}\r
index 4702fc5d689da3de0b85c72f540d59475145e085..3cc3b6d26a38884d1a14dd432d8176a958326ab2 100644 (file)
@@ -59,6 +59,9 @@
 extern "C" {\r
 #endif\r
 \r
+/* Hardware specifics. */\r
+#include "machine.h"\r
+\r
 /*-----------------------------------------------------------\r
  * Port specific definitions.  \r
  *\r
@@ -106,8 +109,9 @@ extern void vTaskSwitchContext( void );
  * These macros should be called directly, but through the taskENTER_CRITICAL()\r
  * and taskEXIT_CRITICAL() macros.\r
  */\r
-#define portENABLE_INTERRUPTS()        \r
-#define portDISABLE_INTERRUPTS()       \r
+extern unsigned char ucIPLToRestore;\r
+#define portENABLE_INTERRUPTS()        set_ipl( ucIPLToRestore )\r
+#define portDISABLE_INTERRUPTS()       vPortSetInterruptMask()\r
 \r
 /* Critical nesting counts are stored in the TCB. */\r
 #define portCRITICAL_NESTING_IN_TCB ( 1 )\r