]> rtime.felk.cvut.cz Git - arc.git/blob - system/EcuM/EcuM.c
EcuM/MCU: Sleep code there..does not work
[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 \r
17 /** @reqSettings DEFAULT_SPECIFICATION_REVISION=3.1.5 */\r
18 \r
19 /* ----------------------------[information]----------------------------------*/\r
20 /*\r
21  * Author: ?+mahi\r
22  *\r
23  * Part of Release:\r
24  *   3.1.5\r
25  *\r
26  * Description:\r
27  *   Implements the Can Driver module\r
28  *\r
29  * Support:\r
30  *   General                  Have Support\r
31  *   -------------------------------------------\r
32  *   ECUM_TTII_ENABLED                          N\r
33  *   ECUM_DEV_ERROR_DETECT                              Y\r
34  *   ECUM_VERSION_INFO_API                              Y\r
35  *   ECUM_INCLUDE_DEM                                   N (controlled by USE_x macro's instead)\r
36  *   ECUM_INCLUDE_NVRAM_MGR                             N (controlled by USE_x macro's instead)\r
37  *   ECUM_INLCUDE_DET                                   N (controlled by USE_x macro's instead)\r
38  *   ECUM_MAIN_FUNCTION_PERDIOD                 Y\r
39  *   ECUM_TTII_WKSOURCE                                 N\r
40  *\r
41  *   Configuration            Have Support\r
42  *   -------------------------------------------\r
43  *   ECUM_SLEEP_ACTIVITY_PERIOD                 ?\r
44  *   ECUM_CONFIGCONSISTENCY_HASH                N\r
45  *   ECUM_RUN_SELF_REQUEST_PERIOD               ?\r
46  *   ECUM_NVRAM_WRITEALL_TIMEOUT                Y\r
47  *   ECUM_DEFAULT_APP_MODE                              ?\r
48  *\r
49  *\r
50  *   DefaultShutdownTarget\r
51  *   -------------------------------------------\r
52  *   ECUM_DEFAULT_SHUTDOWN_TARGET               N\r
53  *\r
54  *\r
55  * Things to start with:\r
56  * - EcuM2181\r
57  * - EcuM2861 , Watchdog\r
58  * - ComM_EcuM_RunModeIndication()  not called, See Figure 8 (Seems that the ComM does not do much either)\r
59  *\r
60  *\r
61  *\r
62  */\r
63 \r
64 //lint -emacro(904,VALIDATE,VALIDATE_RV,VALIDATE_NO_RV) //904 PC-Lint exception to MISRA 14.7 (validate macros).\r
65 \r
66 \r
67 /* ----------------------------[includes]------------------------------------*/\r
68 \r
69 #include "Std_Types.h"\r
70 #include "EcuM.h"\r
71 #include "Modules.h"\r
72 #include <string.h>\r
73 #include <Os.h>\r
74 #include "EcuM_Generated_Types.h"\r
75 #include "EcuM_Internals.h"\r
76 #include "EcuM_Cbk.h"\r
77 #include "SchM_EcuM.h"\r
78 #include "MemMap.h"\r
79 #include "Mcu.h"\r
80 #include "ComStack_Types.h"\r
81 #if defined(USE_DET)\r
82 #include "Det.h"\r
83 #endif\r
84 #include "isr.h"\r
85 #if defined(USE_NVM)\r
86 #include "NvM.h"\r
87 #endif\r
88 #if defined(USE_RTE)\r
89 #include "Rte_Main.h"\r
90 #endif\r
91 #if defined(USE_SCHM)\r
92 #include "SchM.h"\r
93 #endif\r
94 \r
95 \r
96 /* ----------------------------[private define]------------------------------*/\r
97 /* ----------------------------[private macro]-------------------------------*/\r
98 /* ----------------------------[private typedef]-----------------------------*/\r
99 /* ----------------------------[private function prototypes]-----------------*/\r
100 /* ----------------------------[private variables]---------------------------*/\r
101 \r
102 EcuM_GlobalType internal_data;\r
103 \r
104 /* ----------------------------[private functions]---------------------------*/\r
105 /* ----------------------------[public functions]----------------------------*/\r
106 \r
107 #if !defined(USE_DET) && defined(ECUM_DEV_ERROR_DETECT)\r
108 #error EcuM configuration error. DET is not enabled when ECUM_DEV_ERROR_DETECT is set\r
109 #endif\r
110 \r
111 void EcuM_Init( void )\r
112 {\r
113         Std_ReturnType status;\r
114         set_current_state(ECUM_STATE_STARTUP_ONE);\r
115 \r
116         // Initialize drivers that are needed to determine PostBuild configuration\r
117         EcuM_AL_DriverInitZero();\r
118 \r
119         // Initialize the OS\r
120         InitOS();\r
121 \r
122         // Setup interrupts\r
123         Os_IsrInit();\r
124 \r
125         // Determine PostBuild configuration\r
126         internal_data.config = EcuM_DeterminePbConfiguration();\r
127 \r
128 \r
129         // TODO: Check consistency of PB configuration\r
130 \r
131         // Initialize drivers needed before the OS-starts\r
132         EcuM_AL_DriverInitOne(internal_data.config);\r
133 \r
134         // Determine the reset/wakeup reason\r
135         // TODO Mcu_ResetType type = Mcu_GetResetReason();\r
136 \r
137         // Moved this here because EcuM_SelectShutdownTarget needs us to be initilized.\r
138         internal_data.initiated = TRUE;\r
139 \r
140         // Set default shutdown target\r
141         status = EcuM_SelectShutdownTarget(internal_data.config->EcuMDefaultShutdownTarget,internal_data.config->EcuMDefaultSleepMode);/** @req EcuM2181 */\r
142         if(status!=E_OK){\r
143                 //TODO: Report error.\r
144         }\r
145 \r
146 \r
147         // Set default application mode\r
148         status =  EcuM_SelectApplicationMode(internal_data.config->EcuMDefaultAppMode);\r
149         if(status!=E_OK){\r
150                 //TODO: Report error.\r
151         }\r
152 \r
153 #if defined(USE_COMM) || defined(USE_ECUM_COMM)\r
154         internal_data.run_comm_requests = 0;\r
155 #endif\r
156         internal_data.run_requests = 0;\r
157         internal_data.postrun_requests = 0;\r
158 \r
159         // Start this baby up\r
160         AppModeType appMode;\r
161         status = EcuM_GetApplicationMode(&appMode);\r
162         if(status!=E_OK){\r
163                 //TODO: Report error.\r
164         }\r
165         StartOS(appMode); /** @req EcuM2141 */\r
166 }\r
167 \r
168 /*\r
169  * The order defined here is found in 3.1.5/EcuM2411\r
170  */\r
171 void EcuM_StartupTwo(void)\r
172 {\r
173         //TODO:  Validate that we are in state STARTUP_ONE.\r
174 #if defined(USE_NVM)\r
175         extern CounterType Os_Arc_OsTickCounter;\r
176         TickType tickTimerStart, tickTimerElapsed;\r
177         static NvM_RequestResultType readAllResult;\r
178         TickType tickTimer;\r
179         StatusType tickTimerStatus;\r
180 #endif\r
181 \r
182         // Initialize the BSW scheduler\r
183 #if defined(USE_SCHM)\r
184         SchM_Init();\r
185 #endif\r
186 \r
187         // Initialize drivers that don't need NVRAM data\r
188         EcuM_AL_DriverInitTwo(internal_data.config);\r
189 \r
190 #if defined(USE_NVM)\r
191         // Start timer to wait for NVM job to complete\r
192         tickTimerStart = GetOsTick();\r
193 #endif\r
194 \r
195         // Prepare the system to startup RTE\r
196         // TODO EcuM_OnRTEStartup();\r
197 #if defined(USE_RTE)\r
198         Rte_Start();\r
199 #endif\r
200 \r
201         set_current_state(ECUM_STATE_STARTUP_TWO);\r
202 \r
203 #if defined(USE_NVM)\r
204 \r
205 #if 0\r
206         /* Wait for the NVM job (NvmReadAll) to terminate. This assumes that:\r
207          * - A task runs the memory MainFunctions, e.g. Ea_MainFunction(), Eep_MainFunction()\r
208          *    Prio: HIGH\r
209          * - A task runs the service functions for EcuM, Nvm.\r
210          *    Prio: MIDDLE\r
211          * - This task:\r
212          *    Prio: LOW  (So that the service functions for the other may run)\r
213          */\r
214         do {\r
215                 /* Read the multiblock status */\r
216                 NvM_GetErrorStatus(0, &readAllResult);\r
217                 tickTimerElapsed = OS_TICKS2MS_OsTick(GetOsTick() - tickTimerStart);\r
218                 /* The timeout EcuMNvramReadAllTimeout is in ms */\r
219         } while( (readAllResult == NVM_REQ_PENDING) && (tickTimerElapsed < internal_data.config->EcuMNvramReadAllTimeout) );\r
220 #else\r
221         // Wait for the NVM job (NvmReadAll) to terminate\r
222                 do {\r
223                         NvM_GetErrorStatus(0, &readAllResult);  // Read the multiblock status\r
224                         tickTimer = tickTimerStart;     // Save this because the GetElapsedCounterValue() will destroy it.\r
225                         tickTimerStatus =  GetElapsedCounterValue(Os_Arc_OsTickCounter, &tickTimer, &tickTimerElapsed);\r
226                         if (tickTimerStatus != E_OK) {\r
227                                 DET_REPORTERROR(MODULE_ID_ECUM, 0, ECUM_ARC_STARTUPTWO_ID, ECUM_E_ARC_TIMERERROR);\r
228                         }\r
229                 } while( (readAllResult == NVM_REQ_PENDING) && (tickTimerElapsed < internal_data.config->EcuMNvramReadAllTimeout) );\r
230 #endif\r
231 #endif\r
232 \r
233         // Initialize drivers that need NVRAM data\r
234         EcuM_AL_DriverInitThree(internal_data.config);\r
235 \r
236         // TODO: Indicate mode change to RTE\r
237 \r
238         // If coming from startup sequence, enter Run mode\r
239 //      if (internal_data.current_state == ECUM_STATE_STARTUP_TWO)\r
240                 EcuM_enter_run_mode();\r
241 \r
242 }\r
243 \r
244 // Typically called from OS shutdown hook\r
245 void EcuM_Shutdown(void)\r
246 {\r
247         set_current_state(ECUM_STATE_GO_OFF_TWO);\r
248 \r
249         // Let the last drivers do a nice shutdown\r
250         EcuM_OnGoOffTwo();\r
251 \r
252         if (internal_data.shutdown_target == ECUM_STATE_OFF)\r
253         {\r
254                 EcuM_AL_SwitchOff();\r
255         }\r
256         else\r
257         {\r
258 #if (MCU_PERFORM_RESET_API == STD_ON)\r
259                 Mcu_PerformReset();\r
260 #else\r
261                 for(;;)\r
262                 {\r
263                   ;\r
264                 }\r
265 #endif\r
266         }\r
267 }\r
268 \r
269 Std_ReturnType EcuM_GetState(EcuM_StateType* state)\r
270 {\r
271         VALIDATE_RV(internal_data.initiated, ECUM_GETSTATE_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
272         VALIDATE_RV(state != NULL, ECUM_GETSTATE_ID, ECUM_E_NULL_POINTER, E_NOT_OK);\r
273 \r
274         *state = internal_data.current_state;\r
275 \r
276         return E_OK;\r
277 }\r
278 \r
279 Std_ReturnType EcuM_SelectApplicationMode(AppModeType appMode)\r
280 {\r
281         VALIDATE_RV(internal_data.initiated, ECUM_SELECTAPPMODE_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
282 \r
283         internal_data.app_mode = appMode;\r
284 \r
285         return E_OK;\r
286 }\r
287 \r
288 Std_ReturnType EcuM_GetApplicationMode(AppModeType* appMode)\r
289 {\r
290         VALIDATE_RV(internal_data.initiated, ECUM_GETAPPMODE_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
291         VALIDATE_RV(appMode != NULL, ECUM_GETAPPMODE_ID, ECUM_E_NULL_POINTER, E_NOT_OK);\r
292 \r
293         *appMode = internal_data.app_mode;\r
294 \r
295         return E_OK;\r
296 }\r
297 \r
298 Std_ReturnType EcuM_SelectBootTarget(EcuM_BootTargetType target)\r
299 {\r
300         VALIDATE_RV(internal_data.initiated, ECUM_SELECT_BOOTARGET_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
301 \r
302         // TODO Do something great here\r
303         (void) target;\r
304 \r
305         return E_NOT_OK;\r
306 }\r
307 \r
308 Std_ReturnType EcuM_GetBootTarget(EcuM_BootTargetType* target)\r
309 {\r
310         VALIDATE_RV(internal_data.initiated, ECUM_GET_BOOTARGET_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
311         VALIDATE_RV(target != NULL, ECUM_GET_BOOTARGET_ID, ECUM_E_NULL_POINTER, E_NOT_OK);\r
312 \r
313         // TODO Return selected boot target here\r
314         (void) target;\r
315 \r
316         return E_NOT_OK;\r
317 }\r
318 \r
319 \r
320 Std_ReturnType EcuM_SelectShutdownTarget(EcuM_StateType shutdownTarget, uint8 sleepMode)\r
321 {\r
322         VALIDATE_RV(internal_data.initiated, ECUM_SELECTSHUTDOWNTARGET_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
323         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
324 \r
325         internal_data.shutdown_target = shutdownTarget;\r
326         internal_data.sleep_mode = sleepMode;\r
327 \r
328         return E_OK;\r
329 }\r
330 \r
331 \r
332 Std_ReturnType EcuM_GetShutdownTarget(EcuM_StateType* shutdownTarget, uint8* sleepMode) /** @req EcuM2824 */\r
333 {\r
334         VALIDATE_RV(internal_data.initiated, ECUM_GETSHUTDOWNTARGET_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
335         VALIDATE_RV(shutdownTarget != NULL, ECUM_GETSHUTDOWNTARGET_ID, ECUM_E_NULL_POINTER, E_NOT_OK);\r
336         VALIDATE_RV(sleepMode != NULL, ECUM_GETSHUTDOWNTARGET_ID, ECUM_E_NULL_POINTER, E_NOT_OK);\r
337 \r
338         *shutdownTarget = internal_data.shutdown_target;\r
339         *sleepMode = internal_data.sleep_mode;\r
340 \r
341         return E_OK;\r
342 }\r
343 \r
344 \r
345 Std_ReturnType EcuM_RequestRUN(EcuM_UserType user)\r
346 {\r
347         VALIDATE_RV(internal_data.initiated, ECUM_REQUESTRUN_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
348         VALIDATE_RV(user < ECUM_USER_ENDMARK, ECUM_REQUESTRUN_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
349 \r
350         internal_data.run_requests |= (uint32)1 << user;\r
351 \r
352         return E_OK;\r
353 }\r
354 \r
355 Std_ReturnType EcuM_ReleaseRUN(EcuM_UserType user)\r
356 {\r
357         VALIDATE_RV(internal_data.initiated, ECUM_RELEASERUN_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
358         VALIDATE_RV(user < ECUM_USER_ENDMARK, ECUM_RELEASERUN_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
359 \r
360         internal_data.run_requests &= ~((uint32)1 << user);\r
361 \r
362         return E_OK;\r
363 }\r
364 \r
365 void EcuM_KillAllRUNRequests( void ) {\r
366         /* NOT IMPLEMENTED */\r
367 }\r
368 \r
369 void EcuM_SetWakeupEvent(EcuM_WakeupSourceType sources) {\r
370         /* NOT IMPLEMENTED */\r
371 }\r
372 \r
373 #if defined(USE_COMM) || defined(USE_ECUM_COMM)\r
374 Std_ReturnType EcuM_ComM_RequestRUN(NetworkHandleType channel)\r
375 {\r
376         VALIDATE_RV(internal_data.initiated, ECUM_COMM_REQUESTRUN_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
377         VALIDATE_RV(channel < 32, ECUM_COMM_REQUESTRUN_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
378 \r
379         internal_data.run_comm_requests |= (uint32)1 << channel;\r
380 \r
381         return E_OK;\r
382 }\r
383 \r
384 Std_ReturnType EcuM_ComM_ReleaseRUN(NetworkHandleType channel)\r
385 {\r
386         VALIDATE_RV(internal_data.initiated, ECUM_COMM_RELEASERUN_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
387         VALIDATE_RV(channel < 32, ECUM_COMM_RELEASERUN_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
388 \r
389         internal_data.run_comm_requests &= ~((uint32)1 << channel);\r
390 \r
391         return E_OK;\r
392 }\r
393 \r
394 boolean EcuM_ComM_HasRequestedRUN(NetworkHandleType channel)\r
395 {\r
396         VALIDATE_RV(internal_data.initiated, ECUM_COMM_HASREQUESTEDRUN_ID, ECUM_E_NOT_INITIATED, FALSE);\r
397         VALIDATE_RV(channel < 32, ECUM_COMM_HASREQUESTEDRUN_ID, ECUM_E_INVALID_PAR, FALSE);\r
398 \r
399         return (internal_data.run_comm_requests &((uint32)1 << channel)) != 0;\r
400 }\r
401 #endif\r
402 \r
403 Std_ReturnType EcuM_RequestPOST_RUN(EcuM_UserType user)\r
404 {\r
405         VALIDATE_RV(internal_data.initiated, ECUM_REQUESTPOSTRUN_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
406         VALIDATE_RV(user < ECUM_USER_ENDMARK, ECUM_REQUESTPOSTRUN_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
407 \r
408         internal_data.postrun_requests |= (uint32)1 << user;\r
409 \r
410         return E_OK;\r
411 }\r
412 \r
413 Std_ReturnType EcuM_ReleasePOST_RUN(EcuM_UserType user)\r
414 {\r
415         VALIDATE_RV(internal_data.initiated, ECUM_RELEASEPOSTRUN_ID, ECUM_E_NOT_INITIATED, E_NOT_OK);\r
416         VALIDATE_RV(user < ECUM_USER_ENDMARK, ECUM_RELEASEPOSTRUN_ID, ECUM_E_INVALID_PAR, E_NOT_OK);\r
417 \r
418         internal_data.postrun_requests &= ~((uint32)1 << user);\r
419 \r
420         return E_OK;\r
421 }\r
422 \r
423 /*\r
424  * TODO: Don't yet understand the use\r
425  */\r
426 void EcuM_ClearWakeupEvent( EcuM_WakeupSourceType source )\r
427 {\r
428         switch(source) {\r
429         case ECUM_WKSTATUS_NONE:\r
430                 /* Seems quite pointless */\r
431                 break;\r
432         case ECUM_WKSTATUS_PENDING:\r
433                 break;\r
434         case ECUM_WKSTATUS_VALIDATED:\r
435                 break;\r
436         case ECUM_WKSTATUS_EXPIRED:\r
437                 break;\r
438         default:\r
439                 break;\r
440         }\r
441 }\r
442 \r
443 /**\r
444  * TODO:\r
445  * @return\r
446  */\r
447 EcuM_WakeupSourceType EcuM_GetPendingWakeupEvents( void ) {\r
448 \r
449         // TODO:\r
450         return ECUM_WKSOURCE_INTERNAL_RESET;\r
451 \r
452 }\r
453 \r