foxBMS - Unit Tests  1.6.0
The foxBMS Unit Tests API Documentation
redundancy.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2023, 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 redundancy.c
44  * @author foxBMS Team
45  * @date 2020-07-31 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup APPLICATION
49  * @prefix MRC
50  *
51  * @brief Source file for handling redundancy between redundant cell voltage
52  * and cell temperature measurements
53  *
54  */
55 
56 /*========== Includes =======================================================*/
57 #include "redundancy.h"
58 
59 #include "bms.h"
60 #include "database.h"
61 #include "diag.h"
62 #include "foxmath.h"
63 #include "os.h"
64 #include "plausibility.h"
65 
66 #include <math.h>
67 #include <stdbool.h>
68 #include <stdint.h>
69 
70 /*========== Macros and Definitions =========================================*/
71 
72 /*========== Static Constant and Variable Definitions =======================*/
73 /** local copies of database tables */
74 /**@{*/
79 /**@}*/
80 
81 /** state of the redundancy module */
84  .lastRedundancy0CellVoltageTimestamp = 0u,
85  .lastBaseCelltemperatureTimestamp = 0u,
86  .lastRedundancy0CelltemperatureTimestamp = 0u,
87  .lastStringCurrentTimestamp = {0u},
88 };
89 
90 /*========== Extern Constant and Variable Definitions =======================*/
91 
92 /*========== Static Function Prototypes =====================================*/
93 /**
94  * @brief Check timestamp if measurement has been updated at least once.
95  * @param[in] timestamp timestamp of last measurement update
96  * @param[in] previousTimestamp timestamp of previously updated measurement
97  * @return true if measurement has been updated at least once, otherwise false
98  */
99 static bool MRC_MeasurementUpdatedAtLeastOnce(uint32_t timestamp, uint32_t previousTimestamp);
100 
101 /**
102  * @brief Check timestamp if measurement has been updated recently.
103  * @param[in] timestamp timestamp of last measurement update
104  * @param[in] previousTimestamp timestamp of previously updated measurement
105  * @param[in] timeInterval in systicks (type: uint32_t)
106  * @return true if measurement has recently been updated, otherwise false
107  */
109  uint32_t timestamp,
110  uint32_t previousTimestamp,
111  uint32_t timeInterval);
112 
113 /**
114  * @brief Function to validate results of cell voltage measurement
115  * @param[in] pCellVoltageBase base cell voltage measurement
116  * @param[in] pCellVoltageRedundancy0 redundant cell voltage measurement
117  * @return bool true, if measurement has been validated successfully and
118  * database entry needs to be updated, otherwise false.
119  */
121  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageBase,
122  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageRedundancy0);
123 
124 /**
125  * @brief Function to validate results of cell temperature measurement
126  * @param[in] pCellTemperatureBase base cell temperature measurement
127  * @param[in] pCellTemperatureRedundancy0 redundant cell temperature measurement
128  * @return bool true, if measurement has been validated successfully and
129  * database entry needs to be updated, otherwise false.
130  */
132  DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperatureBase,
133  DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperatureRedundancy0);
134 
135 /**
136  * @brief Function to validate results of current measurement
137  * @param[in] pTableCurrentSensor pointer to current measurements
138  */
139 static void MRC_ValidateCurrentMeasurement(DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor);
140 
141 /**
142  * @brief Function to validate results of string voltage measurement
143  * @param[in] pTableCurrentSensor pointer current sensor high voltage measurements
144  * @param[in] pTableCellVoltage pointer to cell voltage measurements
145  */
147  DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor,
148  DATA_BLOCK_CELL_VOLTAGE_s *pTableCellVoltage);
149 
150 /**
151  * @brief Function to validate HV battery voltage measurement
152  */
153 static void MRC_ValidateBatteryVoltageMeasurement(void);
154 
155 /**
156  * @brief Function to validate results of high voltage measurement and calculate
157  * battery voltage and high voltage bus voltage.
158  * @param[in] pTableCurrentSensor pointer current sensor high voltage measurements
159  */
161 
162 /**
163  * @brief Function to validate results of power measurement
164  * @param[in] pTableCurrentSensor pointer to power/current measurements
165  */
166 static void MRC_ValidatePowerMeasurement(DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor);
167 
168 /**
169  * @brief Function calculates minimum, maximum and average cell voltages.
170  * @param[in] pValidatedVoltages validated voltages from base and/or redundant measurements
171  * @param[out] pMinMaxAverageValues calculated cell voltage min/max/average values
172  * @return #STD_NOT_OK if all cell voltage are invalid and no minimum, maximum
173  * and average cell voltage values could be calculated, otherwise #STD_OK
174  */
176  const DATA_BLOCK_CELL_VOLTAGE_s *const pValidatedVoltages,
177  DATA_BLOCK_MIN_MAX_s *pMinMaxAverageValues);
178 
179 /**
180  * @brief Function calculates minimum, maximum and average cell temperatures.
181  * @param[in] pValidatedTemperatures validated temperatures from base and/or redundant measurements
182  * @param[out] pMinMaxAverageValues calculated cell temperature min/max/average values
183  * @return #STD_NOT_OK if all cell temperatures are invalid and no minimum, maximum
184  * and average cell temperature values could be calculated, otherwise #STD_OK
185  */
187  DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperatures,
188  DATA_BLOCK_MIN_MAX_s *pMinMaxAverageValues);
189 
190 /**
191  * @brief Function compares cell voltage measurements from base measurement with
192  * one redundant measurement and writes result in pValidatedVoltages.
193  * @param[in] pCellVoltageBase base cell voltage measurement
194  * @param[in] pCellVoltageRedundancy0 redundant cell voltage measurement
195  * @param[out] pValidatedVoltages validated voltages from redundant measurement values
196  * @return #STD_NOT_OK if not all cell voltages could be validated, otherwise
197  * #STD_OK
198  */
200  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageBase,
201  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageRedundancy0,
202  DATA_BLOCK_CELL_VOLTAGE_s *pValidatedVoltages);
203 
204 /**
205  * @brief Function updates validated cell voltage measurement with data from a
206  * single measurement source. This can be the case if no redundancy is
207  * used at all or if one or more of the redundant measurements are not
208  * working properly.
209  * @param[in] pCellVoltage cell voltage measurement
210  * @param[out] pValidatedVoltages validated voltage values
211  * @return #STD_NOT_OK if not all cell voltages could be validated, otherwise
212  * #STD_OK
213  */
215  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltage,
216  DATA_BLOCK_CELL_VOLTAGE_s *pValidatedVoltages);
217 
218 /**
219  * @brief Function compares cell temperature measurements from base measurement
220  * with one redundant measurement and writes result in pValidatedTemperatures.
221  * @param[in] pCelltemperatureBase base cell temperature measurement
222  * @param[in] pCelltemperatureRedundancy0 redundant cell temperature measurement
223  * @param[out] pValidatedTemperatures validated temperatures from redundant measurement values
224  * @return #STD_NOT_OK if not all cell voltages could be validated, otherwise
225  * #STD_OK
226  */
228  DATA_BLOCK_CELL_TEMPERATURE_s *pCelltemperatureBase,
229  DATA_BLOCK_CELL_TEMPERATURE_s *pCelltemperatureRedundancy0,
230  DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperatures);
231 
232 /**
233  * @brief Function updates validated cell temperature measurement with data from a
234  * single measurement source. This can be the case if no redundancy is
235  * used at all or if one or more of the redundant measurements are not
236  * working properly.
237  * @param[in] pCellTemperature cell temperature measurement
238  * @param[out] pValidatedTemperature validated temperature values
239  * @return #STD_NOT_OK if not all cell voltages could be validated, otherwise
240  * #STD_OK
241  */
243  DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperature,
244  DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperature);
245 
246 /*========== Static Function Implementations ================================*/
247 static bool MRC_MeasurementUpdatedAtLeastOnce(uint32_t timestamp, uint32_t previousTimestamp) {
248  bool retval = false;
249  if (!((timestamp == 0u) && (previousTimestamp == 0u))) {
250  /* Only possibility for timestamp AND previous timestamp to be 0 is, if
251  the measurement has never been updated. Thus, if this is not the case
252  the measurement must have been updated */
253  retval = true;
254  }
255  return retval;
256 }
257 
259  uint32_t timestamp,
260  uint32_t previousTimestamp,
261  uint32_t timeInterval) {
262  STD_RETURN_TYPE_e retval = STD_NOT_OK;
263  uint32_t currentTimestamp = OS_GetTickCount();
264 
265  /* Unsigned integer arithmetic also works correctly if currentTimestamp is
266  larger than pHeader->timestamp (timer overflow), thus no need to use abs() */
267  if (((currentTimestamp - timestamp) <= timeInterval) &&
268  (MRC_MeasurementUpdatedAtLeastOnce(timestamp, previousTimestamp) == true)) {
269  /* Difference between current timestamp and last update timestamp is
270  smaller than passed time interval */
271  retval = STD_OK;
272  }
273  return retval;
274 }
275 
277  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageBase,
278  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageRedundancy0) {
279  FAS_ASSERT(pCellVoltageBase != NULL_PTR);
280  FAS_ASSERT(pCellVoltageRedundancy0 != NULL_PTR);
281 
282  bool updatedValidatedVoltageDatbaseEntry = false;
283 
284  bool baseCellVoltageUpdated = false;
285 
286  bool useCellVoltageRedundancy = false;
287  bool baseCellVoltageMeasurementTimeoutReached = true;
288  bool redundancy0CellVoltageMeasurementTimeoutReached = true;
289 
290  /* Following decision will be undertaken:
291  *
292  * - Use redundancy only if timestamp of redundant database entry != 0
293  * - Perform redundant check if both timestamps have been updated
294  * - Add timeout and trigger error if timestamps have not been updated in the last XXXXms
295  * - If timeout reached and only one of the two redundant measurements has been updated use this measurement value
296  * but throw an error that one measurement has not been updated recently.
297  */
298 
299  /* -------------- Check if cell voltage redundant measurement is used -- */
300  /* Use redundant cell voltage measurements if measurement values have been acquired once */
301  useCellVoltageRedundancy = DATA_DatabaseEntryUpdatedAtLeastOnce(pCellVoltageRedundancy0->header);
302 
303  /* ----------------- Check timestamp of base measurements--------------- */
305  baseCellVoltageMeasurementTimeoutReached = false;
307  } else {
308  baseCellVoltageMeasurementTimeoutReached = true;
309  /* Set error flag */
311  }
312 
313  /* Check if base measurement values have been updated since last MRC */
314  if (mrc_state.lastBaseCellVoltageTimestamp != pCellVoltageBase->header.timestamp) {
315  baseCellVoltageUpdated = true;
316  } else {
317  baseCellVoltageUpdated = false;
318  }
319 
320  /* ----------------- Check timestamp of redundant measurements --------- */
322  false) &&
323  (useCellVoltageRedundancy == true)) {
324  redundancy0CellVoltageMeasurementTimeoutReached = true;
325  /* Set error flag */
327  } else {
328  redundancy0CellVoltageMeasurementTimeoutReached = false;
330  }
331 
332  /* ----------------- Validate cell voltages ---------------------------- */
333  if (useCellVoltageRedundancy == true) {
334  bool redundany0CellVoltageUpdated = false;
335  /* Check if redundant measurement values have been updated since last MRC */
336  if (mrc_state.lastRedundancy0CellVoltageTimestamp != pCellVoltageRedundancy0->header.timestamp) {
337  redundany0CellVoltageUpdated = true;
338  } else {
339  redundany0CellVoltageUpdated = false;
340  }
341  /* Make sure cell voltage timestamps have been updated since last call */
342  if ((baseCellVoltageUpdated == true) && (redundany0CellVoltageUpdated == true)) {
343  /* Update timestamp */
346 
347  /* Validate cell voltages */
348  MRC_ValidateCellVoltage(pCellVoltageBase, pCellVoltageRedundancy0, &mrc_tableCellVoltages);
349  /* Set to true for following minimum, maximum and average calculation */
350  updatedValidatedVoltageDatbaseEntry = true;
351  } else if ((baseCellVoltageUpdated == true) || (redundany0CellVoltageUpdated == true)) {
352  /* At least one measurement has been updated */
353  if (baseCellVoltageUpdated == true) {
354  /* Has redundant measurement timeout been reached? If yes, update. */
355  if (redundancy0CellVoltageMeasurementTimeoutReached == true) {
356  /* Copy cell voltage base measurement values into validated database struct */
358  /* Set to true for following minimum, maximum and average calculation */
359  updatedValidatedVoltageDatbaseEntry = true;
360  }
361  } else if (redundany0CellVoltageUpdated == true) {
362  /* Has base measurement timeout been reached? If yes, update. */
363  if (baseCellVoltageMeasurementTimeoutReached == true) {
364  /* Copy cell voltage base measurement values into validated database struct */
365  MRC_UpdateCellVoltageValidation(pCellVoltageRedundancy0, &mrc_tableCellVoltages);
366  /* Set to true for following minimum, maximum and average calculation */
367  updatedValidatedVoltageDatbaseEntry = true;
368  }
369  } else {
371  }
372  } else {
373  /* No cell voltage measurement has been updated -> do nothing */
374  }
375  } else {
376  if (baseCellVoltageUpdated == true) {
377  /* Only update database entries if new raw data has been acquired */
378  /* Update timestamp */
380 
381  /* Copy cell voltage base measurement values into validated database struct */
383 
384  /* Set to true for following minimum, maximum and average calculation */
385  updatedValidatedVoltageDatbaseEntry = true;
386  }
387  }
388 
389  if (updatedValidatedVoltageDatbaseEntry == true) {
390  /* Calculate min/max/average cell voltages */
392 
393  /* Individual cell voltages validated and min/max/average calculated -> check voltage spread */
395  /* Recalculate min/max/average cell voltages as at least one cell voltage has been detected as invalid */
397  }
398  }
399 
400  return updatedValidatedVoltageDatbaseEntry;
401 }
402 
404  DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperatureBase,
405  DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperatureRedundancy0) {
406  FAS_ASSERT(pCellTemperatureBase != NULL_PTR);
407  FAS_ASSERT(pCellTemperatureRedundancy0 != NULL_PTR);
408 
409  bool baseCelltemperatureUpdated = false;
410  bool useCelltemperatureRedundancy = false;
411  bool updatedValidatedTemperatureDatbaseEntry = false;
412 
413  bool baseCellTemperatureMeasurementTimeoutReached = true;
414  bool redundancy0CellTemperatureMeasurementTimeoutReached = true;
415 
416  /* Following decision will be undertaken:
417  *
418  * - Use redundancy only if timestamp of redundant database entry != 0
419  * - Perform redundant check if both timestamps have been updated
420  * - Add timeout and trigger error if timestamps have not been updated in the last XXXXms
421  * - If timeout reached and only one of the two redundant measurements has been updated use this measurement value
422  * but throw an error that one measurement has not been updated recently.
423  */
424 
425  /* -------------- Check if cell cell temperature redundant measurement is used ---------- */
426  /* Use redundant cell voltage measurements if measurement values have been acquired once */
427  useCelltemperatureRedundancy = DATA_DatabaseEntryUpdatedAtLeastOnce(pCellTemperatureRedundancy0->header);
428 
429  /* ----------------- Check timestamp of base measurements--------------- */
431  baseCellTemperatureMeasurementTimeoutReached = false;
433  } else {
434  baseCellTemperatureMeasurementTimeoutReached = true;
435  /* Set error flag */
437  }
438  /* Check if base measurement values have been updated since last MRC */
439  if (mrc_state.lastBaseCelltemperatureTimestamp != pCellTemperatureBase->header.timestamp) {
440  baseCelltemperatureUpdated = true;
441  } else {
442  baseCelltemperatureUpdated = false;
443  }
444 
445  /* ----------------- Check timestamp of redundant measurements --------- */
447  false) &&
448  (useCelltemperatureRedundancy == true)) {
449  redundancy0CellTemperatureMeasurementTimeoutReached = true;
450  /* Set error flag */
451  (void)DIAG_Handler(
453  } else {
454  redundancy0CellTemperatureMeasurementTimeoutReached = false;
456  }
457 
458  /* ----------------- Validate cell temperatures ------------------------ */
459  if (useCelltemperatureRedundancy == true) {
460  bool redundancy0CelltemperatureUpdated = false;
461  /* Check if redundant measurement values have been updated since last MRC */
462  if (mrc_state.lastRedundancy0CelltemperatureTimestamp != pCellTemperatureRedundancy0->header.timestamp) {
463  redundancy0CelltemperatureUpdated = true;
464  } else {
465  redundancy0CelltemperatureUpdated = false;
466  }
467  /* Make sure cell voltage timestamps have been updated since last call */
468  if ((baseCelltemperatureUpdated == true) && (redundancy0CelltemperatureUpdated == true)) {
469  /* Update timestamp */
471  mrc_state.lastRedundancy0CelltemperatureTimestamp = pCellTemperatureRedundancy0->header.timestamp;
472 
473  /* Validate cell temperatures */
474  MRC_ValidateCellTemperature(pCellTemperatureBase, pCellTemperatureRedundancy0, &mrc_tableCellTemperatures);
475  /* Set to true for following minimum, maximum and average calculation */
476  updatedValidatedTemperatureDatbaseEntry = true;
477  } else if ((baseCelltemperatureUpdated == true) || (redundancy0CelltemperatureUpdated == true)) {
478  /* At least one measurement has been updated */
479  if (baseCelltemperatureUpdated == true) {
480  /* Has redundant measurement timeout been reached? If yes, update. */
481  if (redundancy0CellTemperatureMeasurementTimeoutReached == true) {
482  /* Copy cell temperature base measurement values into validated database struct */
484  /* Set to true for following minimum, maximum and average calculation */
485  updatedValidatedTemperatureDatbaseEntry = true;
486  }
487  } else if (redundancy0CelltemperatureUpdated == true) {
488  /* Has base measurement timeout been reached? If yes, update. */
489  if (baseCellTemperatureMeasurementTimeoutReached == true) {
490  /* Copy cell temperature redundant measurement values into validated database struct */
491  MRC_UpdateCellTemperatureValidation(pCellTemperatureRedundancy0, &mrc_tableCellTemperatures);
492  /* Set to true for following minimum, maximum and average calculation */
493  updatedValidatedTemperatureDatbaseEntry = true;
494  }
495  } else {
497  }
498  } else {
499  /* No cell temperature measurement has been updated -> do nothing */
500  }
501  } else { /* useCelltemperatureRedundancy == true */
502  if (baseCelltemperatureUpdated == true) {
503  /* Only update database entries if new raw data has been acquired */
504  /* Update timestamp */
506 
507  /* Copy cell temperature base measurement values into validated database struct */
509 
510  /* Set to true for following minimum, maximum and average calculation */
511  updatedValidatedTemperatureDatbaseEntry = true;
512  }
513  }
514 
515  if (updatedValidatedTemperatureDatbaseEntry == true) {
516  /* Calculate min/max/average cell temperatures */
518 
519  /* Individual cell temperatures validated and min/max/average calculated -> check temperature spread */
521  /* Recalculate min/max/average temperatures as at least one temperature has been detected as invalid */
523  }
524  }
525 
526  return updatedValidatedTemperatureDatbaseEntry;
527 }
528 
530  FAS_ASSERT(pTableCurrentSensor != NULL_PTR);
531  int32_t packCurrent_mA = 0;
532 
533  /* Validate pack current. Will be invalidated if not all current measurement values are valid */
535 
536  /* Iterate over all strings to calculate pack current */
537  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
538  /* Check timestamp of measurement */
540  pTableCurrentSensor->timestampCurrent[s],
541  pTableCurrentSensor->previousTimestampCurrent[s],
544 
545  if (noTimeout == STD_OK) {
546  /* Check if current entry has been updated since last call */
547  if (mrc_state.lastStringCurrentTimestamp[s] != pTableCurrentSensor->timestampCurrent[s]) {
548  mrc_state.lastStringCurrentTimestamp[s] = pTableCurrentSensor->timestampCurrent[s];
549  mrc_tablePackValues.stringCurrent_mA[s] = pTableCurrentSensor->current_mA[s];
550  if (pTableCurrentSensor->invalidCurrentMeasurement[s] == 0u) {
551  /* String current measurement valid -> set valid flag */
554  } else {
555  /* String current measurement invalid -> set invalid flag */
558  }
559  } else {
560  /* Nothing to do. Measurement has not been updated but still within timeout */
561  }
562  } else {
563  /* Measurement timeout reached -> set string current invalid */
565  }
566 
568  packCurrent_mA += mrc_tablePackValues.stringCurrent_mA[s];
569  } else {
570  /* One string current is invalid -> pack current cannot be correct.
571  * Set pack current invalid */
573  }
574  }
575  mrc_tablePackValues.packCurrent_mA = packCurrent_mA;
576 }
577 
579  DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor,
580  DATA_BLOCK_CELL_VOLTAGE_s *pTableCellVoltage) {
581  /* Pointer validity check */
582  FAS_ASSERT(pTableCurrentSensor != NULL_PTR);
583  FAS_ASSERT(pTableCellVoltage != NULL_PTR);
584 
585  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
586  /* Check timeout of current sensor measurement */
588  pTableCurrentSensor->timestampHighVoltage[s][0u],
589  pTableCurrentSensor->previousTimestampHighVoltage[s][0u],
592 
593  /* Perform plausibility check if AFE and new current sensor measurement is valid */
594  if ((updatedMeasurement == STD_OK) && (pTableCurrentSensor->invalidHighVoltageMeasurement[s][0u] == 0u) &&
595  (pTableCellVoltage->nrValidCellVoltages[s] == BS_NR_OF_CELL_BLOCKS_PER_STRING)) {
596  STD_RETURN_TYPE_e voltagePlausible = PL_CheckStringVoltage(
597  pTableCellVoltage->stringVoltage_mV[s], pTableCurrentSensor->highVoltage_mV[s][0u]);
599 
600  /* Use current sensor measurement */ /* TODO: use really current sensor? Average of both? AFE measurement? */
601  mrc_tablePackValues.stringVoltage_mV[s] = pTableCurrentSensor->highVoltage_mV[s][0u];
602 
603  if (voltagePlausible == STD_OK) {
605  } else {
607  }
608  } else {
609  /* Plausibility check cannot be performed if we do not have valid
610  * values from AFE and current sensor measurement */
612 
613  if ((updatedMeasurement == STD_OK) && (pTableCurrentSensor->invalidHighVoltageMeasurement[s][0u] == 0u)) {
614  /* Current sensor measurement valid -> use this measurement */
615  mrc_tablePackValues.stringVoltage_mV[s] = pTableCurrentSensor->highVoltage_mV[s][0u];
617  } else if (pTableCellVoltage->nrValidCellVoltages[s] == BS_NR_OF_CELL_BLOCKS_PER_STRING) {
618  /* AFE measurement valid -> use this measurement */
619  mrc_tablePackValues.stringVoltage_mV[s] = pTableCellVoltage->stringVoltage_mV[s];
621  } else {
622  /* AFE and current sensor measurement invalid -> try to construct
623  * a valid from the number of valid cell voltages and substitute
624  * invalid cell voltages with the average cell voltage. */
625  uint16_t numberInvalidCellVoltages =
626  (BS_NR_OF_CELL_BLOCKS_PER_STRING - pTableCellVoltage->nrValidCellVoltages[s]);
627 
629  pTableCellVoltage->stringVoltage_mV[s] +
630  (mrc_tableMinimumMaximumValues.averageCellVoltage_mV[s] * (int16_t)numberInvalidCellVoltages);
631 
632  /* Only use this as valid value if not more than five cell voltages are invalid */
633  if (numberInvalidCellVoltages > MRC_ALLOWED_NUMBER_OF_INVALID_CELL_VOLTAGES) {
635  } else {
637  }
638  }
639  }
640  }
641 }
642 
644  int64_t sumOfStringValues_mV = 0;
645  int8_t numberOfValidStringVoltages = 0;
646  uint8_t numberOfConnectedStrings = BMS_GetNumberOfConnectedStrings();
647 
648  if (0u != numberOfConnectedStrings) {
649  /* Iterate over all strings to see which strings are connected */
650  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
651  bool isStringConnected = BMS_IsStringClosed(s);
652  if ((mrc_tablePackValues.invalidStringVoltage[s] == 0u) && (isStringConnected == true)) {
653  /* AXIVION Disable Style MisraC2012Directive-4.1: Values start with 0, iteration is less than UINT8_MAX; overflow impossible */
654  sumOfStringValues_mV += mrc_tablePackValues.stringVoltage_mV[s];
655  numberOfValidStringVoltages++;
656  /* AXIVION Enable Style MisraC2012Directive-4.1: */
657  }
658  }
659  } else {
660  /* Take average of all strings if no strings are connected */
661  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
663  /* AXIVION Disable Style MisraC2012Directive-4.1: Values start with 0, iteration is less than UINT8_MAX; overflow impossible */
664  sumOfStringValues_mV += mrc_tablePackValues.stringVoltage_mV[s];
665  numberOfValidStringVoltages++;
666  /* AXIVION Enable Style MisraC2012Directive-4.1: */
667  }
668  }
669  }
670 
671  /* Only calculate average if at least one string voltage is valid */
672  if (0 != numberOfValidStringVoltages) {
673  /* AXIVION Next Codeline Style MisraC2012Directive-4.1: truncation impossible;
674  we sum INT32 values x times and divide by x, resulting in INT32 */
675  mrc_tablePackValues.batteryVoltage_mV = (int32_t)(sumOfStringValues_mV / numberOfValidStringVoltages);
677  } else {
680  }
681 }
682 
684  FAS_ASSERT(pTableCurrentSensor != NULL_PTR);
685 
686  int32_t sum_mV = 0;
687  uint8_t validVoltages = 0u;
688  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
689  /* Check timeout of current sensor measurement */
691  pTableCurrentSensor->timestampHighVoltage[s][2u],
692  pTableCurrentSensor->previousTimestampHighVoltage[s][2u],
695 
696  const bool stringClosed = BMS_IsStringClosed(s);
697  const bool stringPrecharging = BMS_IsStringPrecharging(s);
698  if (((stringPrecharging == true) || (stringClosed == true)) && (updatedMeasurement == STD_OK)) {
699  /* Only voltages of connected strings can be used */
700  if (pTableCurrentSensor->invalidHighVoltageMeasurement[s][2] == 0u) {
701  /* Measured high voltage is valid */
702  validVoltages++;
703  sum_mV += pTableCurrentSensor->highVoltage_mV[s][2];
704  }
705  }
706  }
707 
708  if (validVoltages > 0u) {
709  mrc_tablePackValues.highVoltageBusVoltage_mV = (sum_mV / (int32_t)validVoltages);
711  } else {
712  /* TODO: do we want to write special data if no valid values can be read? */
714  }
715 }
716 
718  FAS_ASSERT(pTableCurrentSensor != NULL_PTR);
719  bool calculatePower = false;
720  int32_t packPower_W = 0;
721 
722  /* Validate pack power. Will be invalidated if not all power measurement values are valid */
724 
725  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
726  /* Check timeout of current sensor measurement */
728  pTableCurrentSensor->timestampPower[s],
729  pTableCurrentSensor->previousTimestampPower[s],
732 
733  if (noTimeout == STD_OK) {
734  /* Check if current sensor measurement has been updated */
735  if (pTableCurrentSensor->timestampPower[s] != mrc_state.lastStringPowerTimestamp[s]) {
736  mrc_state.lastStringPowerTimestamp[s] = pTableCurrentSensor->timestampPower[s];
737  /* Check if measurement is valid */
738  if (pTableCurrentSensor->invalidPowerMeasurement[s] == 0u) {
739  mrc_tablePackValues.stringPower_W[s] = pTableCurrentSensor->power_W[s];
741  } else {
742  /* Measurement has been updated but value is invalid -> calculate from current and string voltage */
743  calculatePower = true;
744  /* TODO: do we want to calculate values by hand if we are within time limit but value is invalid? */
745  }
746  } else {
747  /* Nothing to do. Measurement has not been updated but still within timeout */
748  }
749  } else {
750  /* Timeout reached. Set invalid flag */
751  calculatePower = true;
753  }
754  if ((calculatePower == true) && (mrc_tablePackValues.invalidStringCurrent[s] == 0u) &&
756  /* Power measurement is invalid, but current and string voltage measurement are valid */
757  const float_t stringCurrent_A = (float_t)mrc_tablePackValues.stringCurrent_mA[s] /
759  const float_t stringVoltage_V = (float_t)mrc_tablePackValues.stringVoltage_mV[s] /
761  mrc_tablePackValues.stringPower_W[s] = (int32_t)(stringCurrent_A * stringVoltage_V);
763  }
765  packPower_W += mrc_tablePackValues.stringPower_W[s];
767  } else {
768  /* One string power is invalid -> pack power cannot be correct.
769  * Set pack power invalid */
772  }
773  }
774  mrc_tablePackValues.packPower_W = packPower_W;
775 }
776 
778  const DATA_BLOCK_CELL_VOLTAGE_s *const pValidatedVoltages,
779  DATA_BLOCK_MIN_MAX_s *pMinMaxAverageValues) {
780  /* Pointer validity check */
781  FAS_ASSERT(pValidatedVoltages != NULL_PTR);
782  FAS_ASSERT(pMinMaxAverageValues != NULL_PTR);
783 
784  STD_RETURN_TYPE_e retval = STD_OK;
785 
786  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
787  uint16_t nrValidCellVoltages = 0u;
788  int16_t min = INT16_MAX;
789  int16_t max = INT16_MIN;
790  int32_t sum = 0;
791  uint16_t moduleNumberMinimum = 0u;
792  uint16_t cellNumberMinimum = 0u;
793  uint16_t moduleNumberMaximum = 0u;
794  uint16_t cellNumberMaximum = 0u;
795  /* Iterate over all cells in each string */
796  for (uint8_t m = 0u; m < BS_NR_OF_MODULES_PER_STRING; m++) {
797  for (uint8_t cb = 0u; cb < BS_NR_OF_CELL_BLOCKS_PER_MODULE; cb++) {
798  if ((pValidatedVoltages->invalidCellVoltage[s][m] & (0x01u << cb)) == 0u) {
799  /* Cell voltage is valid -> use this voltage for subsequent calculations */
800  nrValidCellVoltages++;
801  sum += pValidatedVoltages->cellVoltage_mV[s][m][cb];
802 
803  if (pValidatedVoltages->cellVoltage_mV[s][m][cb] < min) {
804  min = pValidatedVoltages->cellVoltage_mV[s][m][cb];
805  moduleNumberMinimum = m;
806  cellNumberMinimum = cb;
807  }
808  if (pValidatedVoltages->cellVoltage_mV[s][m][cb] > max) {
809  max = pValidatedVoltages->cellVoltage_mV[s][m][cb];
810  moduleNumberMaximum = m;
811  cellNumberMaximum = cb;
812  }
813  }
814  }
815  }
816  pMinMaxAverageValues->minimumCellVoltage_mV[s] = min;
817  pMinMaxAverageValues->nrCellMinimumCellVoltage[s] = cellNumberMinimum;
818  pMinMaxAverageValues->nrModuleMinimumCellVoltage[s] = moduleNumberMinimum;
819  pMinMaxAverageValues->maximumCellVoltage_mV[s] = max;
820  pMinMaxAverageValues->nrCellMaximumCellVoltage[s] = cellNumberMaximum;
821  pMinMaxAverageValues->nrModuleMaximumCellVoltage[s] = moduleNumberMaximum;
822  pMinMaxAverageValues->validMeasuredCellVoltages[s] = nrValidCellVoltages;
823 
824  /* Prevent division by 0, if all cell voltages are invalid */
825  if (nrValidCellVoltages > 0u) {
826  pMinMaxAverageValues->averageCellVoltage_mV[s] = (int16_t)(sum / (int32_t)nrValidCellVoltages);
827  } else {
828  pMinMaxAverageValues->averageCellVoltage_mV[s] = 0;
829  retval = STD_NOT_OK;
830  }
831  }
832  return retval;
833 }
834 
836  DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperatures,
837  DATA_BLOCK_MIN_MAX_s *pMinMaxAverageValues) {
838  /* Pointer validity check */
839  FAS_ASSERT(pValidatedTemperatures != NULL_PTR);
840  FAS_ASSERT(pMinMaxAverageValues != NULL_PTR);
841 
842  STD_RETURN_TYPE_e retval = STD_OK;
843 
844  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
845  uint16_t moduleNumberMinimum = 0u;
846  uint16_t sensorNumberMinimum = 0u;
847  uint16_t moduleNumberMaximum = 0u;
848  uint16_t sensorNumberMaximum = 0u;
849  uint16_t nrValidCelltemperatures = 0u;
850  int16_t min = INT16_MAX;
851  int16_t max = INT16_MIN;
852  float_t sum_ddegC = 0.0f;
853 
854  for (uint8_t m = 0u; m < BS_NR_OF_MODULES_PER_STRING; m++) {
855  for (uint8_t ts = 0u; ts < BS_NR_OF_TEMP_SENSORS_PER_MODULE; ts++) {
856  if ((pValidatedTemperatures->invalidCellTemperature[s][m] & (0x01u << ts)) == 0u) {
857  /* Cell temperature is valid -> use this voltage for subsequent calculations */
858  nrValidCelltemperatures++;
859  sum_ddegC += (float_t)pValidatedTemperatures->cellTemperature_ddegC[s][m][ts];
860 
861  if (pValidatedTemperatures->cellTemperature_ddegC[s][m][ts] < min) {
862  min = pValidatedTemperatures->cellTemperature_ddegC[s][m][ts];
863  moduleNumberMinimum = m;
864  sensorNumberMinimum = ts;
865  }
866  if (pValidatedTemperatures->cellTemperature_ddegC[s][m][ts] > max) {
867  max = pValidatedTemperatures->cellTemperature_ddegC[s][m][ts];
868  moduleNumberMaximum = m;
869  sensorNumberMaximum = ts;
870  }
871  }
872  }
873  }
874  pMinMaxAverageValues->minimumTemperature_ddegC[s] = min;
875  pMinMaxAverageValues->nrSensorMinimumTemperature[s] = sensorNumberMinimum;
876  pMinMaxAverageValues->nrModuleMinimumTemperature[s] = moduleNumberMinimum;
877  pMinMaxAverageValues->maximumTemperature_ddegC[s] = max;
878  pMinMaxAverageValues->nrSensorMaximumTemperature[s] = sensorNumberMaximum;
879  pMinMaxAverageValues->nrModuleMaximumTemperature[s] = moduleNumberMaximum;
880  pMinMaxAverageValues->validMeasuredCellTemperatures[s] = nrValidCelltemperatures;
881 
882  /* Prevent division by 0, if all cell temperatures are invalid */
883  if (nrValidCelltemperatures > 0u) {
884  pMinMaxAverageValues->averageTemperature_ddegC[s] = (sum_ddegC / (float_t)nrValidCelltemperatures);
885  } else {
886  pMinMaxAverageValues->averageTemperature_ddegC[s] = 0.0f;
887  retval = STD_NOT_OK;
888  }
889  }
890  return retval;
891 }
892 
894  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageBase,
895  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageRedundancy0,
896  DATA_BLOCK_CELL_VOLTAGE_s *pValidatedVoltages) {
897  /* Pointer validity check */
898  FAS_ASSERT(pCellVoltageBase != NULL_PTR);
899  FAS_ASSERT(pCellVoltageRedundancy0 != NULL_PTR);
900  FAS_ASSERT(pValidatedVoltages != NULL_PTR);
901 
902  uint16_t numberValidMeasurements = 0u;
903  STD_RETURN_TYPE_e noPlausibilityIssueDetected = STD_OK; /* Flag if implausible value detected */
904  STD_RETURN_TYPE_e retval = STD_OK;
905 
906  /* Iterate over all cell measurements */
907  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
908  int32_t sum = 0;
909  for (uint8_t m = 0; m < BS_NR_OF_MODULES_PER_STRING; m++) {
910  for (uint8_t cb = 0; cb < BS_NR_OF_CELL_BLOCKS_PER_MODULE; cb++) {
911  if (((pCellVoltageBase->invalidCellVoltage[s][m] & (1u << cb)) == 0u) &&
912  ((pCellVoltageRedundancy0->invalidCellVoltage[s][m] & (1u << cb)) == 0u)) {
913  /* Check if cell voltage of base AND redundant measurement is valid -> do plausibility check */
915  pCellVoltageBase->cellVoltage_mV[s][m][cb],
916  pCellVoltageRedundancy0->cellVoltage_mV[s][m][cb],
917  &pValidatedVoltages->cellVoltage_mV[s][m][cb])) {
918  /* Clear valid flag */
919  pValidatedVoltages->invalidCellVoltage[s][m] = pValidatedVoltages->invalidCellVoltage[s][m] &
920  (~(1u << cb));
921  numberValidMeasurements++;
922  sum += pValidatedVoltages->cellVoltage_mV[s][m][cb];
923  } else {
924  /* Set invalid flag */
925  noPlausibilityIssueDetected = STD_NOT_OK;
926  pValidatedVoltages->invalidCellVoltage[s][m] |= (1u << cb);
927  /* Set return value to #STD_NOT_OK as not all cell voltages have a valid measurement value */
928  retval = STD_NOT_OK;
929  }
930  } else if ((pCellVoltageBase->invalidCellVoltage[s][m] & (1u << cb)) == 0u) {
931  /* Only base measurement value is valid -> use this voltage without further plausibility checks */
932  pValidatedVoltages->cellVoltage_mV[s][m][cb] = pCellVoltageBase->cellVoltage_mV[s][m][cb];
933  /* Reset valid flag */
934  pValidatedVoltages->invalidCellVoltage[s][m] = pValidatedVoltages->invalidCellVoltage[s][m] &
935  (~(1u << cb));
936  numberValidMeasurements++;
937  sum += pValidatedVoltages->cellVoltage_mV[s][m][cb];
938  } else if ((pCellVoltageRedundancy0->invalidCellVoltage[s][m] & (1u << cb)) == 0u) {
939  /* Only redundant measurement value is valid -> use this voltage without further plausibility checks */
940  pValidatedVoltages->cellVoltage_mV[s][m][cb] = pCellVoltageRedundancy0->cellVoltage_mV[s][m][cb];
941  /* Reset valid flag */
942  pValidatedVoltages->invalidCellVoltage[s][m] = pValidatedVoltages->invalidCellVoltage[s][m] &
943  (~(1u << cb));
944  numberValidMeasurements++;
945  sum += pValidatedVoltages->cellVoltage_mV[s][m][cb];
946  } else {
947  /* Both, base and redundant measurement value are invalid */
948  /* Save average cell voltage value of base and redundant */
949  pValidatedVoltages->cellVoltage_mV[s][m][cb] = (pCellVoltageBase->cellVoltage_mV[s][m][cb] +
950  pCellVoltageRedundancy0->cellVoltage_mV[s][m][cb]) /
951  2;
952  /* Set invalid flag */
953  pValidatedVoltages->invalidCellVoltage[s][m] |= (1u << cb);
954  /* Set return value to #STD_NOT_OK as not all cell voltages have a valid measurement value */
955  retval = STD_NOT_OK;
956  }
957  }
958  }
959  pValidatedVoltages->nrValidCellVoltages[s] = numberValidMeasurements;
960  pValidatedVoltages->stringVoltage_mV[s] = sum;
961  numberValidMeasurements = 0u; /* Reset counter for next string */
962 
963  (void)DIAG_CheckEvent(noPlausibilityIssueDetected, DIAG_ID_PLAUSIBILITY_CELL_VOLTAGE, DIAG_STRING, s);
964  noPlausibilityIssueDetected = STD_OK; /* Reset flag for next string */
965  }
966  return retval;
967 }
968 
970  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltage,
971  DATA_BLOCK_CELL_VOLTAGE_s *pValidatedVoltages) {
972  /* Pointer validity check */
973  FAS_ASSERT(pCellVoltage != NULL_PTR);
974  FAS_ASSERT(pValidatedVoltages != NULL_PTR);
975 
976  /* Save header struct to copy to correct database entry */
977  DATA_BLOCK_HEADER_s tmpHeader = pValidatedVoltages->header;
978  /* Copy whole database entry */
979  *pValidatedVoltages = *pCellVoltage;
980  /* Restore previous header */
981  pValidatedVoltages->header = tmpHeader;
982 
983  return STD_OK;
984 }
985 
987  DATA_BLOCK_CELL_TEMPERATURE_s *pCelltemperatureBase,
988  DATA_BLOCK_CELL_TEMPERATURE_s *pCelltemperatureRedundancy0,
989  DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperatures) {
990  /* Pointer validity check */
991  FAS_ASSERT(pCelltemperatureBase != NULL_PTR);
992  FAS_ASSERT(pCelltemperatureRedundancy0 != NULL_PTR);
993  FAS_ASSERT(pValidatedTemperatures != NULL_PTR);
994 
995  uint16_t numberValidMeasurements = 0u;
996  STD_RETURN_TYPE_e noPlausibilityIssueDetected = STD_OK; /* Flag if implausible value detected */
997  STD_RETURN_TYPE_e retval = STD_OK;
998 
999  /* Iterate over all cell measurements */
1000  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
1001  for (uint8_t m = 0u; m < BS_NR_OF_MODULES_PER_STRING; m++) {
1002  for (uint8_t ts = 0u; ts < BS_NR_OF_TEMP_SENSORS_PER_MODULE; ts++) {
1003  if (((pCelltemperatureBase->invalidCellTemperature[s][m] & (1u << ts)) == 0u) &&
1004  ((pCelltemperatureRedundancy0->invalidCellTemperature[s][m] & (1u << ts)) == 0u)) {
1005  /* Check if cell voltage of base AND redundant measurement is valid -> do plausibility check */
1007  pCelltemperatureBase->cellTemperature_ddegC[s][m][ts],
1008  pCelltemperatureRedundancy0->cellTemperature_ddegC[s][m][ts],
1009  &pValidatedTemperatures->cellTemperature_ddegC[s][m][ts])) {
1010  /* Clear valid flag */
1011  pValidatedTemperatures->invalidCellTemperature[s][m] =
1012  pValidatedTemperatures->invalidCellTemperature[s][m] & (~(1u << ts));
1013  numberValidMeasurements++;
1014  } else {
1015  /* Set invalid flag */
1016  noPlausibilityIssueDetected = STD_NOT_OK;
1017  pValidatedTemperatures->invalidCellTemperature[s][m] |= (1u << ts);
1018  /* Set return value to #STD_NOT_OK as not all cell temperatures have a valid measurement value */
1019  retval = STD_NOT_OK;
1020  }
1021  } else if ((pCelltemperatureBase->invalidCellTemperature[s][m] & (1u << ts)) == 0u) {
1022  /* Only base measurement value is valid -> use this temperature without further plausibility checks */
1023  pValidatedTemperatures->cellTemperature_ddegC[s][m][ts] =
1024  pCelltemperatureBase->cellTemperature_ddegC[s][m][ts];
1025  /* Reset valid flag */
1026  pValidatedTemperatures->invalidCellTemperature[s][m] =
1027  pValidatedTemperatures->invalidCellTemperature[s][m] & (~(1u << ts));
1028  numberValidMeasurements++;
1029  } else if ((pCelltemperatureRedundancy0->invalidCellTemperature[s][m] & (1u << ts)) == 0u) {
1030  /* Only redundant measurement value is valid -> use this temperature without further plausibility checks */
1031  pValidatedTemperatures->cellTemperature_ddegC[s][m][ts] =
1032  pCelltemperatureRedundancy0->cellTemperature_ddegC[s][m][ts];
1033  /* Reset valid flag */
1034  pValidatedTemperatures->invalidCellTemperature[s][m] =
1035  pValidatedTemperatures->invalidCellTemperature[s][m] & (~(1u << ts));
1036  numberValidMeasurements++;
1037  } else {
1038  /* Both, base and redundant measurement value are invalid */
1039  /* Save average cell voltage value of base and redundant */
1040  pValidatedTemperatures->cellTemperature_ddegC[s][m][ts] =
1041  (pCelltemperatureBase->cellTemperature_ddegC[s][m][ts] +
1042  pCelltemperatureRedundancy0->cellTemperature_ddegC[s][m][ts]) /
1043  2u;
1044  /* Set invalid flag */
1045  pValidatedTemperatures->invalidCellTemperature[s][m] |= (1u << ts);
1046  /* Set return value to #STD_NOT_OK as not all cell temperatures have a valid measurement value */
1047  retval = STD_NOT_OK;
1048  }
1049  }
1050  }
1051  pValidatedTemperatures->nrValidTemperatures[s] = numberValidMeasurements;
1052  numberValidMeasurements = 0u; /* Reset counter for next string */
1053 
1054  (void)DIAG_CheckEvent(noPlausibilityIssueDetected, DIAG_ID_PLAUSIBILITY_CELL_TEMP, DIAG_STRING, s);
1055  noPlausibilityIssueDetected = STD_OK; /* Reset flag for next string */
1056  }
1057 
1058  return retval;
1059 }
1060 
1062  DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperature,
1063  DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperature) {
1064  /* Pointer validity check */
1065  FAS_ASSERT(pCellTemperature != NULL_PTR);
1066  FAS_ASSERT(pValidatedTemperature != NULL_PTR);
1067 
1068  /* Save header struct to copy to correct database entry */
1069  DATA_BLOCK_HEADER_s tmpHeader = pValidatedTemperature->header;
1070  /* Copy whole database entry */
1071  *pValidatedTemperature = *pCellTemperature;
1072  /* Restore previous header */
1073  pValidatedTemperature->header = tmpHeader;
1074  return STD_OK;
1075 }
1076 
1077 /*========== Extern Function Implementations ================================*/
1079  STD_RETURN_TYPE_e retval = STD_NOT_OK;
1080  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
1081  for (uint8_t m = 0u; m < BS_NR_OF_MODULES_PER_STRING; m++) {
1082  /* Invalidate cell voltage values */
1083  mrc_tableCellVoltages.invalidCellVoltage[s][m] = 0xFFFFFFFFFFFFFFFFuLL;
1085  /* Invalidate cell temperature values */
1087  }
1088  /* Invalidate string values */
1092  }
1093  /* Invalidate pack values */
1094  mrc_tablePackValues.invalidPackCurrent = 0x01; /*!< bitmask if current is valid. 0->valid, 1->invalid */
1095  mrc_tablePackValues.invalidBatteryVoltage = 0x01; /*!< bitmask if voltage is valid. 0->valid, 1->invalid */
1096  mrc_tablePackValues.invalidHvBusVoltage = 0x01; /*!< bitmask if voltage is valid. 0->valid, 1->invalid */
1097  mrc_tablePackValues.invalidPackPower = 0x01; /*!< bitmask if power is valid. 0->valid, 1->invalid */
1098 
1100  return retval;
1101 }
1102 
1104  STD_RETURN_TYPE_e retval = STD_OK;
1105 
1106  /* Database entries are declared static, so that they are placed in the data segment and not on the stack */
1107  static DATA_BLOCK_CELL_VOLTAGE_s mrc_tableCellVoltageBase = {.header.uniqueId = DATA_BLOCK_ID_CELL_VOLTAGE_BASE};
1108  static DATA_BLOCK_CELL_VOLTAGE_s mrc_tableCellVoltageRedundancy0 = {
1110 
1111  static DATA_BLOCK_CELL_TEMPERATURE_s mrc_tableCelltemperatureBase = {
1113  static DATA_BLOCK_CELL_TEMPERATURE_s mrc_tableCelltemperatureRedundancy0 = {
1115 
1116  /* Get measurement values */
1118  &mrc_tableCellVoltageBase,
1119  &mrc_tableCellVoltageRedundancy0,
1120  &mrc_tableCelltemperatureBase,
1121  &mrc_tableCelltemperatureRedundancy0);
1122 
1123  /* Perform validation of cell voltage measurement */
1124  bool updateCellVoltages =
1125  MRC_ValidateCellVoltageMeasurement(&mrc_tableCellVoltageBase, &mrc_tableCellVoltageRedundancy0);
1126 
1127  /* Perform validation of cell temperature measurement */
1128  bool updateCellTemperatures =
1129  MRC_ValidateCellTemperatureMeasurement(&mrc_tableCelltemperatureBase, &mrc_tableCelltemperatureRedundancy0);
1130 
1131  /* Update database entries if necessary */
1132  if ((updateCellVoltages == true) && (updateCellTemperatures == true)) {
1134  } else if (updateCellVoltages == true) {
1136  } else if (updateCellTemperatures == true) {
1138  } else {
1139  retval = STD_NOT_OK;
1140  }
1141  return retval;
1142 }
1143 
1145  STD_RETURN_TYPE_e retval = STD_OK;
1147 
1148  DATA_READ_DATA(&tableCurrentSensor);
1149 
1150  MRC_ValidateCurrentMeasurement(&tableCurrentSensor);
1153  MRC_ValidateHighVoltageBusMeasurement(&tableCurrentSensor);
1154  MRC_ValidatePowerMeasurement(&tableCurrentSensor);
1155 
1157 
1158  return retval;
1159 }
1160 
1161 /*========== Externalized Static Function Implementations (Unit Test) =======*/
1162 #ifdef UNITY_UNIT_TEST
1163 extern bool TEST_MRC_MeasurementUpdatedAtLeastOnce(uint32_t timestamp, uint32_t previousTimestamp) {
1164  return MRC_MeasurementUpdatedAtLeastOnce(timestamp, previousTimestamp);
1165 }
1167  uint32_t timestamp,
1168  uint32_t previousTimestamp,
1169  uint32_t timeInterval) {
1170  return MRC_MeasurementUpdatedRecently(timestamp, previousTimestamp, timeInterval);
1171 }
1173  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageBase,
1174  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageRedundancy0) {
1175  return MRC_ValidateCellVoltageMeasurement(pCellVoltageBase, pCellVoltageRedundancy0);
1176 }
1178  DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperatureBase,
1179  DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperatureRedundancy0) {
1180  return MRC_ValidateCellTemperatureMeasurement(pCellTemperatureBase, pCellTemperatureRedundancy0);
1181 }
1182 
1184  MRC_ValidateCurrentMeasurement(pTableCurrentSensor);
1185 }
1186 
1188  MRC_ValidatePowerMeasurement(pTableCurrentSensor);
1189 }
1191  DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor,
1192  DATA_BLOCK_CELL_VOLTAGE_s *pTableCellVoltage) {
1193  MRC_ValidateStringVoltageMeasurement(pTableCurrentSensor, pTableCellVoltage);
1194 }
1197 }
1199  MRC_ValidateHighVoltageBusMeasurement(pTableCurrentSensor);
1200 }
1202  DATA_BLOCK_CELL_VOLTAGE_s *pValidatedVoltages,
1203  DATA_BLOCK_MIN_MAX_s *pMinMaxAverageValues) {
1204  return MRC_CalculateCellVoltageMinMaxAverage(pValidatedVoltages, pMinMaxAverageValues);
1205 }
1207  DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperatures,
1208  DATA_BLOCK_MIN_MAX_s *pMinMaxAverageValues) {
1209  return MRC_CalculateCellTemperatureMinMaxAverage(pValidatedTemperatures, pMinMaxAverageValues);
1210 }
1212  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageBase,
1213  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageRedundancy0,
1214  DATA_BLOCK_CELL_VOLTAGE_s *pValidatedVoltages) {
1215  return MRC_ValidateCellVoltage(pCellVoltageBase, pCellVoltageRedundancy0, pValidatedVoltages);
1216 }
1218  DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltage,
1219  DATA_BLOCK_CELL_VOLTAGE_s *pValidatedVoltages) {
1220  return MRC_UpdateCellVoltageValidation(pCellVoltage, pValidatedVoltages);
1221 }
1223  DATA_BLOCK_CELL_TEMPERATURE_s *pCelltemperatureBase,
1224  DATA_BLOCK_CELL_TEMPERATURE_s *pCelltemperatureRedundancy0,
1225  DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperatures) {
1226  return MRC_ValidateCellTemperature(pCelltemperatureBase, pCelltemperatureRedundancy0, pValidatedTemperatures);
1227 }
1229  DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperature,
1230  DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperature) {
1231  return MRC_UpdateCellTemperatureValidation(pCellTemperature, pValidatedTemperature);
1232 }
1233 #endif
#define BS_NR_OF_CELL_BLOCKS_PER_MODULE
number of cells per module
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
#define BS_NR_OF_TEMP_SENSORS_PER_MODULE
number of temperature sensors per battery module
#define BS_NR_OF_CELL_BLOCKS_PER_STRING
#define BS_NR_OF_MODULES_PER_STRING
number of modules in a string
bool BMS_IsStringPrecharging(uint8_t stringNumber)
Returns if string is currently precharging or not.
Definition: bms.c:1623
uint8_t BMS_GetNumberOfConnectedStrings(void)
Returns number of connected strings.
Definition: bms.c:1632
bool BMS_IsStringClosed(uint8_t stringNumber)
Returns string state (closed or open)
Definition: bms.c:1614
bms driver header
Database module header.
#define DATA_READ_DATA(...)
Definition: database.h:86
#define DATA_WRITE_DATA(...)
Definition: database.h:96
@ DATA_BLOCK_ID_CELL_VOLTAGE_REDUNDANCY0
Definition: database_cfg.h:91
@ DATA_BLOCK_ID_MIN_MAX
Definition: database_cfg.h:99
@ DATA_BLOCK_ID_CELL_VOLTAGE
Definition: database_cfg.h:89
@ DATA_BLOCK_ID_CELL_TEMPERATURE_REDUNDANCY0
Definition: database_cfg.h:88
@ DATA_BLOCK_ID_CELL_TEMPERATURE_BASE
Definition: database_cfg.h:87
@ DATA_BLOCK_ID_CURRENT_SENSOR
Definition: database_cfg.h:93
@ DATA_BLOCK_ID_CELL_VOLTAGE_BASE
Definition: database_cfg.h:90
@ DATA_BLOCK_ID_PACK_VALUES
Definition: database_cfg.h:105
@ DATA_BLOCK_ID_CELL_TEMPERATURE
Definition: database_cfg.h:86
bool DATA_DatabaseEntryUpdatedAtLeastOnce(DATA_BLOCK_HEADER_s dataBlockHeader)
Checks if passed database entry has been updated at least once.
bool DATA_EntryUpdatedWithinInterval(DATA_BLOCK_HEADER_s dataBlockHeader, uint32_t timeInterval)
Checks if passed database entry has been updated within the last time interval.
STD_RETURN_TYPE_e DIAG_CheckEvent(STD_RETURN_TYPE_e cond, DIAG_ID_e diagId, DIAG_IMPACT_LEVEL_e impact, uint32_t data)
DIAG_CheckEvent provides a simple interface to check an event for STD_OK.
Definition: diag.c:374
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:246
Diagnosis driver header.
@ DIAG_EVENT_NOT_OK
Definition: diag_cfg.h:268
@ DIAG_EVENT_OK
Definition: diag_cfg.h:267
@ DIAG_SYSTEM
Definition: diag_cfg.h:280
@ DIAG_STRING
Definition: diag_cfg.h:281
@ DIAG_ID_POWER_MEASUREMENT_ERROR
Definition: diag_cfg.h:250
@ DIAG_ID_CURRENT_MEASUREMENT_TIMEOUT
Definition: diag_cfg.h:244
@ DIAG_ID_BASE_CELL_TEMPERATURE_MEASUREMENT_TIMEOUT
Definition: diag_cfg.h:240
@ DIAG_ID_PLAUSIBILITY_PACK_VOLTAGE
Definition: diag_cfg.h:231
@ DIAG_ID_PLAUSIBILITY_CELL_VOLTAGE
Definition: diag_cfg.h:190
@ DIAG_ID_PLAUSIBILITY_CELL_TEMP
Definition: diag_cfg.h:193
@ DIAG_ID_CURRENT_SENSOR_POWER_MEASUREMENT_TIMEOUT
Definition: diag_cfg.h:249
@ DIAG_ID_BASE_CELL_VOLTAGE_MEASUREMENT_TIMEOUT
Definition: diag_cfg.h:238
@ DIAG_ID_CURRENT_SENSOR_V1_MEASUREMENT_TIMEOUT
Definition: diag_cfg.h:246
@ DIAG_ID_CURRENT_SENSOR_V3_MEASUREMENT_TIMEOUT
Definition: diag_cfg.h:248
@ DIAG_ID_REDUNDANCY0_CELL_VOLTAGE_MEASUREMENT_TIMEOUT
Definition: diag_cfg.h:239
@ DIAG_ID_CURRENT_MEASUREMENT_ERROR
Definition: diag_cfg.h:245
@ DIAG_ID_REDUNDANCY0_CELL_TEMPERATURE_MEASUREMENT_TIMEOUT
Definition: diag_cfg.h:241
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:251
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:129
math library for often used math functions
#define UNIT_CONVERSION_FACTOR_1000_FLOAT
Definition: foxmath.h:78
STD_RETURN_TYPE_e
Definition: fstd_types.h:82
@ STD_NOT_OK
Definition: fstd_types.h:84
@ STD_OK
Definition: fstd_types.h:83
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
Declaration of the OS wrapper interface.
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:158
STD_RETURN_TYPE_e PL_CheckTemperatureSpread(DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperatures, DATA_BLOCK_MIN_MAX_s *pMinMaxAverageValues)
Cell temperature spread plausibility check.
Definition: plausibility.c:157
STD_RETURN_TYPE_e PL_CheckCelltemperature(int16_t baseCelltemperature, int16_t redundancy0Celltemperature, int16_t *pCelltemperature)
Cell temperature plausibility check between two redundant cell temperature measurement values.
Definition: plausibility.c:106
STD_RETURN_TYPE_e PL_CheckStringVoltage(int32_t voltageAfe_mV, int32_t voltageCurrentSensor_mV)
Pack voltage plausibility check between LTC and current sensor values.
Definition: plausibility.c:76
STD_RETURN_TYPE_e PL_CheckCellVoltage(int16_t baseCellVoltage, int16_t redundancy0CellVoltage, int16_t *pCellVoltage)
Cell voltage plausibility check between two redundant cell voltage measurement values.
Definition: plausibility.c:88
STD_RETURN_TYPE_e PL_CheckVoltageSpread(DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltages, DATA_BLOCK_MIN_MAX_s *pMinMaxAverageValues)
Cell voltage spread plausibility check.
Definition: plausibility.c:125
plausibility checks for cell voltage and cell temperatures
static DATA_BLOCK_CELL_TEMPERATURE_s mrc_tableCellTemperatures
Definition: redundancy.c:77
static DATA_BLOCK_CELL_VOLTAGE_s mrc_tableCellVoltages
Definition: redundancy.c:76
bool TEST_MRC_ValidateCellVoltageMeasurement(DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageBase, DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageRedundancy0)
Definition: redundancy.c:1172
static STD_RETURN_TYPE_e MRC_UpdateCellVoltageValidation(DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltage, DATA_BLOCK_CELL_VOLTAGE_s *pValidatedVoltages)
Function updates validated cell voltage measurement with data from a single measurement source....
Definition: redundancy.c:969
static DATA_BLOCK_MIN_MAX_s mrc_tableMinimumMaximumValues
Definition: redundancy.c:75
static void MRC_ValidatePowerMeasurement(DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor)
Function to validate results of power measurement.
Definition: redundancy.c:717
static STD_RETURN_TYPE_e MRC_ValidateCellVoltage(DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageBase, DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageRedundancy0, DATA_BLOCK_CELL_VOLTAGE_s *pValidatedVoltages)
Function compares cell voltage measurements from base measurement with one redundant measurement and ...
Definition: redundancy.c:893
static void MRC_ValidateStringVoltageMeasurement(DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor, DATA_BLOCK_CELL_VOLTAGE_s *pTableCellVoltage)
Function to validate results of string voltage measurement.
Definition: redundancy.c:578
STD_RETURN_TYPE_e TEST_MRC_CalculateCellTemperatureMinMaxAverage(DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperatures, DATA_BLOCK_MIN_MAX_s *pMinMaxAverageValues)
Definition: redundancy.c:1206
STD_RETURN_TYPE_e MRC_Initialize(void)
Function to initalize redundancy module.
Definition: redundancy.c:1078
bool TEST_MRC_ValidateCellTemperatureMeasurement(DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperatureBase, DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperatureRedundancy0)
Definition: redundancy.c:1177
static void MRC_ValidateHighVoltageBusMeasurement(DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor)
Function to validate results of high voltage measurement and calculate battery voltage and high volta...
Definition: redundancy.c:683
STD_RETURN_TYPE_e TEST_MRC_CalculateCellVoltageMinMaxAverage(DATA_BLOCK_CELL_VOLTAGE_s *pValidatedVoltages, DATA_BLOCK_MIN_MAX_s *pMinMaxAverageValues)
Definition: redundancy.c:1201
void TEST_MRC_ValidateBatteryVoltageMeasurement(void)
Definition: redundancy.c:1195
static DATA_BLOCK_PACK_VALUES_s mrc_tablePackValues
Definition: redundancy.c:78
void TEST_MRC_ValidatePowerMeasurement(DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor)
Definition: redundancy.c:1187
STD_RETURN_TYPE_e TEST_MRC_UpdateCellTemperatureValidation(DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperature, DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperature)
Definition: redundancy.c:1228
static bool MRC_ValidateCellTemperatureMeasurement(DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperatureBase, DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperatureRedundancy0)
Function to validate results of cell temperature measurement.
Definition: redundancy.c:403
bool TEST_MRC_MeasurementUpdatedAtLeastOnce(uint32_t timestamp, uint32_t previousTimestamp)
Definition: redundancy.c:1163
static void MRC_ValidateCurrentMeasurement(DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor)
Function to validate results of current measurement.
Definition: redundancy.c:529
void TEST_MRC_ValidateStringVoltageMeasurement(DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor, DATA_BLOCK_CELL_VOLTAGE_s *pTableCellVoltage)
Definition: redundancy.c:1190
static bool MRC_MeasurementUpdatedAtLeastOnce(uint32_t timestamp, uint32_t previousTimestamp)
Check timestamp if measurement has been updated at least once.
Definition: redundancy.c:247
STD_RETURN_TYPE_e MRC_ValidateAfeMeasurement(void)
Function to validate the measurement between redundant measurement values for cell voltage and cell t...
Definition: redundancy.c:1103
STD_RETURN_TYPE_e TEST_MRC_ValidateCellTemperature(DATA_BLOCK_CELL_TEMPERATURE_s *pCelltemperatureBase, DATA_BLOCK_CELL_TEMPERATURE_s *pCelltemperatureRedundancy0, DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperatures)
Definition: redundancy.c:1222
void TEST_MRC_ValidateCurrentMeasurement(DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor)
Definition: redundancy.c:1183
STD_RETURN_TYPE_e MRC_ValidatePackMeasurement(void)
Function to validate the measurements of pack values (string values, pack values)
Definition: redundancy.c:1144
STD_RETURN_TYPE_e TEST_MRC_UpdateCellVoltageValidation(DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltage, DATA_BLOCK_CELL_VOLTAGE_s *pValidatedVoltages)
Definition: redundancy.c:1217
STD_RETURN_TYPE_e TEST_MRC_MeasurementUpdatedRecently(uint32_t timestamp, uint32_t previousTimestamp, uint32_t timeInterval)
Definition: redundancy.c:1166
static STD_RETURN_TYPE_e MRC_CalculateCellVoltageMinMaxAverage(const DATA_BLOCK_CELL_VOLTAGE_s *const pValidatedVoltages, DATA_BLOCK_MIN_MAX_s *pMinMaxAverageValues)
Function calculates minimum, maximum and average cell voltages.
Definition: redundancy.c:777
static STD_RETURN_TYPE_e MRC_UpdateCellTemperatureValidation(DATA_BLOCK_CELL_TEMPERATURE_s *pCellTemperature, DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperature)
Function updates validated cell temperature measurement with data from a single measurement source....
Definition: redundancy.c:1061
static STD_RETURN_TYPE_e MRC_ValidateCellTemperature(DATA_BLOCK_CELL_TEMPERATURE_s *pCelltemperatureBase, DATA_BLOCK_CELL_TEMPERATURE_s *pCelltemperatureRedundancy0, DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperatures)
Function compares cell temperature measurements from base measurement with one redundant measurement ...
Definition: redundancy.c:986
STD_RETURN_TYPE_e TEST_MRC_ValidateCellVoltage(DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageBase, DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageRedundancy0, DATA_BLOCK_CELL_VOLTAGE_s *pValidatedVoltages)
Definition: redundancy.c:1211
static MRC_STATE_s mrc_state
Definition: redundancy.c:82
static STD_RETURN_TYPE_e MRC_CalculateCellTemperatureMinMaxAverage(DATA_BLOCK_CELL_TEMPERATURE_s *pValidatedTemperatures, DATA_BLOCK_MIN_MAX_s *pMinMaxAverageValues)
Function calculates minimum, maximum and average cell temperatures.
Definition: redundancy.c:835
static void MRC_ValidateBatteryVoltageMeasurement(void)
Function to validate HV battery voltage measurement.
Definition: redundancy.c:643
static bool MRC_ValidateCellVoltageMeasurement(DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageBase, DATA_BLOCK_CELL_VOLTAGE_s *pCellVoltageRedundancy0)
Function to validate results of cell voltage measurement.
Definition: redundancy.c:276
static STD_RETURN_TYPE_e MRC_MeasurementUpdatedRecently(uint32_t timestamp, uint32_t previousTimestamp, uint32_t timeInterval)
Check timestamp if measurement has been updated recently.
Definition: redundancy.c:258
void TEST_MRC_ValidateHighVoltageMeasurement(DATA_BLOCK_CURRENT_SENSOR_s *pTableCurrentSensor)
Definition: redundancy.c:1198
Header fileS for handling redundancy between redundant cell voltage and cell temperature measurements...
#define MRC_ALLOWED_NUMBER_OF_INVALID_CELL_VOLTAGES
Definition: redundancy.h:112
#define MRC_CURRENT_MEASUREMENT_PERIOD_TIMEOUT_ms
Definition: redundancy.h:75
#define MRC_CURRENT_SENSOR_MEASUREMENT_TIMEOUT_ms
Definition: redundancy.h:102
#define MRC_AFE_MEASUREMENT_PERIOD_TIMEOUT_ms
Definition: redundancy.h:89
int16_t cellTemperature_ddegC[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING][BS_NR_OF_TEMP_SENSORS_PER_MODULE]
Definition: database_cfg.h:156
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:153
uint16_t nrValidTemperatures[BS_NR_OF_STRINGS]
Definition: database_cfg.h:159
uint16_t invalidCellTemperature[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]
Definition: database_cfg.h:158
int16_t cellVoltage_mV[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING][BS_NR_OF_CELL_BLOCKS_PER_MODULE]
Definition: database_cfg.h:139
bool validModuleVoltage[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]
Definition: database_cfg.h:145
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:135
uint64_t invalidCellVoltage[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING]
Definition: database_cfg.h:142
uint16_t nrValidCellVoltages[BS_NR_OF_STRINGS]
Definition: database_cfg.h:143
int32_t stringVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:137
uint32_t previousTimestampCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:223
uint32_t timestampCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:224
uint32_t previousTimestampHighVoltage[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:245
int32_t current_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:220
uint32_t timestampHighVoltage[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:247
uint32_t previousTimestampPower[BS_NR_OF_STRINGS]
Definition: database_cfg.h:230
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:219
uint32_t timestampPower[BS_NR_OF_STRINGS]
Definition: database_cfg.h:231
int32_t highVoltage_mV[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:242
uint8_t invalidCurrentMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:221
uint8_t invalidHighVoltageMeasurement[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:241
int32_t power_W[BS_NR_OF_STRINGS]
Definition: database_cfg.h:227
uint8_t invalidPowerMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:228
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:125
int16_t minimumTemperature_ddegC[BS_NR_OF_STRINGS]
Definition: database_cfg.h:180
uint16_t nrSensorMinimumTemperature[BS_NR_OF_STRINGS]
Definition: database_cfg.h:182
uint16_t nrModuleMinimumTemperature[BS_NR_OF_STRINGS]
Definition: database_cfg.h:181
uint16_t nrModuleMaximumTemperature[BS_NR_OF_STRINGS]
Definition: database_cfg.h:184
int16_t maximumTemperature_ddegC[BS_NR_OF_STRINGS]
Definition: database_cfg.h:183
int16_t averageCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:169
uint16_t nrSensorMaximumTemperature[BS_NR_OF_STRINGS]
Definition: database_cfg.h:185
uint16_t validMeasuredCellVoltages[BS_NR_OF_STRINGS]
Definition: database_cfg.h:178
uint16_t validMeasuredCellTemperatures[BS_NR_OF_STRINGS]
Definition: database_cfg.h:186
uint16_t nrCellMaximumCellVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:177
float_t averageTemperature_ddegC[BS_NR_OF_STRINGS]
Definition: database_cfg.h:179
uint16_t nrCellMinimumCellVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:175
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:167
uint16_t nrModuleMinimumCellVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:174
uint16_t nrModuleMaximumCellVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:176
int16_t maximumCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:172
int16_t minimumCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:170
int32_t stringVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:206
int32_t stringPower_W[BS_NR_OF_STRINGS]
Definition: database_cfg.h:210
uint8_t invalidStringPower[BS_NR_OF_STRINGS]
Definition: database_cfg.h:211
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:195
int32_t stringCurrent_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:208
uint8_t invalidStringCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:209
uint8_t invalidStringVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:207
uint32_t lastBaseCelltemperatureTimestamp
Definition: redundancy.h:121
uint32_t lastStringCurrentTimestamp[BS_NR_OF_STRINGS]
Definition: redundancy.h:123
uint32_t lastRedundancy0CelltemperatureTimestamp
Definition: redundancy.h:122
uint32_t lastRedundancy0CellVoltageTimestamp
Definition: redundancy.h:120
uint32_t lastStringPowerTimestamp[BS_NR_OF_STRINGS]
Definition: redundancy.h:124
uint32_t lastBaseCellVoltageTimestamp
Definition: redundancy.h:119