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