/* Library includes. */\r
#include "string.h"\r
\r
+/* Hardware specifics. */\r
+#include "iodefine.h"\r
+\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
+/* Tasks should start with interrupts enabled, therefore PSW is set with U,I,PM \r
+flags set and IPL clear. */\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
/*-----------------------------------------------------------*/\r
\r
*/\r
void vPortStartFirstTask( void );\r
\r
+void vPortPendContextSwitch( void );\r
+\r
+static void prvStartFirstTask( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+extern void *pxCurrentTCB;\r
+\r
/*-----------------------------------------------------------*/\r
\r
/* \r
*/\r
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
{\r
+ /* R0 is not included as it is the stack pointer. */\r
+ \r
+ *pxTopOfStack = 0xdeadbeef;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = portINITIAL_PSW;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) pxCode;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0xffffffff; /* r15. */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0xeeeeeeee;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0xdddddddd;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0xcccccccc;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0xbbbbbbbb;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0xaaaaaaaa;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0x99999999;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0x88888888;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0x77777777;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0x66666666;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0x55555555;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0x44444444;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0x33333333;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0x22222222;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R1 */\r
+ pxTopOfStack--; \r
+ *pxTopOfStack = portINITIAL_FPSW;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0x12345678; /* Accumulator. */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = 0x87654321; /* Accumulator. */\r
+\r
return pxTopOfStack;\r
}\r
/*-----------------------------------------------------------*/\r
{\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
+ /* Enable the software interrupt. */ \r
+ _IEN( _ICU_SWINT ) = 1;\r
+ \r
+ /* Ensure the software interrupt is clear. */\r
+ _IR( _ICU_SWINT ) = 0;\r
+ \r
+ /* Ensure the software interrupt is set to the kernel priority. */\r
+ _IPR( _ICU_SWINT ) = configKERNEL_INTERRUPT_PRIORITY;\r
+ \r
+ /* Start the first task. */\r
+ prvStartFirstTask();\r
+ }\r
\r
/* Should not get here. */\r
return pdFAIL;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void vPortYield( void )\r
-{\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-portBASE_TYPE xPortUsesFloatingPoint( xTaskHandle xTask )\r
+#pragma interrupt ( vTickISR( vect = _VECT( configTICK_VECTOR ), enable ) )\r
+void vTickISR( void )\r
{\r
-unsigned long *pulFlopBuffer;\r
-portBASE_TYPE xReturn;\r
-extern void * volatile pxCurrentTCB;\r
+static volatile unsigned long ul = 0;\r
\r
- /* This function tells the kernel that the task referenced by xTask is\r
- going to use the floating point registers and therefore requires the\r
- floating point registers saved as part of its context. */\r
-\r
- /* Passing NULL as xTask is used to indicate that the calling task is the\r
- subject task - so pxCurrentTCB is the task handle. */\r
- if( xTask == NULL )\r
- {\r
- xTask = ( xTaskHandle ) pxCurrentTCB;\r
- }\r
-\r
- /* Allocate a buffer large enough to hold all the flop registers. */\r
- pulFlopBuffer = ( unsigned long * ) pvPortMalloc( portFLOP_STORAGE_SIZE );\r
+ ul++;\r
\r
- if( pulFlopBuffer != NULL )\r
- {\r
- /* Start with the registers in a benign state. */\r
- memset( ( void * ) pulFlopBuffer, 0x00, portFLOP_STORAGE_SIZE );\r
- \r
- /* The first thing to get saved in the buffer is the FPSCR value -\r
- initialise this to the current FPSCR value. */\r
-//_RB_ *pulFlopBuffer = get_fpscr();\r
- \r
- /* Use the task tag to point to the flop buffer. Pass pointer to just \r
- above the buffer because the flop save routine uses a pre-decrement. */\r
- vTaskSetApplicationTaskTag( xTask, ( void * ) ( pulFlopBuffer + portFLOP_REGISTERS_TO_STORE ) ); \r
- xReturn = pdPASS;\r
- }\r
- else\r
- {\r
- xReturn = pdFAIL;\r
- }\r
+ /* Clear the interrupt. */\r
+// vTaskIncrementTick();\r
\r
- return xReturn;\r
+ #if( configUSE_PREEMPTION == 1 )\r
+// taskYIELD();\r
+ #endif\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void vPortSaveFlopRegisters( void *pvBuffer )\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
\r
-void vPortRestoreFlopRegisters( void *pvBuffer )\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
-/*-----------------------------------------------------------*/\r
+\r
\r