]> rtime.felk.cvut.cz Git - arc.git/blob - system/kernel/init.c
Merged in from default
[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 \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 "arch.h"\r
24 \r
25 extern void Os_CfgGetInterruptStackInfo( OsStackType *stack );\r
26 extern uint32_t McuE_GetSystemClock( void );\r
27 extern OsTickType OsTickFreq;\r
28 \r
29 sys_t os_sys;\r
30 \r
31 Os_IntCounterType Os_IntDisableAllCnt;\r
32 Os_IntCounterType Os_IntSuspendAllCnt;\r
33 Os_IntCounterType Os_IntSuspendOsCnt;\r
34 \r
35 \r
36 /**\r
37  * Copy rom pcb data(r_pcb) to ram data\r
38  *\r
39  * @param       pcb             ram data\r
40  * @param       r_pcb   rom data\r
41  */\r
42 \r
43 static void os_pcb_rom_copy( OsPcbType *pcb, const OsRomPcbType *r_pcb ) {\r
44 \r
45 #if 0 //?????\r
46         // Check to that the memory is ok\r
47         {\r
48                 int cnt = sizeof(OsPcbType);\r
49                 for(int i=0;i<cnt;i++) {\r
50                         if( *((unsigned char *)pcb) != 0 ) {\r
51                                 while(1);\r
52                         }\r
53                 }\r
54         }\r
55 #endif\r
56 \r
57 //      memset(pcb,sizeof(OsPcbType),0);\r
58         pcb->pid = r_pcb->pid;\r
59         pcb->prio = r_pcb->prio;\r
60 #if ( OS_SC3 == STD_ON ) || ( OS_SC4 == STD_ON )\r
61         pcb->application = Os_CfgGetApplObj(r_pcb->application_id);\r
62 #endif\r
63         pcb->entry = r_pcb->entry;\r
64         pcb->proc_type = r_pcb->proc_type;\r
65         pcb->autostart =  r_pcb->autostart;\r
66         pcb->stack= r_pcb->stack;\r
67         pcb->pcb_rom_p = r_pcb;\r
68         pcb->resource_int_p = r_pcb->resource_int_p;\r
69         pcb->scheduling = r_pcb->scheduling;\r
70         pcb->resourceAccess = r_pcb->resourceAccess;\r
71         pcb->activationLimit = r_pcb->activationLimit;\r
72 //      pcb->app = &app_list[r_pcb->app];\r
73 //      pcb->app_mask = app_mask[r_pcb->app];\r
74         strncpy(pcb->name,r_pcb->name,16);\r
75 }\r
76 \r
77 static _Bool init_os_called = 0;\r
78 \r
79 /**\r
80  * Initialization of kernel structures and start of the first\r
81  * task.\r
82  */\r
83 \r
84 void InitOS( void ) {\r
85         int i;\r
86         OsPcbType *tmp_pcb;\r
87         OsStackType int_stack;\r
88 \r
89         init_os_called = 1;\r
90 \r
91         DEBUG(DEBUG_LOW,"os_init");\r
92 \r
93         /* Clear sys */\r
94         memset(&os_sys,0,sizeof(sys_t));\r
95 \r
96         Os_ArchInit();\r
97 \r
98         // Assign pcb list and init ready queue\r
99         os_sys.pcb_list = pcb_list;\r
100         TAILQ_INIT(& os_sys.ready_head);\r
101         TAILQ_INIT(& os_sys.pcb_head);\r
102 \r
103         // Calc interrupt stack\r
104         Os_CfgGetInterruptStackInfo(&int_stack);\r
105         // TODO: 16 is arch dependent\r
106         os_sys.int_stack = int_stack.top + int_stack.size - 16;\r
107 \r
108         // Init counter.. with alarms and schedule tables\r
109         Os_CounterInit();\r
110         Os_SchTblInit();\r
111 \r
112         // Put all tasks in the pcb list\r
113         // Put the one that belong in the ready queue there\r
114         // TODO: we should really hash on priority here to get speed, but I don't care for the moment\r
115         // TODO: Isn't this just EXTENED tasks ???\r
116         for( i=0; i < Os_CfgGetTaskCnt(); i++) {\r
117                 tmp_pcb = os_get_pcb(i);\r
118 \r
119                 assert(tmp_pcb->prio<=OS_TASK_PRIORITY_MAX);\r
120 \r
121                 os_pcb_rom_copy(tmp_pcb,os_get_rom_pcb(i));\r
122                 if( !(tmp_pcb->proc_type & PROC_ISR) ) {\r
123                         Os_ContextInit(tmp_pcb);\r
124                 }\r
125 \r
126                 TAILQ_INIT(&tmp_pcb->resource_head);\r
127 \r
128                 Os_AddTask(tmp_pcb);\r
129 \r
130                 DEBUG(DEBUG_LOW,"pid:%d name:%s prio:%d\n",tmp_pcb->pid,tmp_pcb->name,tmp_pcb->prio);\r
131         }\r
132 \r
133         Os_ResourceInit();\r
134 \r
135         // Now all tasks should be created.\r
136 }\r
137 \r
138 static void os_start( void ) {\r
139         OsPcbType *tmp_pcb;\r
140 \r
141         // We will be setting up interrupts,\r
142         // but we don't want them to fire just yet\r
143         Irq_Disable();\r
144 \r
145         assert(init_os_called);\r
146 \r
147         /* TODO: fix ugly */\r
148         /* Call the startup hook */\r
149         extern struct OsHooks os_conf_global_hooks;\r
150         os_sys.hooks = &os_conf_global_hooks;\r
151         if( os_sys.hooks->StartupHook!=NULL ) {\r
152                 os_sys.hooks->StartupHook();\r
153         }\r
154 \r
155         /* Alarm autostart */\r
156         for(int j=0; j < Os_CfgGetAlarmCnt(); j++ ) {\r
157                 OsAlarmType *alarmPtr;\r
158                 alarmPtr = Os_CfgGetAlarmObj(j);\r
159                 if(alarmPtr->autostartPtr != NULL ) {\r
160                         const OsAlarmAutostartType *autoPtr = alarmPtr->autostartPtr;\r
161 \r
162                         if( os_sys.appMode & autoPtr->appModeRef) {\r
163                         if( autoPtr->autostartType == ALARM_AUTOSTART_ABSOLUTE ) {\r
164                                 SetAbsAlarm(j,autoPtr->alarmTime, autoPtr->cycleTime);\r
165                         } else {\r
166                                 SetRelAlarm(j,autoPtr->alarmTime, autoPtr->cycleTime);\r
167                         }\r
168                 }\r
169         }\r
170         }\r
171 \r
172         Os_SchTblAutostart();\r
173 \r
174         // Set up the systick interrupt\r
175         {\r
176                 uint32_t sys_freq = McuE_GetSystemClock();\r
177                 Os_SysTickInit();\r
178                 Os_SysTickStart(sys_freq/OsTickFreq);\r
179         }\r
180 \r
181         /* Find highest Autostart task */\r
182         {\r
183                 OsPcbType *iterPcbPtr;\r
184                 OsPriorityType topPrio = -1;\r
185 \r
186                 TAILQ_FOREACH(iterPcbPtr,& os_sys.pcb_head,pcb_list) {\r
187                         if(     iterPcbPtr->autostart ) {\r
188                                 if( iterPcbPtr->prio > topPrio ) {\r
189                                         tmp_pcb = iterPcbPtr;\r
190                                         topPrio = iterPcbPtr->prio;\r
191                                 }\r
192                         }\r
193                 }\r
194         }\r
195 \r
196         // Swap in prio proc.\r
197         {\r
198                 // FIXME: Do this in a more structured way.. setting os_sys.curr_pcb manually is not the way to go..\r
199                 os_sys.curr_pcb = tmp_pcb;\r
200                 // NOTE! We don't go for os_swap_context() here..\r
201                 // first arg(NULL) is dummy only\r
202                 Os_TaskSwapContextTo(NULL,tmp_pcb);\r
203                 // We should not return here\r
204                 assert(0);\r
205         }\r
206 }\r
207 #if 0\r
208 static void os_start( void ) {\r
209 \r
210 }\r
211 #endif\r
212 \r
213 #define TEST_DATA  12345\r
214 int test_data = TEST_DATA;\r
215 int test_bss = 0;\r
216 \r
217 \r
218 void noooo( void ) {\r
219         while(1);\r
220 }\r
221 \r
222 extern void EcuM_Init();\r
223 int main( void )\r
224 {\r
225         EcuM_Init();\r
226 \r
227 }\r
228 \r
229 /**\r
230  * Starts the OS\r
231  *\r
232  * @param Mode - Application mode to start in\r
233  *\r
234  */\r
235 void StartOS(AppModeType Mode) {\r
236 \r
237         /* Check link file */\r
238         if (TEST_DATA != test_data) {\r
239                 noooo();\r
240         }\r
241 \r
242         if (test_bss != 0) {\r
243                 noooo();\r
244         }\r
245 \r
246         os_sys.appMode = Mode;\r
247 \r
248         Os_CfgValidate();\r
249 \r
250         os_start();\r
251 \r
252         /** @req OS424 */\r
253         assert(0);\r
254 }\r
255 \r
256 /**\r
257  * OS shutdown\r
258  *\r
259  * @param Error - Reason for shutdown\r
260  */\r
261 \r
262 /** @req OS071 */\r
263 void ShutdownOS( StatusType Error ) {\r
264 \r
265         if( os_sys.hooks->ShutdownHook != NULL ) {\r
266                 os_sys.hooks->ShutdownHook(Error);\r
267         }\r
268 \r
269         Irq_Disable();\r
270         /** @req OS425 */\r
271         while(1) {      }\r
272 \r
273 }\r
274 \r
275 \r
276 \r