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