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