1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\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
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
14 * -------------------------------- Arctic Core ------------------------------*/
\r
20 #include "internal.h"
\r
25 extern void Os_CfgGetInterruptStackInfo( OsStackType *stack );
\r
26 extern uint32_t McuE_GetSystemClock( void );
\r
27 extern OsTickType OsTickFreq;
\r
31 Os_IntCounterType Os_IntDisableAllCnt;
\r
32 Os_IntCounterType Os_IntSuspendAllCnt;
\r
33 Os_IntCounterType Os_IntSuspendOsCnt;
\r
37 * Copy rom pcb data(r_pcb) to ram data
\r
39 * @param pcb ram data
\r
40 * @param r_pcb rom data
\r
43 static void os_pcb_rom_copy( OsPcbType *pcb, const OsRomPcbType *r_pcb ) {
\r
46 // Check to that the memory is ok
\r
48 int cnt = sizeof(OsPcbType);
\r
49 for(int i=0;i<cnt;i++) {
\r
50 if( *((unsigned char *)pcb) != 0 ) {
\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
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
77 static _Bool init_os_called = 0;
\r
80 * Initialization of kernel structures and start of the first
\r
84 void InitOS( void ) {
\r
87 OsStackType int_stack;
\r
91 DEBUG(DEBUG_LOW,"os_init");
\r
94 memset(&os_sys,0,sizeof(sys_t));
\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
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
108 // Init counter.. with alarms and schedule tables
\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
119 assert(tmp_pcb->prio<=OS_TASK_PRIORITY_MAX);
\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
126 TAILQ_INIT(&tmp_pcb->resource_head);
\r
128 Os_AddTask(tmp_pcb);
\r
130 DEBUG(DEBUG_LOW,"pid:%d name:%s prio:%d\n",tmp_pcb->pid,tmp_pcb->name,tmp_pcb->prio);
\r
135 // Now all tasks should be created.
\r
138 static void os_start( void ) {
\r
139 OsPcbType *tmp_pcb;
\r
141 // We will be setting up interrupts,
\r
142 // but we don't want them to fire just yet
\r
145 assert(init_os_called);
\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
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
162 if( os_sys.appMode & autoPtr->appModeRef) {
\r
163 if( autoPtr->autostartType == ALARM_AUTOSTART_ABSOLUTE ) {
\r
164 SetAbsAlarm(j,autoPtr->alarmTime, autoPtr->cycleTime);
\r
166 SetRelAlarm(j,autoPtr->alarmTime, autoPtr->cycleTime);
\r
172 Os_SchTblAutostart();
\r
174 // Set up the systick interrupt
\r
176 uint32_t sys_freq = McuE_GetSystemClock();
\r
178 Os_SysTickStart(sys_freq/OsTickFreq);
\r
181 /* Find highest Autostart task */
\r
183 OsPcbType *iterPcbPtr;
\r
184 OsPriorityType topPrio = -1;
\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
196 // Swap in prio proc.
\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
208 static void os_start( void ) {
\r
213 #define TEST_DATA 12345
\r
214 int test_data = TEST_DATA;
\r
218 void noooo( void ) {
\r
222 extern void EcuM_Init();
\r
232 * @param Mode - Application mode to start in
\r
235 void StartOS(AppModeType Mode) {
\r
237 /* Check link file */
\r
238 if (TEST_DATA != test_data) {
\r
242 if (test_bss != 0) {
\r
246 os_sys.appMode = Mode;
\r
259 * @param Error - Reason for shutdown
\r
263 void ShutdownOS( StatusType Error ) {
\r
265 if( os_sys.hooks->ShutdownHook != NULL ) {
\r
266 os_sys.hooks->ShutdownHook(Error);
\r