+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ http://www.FreeRTOS.org - Documentation, training, latest information,\r
+ license and contact details.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell\r
+ the code with commercial support, indemnification, and middleware, under\r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under\r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Count of the critical section nesting depth. */\r
+unsigned portLONG ulCriticalNesting = 9999;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Registers required to configure the RTI. */\r
+#define portRTI_GCTRL_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC00 ) )\r
+#define portRTI_TBCTRL_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC04 ) )\r
+#define portRTI_COMPCTRL_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC0C ) )\r
+#define portRTI_CNT0_FRC0_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC10 ) )\r
+#define portRTI_CNT0_UC0_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC14 ) )\r
+#define portRTI_CNT0_CPUC0_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC18 ) )\r
+#define portRTI_CNT0_COMP0_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC50 ) )\r
+#define portRTI_CNT0_UDCP0_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC54 ) )\r
+#define portRTI_SETINTENA_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC80 ) )\r
+#define portRTI_CLEARINTENA_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC84 ) )\r
+#define portRTI_INTFLAG_REG ( * ( ( volatile unsigned long * ) 0xFFFFFC88 ) )\r
+\r
+\r
+/* Constants required to set up the initial stack of each task. */\r
+#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1F )\r
+#define portINITIAL_FPSCR ( ( portSTACK_TYPE ) 0x00 )\r
+#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 0x04 )\r
+#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )\r
+\r
+/* The number of words on the stack frame between the saved Top Of Stack and\r
+R0 (in which the parameters are passed. */\r
+#define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* vPortStartFirstSTask() is defined in portASM.asm */\r
+extern void vPortStartFirstTask( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Saved as part of the task context. Set to pdFALSE if the task does not\r
+require an FPU context. */\r
+unsigned long ulTaskHasFPUContext = 0;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+/*\r
+ * See header file for description.\r
+ */\r
+portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
+{\r
+portSTACK_TYPE *pxOriginalTOS;\r
+\r
+ pxOriginalTOS = pxTopOfStack;\r
+\r
+ #if __TI_VFP_SUPPORT__\r
+ {\r
+ /* Ensure the stack is correctly aligned on exit. */\r
+ pxTopOfStack--;\r
+ }\r
+ #endif\r
+\r
+ /* Setup the initial stack of the task. The stack is set exactly as\r
+ expected by the portRESTORE_CONTEXT() macro. */\r
+\r
+ /* First on the stack is the return address - which is the start of the as\r
+ the task has not executed yet. The offset is added to make the return\r
+ address appear as it would within an IRQ ISR. */\r
+ *pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;\r
+ pxTopOfStack--;\r
+\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x00000000; /* R14 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */\r
+ pxTopOfStack--;\r
+\r
+ #ifdef portPRELOAD_TASK_REGISTERS\r
+ {\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */\r
+ pxTopOfStack--;\r
+ }\r
+ #else\r
+ {\r
+ pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS;\r
+ }\r
+ #endif\r
+\r
+ /* Function parameters are passed in R0. */\r
+ *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */\r
+ pxTopOfStack--;\r
+\r
+ /* Set the status register for system mode, with interrupts enabled. */\r
+ *pxTopOfStack = ( portSTACK_TYPE ) ( ( _get_CPSR() & ~0xFF ) | portINITIAL_SPSR );\r
+\r
+ if( ( ( unsigned long ) pxCode & 0x01UL ) != 0x00 )\r
+ {\r
+ /* The task will start in thumb mode. */\r
+ *pxTopOfStack |= portTHUMB_MODE_BIT;\r
+ }\r
+\r
+ #ifdef __TI_VFP_SUPPORT__\r
+ {\r
+ pxTopOfStack--;\r
+\r
+ /* The last thing on the stack is the tasks ulUsingFPU value, which by\r
+ default is set to indicate that the stack frame does not include FPU\r
+ registers. */\r
+ *pxTopOfStack = pdFALSE;\r
+ }\r
+ #endif\r
+\r
+ return pxTopOfStack;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSetupTimerInterrupt(void)\r
+{\r
+ /* Disable timer 0. */\r
+ portRTI_GCTRL_REG &= 0xFFFFFFFEUL;\r
+\r
+ /* Use the internal counter. */\r
+ portRTI_TBCTRL_REG = 0x00000000U;\r
+\r
+ /* COMPSEL0 will use the RTIFRC0 counter. */\r
+ portRTI_COMPCTRL_REG = 0x00000000U;\r
+\r
+ /* Initialise the counter and the prescale counter registers. */\r
+ portRTI_CNT0_UC0_REG = 0x00000000U;\r
+ portRTI_CNT0_FRC0_REG = 0x00000000U;\r
+\r
+ /* Set Prescalar for RTI clock. */\r
+ portRTI_CNT0_CPUC0_REG = 0x00000001U;\r
+ portRTI_CNT0_COMP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ;\r
+ portRTI_CNT0_UDCP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ;\r
+\r
+ /* Clear interrupts. */\r
+ portRTI_INTFLAG_REG = 0x0007000FU;\r
+ portRTI_CLEARINTENA_REG = 0x00070F0FU;\r
+\r
+ /* Enable the compare 0 interrupt. */\r
+ portRTI_SETINTENA_REG = 0x00000001U;\r
+ portRTI_GCTRL_REG |= 0x00000001U;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * See header file for description.\r
+ */\r
+portBASE_TYPE xPortStartScheduler(void)\r
+{\r
+ /* Start the timer that generates the tick ISR. */\r
+ prvSetupTimerInterrupt();\r
+\r
+ /* Reset the critical section nesting count read to execute the first task. */\r
+ ulCriticalNesting = 0;\r
+\r
+ /* Start the first task. This is done from portASM.asm as ARM mode must be\r
+ used. */\r
+ vPortStartFirstTask();\r
+\r
+ /* Should not get here! */\r
+ return pdFAIL;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * See header file for description.\r
+ */\r
+void vPortEndScheduler(void)\r
+{\r
+ /* It is unlikely that the port will require this function as there\r
+ is nothing to return to. */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configUSE_PREEMPTION == 0\r
+\r
+ /* The cooperative scheduler requires a normal IRQ service routine to\r
+ * simply increment the system tick. */\r
+ __interrupt void vPortNonPreemptiveTick( void )\r
+ {\r
+ /* clear clock interrupt flag */\r
+ RTI->INTFLAG = 0x00000001;\r
+\r
+ /* Increment the tick count - this may make a delaying task ready\r
+ to run - but a context switch is not performed. */\r
+ vTaskIncrementTick();\r
+ }\r
+\r
+ #else\r
+\r
+ /*\r
+ **************************************************************************\r
+ * The preemptive scheduler ISR is written in assembler and can be found\r
+ * in the portASM.asm file. This will only get used if portUSE_PREEMPTION\r
+ * is set to 1 in portmacro.h\r
+ **************************************************************************\r
+ */\r
+ void vPortPreemptiveTick( void );\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+/*\r
+ * Disable interrupts, and keep a count of the nesting depth.\r
+ */\r
+void vPortEnterCritical( void )\r
+{\r
+ /* Disable interrupts as per portDISABLE_INTERRUPTS(); */\r
+ portDISABLE_INTERRUPTS();\r
+\r
+ /* Now interrupts are disabled ulCriticalNesting can be accessed\r
+ directly. Increment ulCriticalNesting to keep a count of how many times\r
+ portENTER_CRITICAL() has been called. */\r
+ ulCriticalNesting++;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Decrement the critical nesting count, and if it has reached zero, re-enable\r
+ * interrupts.\r
+ */\r
+void vPortExitCritical( void )\r
+{\r
+ if( ulCriticalNesting > 0 )\r
+ {\r
+ /* Decrement the nesting count as we are leaving a critical section. */\r
+ ulCriticalNesting--;\r
+\r
+ /* If the nesting level has reached zero then interrupts should be\r
+ re-enabled. */\r
+ if( ulCriticalNesting == 0 )\r
+ {\r
+ /* Enable interrupts as per portENABLE_INTERRUPTS(). */\r
+ portENABLE_INTERRUPTS();\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if __TI_VFP_SUPPORT__\r
+\r
+ void vPortTaskUsesFPU( void )\r
+ {\r
+ extern void vPortInitialiseFPSCR( void );\r
+\r
+ /* A task is registering the fact that it needs an FPU context. Set the\r
+ FPU flag (saved as part of the task context. */\r
+ ulTaskHasFPUContext = pdTRUE;\r
+\r
+ /* Initialise the floating point status register. */\r
+ vPortInitialiseFPSCR();\r
+ }\r
+\r
+#endif /* __TI_VFP_SUPPORT__ */\r
+\r
+/*-----------------------------------------------------------*/\r
+\r