/* Library includes. */\r
#include "string.h"\r
\r
-#define portINITIAL_SR 0UL /* No interrupts masked. */\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The SR assigned to a newly created task. The only important thing in this\r
+value is for all interrupts to be enabled. */\r
+#define portINITIAL_SR ( 0UL )\r
\r
-/* Allocate enough space for FPR0 to FPR15, FPUL and FPSCR, each of which is 4\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
\r
/*-----------------------------------------------------------*/\r
\r
-/*\r
- * Setup a peripheral timer to generate the RTOS tick interrupt.\r
- */\r
-static void prvSetupTimerInterrupt( void );\r
-\r
/*\r
* The TRAPA handler used to force a context switch.\r
*/\r
\r
portBASE_TYPE xPortStartScheduler( void )\r
{\r
- /* Start the tick interrupt. */\r
- prvSetupTimerInterrupt();\r
- \r
- /* Start the first task. */\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
+\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
\r
/* Should not get here. */\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void vPortTickInterrupt( void )\r
-{\r
- vTaskIncrementTick();\r
- #if configUSE_PREEMPTION == 1\r
- vTaskSwitchContext();\r
- #endif\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvSetupTimerInterrupt( void )\r
-{\r
-extern void vApplicationSetupTimerInterrupt( void );\r
-\r
- /* Call an application function to set up the timer. This way the application\r
- can decide which peripheral to use. A demo application is provided to show a\r
- suitable example. */\r
- vApplicationSetupTimerInterrupt();\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
void vPortYield( void )\r
{\r
long lInterruptMask;\r
\r
+ /* Ensure the yield trap runs at the same priority as the other interrupts\r
+ that can cause a context switch. */\r
lInterruptMask = get_imask();\r
\r
/* taskYIELD() can only be called from a task, not an interrupt, so the\r
\r
trapa( portYIELD_TRAP_NO );\r
\r
+ /* Restore the interrupt mask to whatever it was previously (when the\r
+ function was entered. */\r
set_imask( ( int ) lInterruptMask );\r
}\r
/*-----------------------------------------------------------*/\r
portBASE_TYPE xReturn;\r
extern void * volatile pxCurrentTCB;\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 = pxCurrentTCB;\r
+ xTask = ( xTaskHandle ) pxCurrentTCB;\r
}\r
\r
/* Allocate a buffer large enough to hold all the flop registers. */\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
*pulFlopBuffer = get_fpscr();\r
\r
- /* Use the task tag to point to the flop buffer. Pass pointer to just above\r
- the buffer because the flop save routine uses a pre-decrement. */\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