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]------------------------------------*/
26 #include "counter_i.h"
27 #include "application.h"
28 #include "sched_table_i.h"
32 /* ----------------------------[private define]------------------------------*/
33 /* ----------------------------[private macro]-------------------------------*/
34 #define OS_VALIDATE(_a,_b) if((_a)!=(_b) ) { \
37 /* ----------------------------[private typedef]-----------------------------*/
38 /* ----------------------------[private function prototypes]-----------------*/
39 /* ----------------------------[private variables]---------------------------*/
42 Os_IntCounterType Os_IntDisableAllCnt;
43 Os_IntCounterType Os_IntSuspendAllCnt;
44 Os_IntCounterType Os_IntSuspendOsCnt;
48 /* ----------------------------[private functions]---------------------------*/
51 static void Os_CfgValidate(void ) {
52 OS_VALIDATE(OS_COUNTER_CNT,ARRAY_SIZE(counter_list));
54 OS_VALIDATE(OS_RESOURCE_CNT,ARRAY_SIZE(resource_list));
56 OS_VALIDATE(OS_TASK_CNT ,ARRAY_SIZE( Os_TaskConstList));
58 OS_VALIDATE(OS_ALARM_CNT,ARRAY_SIZE(alarm_list));
60 #if (OS_SCHTBL_CNT!=0)
61 OS_VALIDATE(OS_SCHTBL_CNT, ARRAY_SIZE(sched_list));
65 /* ----------------------------[public functions]----------------------------*/
67 extern uint32_t McuE_GetSystemClock( void );
68 extern OsTickType OsTickFreq;
72 * Copy rom pcb data(r_pcb) to ram data
75 * @param r_pcb rom data
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;
85 static _Bool init_os_called = 0;
88 * Initialization of kernel structures and start of the first
94 OsTaskVarType *tmpPcbPtr;
95 OsIsrStackType intStack;
101 DEBUG(DEBUG_LOW,"os_init");
104 memset(&Os_Sys,0,sizeof(Os_SysType));
108 /* Get the numbers defined in the editor */
109 Os_Sys.isrCnt = OS_ISR_CNT;
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);
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);
124 // Init counter.. with alarms and schedule tables
125 #if OS_COUNTER_CNT!=0
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);
139 copyPcbParts(tmpPcbPtr,&Os_TaskConstList[i]);
140 Os_TaskContextInit(tmpPcbPtr);
141 TAILQ_INIT(&tmpPcbPtr->resourceHead);
144 Os_AddTask(tmpPcbPtr);
147 DEBUG(DEBUG_LOW,"pid:%d name:%s prio:%d\n",tmpPcbPtr->pid,tmpPcbPtr->name,tmpPcbPtr->prio);
152 // Now all tasks should be created.
155 static void os_start( void ) {
157 OsTaskVarType *tmpPcbPtr = NULL;
159 // We will be setting up interrupts,
160 // but we don't want them to fire just yet
163 assert(init_os_called);
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();
174 #if (OS_USE_APPLICATIONS == STD_ON)
175 /* Start applications */
180 /* Alarm autostart */
186 Os_SchTblAutostart();
189 // Set up the systick interrupt
191 uint32_t sys_freq = McuE_GetSystemClock();
193 Os_SysTickStart(sys_freq/OsTickFreq);
196 /* Find highest Autostart task */
198 OsTaskVarType *iterPcbPtr;
199 OsPriorityType topPrio = -1;
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;
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;
222 // Swap in prio proc.
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;
231 // register this auto-start activation
232 assert(tmpPcbPtr->activations < tmpPcbPtr->constPtr->activationLimit);
233 tmpPcbPtr->activations++;
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
243 static void os_start( void ) {
248 #define TEST_DATA 12345
249 int test_data = TEST_DATA;
257 extern void EcuM_Init();
267 * @param Mode - Application mode to start in
270 void StartOS(AppModeType Mode) {
272 /* Check link file */
273 if (TEST_DATA != test_data) {
281 Os_Sys.appMode = Mode;
294 * @param Error - Reason for shutdown
298 void ShutdownOS( StatusType Error ) {
300 if( Os_Sys.hooks->ShutdownHook != NULL ) {
301 Os_Sys.hooks->ShutdownHook(Error);