]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/Paradigm/Tern_EE/small/port.c
Update license information text files for the CLI, TCP and UDP products to be correct...
[freertos] / FreeRTOS / Source / portable / Paradigm / Tern_EE / small / port.c
1 /*\r
2  * FreeRTOS Kernel V10.0.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software. If you wish to use our Amazon\r
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
15  *\r
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22  *\r
23  * http://www.FreeRTOS.org\r
24  * http://aws.amazon.com/freertos\r
25  *\r
26  * 1 tab == 4 spaces!\r
27  */\r
28 \r
29 \r
30 /*-----------------------------------------------------------\r
31  * Implementation of functions defined in portable.h for the Tern EE 186\r
32  * port.\r
33  *----------------------------------------------------------*/\r
34 \r
35 /* Library includes. */\r
36 #include <embedded.h>\r
37 #include <ae.h>\r
38 \r
39 /* Scheduler includes. */\r
40 #include "FreeRTOS.h"\r
41 #include "task.h"\r
42 #include "portasm.h"\r
43 \r
44 /* The timer increments every four clocks, hence the divide by 4. */\r
45 #define portPRESCALE_VALUE ( 16 )\r
46 #define portTIMER_COMPARE ( configCPU_CLOCK_HZ  / ( configTICK_RATE_HZ * 4UL ) )\r
47 \r
48 /* From the RDC data sheet. */\r
49 #define portENABLE_TIMER_AND_INTERRUPT  ( uint16_t ) 0xe00b\r
50 #define portENABLE_TIMER                                ( uint16_t ) 0xC001\r
51 \r
52 /* Interrupt control. */\r
53 #define portEIO_REGISTER 0xff22\r
54 #define portCLEAR_INTERRUPT 0x0008\r
55 \r
56 /* Setup the hardware to generate the required tick frequency. */\r
57 static void prvSetupTimerInterrupt( void );\r
58 \r
59 /* The ISR used depends on whether the preemptive or cooperative scheduler\r
60 is being used. */\r
61 #if( configUSE_PREEMPTION == 1 )\r
62         /* Tick service routine used by the scheduler when preemptive scheduling is\r
63         being used. */\r
64         static void __interrupt __far prvPreemptiveTick( void );\r
65 #else\r
66         /* Tick service routine used by the scheduler when cooperative scheduling is\r
67         being used. */\r
68         static void __interrupt __far prvNonPreemptiveTick( void );\r
69 #endif\r
70 \r
71 /* Trap routine used by taskYIELD() to manually cause a context switch. */\r
72 static void __interrupt __far prvYieldProcessor( void );\r
73 \r
74 /*-----------------------------------------------------------*/\r
75 /* See header file for description. */\r
76 StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )\r
77 {\r
78 StackType_t DS_Reg = 0;\r
79 \r
80         /* We need the true data segment. */\r
81         __asm{  MOV DS_Reg, DS };\r
82 \r
83         /* Place a few bytes of known values on the bottom of the stack.\r
84         This is just useful for debugging. */\r
85 \r
86         *pxTopOfStack = 0x1111;\r
87         pxTopOfStack--;\r
88         *pxTopOfStack = 0x2222;\r
89         pxTopOfStack--;\r
90         *pxTopOfStack = 0x3333;\r
91         pxTopOfStack--;\r
92 \r
93         /* We are going to start the scheduler using a return from interrupt\r
94         instruction to load the program counter, so first there would be the\r
95         function call with parameters preamble. */\r
96         \r
97         *pxTopOfStack = FP_OFF( pvParameters );\r
98         pxTopOfStack--;\r
99         *pxTopOfStack = FP_OFF( pxCode );\r
100         pxTopOfStack--;\r
101 \r
102         /* Next the status register and interrupt return address. */\r
103         *pxTopOfStack = portINITIAL_SW;\r
104         pxTopOfStack--;\r
105         *pxTopOfStack = FP_SEG( pxCode );\r
106         pxTopOfStack--;\r
107         *pxTopOfStack = FP_OFF( pxCode );\r
108         pxTopOfStack--;\r
109 \r
110         /* The remaining registers would be pushed on the stack by our context\r
111         switch function.  These are loaded with values simply to make debugging\r
112         easier. */\r
113         *pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */\r
114         pxTopOfStack--;\r
115         *pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */\r
116         pxTopOfStack--;\r
117         *pxTopOfStack = ( StackType_t ) 0xCCCC; /* CX */\r
118         pxTopOfStack--;\r
119         *pxTopOfStack = ( StackType_t ) 0xDDDD; /* DX */\r
120         pxTopOfStack--;\r
121         *pxTopOfStack = ( StackType_t ) 0xEEEE; /* ES */\r
122         pxTopOfStack--;\r
123 \r
124         *pxTopOfStack = DS_Reg;                                         /* DS */\r
125         pxTopOfStack--;\r
126         *pxTopOfStack = ( StackType_t ) 0x0123; /* SI */\r
127         pxTopOfStack--;\r
128         *pxTopOfStack = ( StackType_t ) 0xDDDD; /* DI */\r
129         pxTopOfStack--;\r
130         *pxTopOfStack = ( StackType_t ) 0xBBBB; /* BP */\r
131 \r
132         return pxTopOfStack;\r
133 }\r
134 /*-----------------------------------------------------------*/\r
135 \r
136 BaseType_t xPortStartScheduler( void )\r
137 {\r
138         /* This is called with interrupts already disabled. */\r
139 \r
140         /* Put our manual switch (yield) function on a known\r
141         vector. */\r
142         setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );\r
143 \r
144         /* Setup the tick interrupt. */\r
145         prvSetupTimerInterrupt();\r
146 \r
147         /* Kick off the scheduler by setting up the context of the first task. */\r
148         portFIRST_CONTEXT();\r
149 \r
150         /* Should not get here! */\r
151         return pdFALSE;\r
152 }\r
153 /*-----------------------------------------------------------*/\r
154 \r
155 /* The ISR used depends on whether the preemptive or cooperative scheduler\r
156 is being used. */\r
157 #if( configUSE_PREEMPTION == 1 )\r
158         static void __interrupt __far prvPreemptiveTick( void )\r
159         {\r
160                 /* Get the scheduler to update the task states following the tick. */\r
161                 if( xTaskIncrementTick() != pdFALSE )\r
162                 {\r
163                         /* Switch in the context of the next task to be run. */\r
164                         portEND_SWITCHING_ISR();\r
165                 }\r
166 \r
167                 /* Reset interrupt. */\r
168                 outport( portEIO_REGISTER, portCLEAR_INTERRUPT );\r
169         }\r
170 #else\r
171         static void __interrupt __far prvNonPreemptiveTick( void )\r
172         {\r
173                 /* Same as preemptive tick, but the cooperative scheduler is being used\r
174                 so we don't have to switch in the context of the next task. */\r
175                 xTaskIncrementTick();\r
176                 \r
177                 /* Reset interrupt. */\r
178                 outport( portEIO_REGISTER, portCLEAR_INTERRUPT );\r
179         }\r
180 #endif\r
181 /*-----------------------------------------------------------*/\r
182 \r
183 static void __interrupt __far prvYieldProcessor( void )\r
184 {\r
185         /* Switch in the context of the next task to be run. */\r
186         portEND_SWITCHING_ISR();\r
187 }\r
188 /*-----------------------------------------------------------*/\r
189 \r
190 void vPortEndScheduler( void )\r
191 {\r
192         /* Not implemented. */\r
193 }\r
194 /*-----------------------------------------------------------*/\r
195 \r
196 static void prvSetupTimerInterrupt( void )\r
197 {\r
198 const uint32_t ulCompareValue = portTIMER_COMPARE;\r
199 uint16_t usTimerCompare;\r
200 \r
201         usTimerCompare = ( uint16_t ) ( ulCompareValue >> 4 );\r
202     t2_init( portENABLE_TIMER, portPRESCALE_VALUE, NULL );\r
203 \r
204         #if( configUSE_PREEMPTION == 1 )\r
205                 /* Tick service routine used by the scheduler when preemptive scheduling is\r
206                 being used. */\r
207                 t1_init( portENABLE_TIMER_AND_INTERRUPT, usTimerCompare, usTimerCompare, prvPreemptiveTick );\r
208         #else\r
209                 /* Tick service routine used by the scheduler when cooperative scheduling is\r
210                 being used. */\r
211                 t1_init( portENABLE_TIMER_AND_INTERRUPT, usTimerCompare, usTimerCompare, prvNonPreemptiveTick );\r
212         #endif\r
213 }\r
214 \r
215 \r
216 \r
217 \r
218 \r
219 \r
220 \r