]> rtime.felk.cvut.cz Git - arc.git/blob - system/kernel/init.c
Fix for scheduletable autostart
[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 }
76
77 static _Bool init_os_called = 0;
78
79 /**
80  * Initialization of kernel structures and start of the first
81  * task.
82  */
83
84 void InitOS( void ) {
85         int i;
86         OsPcbType *tmp_pcb;
87         OsStackType int_stack;
88
89         init_os_called = 1;
90
91         DEBUG(DEBUG_LOW,"os_init");
92
93         /* Clear sys */
94         memset(&os_sys,0,sizeof(sys_t));
95
96         Os_ArchInit();
97
98         // Assign pcb list and init ready queue
99         os_sys.pcb_list = pcb_list;
100         TAILQ_INIT(& os_sys.ready_head);
101         TAILQ_INIT(& os_sys.pcb_head);
102
103         // Calc interrupt stack
104         Os_CfgGetInterruptStackInfo(&int_stack);
105         // TODO: 16 is arch dependent
106         os_sys.int_stack = int_stack.top + int_stack.size - 16;
107
108         // Init counter.. with alarms and schedule tables
109         Os_CounterInit();
110         Os_SchTblInit();
111
112         // Put all tasks in the pcb list
113         // Put the one that belong in the ready queue there
114         // TODO: we should really hash on priority here to get speed, but I don't care for the moment
115         // TODO: Isn't this just EXTENED tasks ???
116         for( i=0; i < Os_CfgGetTaskCnt(); i++) {
117                 tmp_pcb = os_get_pcb(i);
118
119                 assert(tmp_pcb->prio<=OS_TASK_PRIORITY_MAX);
120
121                 os_pcb_rom_copy(tmp_pcb,os_get_rom_pcb(i));
122                 if( !(tmp_pcb->proc_type & PROC_ISR) ) {
123                         Os_ContextInit(tmp_pcb);
124                 }
125
126                 TAILQ_INIT(&tmp_pcb->resource_head);
127
128                 Os_AddTask(tmp_pcb);
129
130                 DEBUG(DEBUG_LOW,"pid:%d name:%s prio:%d\n",tmp_pcb->pid,tmp_pcb->name,tmp_pcb->prio);
131         }
132
133         Os_ResourceInit();
134
135         // Now all tasks should be created.
136 }
137
138 static void os_start( void ) {
139         OsPcbType *tmp_pcb;
140
141         // We will be setting up interrupts,
142         // but we don't want them to fire just yet
143         Irq_Disable();
144
145         assert(init_os_called);
146
147         /* TODO: fix ugly */
148         /* Call the startup hook */
149         extern struct OsHooks os_conf_global_hooks;
150         os_sys.hooks = &os_conf_global_hooks;
151         if( os_sys.hooks->StartupHook!=NULL ) {
152                 os_sys.hooks->StartupHook();
153         }
154
155         /* Alarm autostart */
156         for(int j=0; j < Os_CfgGetAlarmCnt(); j++ ) {
157                 OsAlarmType *alarmPtr;
158                 alarmPtr = Os_CfgGetAlarmObj(j);
159                 if(alarmPtr->autostartPtr != NULL ) {
160                         const OsAlarmAutostartType *autoPtr = alarmPtr->autostartPtr;
161
162                         if( os_sys.appMode & autoPtr->appModeRef) {
163                                 if( autoPtr->autostartType == ALARM_AUTOSTART_ABSOLUTE ) {
164                                         SetAbsAlarm(j,autoPtr->alarmTime, autoPtr->cycleTime);
165                                 } else {
166                                         SetRelAlarm(j,autoPtr->alarmTime, autoPtr->cycleTime);
167                                 }
168                         }
169                 }
170         }
171
172         Os_SchTblAutostart();
173
174         // Set up the systick interrupt
175         {
176                 uint32_t sys_freq = McuE_GetSystemClock();
177                 Os_SysTickInit();
178                 Os_SysTickStart(sys_freq/OsTickFreq);
179         }
180
181         /* Find highest Autostart task */
182         {
183                 OsPcbType *iterPcbPtr;
184                 OsPriorityType topPrio = -1;
185
186                 TAILQ_FOREACH(iterPcbPtr,& os_sys.pcb_head,pcb_list) {
187                         if(     iterPcbPtr->autostart ) {
188                                 if( iterPcbPtr->prio > topPrio ) {
189                                         tmp_pcb = iterPcbPtr;
190                                         topPrio = iterPcbPtr->prio;
191                                 }
192                         }
193                 }
194         }
195
196         // Swap in prio proc.
197         {
198                 // FIXME: Do this in a more structured way.. setting os_sys.curr_pcb manually is not the way to go..
199                 os_sys.curr_pcb = tmp_pcb;
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