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