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