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