]> rtime.felk.cvut.cz Git - arc.git/blob - system/kernel/init.c
merged second mahi-applications head
[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         OS_VALIDATE(OS_COUNTER_CNT,ARRAY_SIZE(counter_list));\r
53 #if (RESOURCE_CNT!=0)\r
54         OS_VALIDATE(OS_RESOURCE_CNT,ARRAY_SIZE(resource_list));\r
55 #endif\r
56         OS_VALIDATE(OS_TASK_CNT ,ARRAY_SIZE( Os_TaskConstList));\r
57 #if (RESOURCE_CNT!=0)\r
58         OS_VALIDATE(OS_ALARM_CNT,ARRAY_SIZE(alarm_list));\r
59 #endif\r
60 #if (OS_SCHTBL_CNT!=0)\r
61         OS_VALIDATE(OS_SCHTBL_CNT, ARRAY_SIZE(sched_list));\r
62 #endif\r
63 }\r
64 \r
65 /* ----------------------------[public functions]----------------------------*/\r
66 \r
67 extern uint32_t McuE_GetSystemClock( void );\r
68 extern OsTickType OsTickFreq;\r
69 \r
70 \r
71 /**\r
72  * Copy rom pcb data(r_pcb) to ram data\r
73  *\r
74  * @param       pcb             ram data\r
75  * @param       r_pcb   rom data\r
76  */\r
77 \r
78 static void copyPcbParts( OsTaskVarType *pcb, const OsTaskConstType *r_pcb ) {\r
79         assert(r_pcb->prio<=OS_TASK_PRIORITY_MAX);\r
80         pcb->activePriority = r_pcb->prio;\r
81         pcb->stack= r_pcb->stack;\r
82         pcb->constPtr = r_pcb;\r
83 }\r
84 \r
85 static _Bool init_os_called = 0;\r
86 \r
87 /**\r
88  * Initialization of kernel structures and start of the first\r
89  * task.\r
90  */\r
91 \r
92 void InitOS( void ) {\r
93         int i;\r
94         OsTaskVarType *tmpPcbPtr;\r
95         OsIsrStackType intStack;\r
96 \r
97         init_os_called = 1;\r
98 \r
99         Os_CfgValidate();\r
100 \r
101         DEBUG(DEBUG_LOW,"os_init");\r
102 \r
103         /* Clear sys */\r
104         memset(&Os_Sys,0,sizeof(Os_SysType));\r
105 \r
106         Os_ArchInit();\r
107 \r
108         // Assign pcb list and init ready queue\r
109         Os_Sys.pcb_list = Os_TaskVarList;\r
110         TAILQ_INIT(& Os_Sys.ready_head);\r
111 //      TAILQ_INIT(& Os_Sys.pcb_head);\r
112 #if defined(USE_KERNEL_EXTRA)\r
113         TAILQ_INIT(& Os_Sys.timerHead);\r
114 #endif\r
115 \r
116         // Calc interrupt stack\r
117         Os_IsrGetStackInfo(&intStack);\r
118         // TODO: 16 is arch dependent\r
119         Os_Sys.intStack = (void *)((size_t)intStack.top + (size_t)intStack.size - 16);\r
120 \r
121         // Init counter.. with alarms and schedule tables\r
122 #if OS_COUNTER_CNT!=0\r
123         Os_CounterInit();\r
124 #endif\r
125 #if OS_SCHTBL_CNT!=0\r
126         Os_SchTblInit();\r
127 #endif\r
128 \r
129         // Put all tasks in the pcb list\r
130         // Put the one that belong in the ready queue there\r
131         // TODO: we should really hash on priority here to get speed, but I don't care for the moment\r
132         // TODO: Isn't this just EXTENED tasks ???\r
133         for( i=0; i < OS_TASK_CNT; i++) {\r
134                 tmpPcbPtr = Os_TaskGet(i);\r
135 \r
136                 copyPcbParts(tmpPcbPtr,&Os_TaskConstList[i]);\r
137                 Os_TaskContextInit(tmpPcbPtr);\r
138                 TAILQ_INIT(&tmpPcbPtr->resourceHead);\r
139 \r
140 #if 0\r
141                 Os_AddTask(tmpPcbPtr);\r
142 #endif\r
143 \r
144                 DEBUG(DEBUG_LOW,"pid:%d name:%s prio:%d\n",tmpPcbPtr->pid,tmpPcbPtr->name,tmpPcbPtr->prio);\r
145         }\r
146 \r
147         Os_ResourceInit();\r
148 \r
149         // Now all tasks should be created.\r
150 }\r
151 \r
152 static void os_start( void ) {\r
153         uint16_t i;\r
154         OsTaskVarType *tmpPcbPtr = NULL;\r
155 \r
156         // We will be setting up interrupts,\r
157         // but we don't want them to fire just yet\r
158         Irq_Disable();\r
159 \r
160         assert(init_os_called);\r
161 \r
162         /* TODO: fix ugly */\r
163         /* Call the startup hook */\r
164         extern struct OsHooks os_conf_global_hooks;\r
165         Os_Sys.hooks = &os_conf_global_hooks;\r
166         if( Os_Sys.hooks->StartupHook!=NULL ) {\r
167                 Os_Sys.hooks->StartupHook();\r
168         }\r
169 \r
170 \r
171 #if     (OS_USE_APPLICATIONS == STD_ON)\r
172         /* Start applications */\r
173         Os_ApplStart();\r
174 #endif\r
175 \r
176 \r
177         /* Alarm autostart */\r
178 #if OS_ALARM_CNT!=0\r
179         Os_AlarmAutostart();\r
180 #endif\r
181 \r
182 #if OS_SCHTBL_CNT!=0\r
183         Os_SchTblAutostart();\r
184 #endif\r
185 \r
186         // Set up the systick interrupt\r
187         {\r
188                 uint32_t sys_freq = McuE_GetSystemClock();\r
189                 Os_SysTickInit();\r
190                 Os_SysTickStart(sys_freq/OsTickFreq);\r
191         }\r
192 \r
193         /* Find highest Autostart task */\r
194         {\r
195                 OsTaskVarType *iterPcbPtr;\r
196                 OsPriorityType topPrio = -1;\r
197 \r
198                 for(i=0;i<OS_TASK_CNT;i++) {\r
199                         iterPcbPtr = Os_TaskGet(i);\r
200                         if(     iterPcbPtr->constPtr->autostart ) {\r
201                                 if( iterPcbPtr->activePriority > topPrio ) {\r
202                                         tmpPcbPtr = iterPcbPtr;\r
203                                         topPrio = iterPcbPtr->activePriority;\r
204                                 }\r
205                         }\r
206                 }\r
207 #if 0\r
208                 TAILQ_FOREACH(iterPcbPtr,& Os_Sys.pcb_head,pcb_list) {\r
209                         if(     iterPcbPtr->constPtr->autostart ) {\r
210                                 if( iterPcbPtr->activePriority > topPrio ) {\r
211                                         tmpPcbPtr = iterPcbPtr;\r
212                                         topPrio = iterPcbPtr->activePriority;\r
213                                 }\r
214                         }\r
215                 }\r
216 #endif\r
217         }\r
218 \r
219         // Swap in prio proc.\r
220         {\r
221                 // FIXME: Do this in a more structured way.. setting Os_Sys.currTaskPtr manually is not the way to go..\r
222                 Os_Sys.currTaskPtr = tmpPcbPtr;\r
223 #if     (OS_USE_APPLICATIONS == STD_ON)\r
224                 /* Set current application */\r
225                 Os_Sys.currApplId = tmpPcbPtr->constPtr->applOwnerId;\r
226 #endif\r
227 \r
228                 // register this auto-start activation\r
229                 assert(tmpPcbPtr->activations < tmpPcbPtr->constPtr->activationLimit);\r
230                 tmpPcbPtr->activations++;\r
231 \r
232                 // NOTE! We don't go for os_swap_context() here..\r
233                 // first arg(NULL) is dummy only\r
234                 Os_TaskSwapContextTo(NULL,tmpPcbPtr);\r
235                 // We should not return here\r
236                 assert(0);\r
237         }\r
238 }\r
239 #if 0\r
240 static void os_start( void ) {\r
241 \r
242 }\r
243 #endif\r
244 \r
245 #define TEST_DATA  12345\r
246 int test_data = TEST_DATA;\r
247 int test_bss = 0;\r
248 \r
249 \r
250 void noooo( void ) {\r
251         while(1);\r
252 }\r
253 \r
254 extern void EcuM_Init();\r
255 int main( void )\r
256 {\r
257         EcuM_Init();\r
258 \r
259 }\r
260 \r
261 /**\r
262  * Starts the OS\r
263  *\r
264  * @param Mode - Application mode to start in\r
265  *\r
266  */\r
267 void StartOS(AppModeType Mode) {\r
268 \r
269         /* Check link file */\r
270         if (TEST_DATA != test_data) {\r
271                 noooo();\r
272         }\r
273 \r
274         if (test_bss != 0) {\r
275                 noooo();\r
276         }\r
277 \r
278         Os_Sys.appMode = Mode;\r
279 \r
280         Os_CfgValidate();\r
281 \r
282         os_start();\r
283 \r
284         /** @req OS424 */\r
285         assert(0);\r
286 }\r
287 \r
288 /**\r
289  * OS shutdown\r
290  *\r
291  * @param Error - Reason for shutdown\r
292  */\r
293 \r
294 /** @req OS071 */\r
295 void ShutdownOS( StatusType Error ) {\r
296 \r
297         if( Os_Sys.hooks->ShutdownHook != NULL ) {\r
298                 Os_Sys.hooks->ShutdownHook(Error);\r
299         }\r
300 \r
301         Irq_Disable();\r
302         /** @req OS425 */\r
303         while(1) {      }\r
304 \r
305 }\r
306 \r
307 \r
308 \r