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