]> rtime.felk.cvut.cz Git - arc.git/blob - system/EcuM/EcuM_Main.c
Merge with c4b49c44c0dfd6a3410a0dba1ea61ec3b392327e
[arc.git] / system / EcuM / EcuM_Main.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 "EcuM_Generated_Types.h"\r
21 #include "EcuM_Internals.h"\r
22 \r
23 #if defined(USE_DEM)\r
24 #include "Dem.h"\r
25 #endif\r
26 #if defined(USE_NVM)\r
27 #include "NvM.h"\r
28 #endif\r
29 \r
30 static uint32 internal_data_run_state_timeout = 0;\r
31 #if defined(USE_NVM)\r
32 static uint32 internal_data_go_off_one_state_timeout = 0;\r
33 static NvM_RequestResultType writeAllResult;\r
34 #endif\r
35 \r
36 #ifdef CFG_ECUM_USE_SERVICE_COMPONENT\r
37 /** @req EcuM2749 */\r
38 static Rte_ModeType_EcuM_Mode currentMode;\r
39 \r
40 void set_current_state(EcuM_StateType state) {\r
41         Rte_ModeType_EcuM_Mode newMode = currentMode;\r
42         switch( state ) {\r
43         case ECUM_STATE_WAKEUP:\r
44         case ECUM_STATE_WAKEUP_ONE:\r
45         case ECUM_STATE_WAKEUP_VALIDATION:\r
46         case ECUM_STATE_WAKEUP_REACTION:\r
47         case ECUM_STATE_WAKEUP_TWO:\r
48         case ECUM_STATE_SLEEP:\r
49         case ECUM_STATE_SHUTDOWN:\r
50                 newMode = RTE_MODE_EcuM_Mode_SLEEP;\r
51                 break;\r
52         case ECUM_STATE_GO_SLEEP:\r
53                 if( internal_data.shutdown_target == ECUM_STATE_SLEEP ) {\r
54                         newMode = RTE_MODE_EcuM_Mode_SLEEP; /** @req EcuM2752 */\r
55                 }\r
56                 break;\r
57         case ECUM_STATE_GO_OFF_ONE:\r
58         case ECUM_STATE_GO_OFF_TWO:\r
59                 newMode = RTE_MODE_EcuM_Mode_SHUTDOWN;\r
60                 break;\r
61         case ECUM_STATE_WAKEUP_TTII:\r
62                 if( internal_data.shutdown_target == ECUM_STATE_SLEEP ) {\r
63                         newMode = RTE_MODE_EcuM_Mode_WAKE_SLEEP; /** @req EcuM2752 */\r
64                 }\r
65                 break;\r
66         case ECUM_STATE_PREP_SHUTDOWN:\r
67         case ECUM_STATE_APP_POST_RUN: /* Assuming this is same as RUN_III */\r
68                 newMode = RTE_MODE_EcuM_Mode_POST_RUN;\r
69                 break;\r
70         case ECUM_STATE_APP_RUN: /* Assuming this is same as RUN_II */\r
71                 newMode = RTE_MODE_EcuM_Mode_RUN;\r
72                 break;\r
73         case ECUM_STATE_STARTUP_TWO:\r
74                 newMode = RTE_MODE_EcuM_Mode_STARTUP;\r
75                 break;\r
76         default:\r
77                 /* Do nothing */\r
78                 break;\r
79         }\r
80 \r
81         if( newMode != currentMode ) {\r
82                 currentMode = newMode;\r
83                 Rte_Switch_EcuM_CurrentMode_currentMode(currentMode); /** @req EcuM2750 */\r
84         }\r
85 }\r
86 #endif\r
87 \r
88 \r
89 void EcuM_enter_run_mode(void){\r
90         set_current_state(ECUM_STATE_APP_RUN);\r
91         EcuM_OnEnterRUN(); /** @req EcuM2308 */\r
92         //TODO: Call ComM_EcuM_RunModeIndication(NetworkHandleType Channel) for all channels that have requested run.\r
93         internal_data_run_state_timeout = internal_data.config->EcuMRunMinimumDuration / ECUM_MAIN_FUNCTION_PERIOD; /** @req EcuM2310 */\r
94 }\r
95 \r
96 \r
97 //--------- Local functions ------------------------------------------------------------------------------------------------\r
98 \r
99 static inline void enter_go_sleep_mode(void){\r
100         set_current_state(ECUM_STATE_GO_SLEEP);\r
101         EcuM_OnGoSleep();\r
102 }\r
103 \r
104 static inline void enter_go_off_one_mode(void){\r
105         set_current_state(ECUM_STATE_GO_OFF_ONE);\r
106         EcuM_OnGoOffOne();\r
107 \r
108 #if defined(USE_COMM)\r
109         ComM_DeInit();\r
110 #endif\r
111 \r
112 #if defined(USE_NVM)\r
113 \r
114         // Start NvM_WriteAll and timeout timer\r
115         NvM_WriteAll();\r
116 \r
117         internal_data_go_off_one_state_timeout = internal_data.config->EcuMNvramWriteAllTimeout / ECUM_MAIN_FUNCTION_PERIOD;\r
118 #endif\r
119 }\r
120 \r
121 \r
122 static inline boolean hasRunRequests(void){\r
123         uint32 result = internal_data.run_requests;\r
124 \r
125 #if defined(USE_COMM)\r
126         result |= internal_data.run_comm_requests;\r
127 #endif\r
128 \r
129         return (result != 0);\r
130 }\r
131 \r
132 static inline boolean hasPostRunRequests(void){\r
133         return (internal_data.postrun_requests != 0);\r
134 }\r
135 \r
136 \r
137 \r
138 static inline void in_state_appRun(void){\r
139         if (internal_data_run_state_timeout){\r
140                 internal_data_run_state_timeout--;\r
141         }\r
142 \r
143         if ((!hasRunRequests()) && (internal_data_run_state_timeout == 0)){\r
144                 EcuM_OnExitRun();       /** @req EcuM2865 */\r
145                 set_current_state(ECUM_STATE_APP_POST_RUN);/** @req EcuM2865 */\r
146         }\r
147 }\r
148 \r
149 \r
150 static inline void in_state_appPostRun(void){\r
151         if (hasRunRequests()){\r
152                 set_current_state(ECUM_STATE_APP_RUN);/** @req EcuM2866 */ /** @req EcuM2308 */\r
153                 EcuM_OnEnterRUN(); /** @req EcuM2308 */\r
154                 //TODO: Call ComM_EcuM_RunModeIndication(NetworkHandleType Channel) for all channels that have requested run.\r
155                 internal_data_run_state_timeout = internal_data.config->EcuMRunMinimumDuration / ECUM_MAIN_FUNCTION_PERIOD; /** @req EcuM2310 */\r
156 \r
157         } else if (!hasPostRunRequests()){\r
158                 EcuM_OnExitPostRun(); /** @req EcuM2761 */\r
159                 set_current_state(ECUM_STATE_PREP_SHUTDOWN);/** @req EcuM2761 */\r
160 \r
161                 EcuM_OnPrepShutdown();\r
162         } else {\r
163                 // TODO: Do something?\r
164         }\r
165 }\r
166 \r
167 static inline void in_state_prepShutdown(void){\r
168 #if defined(USE_DEM)\r
169         // DEM shutdown\r
170         Dem_Shutdown();\r
171 #endif\r
172 \r
173         // Switch shutdown mode\r
174         switch(internal_data.shutdown_target){\r
175                 //If in state Off or Reset go into Go_Off_One:\r
176                 case ECUM_STATE_OFF:\r
177                 case ECUM_STATE_RESET:\r
178                         enter_go_off_one_mode();\r
179                         break;\r
180                 case ECUM_STATE_SLEEP:\r
181                         enter_go_sleep_mode();\r
182                         break;\r
183                 default:\r
184                         //TODO: Report error.\r
185                         break;\r
186         }\r
187 }\r
188 \r
189 static inline void in_state_goOffOne(void){\r
190 #if defined(USE_NVM)\r
191                 if (internal_data_go_off_one_state_timeout){\r
192                         internal_data_go_off_one_state_timeout--;\r
193                 }\r
194                 // Wait for the NVM job (NvmWriteAll) to terminate\r
195                 NvM_GetErrorStatus(0, &writeAllResult);\r
196                 if ((writeAllResult != NVM_REQ_PENDING) || (internal_data_go_off_one_state_timeout == 0)){\r
197                         ShutdownOS(E_OK);\r
198                 }\r
199 #else\r
200                 ShutdownOS(E_OK);\r
201 #endif\r
202 }\r
203 \r
204 \r
205 //----- MAIN -----------------------------------------------------------------------------------------------------------------\r
206 void EcuM_MainFunction(void){\r
207         VALIDATE_NO_RV(internal_data.initiated, ECUM_MAINFUNCTION_ID, ECUM_E_NOT_INITIATED);\r
208 \r
209         switch(internal_data.current_state){\r
210 \r
211                 case ECUM_STATE_APP_RUN:\r
212                         in_state_appRun();\r
213                         break;\r
214                 case ECUM_STATE_APP_POST_RUN:\r
215                         in_state_appPostRun();\r
216                         break;\r
217                 case ECUM_STATE_PREP_SHUTDOWN:\r
218                         in_state_prepShutdown();\r
219                         break;\r
220                 case ECUM_STATE_GO_OFF_ONE:\r
221                         in_state_goOffOne();\r
222                         break;\r
223                 case ECUM_STATE_GO_SLEEP:\r
224                         // TODO: Fill out\r
225                         break;\r
226                 default:\r
227                         //TODO: Report error.\r
228                         break;\r
229         }\r
230 }\r