]> rtime.felk.cvut.cz Git - arc.git/blob - system/EcuM/EcuM.c
Re-added generic callout stubs file for Dcm (with make rule).
[arc.git] / system / EcuM / EcuM.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\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
9  *\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
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 //lint -emacro(904,VALIDATE,VALIDATE_RV,VALIDATE_NO_RV) //904 PC-Lint exception to MISRA 14.7 (validate macros).\r
17 \r
18 #include "Std_Types.h"\r
19 #include "EcuM.h"\r
20 #include "Modules.h"\r
21 #include <string.h>\r
22 #include <Os.h>\r
23 #include "EcuM_Generated_Types.h"\r
24 #include "EcuM_Internals.h"\r
25 #include "EcuM_Cbk.h"\r
26 #include "SchM_EcuM.h"\r
27 #include "MemMap.h"\r
28 #include "Mcu.h"\r
29 #include "ComStack_Types.h"\r
30 #if defined(USE_DET)\r
31 #include "Det.h"\r
32 #endif\r
33 #include "isr.h"\r
34 #if defined(USE_NVM)\r
35 #include "NvM.h"\r
36 #endif\r
37 #if defined(USE_RTE)\r
38 #include "Rte_Main.h"\r
39 #endif\r
40 #if defined(USE_SCHM)\r
41 #include "SchM.h"\r
42 #endif\r
43 \r
44 \r
45 \r
46 EcuM_GlobalType internal_data;\r
47 \r
48 #if !defined(USE_DET) && defined(ECUM_DEV_ERROR_DETECT)\r
49 #error EcuM configuration error. DET is not enabled when ECUM_DEV_ERROR_DETECT is set\r
50 #endif\r
51 \r
52 void EcuM_Init( void )\r
53 {\r
54         Std_ReturnType status;\r
55         set_current_state(ECUM_STATE_STARTUP_ONE);\r
56 \r
57         // Initialize drivers that are needed to determine PostBuild configuration\r
58         EcuM_AL_DriverInitZero();\r
59 \r
60         // Initialize the OS\r
61         InitOS();\r
62 \r
63         // Setup interrupts\r
64         Os_IsrInit();\r
65 \r
66         // Determine PostBuild configuration\r
67         internal_data.config = EcuM_DeterminePbConfiguration();\r
68 \r
69         // TODO: Check consistency of PB configuration\r
70 \r
71         // Initialize drivers needed before the OS-starts\r
72         EcuM_AL_DriverInitOne(internal_data.config);\r
73 \r
74         // Determine the reset/wakeup reason\r
75         // TODO Mcu_ResetType type = Mcu_GetResetReason();\r
76 \r
77         // Moved this here because EcuM_SelectShutdownTarget needs us to be initilized.\r
78         internal_data.initiated = TRUE;\r
79 \r
80         // Set default shutdown target\r
81         status = EcuM_SelectShutdownTarget(internal_data.config->EcuMDefaultShutdownTarget,internal_data.config->EcuMDefaultSleepMode);/** @req EcuM2181 */\r
82         if(status!=E_OK){\r
83                 //TODO: Report error.\r
84         }\r
85 \r
86 \r
87         // Set default application mode\r
88         status =  EcuM_SelectApplicationMode(internal_data.config->EcuMDefaultAppMode);\r
89         if(status!=E_OK){\r
90                 //TODO: Report error.\r
91         }\r
92 \r
93 #if defined(USE_COMM) || defined(USE_ECUM_COMM)\r
94         internal_data.run_comm_requests = 0;\r
95 #endif\r
96         internal_data.run_requests = 0;\r
97         internal_data.postrun_requests = 0;\r
98 \r
99         // Start this baby up\r
100         AppModeType appMode;\r
101         status = EcuM_GetApplicationMode(&appMode);\r
102         if(status!=E_OK){\r
103                 //TODO: Report error.\r
104         }\r
105         StartOS(appMode); /** @req EcuM2141 */\r
106 }\r
107 \r
108 /*\r
109  * The order defined here is found in 3.1.5/EcuM2411\r
110  */\r
111 void EcuM_StartupTwo(void)\r
112 {\r
113         //TODO:  Validate that we are in state STARTUP_ONE.\r
114 #if defined(USE_NVM)\r
115         extern CounterType Os_Arc_OsTickCounter;\r
116         TickType tickTimerStart, tickTimerElapsed;\r
117         static NvM_RequestResultType readAllResult;\r
118         TickType tickTimer;\r
119         StatusType tickTimerStatus;\r
120 #endif\r
121 \r
122         // Initialize the BSW scheduler\r
123 #if defined(USE_SCHM)\r
124         SchM_Init();\r
125 #endif\r
126 \r
127         // Initialize drivers that don't need NVRAM data\r
128         EcuM_AL_DriverInitTwo(internal_data.config);\r
129 \r
130 #if defined(USE_NVM)\r
131         // Start timer to wait for NVM job to complete\r
132         tickTimerStart = GetOsTick();\r
133 #endif\r
134 \r
135         // Prepare the system to startup RTE\r
136         // TODO EcuM_OnRTEStartup();\r
137 #if defined(USE_RTE)\r
138         Rte_Start();\r
139 #endif\r
140 \r
141         set_current_state(ECUM_STATE_STARTUP_TWO);\r
142 \r
143 #if defined(USE_NVM)\r
144 \r
145 #if 0\r
146         /* Wait for the NVM job (NvmReadAll) to terminate. This assumes that:\r
147          * - A task runs the memory MainFunctions, e.g. Ea_MainFunction(), Eep_MainFunction()\r
148          *    Prio: HIGH\r
149          * - A task runs the service functions for EcuM, Nvm.\r
150          *    Prio: MIDDLE\r
151          * - This task:\r
152          *    Prio: LOW  (So that the service functions for the other may run)\r
153          */\r
154         do {\r
155                 /* Read the multiblock status */\r
156                 NvM_GetErrorStatus(0, &readAllResult);\r
157                 tickTimerElapsed = OS_TICKS2MS_OsTick(GetOsTick() - tickTimerStart);\r
158                 /* The timeout EcuMNvramReadAllTimeout is in ms */\r
159         } while( (readAllResult == NVM_REQ_PENDING) && (tickTimerElapsed < internal_data.config->EcuMNvramReadAllTimeout) );\r
160 #else\r
161         // Wait for the NVM job (NvmReadAll) to terminate\r
162                 do {\r
163                         NvM_GetErrorStatus(0, &readAllResult);  // Read the multiblock status\r
164                         tickTimer = tickTimerStart;     // Save this because the GetElapsedCounterValue() will destroy it.\r
165                         tickTimerStatus =  GetElapsedCounterValue(Os_Arc_OsTickCounter, &tickTimer, &tickTimerElapsed);\r
166                         if (tickTimerStatus != E_OK) {\r
167                                 DET_REPORTERROR(MODULE_ID_ECUM, 0, ECUM_ARC_STARTUPTWO_ID, ECUM_E_ARC_TIMERERROR);\r
168                         }\r
169                 } while( (readAllResult == NVM_REQ_PENDING) && (tickTimerElapsed < internal_data.config->EcuMNvramReadAllTimeout) );\r
170 #endif\r
171 #endif\r
172 \r
173         // Initialize drivers that need NVRAM data\r
174         EcuM_AL_DriverInitThree(internal_data.config);\r
175 \r
176         // TODO: Indicate mode change to RTE\r
177 \r
178         // If coming from startup sequence, enter Run mode\r
179 //      if (internal_data.current_state == ECUM_STATE_STARTUP_TWO)\r
180                 EcuM_enter_run_mode();\r
181 \r
182 }\r
183 \r
184 // Typically called from OS shutdown hook\r
185 void EcuM_Shutdown(void)\r
186 {\r
187         set_current_state(ECUM_STATE_GO_OFF_TWO);\r
188 \r
189         // Let the last drivers do a nice shutdown\r
190         EcuM_OnGoOffTwo();\r
191 \r
192         if (internal_data.shutdown_target == ECUM_STATE_OFF)\r
193         {\r
194                 EcuM_AL_SwitchOff();\r
195         }\r
196         else\r
197         {\r
198 #if (MCU_PERFORM_RESET_API == STD_ON)\r
199                 Mcu_PerformReset();\r
200 #else\r
201                 for(;;)\r
202                 {\r
203                   ;\r
204                 }\r
205 #endif\r
206         }\r
207 }\r
208 \r
209 Std_ReturnType EcuM_GetState(EcuM_StateType* state)\r
210 {\r
211         VALIDATE_RV(internal_data.initiated, ECUM_GETSTATE_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
212         VALIDATE_RV(state != NULL, ECUM_GETSTATE_ID, ECUM_E_NULL_POINTER, E_NOT_OK);\r
213 \r
214         *state = internal_data.current_state;\r
215 \r
216         return E_OK;\r
217 }\r
218 \r
219 Std_ReturnType EcuM_SelectApplicationMode(AppModeType appMode)\r
220 {\r
221         VALIDATE_RV(internal_data.initiated, ECUM_SELECTAPPMODE_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
222 \r
223         internal_data.app_mode = appMode;\r
224 \r
225         return E_OK;\r
226 }\r
227 \r
228 Std_ReturnType EcuM_GetApplicationMode(AppModeType* appMode)\r
229 {\r
230         VALIDATE_RV(internal_data.initiated, ECUM_GETAPPMODE_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
231         VALIDATE_RV(appMode != NULL, ECUM_GETAPPMODE_ID, ECUM_E_NULL_POINTER, E_NOT_OK);\r
232 \r
233         *appMode = internal_data.app_mode;\r
234 \r
235         return E_OK;\r
236 }\r
237 \r
238 Std_ReturnType EcuM_SelectBootTarget(EcuM_BootTargetType target)\r
239 {\r
240         VALIDATE_RV(internal_data.initiated, ECUM_SELECT_BOOTARGET_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
241 \r
242         // TODO Do something great here\r
243         (void) target;\r
244 \r
245         return E_NOT_OK;\r
246 }\r
247 \r
248 Std_ReturnType EcuM_GetBootTarget(EcuM_BootTargetType* target)\r
249 {\r
250         VALIDATE_RV(internal_data.initiated, ECUM_GET_BOOTARGET_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
251         VALIDATE_RV(target != NULL, ECUM_GET_BOOTARGET_ID, ECUM_E_NULL_POINTER, E_NOT_OK);\r
252 \r
253         // TODO Return selected boot target here\r
254         (void) target;\r
255 \r
256         return E_NOT_OK;\r
257 }\r
258 \r
259 \r
260 Std_ReturnType EcuM_SelectShutdownTarget(EcuM_StateType shutdownTarget, uint8 sleepMode)\r
261 {\r
262         VALIDATE_RV(internal_data.initiated, ECUM_SELECTSHUTDOWNTARGET_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
263         VALIDATE_RV((shutdownTarget == ECUM_STATE_OFF) || (shutdownTarget == ECUM_STATE_RESET) || (shutdownTarget == ECUM_STATE_SLEEP), ECUM_SELECTSHUTDOWNTARGET_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
264 \r
265         internal_data.shutdown_target = shutdownTarget;\r
266         internal_data.sleep_mode = sleepMode;\r
267 \r
268         return E_OK;\r
269 }\r
270 \r
271 \r
272 Std_ReturnType EcuM_GetShutdownTarget(EcuM_StateType* shutdownTarget, uint8* sleepMode) /** @req EcuM2824 */\r
273 {\r
274         VALIDATE_RV(internal_data.initiated, ECUM_GETSHUTDOWNTARGET_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
275         VALIDATE_RV(shutdownTarget != NULL, ECUM_GETSHUTDOWNTARGET_ID, ECUM_E_NULL_POINTER, E_NOT_OK);\r
276         VALIDATE_RV(sleepMode != NULL, ECUM_GETSHUTDOWNTARGET_ID, ECUM_E_NULL_POINTER, E_NOT_OK);\r
277 \r
278         *shutdownTarget = internal_data.shutdown_target;\r
279         *sleepMode = internal_data.sleep_mode;\r
280 \r
281         return E_OK;\r
282 }\r
283 \r
284 \r
285 Std_ReturnType EcuM_RequestRUN(EcuM_UserType user)\r
286 {\r
287         VALIDATE_RV(internal_data.initiated, ECUM_REQUESTRUN_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
288         VALIDATE_RV(user < ECUM_USER_ENDMARK, ECUM_REQUESTRUN_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
289 \r
290         internal_data.run_requests |= (uint32)1 << user;\r
291 \r
292         return E_OK;\r
293 }\r
294 \r
295 Std_ReturnType EcuM_ReleaseRUN(EcuM_UserType user)\r
296 {\r
297         VALIDATE_RV(internal_data.initiated, ECUM_RELEASERUN_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
298         VALIDATE_RV(user < ECUM_USER_ENDMARK, ECUM_RELEASERUN_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
299 \r
300         internal_data.run_requests &= ~((uint32)1 << user);\r
301 \r
302         return E_OK;\r
303 }\r
304 \r
305 void EcuM_KillAllRUNRequests( void ) {\r
306         /* NOT IMPLEMENTED */\r
307 }\r
308 \r
309 void EcuM_SetWakeupEvent(EcuM_WakeupSourceType sources) {\r
310         /* NOT IMPLEMENTED */\r
311 }\r
312 \r
313 #if defined(USE_COMM) || defined(USE_ECUM_COMM)\r
314 Std_ReturnType EcuM_ComM_RequestRUN(NetworkHandleType channel)\r
315 {\r
316         VALIDATE_RV(internal_data.initiated, ECUM_COMM_REQUESTRUN_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
317         VALIDATE_RV(channel < 32, ECUM_COMM_REQUESTRUN_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
318 \r
319         internal_data.run_comm_requests |= (uint32)1 << channel;\r
320 \r
321         return E_OK;\r
322 }\r
323 \r
324 Std_ReturnType EcuM_ComM_ReleaseRUN(NetworkHandleType channel)\r
325 {\r
326         VALIDATE_RV(internal_data.initiated, ECUM_COMM_RELEASERUN_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
327         VALIDATE_RV(channel < 32, ECUM_COMM_RELEASERUN_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
328 \r
329         internal_data.run_comm_requests &= ~((uint32)1 << channel);\r
330 \r
331         return E_OK;\r
332 }\r
333 \r
334 boolean EcuM_ComM_HasRequestedRUN(NetworkHandleType channel)\r
335 {\r
336         VALIDATE_RV(internal_data.initiated, ECUM_COMM_HASREQUESTEDRUN_ID, ECUM_E_NOT_INITIATED, FALSE);\r
337         VALIDATE_RV(channel < 32, ECUM_COMM_HASREQUESTEDRUN_ID, ECUM_E_INVALID_PAR, FALSE);\r
338 \r
339         return (internal_data.run_comm_requests &((uint32)1 << channel)) != 0;\r
340 }\r
341 #endif\r
342 \r
343 Std_ReturnType EcuM_RequestPOST_RUN(EcuM_UserType user)\r
344 {\r
345         VALIDATE_RV(internal_data.initiated, ECUM_REQUESTPOSTRUN_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
346         VALIDATE_RV(user < ECUM_USER_ENDMARK, ECUM_REQUESTPOSTRUN_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
347 \r
348         internal_data.postrun_requests |= (uint32)1 << user;\r
349 \r
350         return E_OK;\r
351 }\r
352 \r
353 Std_ReturnType EcuM_ReleasePOST_RUN(EcuM_UserType user)\r
354 {\r
355         VALIDATE_RV(internal_data.initiated, ECUM_RELEASEPOSTRUN_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
356         VALIDATE_RV(user < ECUM_USER_ENDMARK, ECUM_RELEASEPOSTRUN_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
357 \r
358         internal_data.postrun_requests &= ~((uint32)1 << user);\r
359 \r
360         return E_OK;\r
361 }\r
362 \r