foxBMS  1.3.0
The foxBMS Battery Management System API Documentation
sbc.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2022, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file sbc.c
44  * @author foxBMS Team
45  * @date 2020-07-14 (date of creation)
46  * @updated 2022-05-30 (date of last update)
47  * @version v1.3.0
48  * @ingroup DRIVERS
49  * @prefix SBC
50  *
51  * @brief Driver for the SBC module
52  *
53  * @details It must always be used when creating new c source files.
54  *
55  */
56 
57 /*========== Includes =======================================================*/
58 #include "sbc.h"
59 
60 #include "HL_gio.h"
61 
62 #include "os.h"
63 
64 /*========== Macros and Definitions =========================================*/
65 
66 /** Symbolic names to check re-entrance in #SBC_Trigger */
67 typedef enum {
68  SBC_REENTRANCE_NO, /*!< no re-entrance */
69  SBC_REENTRANCE_YES, /*!< re-entrance*/
71 
72 /*========== Static Constant and Variable Definitions =======================*/
73 
74 /*========== Extern Constant and Variable Definitions =======================*/
75 /** state of the SBC module */
77  .timer = 0u, /*!< time in milliseconds before the state machine processes the next state, in counts of 10ms */
78  .stateRequest = SBC_STATE_NO_REQUEST, /*!< current state request made to the state machine */
80  .substate = SBC_ENTRY,
81  .lastState = SBC_STATEMACHINE_UNINITIALIZED,
82  .lastSubstate = SBC_ENTRY,
83  .illegalRequestsCounter = 0u, /*!< counts the number of illegal requests to the SBC state machine */
84  .retryCounter = 0u, /*!< counter to retry subsystem initialization if fails */
85  .requestWatchdogTrigger = 0u, /*!< correct value set during init process */
86  .triggerEntry = 0u, /*!< counter for re-entrance protection (function running flag) */
87  .pFs85xxInstance = &fs85xx_mcuSupervisor, /*!< pointer to FS85xx instance */
88  .watchdogState = SBC_PERIODIC_WATCHDOG_DEACTIVATED,
89  .watchdogPeriod_10ms = 10u,
90 };
91 
92 /*========== Static Function Prototypes =====================================*/
93 
94 /**
95  * @brief Saves the last state and last substate
96  * @param[in,out] pInstance
97  */
98 static void SBC_SaveLastStates(SBC_STATE_s *pInstance);
99 
100 /**
101  * @brief checks the state requests that are made.
102  * @details This function checks the validity of the state requests.
103  * The results of the checked is returned immediately.
104  * @param[in,out] pInstance
105  * @param[in] stateRequest state request to be checked
106  * @return result of the state request that was made, taken from
107  * #SBC_RETURN_TYPE_e
108  */
110 
111 /**
112  * @brief Re-entrance check of SBC state machine trigger function
113  * @details This function is not re-entrant and should only be called time- or
114  * event-triggered. It increments the triggerentry counter from the
115  * state variable pInstance->triggerEntry. It should never be called
116  * by two different processes, so if it is the case, triggerEntry
117  * should never be higher than 0 when this function is called.
118  * @return #SBC_REENTRANCE_NO if no further instance of the function is
119  * active, otherwise #SBC_REENTRANCE_YES
120  */
122 
123 /**
124  * @brief Transfers the current state request to the state machine.
125  * @details This function takes the current state request from
126  * pInstance->stateRequest and transfers it to the state
127  * machine. It resets the value from stateRequest to
128  * #SBC_STATE_NO_REQUEST
129  * @param[in,out] pInstance
130  * @return retVal current state request, taken from
131  * #SYS_STATE_REQUEST_e
132  */
134 
135 /*========== Static Function Implementations ================================*/
136 static void SBC_SaveLastStates(SBC_STATE_s *pInstance) {
137  FAS_ASSERT(pInstance != NULL_PTR);
138 
139  if (pInstance->lastState != pInstance->state) {
140  pInstance->lastState = pInstance->state;
141  pInstance->lastSubstate = pInstance->substate;
142  } else if (pInstance->lastSubstate != pInstance->substate) {
143  pInstance->lastSubstate = pInstance->substate;
144  } else {
145  /* Do not set new substate as nothing changed */
146  ;
147  }
148 }
149 
151  FAS_ASSERT(pInstance != NULL_PTR);
152 
154  if (stateRequest == SBC_STATE_ERROR_REQUEST) {
155  retval = SBC_OK;
156  } else {
157  if (pInstance->stateRequest == SBC_STATE_NO_REQUEST) {
158  /* init only allowed from the uninitialized state */
159  if (stateRequest == SBC_STATE_INIT_REQUEST) {
160  if (pInstance->state == SBC_STATEMACHINE_UNINITIALIZED) {
161  retval = SBC_OK;
162  } else {
163  retval = SBC_ALREADY_INITIALIZED;
164  }
165  } else {
166  retval = SBC_ILLEGAL_REQUEST;
167  }
168  } else {
169  retval = SBC_REQUEST_PENDING;
170  }
171  }
172  return retval;
173 }
174 
175 /**
176  * @brief re-entrance check of SYS state machine trigger function
177  * @details This function is not re-entrant and should only be called time- or
178  * event-triggered. It increments the triggerentry counter from the
179  * state variable sys_systemState. It should never be called by two
180  * different processes, so if it is the case, triggerentry should
181  * never be higher than 0 when this function is called.
182  * @return retval 0 if no further instance of the function is active, 0xff
183  * else
184  */
186  FAS_ASSERT(pInstance != NULL_PTR);
187 
189 
191  if (!pInstance->triggerEntry) {
192  pInstance->triggerEntry++;
193  } else {
194  isReEntrance = SBC_REENTRANCE_YES;
195  }
197 
198  return isReEntrance;
199 }
200 
202  FAS_ASSERT(pInstance != NULL_PTR);
203 
205 
207  retval = pInstance->stateRequest;
208  pInstance->stateRequest = SBC_STATE_NO_REQUEST;
210 
211  return (retval);
212 }
213 
214 /*========== Extern Function Implementations ================================*/
216  FAS_ASSERT(pInstance != NULL_PTR);
217 
219 
221  retVal = SBC_CheckStateRequest(pInstance, stateRequest);
222 
223  if (retVal == SBC_OK) {
224  pInstance->stateRequest = stateRequest;
225  }
227 
228  return (retVal);
229 }
230 
232  FAS_ASSERT(pInstance != NULL_PTR);
233 
234  return pInstance->state;
235 }
236 
237 extern void SBC_Trigger(SBC_STATE_s *pInstance) {
238  FAS_ASSERT(pInstance != NULL_PTR);
239 
241 
242  /* Check re-entrance of function */
243  if (SBC_CheckReEntrance(pInstance) == SBC_REENTRANCE_YES) {
244  return;
245  }
246 
247  /* Periodic watchdog triggering */
249  if (pInstance->watchdogTrigger > 0u) {
250  pInstance->watchdogTrigger--;
251  if (pInstance->watchdogTrigger == 0u) {
252  if (STD_OK != SBC_TriggerWatchdog(pInstance->pFs85xxInstance)) {
253  /* Do what if triggering of watchdog fails? */
254  } else {
255  /* Debug LED Ball V2! :*/
256  /* gioToggleBit(hetPORT1, 1); */
257  /* Reset watchdog counter:
258  * Decremented every SBC_TASK_CYCLE_CONTEXT_MS and checked in next cycle -> Period-1 */
259  pInstance->watchdogTrigger = pInstance->watchdogPeriod_10ms;
260  }
261  }
262  }
263  }
264 
265  if (pInstance->timer > 0u) {
266  if ((--pInstance->timer) > 0u) {
267  pInstance->triggerEntry--;
268  return; /* handle state machine only if timer has elapsed */
269  }
270  }
271 
272  switch (pInstance->state) {
273  /****************************UNINITIALIZED***********************************/
275  /* waiting for Initialization Request */
276  stateRequest = SBC_TransferStateRequest(pInstance);
277  if (stateRequest == SBC_STATE_INIT_REQUEST) {
278  SBC_SaveLastStates(pInstance);
279  pInstance->timer = SBC_STATEMACHINE_SHORTTIME;
281  pInstance->substate = SBC_ENTRY;
282  } else if (stateRequest == SBC_STATE_NO_REQUEST) {
283  /* no actual request pending */
284  } else {
285  pInstance->illegalRequestsCounter++; /* illegal request pending */
286  }
287  break;
288  /****************************INITIALIZATION**********************************/
290  SBC_SaveLastStates(pInstance);
291  /* Initializations done here */
292 
293  if (pInstance->substate == SBC_ENTRY) {
294  /* Init SBC */
296  /* Retry init if it fails */
297  pInstance->retryCounter++;
298  if (pInstance->retryCounter > 3u) {
299  /* Maximum number of retries -> goto error */
300  pInstance->retryCounter = 0u;
301  pInstance->timer = SBC_STATEMACHINE_SHORTTIME;
302  pInstance->state = SBC_STATEMACHINE_ERROR;
303  pInstance->substate = SBC_ENTRY;
304  }
305  } else {
306  /* First part of init successful -> start periodic watchdog triggering */
308  pInstance->watchdogTrigger = pInstance->watchdogPeriod_10ms;
309  pInstance->timer = SBC_STATEMACHINE_SHORTTIME;
311  pInstance->retryCounter = 0u;
312  }
313  } else if (pInstance->substate == SBC_INIT_RESET_FAULT_ERROR_COUNTER_PART1) {
314  /* Fault error counter is reset with valid watchdog refreshes
315  * -> first get required numbers of refreshes */
316  uint8_t requiredWatchdogTrigger = 0;
318  pInstance->pFs85xxInstance, &requiredWatchdogTrigger)) {
319  /* Retry init if it fails */
320  pInstance->retryCounter++;
321  if (pInstance->retryCounter > 3u) {
322  /* Maximum number of retries -> goto error */
323  pInstance->retryCounter = 0;
324  pInstance->timer = SBC_STATEMACHINE_SHORTTIME;
325  pInstance->state = SBC_STATEMACHINE_ERROR;
326  pInstance->substate = SBC_ENTRY;
327  }
328  } else {
329  /* Wait requiredWatchdogTrigger's */
330  pInstance->retryCounter = 0;
331  pInstance->timer = (requiredWatchdogTrigger * pInstance->watchdogPeriod_10ms);
333  }
334  } else if (pInstance->substate == SBC_INIT_RESET_FAULT_ERROR_COUNTER_PART2) {
335  /* Check if fault error counter is zero */
337  pInstance->retryCounter++;
338  if (pInstance->retryCounter > 3u) {
339  /* Goto error state */
340  pInstance->retryCounter = 0;
341  pInstance->state = SBC_STATEMACHINE_ERROR;
342  pInstance->substate = SBC_ENTRY;
343  }
344  pInstance->timer = SBC_STATEMACHINE_SHORTTIME;
345  } else {
347  pInstance->timer = SBC_STATEMACHINE_SHORTTIME;
348  }
349  } else if (pInstance->substate == SBC_INITIALIZE_SAFETY_PATH_CHECK) {
350  if (STD_NOT_OK == FS85_SafetyPathChecks(pInstance->pFs85xxInstance)) {
351  pInstance->retryCounter++;
352  if (pInstance->retryCounter > 3u) {
353  /* Goto error state */
354  pInstance->retryCounter = 0;
355  pInstance->state = SBC_STATEMACHINE_ERROR;
356  pInstance->substate = SBC_ENTRY;
357  }
358  } else {
359  pInstance->retryCounter = 0;
360  pInstance->state = SBC_STATEMACHINE_RUNNING;
361  pInstance->substate = SBC_ENTRY;
362  }
363  pInstance->timer = SBC_STATEMACHINE_SHORTTIME;
364  } else {
366  }
367  break;
368 
369  /****************************RUNNING*************************************/
371  SBC_SaveLastStates(pInstance);
372  pInstance->timer = SBC_STATEMACHINE_LONGTIME;
373  break;
374 
375  /****************************ERROR*************************************/
377  SBC_SaveLastStates(pInstance);
378  pInstance->timer = SBC_STATEMACHINE_LONGTIME;
379  break;
380  /***************************DEFAULT CASE*************************************/
381  default:
382  /* invalid state */
384  break;
385  } /* end switch (sys_systemState.state) */
386  pInstance->triggerEntry--;
387 }
388 
389 /*========== Externalized Static Function Implementations (Unit Test) =======*/
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:241
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:115
@ STD_NOT_OK
Definition: fstd_types.h:83
@ STD_OK
Definition: fstd_types.h:82
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:76
STD_RETURN_TYPE_e FS85_InitializeNumberOfRequiredWatchdogRefreshes(FS85_STATE_s *pInstance, uint8_t *requiredWatchdogRefreshes)
Calculates the number of required watchdog refresh to reset fault error counter.
Definition: nxpfs85xx.c:869
FS85_STATE_s fs85xx_mcuSupervisor
Definition: nxpfs85xx.c:81
STD_RETURN_TYPE_e FS85_InitializeFsPhase(FS85_STATE_s *pInstance)
Configures SBC during INIT_FS phase.
Definition: nxpfs85xx.c:484
STD_RETURN_TYPE_e SBC_TriggerWatchdog(FS85_STATE_s *pInstance)
Trigger watchdog.
Definition: nxpfs85xx.c:1007
STD_RETURN_TYPE_e FS85_SafetyPathChecks(FS85_STATE_s *pInstance)
Performs SBC safety path checks.
Definition: nxpfs85xx.c:941
STD_RETURN_TYPE_e FS85_CheckFaultErrorCounter(FS85_STATE_s *pInstance)
Checks if fault error counter is zero.
Definition: nxpfs85xx.c:926
Declaration of the OS wrapper interface.
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:135
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:131
SBC_STATEMACHINE_e SBC_GetState(SBC_STATE_s *pInstance)
gets the current state of passed state variable
Definition: sbc.c:231
void SBC_Trigger(SBC_STATE_s *pInstance)
trigger function for the SYS driver state machine.
Definition: sbc.c:237
static void SBC_SaveLastStates(SBC_STATE_s *pInstance)
Saves the last state and last substate.
Definition: sbc.c:136
static SBC_CHECK_REENTRANCE_e SBC_CheckReEntrance(SBC_STATE_s *pInstance)
Re-entrance check of SBC state machine trigger function.
Definition: sbc.c:185
static SBC_RETURN_TYPE_e SBC_CheckStateRequest(SBC_STATE_s *pInstance, SBC_STATE_REQUEST_e stateRequest)
checks the state requests that are made.
Definition: sbc.c:150
SBC_STATE_s sbc_stateMcuSupervisor
Definition: sbc.c:76
static SBC_STATE_REQUEST_e SBC_TransferStateRequest(SBC_STATE_s *pInstance)
Transfers the current state request to the state machine.
Definition: sbc.c:201
SBC_CHECK_REENTRANCE_e
Definition: sbc.c:67
@ SBC_REENTRANCE_YES
Definition: sbc.c:69
@ SBC_REENTRANCE_NO
Definition: sbc.c:68
SBC_RETURN_TYPE_e SBC_SetStateRequest(SBC_STATE_s *pInstance, SBC_STATE_REQUEST_e stateRequest)
sets the current state request of passed state variable
Definition: sbc.c:215
Header for the driver for the SBC module.
SBC_STATEMACHINE_e
Definition: sbc.h:132
@ SBC_STATEMACHINE_RUNNING
Definition: sbc.h:136
@ SBC_STATEMACHINE_UNINITIALIZED
Definition: sbc.h:134
@ SBC_STATEMACHINE_INITIALIZATION
Definition: sbc.h:135
@ SBC_STATEMACHINE_ERROR
Definition: sbc.h:137
SBC_RETURN_TYPE_e
Definition: sbc.h:122
@ SBC_ILLEGAL_REQUEST
Definition: sbc.h:126
@ SBC_REQUEST_PENDING
Definition: sbc.h:125
@ SBC_ALREADY_INITIALIZED
Definition: sbc.h:127
@ SBC_OK
Definition: sbc.h:123
SBC_STATE_REQUEST_e
Definition: sbc.h:109
@ SBC_STATE_INIT_REQUEST
Definition: sbc.h:110
@ SBC_STATE_ERROR_REQUEST
Definition: sbc.h:111
@ SBC_STATE_NO_REQUEST
Definition: sbc.h:112
@ SBC_PERIODIC_WATCHDOG_DEACTIVATED
Definition: sbc.h:118
@ SBC_PERIODIC_WATCHDOG_ACTIVATED
Definition: sbc.h:117
#define SBC_STATEMACHINE_LONGTIME
Definition: sbc.h:101
#define SBC_STATEMACHINE_SHORTTIME
Definition: sbc.h:89
@ SBC_ENTRY
Definition: sbc.h:143
@ SBC_INIT_RESET_FAULT_ERROR_COUNTER_PART2
Definition: sbc.h:145
@ SBC_INITIALIZE_SAFETY_PATH_CHECK
Definition: sbc.h:146
@ SBC_INIT_RESET_FAULT_ERROR_COUNTER_PART1
Definition: sbc.h:144
SBC_STATEMACHINE_SUB_e lastSubstate
Definition: sbc.h:162
FS85_STATE_s * pFs85xxInstance
Definition: sbc.h:168
uint16_t timer
Definition: sbc.h:156
uint8_t triggerEntry
Definition: sbc.h:166
uint16_t watchdogTrigger
Definition: sbc.h:157
SBC_STATE_REQUEST_e stateRequest
Definition: sbc.h:158
SBC_STATEMACHINE_e lastState
Definition: sbc.h:161
SBC_STATEMACHINE_e state
Definition: sbc.h:159
SBC_PERIODIC_WATCHDOG_STATE_e watchdogState
Definition: sbc.h:167
uint32_t illegalRequestsCounter
Definition: sbc.h:163
SBC_STATEMACHINE_SUB_e substate
Definition: sbc.h:160
uint16_t watchdogPeriod_10ms
Definition: sbc.h:169
uint8_t retryCounter
Definition: sbc.h:164