]> rtime.felk.cvut.cz Git - arc.git/blob - system/kernel/init.c
Added MPC5606S_XPC560S
[arc.git] / system / kernel / init.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 /* ----------------------------[includes]------------------------------------*/\r
17 #include <stdlib.h>\r
18 #include <string.h>\r
19 #include "Os.h"\r
20 #include "internal.h"\r
21 #include "arc.h"\r
22 #include "debug.h"\r
23 #include "task_i.h"\r
24 #include "sys.h"\r
25 #include "isr.h"\r
26 #include "counter_i.h"\r
27 #include "application.h"\r
28 #include "sched_table_i.h"\r
29 #include "alarm_i.h"\r
30 #include "arch.h"\r
31 \r
32 /* ----------------------------[private define]------------------------------*/\r
33 /* ----------------------------[private macro]-------------------------------*/\r
34 #define OS_VALIDATE(_a,_b)   if((_a)!=(_b) ) { \\r
35                                                                 assert(#_a  #_b); \\r
36                                                           }\r
37 /* ----------------------------[private typedef]-----------------------------*/\r
38 /* ----------------------------[private function prototypes]-----------------*/\r
39 /* ----------------------------[private variables]---------------------------*/\r
40 Os_SysType Os_Sys;\r
41 \r
42 Os_IntCounterType Os_IntDisableAllCnt;\r
43 Os_IntCounterType Os_IntSuspendAllCnt;\r
44 Os_IntCounterType Os_IntSuspendOsCnt;\r
45 \r
46 OsErrorType os_error;\r
47 \r
48 /* ----------------------------[private functions]---------------------------*/\r
49 \r
50 \r
51 static void Os_CfgValidate(void ) {\r
52 #if (OS_COUNTER_CNT!=0)\r
53         OS_VALIDATE(OS_COUNTER_CNT,ARRAY_SIZE(counter_list));\r
54 #endif\r
55 #if (OS_RESOURCE_CNT!=0)\r
56         OS_VALIDATE(OS_RESOURCE_CNT,ARRAY_SIZE(resource_list));\r
57 #endif\r
58         OS_VALIDATE(OS_TASK_CNT ,ARRAY_SIZE( Os_TaskConstList));\r
59 #if (OS_ALARM_CNT!=0)\r
60         OS_VALIDATE(OS_ALARM_CNT,ARRAY_SIZE(alarm_list));\r
61 #endif\r
62 #if (OS_SCHTBL_CNT!=0)\r
63         OS_VALIDATE(OS_SCHTBL_CNT, ARRAY_SIZE(sched_list));\r
64 #endif\r
65 }\r
66 \r
67 /* ----------------------------[public functions]----------------------------*/\r
68 \r
69 extern uint32_t McuE_GetSystemClock( void );\r
70 extern OsTickType OsTickFreq;\r
71 \r
72 \r
73 /**\r
74  * Copy rom pcb data(r_pcb) to ram data\r
75  *\r
76  * @param       pcb             ram data\r
77  * @param       r_pcb   rom data\r
78  */\r
79 \r
80 static void copyPcbParts( OsTaskVarType *pcb, const OsTaskConstType *r_pcb ) {\r
81         assert(r_pcb->prio<=OS_TASK_PRIORITY_MAX);\r
82         pcb->activePriority = r_pcb->prio;\r
83         pcb->stack= r_pcb->stack;\r
84         pcb->constPtr = r_pcb;\r
85 }\r
86 \r
87 static _Bool init_os_called = 0;\r
88 \r
89 /**\r
90  * Initialization of kernel structures and start of the first\r
91  * task.\r
92  */\r
93 \r
94 void InitOS( void ) {\r
95         int i;\r
96         OsTaskVarType *tmpPcbPtr;\r
97         OsIsrStackType intStack;\r
98 \r
99         init_os_called = 1;\r
100 \r
101         Os_CfgValidate();\r
102 \r
103         DEBUG(DEBUG_LOW,"os_init");\r
104 \r
105         /* Clear sys */\r
106         memset(&Os_Sys,0,sizeof(Os_SysType));\r
107 \r
108         Os_ArchInit();\r
109 \r
110         /* Get the numbers defined in the editor */\r
111         Os_Sys.isrCnt = OS_ISR_CNT;\r
112 \r
113         // Assign pcb list and init ready queue\r
114         Os_Sys.pcb_list = Os_TaskVarList;\r
115         TAILQ_INIT(& Os_Sys.ready_head);\r
116 //      TAILQ_INIT(& Os_Sys.pcb_head);\r
117 #if defined(USE_KERNEL_EXTRA)\r
118         TAILQ_INIT(& Os_Sys.timerHead);\r
119 #endif\r
120 \r
121         // Calc interrupt stack\r
122         Os_IsrGetStackInfo(&intStack);\r
123         // TODO: 16 is arch dependent\r
124         Os_Sys.intStack = (void *)((size_t)intStack.top + (size_t)intStack.size - 16);\r
125 \r
126         // Init counter.. with alarms and schedule tables\r
127 #if OS_COUNTER_CNT!=0\r
128         Os_CounterInit();\r
129 #endif\r
130 #if OS_SCHTBL_CNT!=0\r
131         Os_SchTblInit();\r
132 #endif\r
133 \r
134         // Put all tasks in the pcb list\r
135         // Put the one that belong in the ready queue there\r
136         // TODO: we should really hash on priority here to get speed, but I don't care for the moment\r
137         // TODO: Isn't this just EXTENED tasks ???\r
138         for( i=0; i < OS_TASK_CNT; i++) {\r
139                 tmpPcbPtr = Os_TaskGet(i);\r
140 \r
141                 copyPcbParts(tmpPcbPtr,&Os_TaskConstList[i]);\r
142                 Os_TaskContextInit(tmpPcbPtr);\r
143                 TAILQ_INIT(&tmpPcbPtr->resourceHead);\r
144 \r
145 #if 0\r
146                 Os_AddTask(tmpPcbPtr);\r
147 #endif\r
148 \r
149                 DEBUG(DEBUG_LOW,"pid:%d name:%s prio:%d\n",tmpPcbPtr->pid,tmpPcbPtr->name,tmpPcbPtr->prio);\r
150         }\r
151 \r
152         Os_ResourceInit();\r
153 \r
154         // Now all tasks should be created.\r
155 }\r
156 \r
157 static void os_start( void ) {\r
158         uint16_t i;\r
159         OsTaskVarType *tmpPcbPtr = NULL;\r
160 \r
161         // We will be setting up interrupts,\r
162         // but we don't want them to fire just yet\r
163         Irq_Disable();\r
164 \r
165         assert(init_os_called);\r
166 \r
167         /* TODO: fix ugly */\r
168         /* Call the startup hook */\r
169         extern struct OsHooks os_conf_global_hooks;\r
170         Os_Sys.hooks = &os_conf_global_hooks;\r
171         if( Os_Sys.hooks->StartupHook!=NULL ) {\r
172                 Os_Sys.hooks->StartupHook();\r
173         }\r
174 \r
175 \r
176 #if     (OS_USE_APPLICATIONS == STD_ON)\r
177         /* Start applications */\r
178         Os_ApplStart();\r
179 #endif\r
180 \r
181 \r
182         /* Alarm autostart */\r
183 #if OS_ALARM_CNT!=0\r
184         Os_AlarmAutostart();\r
185 #endif\r
186 \r
187 #if OS_SCHTBL_CNT!=0\r
188         Os_SchTblAutostart();\r
189 #endif\r
190 \r
191         // Set up the systick interrupt\r
192         {\r
193                 uint32_t sys_freq = McuE_GetSystemClock();\r
194                 Os_SysTickInit();\r
195                 Os_SysTickStart(sys_freq/OsTickFreq);\r
196         }\r
197 \r
198         /* Find highest Autostart task */\r
199         {\r
200                 OsTaskVarType *iterPcbPtr;\r
201                 OsPriorityType topPrio = -1;\r
202 \r
203                 for(i=0;i<OS_TASK_CNT;i++) {\r
204                         iterPcbPtr = Os_TaskGet(i);\r
205                         if(     iterPcbPtr->constPtr->autostart ) {\r
206                                 if( iterPcbPtr->activePriority > topPrio ) {\r
207                                         tmpPcbPtr = iterPcbPtr;\r
208                                         topPrio = iterPcbPtr->activePriority;\r
209                                 }\r
210                         }\r
211                 }\r
212 #if 0\r
213                 TAILQ_FOREACH(iterPcbPtr,& Os_Sys.pcb_head,pcb_list) {\r
214                         if(     iterPcbPtr->constPtr->autostart ) {\r
215                                 if( iterPcbPtr->activePriority > topPrio ) {\r
216                                         tmpPcbPtr = iterPcbPtr;\r
217                                         topPrio = iterPcbPtr->activePriority;\r
218                                 }\r
219                         }\r
220                 }\r
221 #endif\r
222         }\r
223 \r
224         // Swap in prio proc.\r
225         {\r
226                 // FIXME: Do this in a more structured way.. setting Os_Sys.currTaskPtr manually is not the way to go..\r
227                 Os_Sys.currTaskPtr = tmpPcbPtr;\r
228 #if     (OS_USE_APPLICATIONS == STD_ON)\r
229                 /* Set current application */\r
230                 Os_Sys.currApplId = tmpPcbPtr->constPtr->applOwnerId;\r
231 #endif\r
232 \r
233                 // register this auto-start activation\r
234                 assert(tmpPcbPtr->activations < tmpPcbPtr->constPtr->activationLimit);\r
235                 tmpPcbPtr->activations++;\r
236 \r
237                 // NOTE! We don't go for os_swap_context() here..\r
238                 // first arg(NULL) is dummy only\r
239                 Os_TaskSwapContextTo(NULL,tmpPcbPtr);\r
240                 // We should not return here\r
241                 assert(0);\r
242         }\r
243 }\r
244 #if 0\r
245 static void os_start( void ) {\r
246 \r
247 }\r
248 #endif\r
249 \r
250 #define TEST_DATA  12345\r
251 int test_data = TEST_DATA;\r
252 int test_bss = 0;\r
253 \r
254 \r
255 void noooo( void ) {\r
256         while(1) {}\r
257 }\r
258 \r
259 extern void EcuM_Init();\r
260 int main( void )\r
261 {\r
262         EcuM_Init();\r
263 \r
264 }\r
265 \r
266 /**\r
267  * Starts the OS\r
268  *\r
269  * @param Mode - Application mode to start in\r
270  *\r
271  */\r
272 void StartOS(AppModeType Mode) {\r
273 \r
274         /* Check link file */\r
275         if (TEST_DATA != test_data) {\r
276                 noooo();\r
277         }\r
278 \r
279         if (test_bss != 0) {\r
280                 noooo();\r
281         }\r
282 \r
283         Os_Sys.appMode = Mode;\r
284 \r
285         Os_CfgValidate();\r
286 \r
287         os_start();\r
288 \r
289         /** @req OS424 */\r
290         assert(0);\r
291 }\r
292 \r
293 /**\r
294  * OS shutdown\r
295  *\r
296  * @param Error - Reason for shutdown\r
297  */\r
298 \r
299 /** @req OS071 */\r
300 void ShutdownOS( StatusType Error ) {\r
301 \r
302         if( Os_Sys.hooks->ShutdownHook != NULL ) {\r
303                 Os_Sys.hooks->ShutdownHook(Error);\r
304         }\r
305 \r
306         Irq_Disable();\r
307         /** @req OS425 */\r
308         while(1) {      }\r
309 \r
310 }\r
311 \r
312 \r
313 \r