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