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