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