1 /* -------------------------------- Arctic Core ------------------------------
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
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>.
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
14 * -------------------------------- Arctic Core ------------------------------*/
16 /* ----------------------------[includes]------------------------------------*/
25 /* ----------------------------[private define]------------------------------*/
26 /* ----------------------------[private macro]-------------------------------*/
27 /* ----------------------------[private typedef]-----------------------------*/
28 /* ----------------------------[private function prototypes]-----------------*/
29 /* ----------------------------[private variables]---------------------------*/
32 Os_IntCounterType Os_IntDisableAllCnt;
33 Os_IntCounterType Os_IntSuspendAllCnt;
34 Os_IntCounterType Os_IntSuspendOsCnt;
36 /* ----------------------------[private functions]---------------------------*/
37 /* ----------------------------[public functions]----------------------------*/
39 extern uint32_t McuE_GetSystemClock( void );
40 extern OsTickType OsTickFreq;
44 * Copy rom pcb data(r_pcb) to ram data
47 * @param r_pcb rom data
50 static void copyPcbParts( OsTaskVarType *pcb, const OsTaskConstType *r_pcb ) {
52 /* Copy VAR stuff first */
58 // Check to that the memory is ok
60 int cnt = sizeof(OsTaskVarType);
61 for(int i=0;i<cnt;i++) {
62 if( *((unsigned char *)pcb) != 0 ) {
69 // memset(pcb,sizeof(OsTaskVarType),0);
70 // pcb->pid = r_pcb->pid;
71 assert(r_pcb->prio<=OS_TASK_PRIORITY_MAX);
72 pcb->activePriority = r_pcb->prio;
73 #if (OS_USE_APPLICATIONS == STD_ON)
74 // pcb->accessingApp = Os_CfgGetApplObj(r_pcb->application_id);
76 // pcb->entry = r_pcb->entry;
77 // pcb->proc_type = r_pcb->proc_type;
78 // pcb->autostart = r_pcb->autostart;
79 pcb->stack= r_pcb->stack;
80 pcb->constPtr = r_pcb;
81 // pcb->resourceIntPtr = r_pcb->resourceIntPtr;
82 // pcb->scheduling = r_pcb->scheduling;
83 // pcb->resourceAccess = r_pcb->resourceAccess;
84 // pcb->activationLimit = r_pcb->activationLimit;
85 // pcb->app = &app_list[r_pcb->app];
86 // pcb->app_mask = app_mask[r_pcb->app];
87 // strncpy(pcb->name,r_pcb->name,16);
88 // pcb->name[15] = '\0';
91 static _Bool init_os_called = 0;
94 * Initialization of kernel structures and start of the first
100 OsTaskVarType *tmpPcbPtr;
101 OsIsrStackType intStack;
105 DEBUG(DEBUG_LOW,"os_init");
108 memset(&Os_Sys,0,sizeof(Os_SysType));
112 // Assign pcb list and init ready queue
113 Os_Sys.pcb_list = Os_TaskVarList;
114 TAILQ_INIT(& Os_Sys.ready_head);
115 // TAILQ_INIT(& Os_Sys.pcb_head);
116 #if defined(USE_KERNEL_EXTRA)
117 TAILQ_INIT(& Os_Sys.timerHead);
120 // Calc interrupt stack
121 Os_IsrGetStackInfo(&intStack);
122 // TODO: 16 is arch dependent
123 Os_Sys.intStack = (void *)((size_t)intStack.top + (size_t)intStack.size - 16);
125 // Init counter.. with alarms and schedule tables
126 #if OS_COUNTER_CNT!=0
133 // Put all tasks in the pcb list
134 // Put the one that belong in the ready queue there
135 // TODO: we should really hash on priority here to get speed, but I don't care for the moment
136 // TODO: Isn't this just EXTENED tasks ???
137 for( i=0; i < OS_TASK_CNT; i++) {
138 tmpPcbPtr = Os_TaskGet(i);
140 copyPcbParts(tmpPcbPtr,&Os_TaskConstList[i]);
143 Os_TaskContextInit(tmpPcbPtr);
145 if( !(tmpPcbPtr->constPtr->proc_type & PROC_ISR) ) {
146 Os_TaskContextInit(tmpPcbPtr);
150 TAILQ_INIT(&tmpPcbPtr->resourceHead);
153 Os_AddTask(tmpPcbPtr);
156 DEBUG(DEBUG_LOW,"pid:%d name:%s prio:%d\n",tmpPcbPtr->pid,tmpPcbPtr->name,tmpPcbPtr->prio);
161 // Now all tasks should be created.
164 static void os_start( void ) {
166 OsTaskVarType *tmpPcbPtr = NULL;
168 // We will be setting up interrupts,
169 // but we don't want them to fire just yet
172 assert(init_os_called);
175 /* Call the startup hook */
176 extern struct OsHooks os_conf_global_hooks;
177 Os_Sys.hooks = &os_conf_global_hooks;
178 if( Os_Sys.hooks->StartupHook!=NULL ) {
179 Os_Sys.hooks->StartupHook();
183 #if (OS_USE_APPLICATIONS == STD_ON)
184 /* Start applications */
189 /* Alarm autostart */
195 Os_SchTblAutostart();
198 // Set up the systick interrupt
200 uint32_t sys_freq = McuE_GetSystemClock();
202 Os_SysTickStart(sys_freq/OsTickFreq);
205 /* Find highest Autostart task */
207 OsTaskVarType *iterPcbPtr;
208 OsPriorityType topPrio = -1;
210 for(i=0;i<OS_TASK_CNT;i++) {
211 iterPcbPtr = Os_TaskGet(i);
212 if( iterPcbPtr->constPtr->autostart ) {
213 if( iterPcbPtr->activePriority > topPrio ) {
214 tmpPcbPtr = iterPcbPtr;
215 topPrio = iterPcbPtr->activePriority;
220 TAILQ_FOREACH(iterPcbPtr,& Os_Sys.pcb_head,pcb_list) {
221 if( iterPcbPtr->constPtr->autostart ) {
222 if( iterPcbPtr->activePriority > topPrio ) {
223 tmpPcbPtr = iterPcbPtr;
224 topPrio = iterPcbPtr->activePriority;
231 // Swap in prio proc.
233 // FIXME: Do this in a more structured way.. setting Os_Sys.currTaskPtr manually is not the way to go..
234 Os_Sys.currTaskPtr = tmpPcbPtr;
235 #if (OS_USE_APPLICATIONS == STD_ON)
236 /* Set current application */
237 Os_Sys.currApplId = tmpPcbPtr->constPtr->applOwnerId;
240 // register this auto-start activation
241 assert(tmpPcbPtr->activations < tmpPcbPtr->constPtr->activationLimit);
242 tmpPcbPtr->activations++;
244 // NOTE! We don't go for os_swap_context() here..
245 // first arg(NULL) is dummy only
246 Os_TaskSwapContextTo(NULL,tmpPcbPtr);
247 // We should not return here
252 static void os_start( void ) {
257 #define TEST_DATA 12345
258 int test_data = TEST_DATA;
266 extern void EcuM_Init();
276 * @param Mode - Application mode to start in
279 void StartOS(AppModeType Mode) {
281 /* Check link file */
282 if (TEST_DATA != test_data) {
290 Os_Sys.appMode = Mode;
303 * @param Error - Reason for shutdown
307 void ShutdownOS( StatusType Error ) {
309 if( Os_Sys.hooks->ShutdownHook != NULL ) {
310 Os_Sys.hooks->ShutdownHook(Error);