foxBMS - Unit Tests  1.4.0
The foxBMS Unit Tests API Documentation
sys_mon.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 sys_mon.c
44  * @author foxBMS Team
45  * @date 2019-11-28 (date of creation)
46  * @updated 2022-07-28 (date of last update)
47  * @version v1.4.0
48  * @ingroup ENGINE
49  * @prefix SYSM
50  *
51  * @brief system monitoring module
52  */
53 
54 /*========== Includes =======================================================*/
55 #include "sys_mon.h"
56 
57 #include "diag.h"
58 #include "fram.h"
59 #include "os.h"
60 
61 /*========== Macros and Definitions =========================================*/
62 
63 /*========== Static Constant and Variable Definitions =======================*/
64 /** tracking variable for System monitoring notifications */
66 
67 /** local shadow copy of the FRAM entry */
69 
70 /** flag, indicating that the FRAM entry has been changed and should be written */
71 static volatile bool sysm_flagFramCopyHasChanges = false;
72 
73 /*========== Extern Constant and Variable Definitions =======================*/
74 
75 /*========== Static Function Prototypes =====================================*/
76 /**
77  * @brief Records the violation of a timing in non volatile memory
78  *
79  * @param[in] taskId id of the violating task
80  * @param[in] taskDuration duration of the task when recording the violation
81  * @param[in] timestampEnter timestamp that the task has entered
82  */
83 static void SYSM_RecordTimingViolation(SYSM_TASK_ID_e taskId, uint32_t taskDuration, uint32_t timestampEnter);
84 
85 /**
86  * @brief Convert recorded timings into a decision (bool) whether the timing has been violated or not
87  * @details Timing has been violated if both duration or timestamp are not equal to zero
88  * @param[in] duration duration in ticks
89  * @param[in] timestampEnter entry timestamp in ticks
90  * @returns bool describing whether this is a violation (true) or not (false)
91  */
92 static bool SYSM_ConvertRecordedTimingsToViolation(uint32_t duration, uint32_t timestampEnter);
93 
94 /*========== Static Function Implementations ================================*/
95 static void SYSM_RecordTimingViolation(SYSM_TASK_ID_e taskId, uint32_t taskDuration, uint32_t timestampEnter) {
96  FAS_ASSERT(taskId < SYSM_TASK_ID_MAX);
97 
100 
101  switch (taskId) {
102  case SYSM_TASK_ID_ENGINE:
105  break;
108  sysm_localFramCopy.task1msEnterTimestamp = timestampEnter;
109  break;
113  break;
117  break;
121  break;
122  default:
123  /* this should not be possible to happen */
125  break;
126  }
127 }
128 
129 static bool SYSM_ConvertRecordedTimingsToViolation(uint32_t duration, uint32_t timestampEnter) {
130  bool returnValue = false;
131  if ((duration != 0u) || (timestampEnter != 0u)) {
132  returnValue = true;
133  }
134  return returnValue;
135 }
136 
137 /*========== Extern Function Implementations ================================*/
139  /* no need to check for the configuration as it is already checked with a
140  static assert */
141 
142  /* read from FRAM interface the sys mon violations */
144  /* copy FRAM into local shadow copy */
146 
147  return STD_OK;
148 }
149 
151  static uint32_t sysm_timestamp = 0;
152 
153  /** early exit if nothing to do */
154  uint32_t local_timer = OS_GetTickCount();
155  if (sysm_timestamp == local_timer) {
156  return;
157  }
158  sysm_timestamp = local_timer;
159 
160  uint32_t time_since_last_call = 0;
161  uint32_t max_allowed_jitter = 0;
162 
163  for (SYSM_TASK_ID_e taskId = (SYSM_TASK_ID_e)0; taskId < SYSM_TASK_ID_MAX; taskId++) {
164  if (sysm_ch_cfg[taskId].enable == SYSM_ENABLED) {
165  /* check that the task gets called within its timing threshold plus jitter and
166  then check that the tasks duration is shorter than tasks cycle time */
167  time_since_last_call = local_timer - sysm_notifications[taskId].timestampEnter;
168  max_allowed_jitter = sysm_ch_cfg[taskId].cycleTime + sysm_ch_cfg[taskId].maxJitter;
169  if ((time_since_last_call > max_allowed_jitter) &&
170  (sysm_notifications[taskId].duration > sysm_ch_cfg[taskId].cycleTime)) {
171  /* module not running within its timed limits */
173  if (sysm_ch_cfg[taskId].enableRecording == SYSM_RECORDING_ENABLED) {
175  taskId, sysm_notifications[taskId].duration, sysm_notifications[taskId].timestampEnter);
176  }
177  sysm_ch_cfg[taskId].callbackFunction(taskId);
178  }
179  }
180  }
181 }
182 
183 void SYSM_Notify(SYSM_TASK_ID_e taskId, SYSM_NOTIFY_TYPE_e state, uint32_t timestamp) {
184  FAS_ASSERT(taskId < SYSM_TASK_ID_MAX);
185  FAS_ASSERT((state == SYSM_NOTIFY_ENTER) || (state == SYSM_NOTIFY_EXIT));
187  sysm_notifications[taskId].state = state;
188  if (state == SYSM_NOTIFY_ENTER) {
189  sysm_notifications[taskId].timestampEnter = timestamp;
190  } else if (state == SYSM_NOTIFY_EXIT) {
191  sysm_notifications[taskId].timestampExit = timestamp;
192  sysm_notifications[taskId].duration = timestamp - sysm_notifications[taskId].timestampEnter;
193  } else {
194  /* state has an illegal value */
196  }
198 }
199 
201  FAS_ASSERT(pAnswer != NULL_PTR);
202 
204  FRAM_SYS_MON_RECORD_s localSysMonRecord = {0};
205  SYSM_CopyFramStruct(&fram_sys_mon_record, &localSysMonRecord);
207 
208  if (localSysMonRecord.anyTimingIssueOccurred == false) {
209  /* no timing violations recorded, abort */
210  pAnswer->recordedViolationAny = false;
211  pAnswer->recordedViolationEngine = false;
212  pAnswer->recordedViolation1ms = false;
213  pAnswer->recordedViolation10ms = false;
214  pAnswer->recordedViolation100ms = false;
215  pAnswer->recordedViolation100msAlgo = false;
216  } else {
217  /* timing violation, find it */
218  pAnswer->recordedViolationAny = true;
220  localSysMonRecord.taskEngineViolatingDuration, localSysMonRecord.taskEngineEnterTimestamp);
222  localSysMonRecord.task1msViolatingDuration, localSysMonRecord.task1msEnterTimestamp);
224  localSysMonRecord.task10msViolatingDuration, localSysMonRecord.task10msEnterTimestamp);
226  localSysMonRecord.task100msViolatingDuration, localSysMonRecord.task100msEnterTimestamp);
228  localSysMonRecord.task100msAlgorithmViolatingDuration, localSysMonRecord.task100msAlgorithmEnterTimestamp);
229  }
230 }
231 
232 extern void SYSM_ClearAllTimingViolations(void) {
233  /* clear all diag entries */
234  for (SYSM_TASK_ID_e taskId = (SYSM_TASK_ID_e)0; taskId < SYSM_TASK_ID_MAX; taskId++) {
236  }
237  /* clear local FRAM copy */
252  /* commit to FRAM */
254 }
255 
256 extern void SYSM_UpdateFramData(void) {
258  const bool updateNecessary = sysm_flagFramCopyHasChanges;
260  if (updateNecessary == true) {
265 
267  }
268 }
269 
270 extern void SYSM_CopyFramStruct(const FRAM_SYS_MON_RECORD_s *const kpkFrom, FRAM_SYS_MON_RECORD_s *pTo) {
271  FAS_ASSERT(kpkFrom != NULL_PTR);
272  FAS_ASSERT(pTo != NULL_PTR);
273 
274  /* copy all elements in order to make sure that we are always compatible (independently of C-version) */
286 }
287 
288 /*========== Getter for static Variables (Unit Test) ========================*/
289 #ifdef UNITY_UNIT_TEST
291  return sysm_notifications;
292 }
293 #endif
294 
295 /*========== Externalized Static Function Implementations (Unit Test) =======*/
DIAG_RETURNTYPE_e DIAG_Handler(DIAG_ID_e diagId, DIAG_EVENT_e event, DIAG_IMPACT_LEVEL_e impact, uint32_t data)
DIAG_Handler provides generic error handling, based on diagnosis group.
Definition: diag.c:231
Diagnosis driver header.
@ DIAG_EVENT_NOT_OK
Definition: diag_cfg.h:239
@ DIAG_EVENT_OK
Definition: diag_cfg.h:238
@ DIAG_SYSTEM
Definition: diag_cfg.h:251
@ DIAG_ID_SYSTEM_MONITORING
Definition: diag_cfg.h:159
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:248
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:126
FRAM_RETURN_TYPE_e FRAM_ReadData(FRAM_BLOCK_ID_e blockId)
Reads a variable from the FRAM.
Definition: fram.c:193
FRAM_RETURN_TYPE_e FRAM_WriteData(FRAM_BLOCK_ID_e blockId)
Writes a variable to the FRAM.
Definition: fram.c:115
Header for the driver for the FRAM module.
FRAM_SYS_MON_RECORD_s fram_sys_mon_record
Definition: fram_cfg.c:76
@ FRAM_BLOCK_ID_SYS_MON_RECORD
Definition: fram_cfg.h:106
STD_RETURN_TYPE_e
Definition: fstd_types.h:81
@ STD_OK
Definition: fstd_types.h:82
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:76
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
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:139
struct that stores for each task the last violation of timing
Definition: fram_cfg.h:164
uint32_t taskEngineViolatingDuration
Definition: fram_cfg.h:168
uint32_t taskEngineEnterTimestamp
Definition: fram_cfg.h:170
uint32_t task10msViolatingDuration
Definition: fram_cfg.h:176
uint32_t task100msViolatingDuration
Definition: fram_cfg.h:180
uint32_t task100msEnterTimestamp
Definition: fram_cfg.h:182
uint32_t task1msViolatingDuration
Definition: fram_cfg.h:172
uint32_t task100msAlgorithmEnterTimestamp
Definition: fram_cfg.h:186
uint32_t task10msEnterTimestamp
Definition: fram_cfg.h:178
uint32_t task1msEnterTimestamp
Definition: fram_cfg.h:174
uint32_t task100msAlgorithmViolatingDuration
Definition: fram_cfg.h:184
void(* callbackFunction)(SYSM_TASK_ID_e taskId)
Definition: sys_mon_cfg.h:102
uint32_t duration
Definition: sys_mon.h:74
uint32_t timestampEnter
Definition: sys_mon.h:72
uint32_t timestampExit
Definition: sys_mon.h:73
SYSM_NOTIFY_TYPE_e state
Definition: sys_mon.h:71
SYSM_NOTIFICATION_s * TEST_SYSM_GetNotifications(void)
Definition: sys_mon.c:290
void SYSM_GetRecordedTimingViolations(SYSM_TIMING_VIOLATION_RESPONSE_s *pAnswer)
Returns the timing violation flags determined from fram state.
Definition: sys_mon.c:200
void SYSM_ClearAllTimingViolations(void)
Clears all timing violations (both current and recorded)
Definition: sys_mon.c:232
void SYSM_CheckNotifications(void)
overall system monitoring
Definition: sys_mon.c:150
void SYSM_Notify(SYSM_TASK_ID_e taskId, SYSM_NOTIFY_TYPE_e state, uint32_t timestamp)
Sets needed bits to indicate that a task is running.
Definition: sys_mon.c:183
void SYSM_UpdateFramData(void)
Commits the stored changes to FRAM if necessary.
Definition: sys_mon.c:256
static void SYSM_RecordTimingViolation(SYSM_TASK_ID_e taskId, uint32_t taskDuration, uint32_t timestampEnter)
Records the violation of a timing in non volatile memory.
Definition: sys_mon.c:95
STD_RETURN_TYPE_e SYSM_Init(void)
initialization function for system monitoring
Definition: sys_mon.c:138
static volatile bool sysm_flagFramCopyHasChanges
Definition: sys_mon.c:71
static SYSM_NOTIFICATION_s sysm_notifications[SYSM_TASK_ID_MAX]
Definition: sys_mon.c:65
static bool SYSM_ConvertRecordedTimingsToViolation(uint32_t duration, uint32_t timestampEnter)
Convert recorded timings into a decision (bool) whether the timing has been violated or not.
Definition: sys_mon.c:129
static FRAM_SYS_MON_RECORD_s sysm_localFramCopy
Definition: sys_mon.c:68
void SYSM_CopyFramStruct(const FRAM_SYS_MON_RECORD_s *const kpkFrom, FRAM_SYS_MON_RECORD_s *pTo)
Copy from the from entry to the to entry.
Definition: sys_mon.c:270
system monitoring module
SYSM_NOTIFY_TYPE_e
Definition: sys_mon.h:64
@ SYSM_NOTIFY_ENTER
Definition: sys_mon.h:65
@ SYSM_NOTIFY_EXIT
Definition: sys_mon.h:66
SYSM_MONITORING_CFG_s sysm_ch_cfg[]
Definition: sys_mon_cfg.c:70
@ SYSM_RECORDING_ENABLED
Definition: sys_mon_cfg.h:84
@ SYSM_ENABLED
Definition: sys_mon_cfg.h:90
SYSM_TASK_ID_e
Definition: sys_mon_cfg.h:73
@ SYSM_TASK_ID_CYCLIC_10ms
Definition: sys_mon_cfg.h:76
@ SYSM_TASK_ID_MAX
Definition: sys_mon_cfg.h:79
@ SYSM_TASK_ID_CYCLIC_ALGORITHM_100ms
Definition: sys_mon_cfg.h:78
@ SYSM_TASK_ID_CYCLIC_100ms
Definition: sys_mon_cfg.h:77
@ SYSM_TASK_ID_CYCLIC_1ms
Definition: sys_mon_cfg.h:75
@ SYSM_TASK_ID_ENGINE
Definition: sys_mon_cfg.h:74