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