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