foxBMS - Unit Tests  1.3.0
The foxBMS Unit Tests API Documentation
test_bender_iso165c.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 test_bender_iso165c.c
44  * @author foxBMS Team
45  * @date 2021-01-19 (date of creation)
46  * @updated 2022-05-30 (date of last update)
47  * @version v1.3.0
48  * @ingroup UNIT_TEST_IMPLEMENTATION
49  * @prefix TEST
50  *
51  * @brief Test of the Bender iso165c driver
52  *
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "unity.h"
57 #include "Mockcan.h"
58 #include "Mockcan_cfg.h"
59 #include "Mockdatabase.h"
60 #include "Mockdiag.h"
61 #include "Mockftask.h"
62 #include "Mockio.h"
63 #include "Mockmcu.h"
64 #include "Mockmpu_prototypes.h"
65 #include "Mockos.h"
66 
67 #include "bender_iso165c.h"
68 #include "test_assert_helper.h"
69 
70 /*========== Definitions and Implementations for Unit Test ==================*/
71 
72 QueueHandle_t ftsk_dataQueue = NULL_PTR;
74 QueueHandle_t ftsk_canRxQueue = NULL_PTR;
75 volatile bool ftsk_allQueuesCreated = false;
76 
77 /*========== Setup and Teardown =============================================*/
78 void setUp(void) {
79 }
80 
81 void tearDown(void) {
82 }
83 
84 /*========== Test Cases =====================================================*/
85 
86 /**
87  * @brief Test function to compose/use CAN messages.
88  *
89  */
91  CAN_BUFFERELEMENT_s canMessage;
92  uint8_t dataWord;
93  uint8_t dataByte;
94  uint16_t data16;
95  uint8_t data8;
96  uint8_t command;
97  uint8_t id;
98  uint8_t tries;
99 
100  /* Do as if there is a message in the queue */
101  OS_GetNumberOfStoredMessagesInQueue_IgnoreAndReturn(1u);
102  MPU_xQueueReceive_IgnoreAndReturn(1u);
103  OS_ReceiveFromQueue_IgnoreAndReturn(OS_SUCCESS);
104 
105  canMessage.id = 0x22u;
106  for (uint8_t i = 1u; i <= 8u; i++) {
107  canMessage.data[i] = i;
108  }
110  /* Reset must set all data to 0 */
111  TEST_I165C_ResetCanData(&canMessage);
112  for (uint8_t i = 0u; i < 8u; i++) {
113  TEST_ASSERT_EQUAL(0u, canMessage.data[i]);
114  }
115 
116  data16 = 666u;
117  dataWord = I165C_DW1;
119  /* Test that data is written correctly to CAN frame */
120  TEST_I165C_WriteDataWord(dataWord, data16, &canMessage);
121  TEST_ASSERT_EQUAL(0x9Au, canMessage.data[1u]);
122  TEST_ASSERT_EQUAL(0x02u, canMessage.data[2u]);
123  dataWord = I165C_DW2;
124  TEST_I165C_WriteDataWord(dataWord, data16, &canMessage);
125  TEST_ASSERT_EQUAL(0x9Au, canMessage.data[3u]);
126  TEST_ASSERT_EQUAL(0x02u, canMessage.data[4u]);
127 
128  for (uint8_t i = 1u; i <= 4u; i++) {
129  canMessage.data[i] = i;
130  }
131  data16 = 0u;
132  dataWord = I165C_DW1;
134  /* Test that dataword data is read correctly from usual CAN frame */
135  TEST_I165C_ReadDataWord(dataWord, &data16, canMessage);
136  TEST_ASSERT_EQUAL(0x201u, data16);
137  data16 = 0u;
138  dataWord = I165C_DW2;
139  TEST_I165C_ReadDataWord(dataWord, &data16, canMessage);
140  TEST_ASSERT_EQUAL(0x403u, data16);
141 
142  for (uint8_t i = 0u; i <= 5u; i++) {
143  canMessage.data[i] = i + 1u;
144  }
145  data16 = 0u;
146  dataWord = I165C_DW1;
148  /* Test that dataword data is read correctly from special IMD_Info CAN frame */
149  TEST_I165C_ReadDataWordImdInfo(dataWord, &data16, canMessage);
150  TEST_ASSERT_EQUAL(0x201u, data16);
151  data16 = 0u;
152  dataWord = I165C_DW2;
153  TEST_I165C_ReadDataWordImdInfo(dataWord, &data16, canMessage);
154  TEST_ASSERT_EQUAL(0x403u, data16);
155  data16 = 0u;
156  dataWord = I165C_DW3;
157  TEST_I165C_ReadDataWordImdInfo(dataWord, &data16, canMessage);
158  TEST_ASSERT_EQUAL(0x605u, data16);
159 
160  for (uint8_t i = 1u; i <= 4u; i++) {
161  canMessage.data[i] = i;
162  }
163  data8 = 0u;
164  dataByte = I165C_DB1;
166  /* Test that databyte data is read correctly from usual CAN frame */
167  TEST_I165C_ReadDataByte(dataByte, &data8, canMessage);
168  TEST_ASSERT_EQUAL(0x1u, data8);
169  data8 = 0u;
170  dataByte = I165C_DB2;
171  TEST_I165C_ReadDataByte(dataByte, &data8, canMessage);
172  TEST_ASSERT_EQUAL(0x2u, data8);
173  data8 = 0u;
174  dataByte = I165C_DB3;
175  TEST_I165C_ReadDataByte(dataByte, &data8, canMessage);
176  TEST_ASSERT_EQUAL(0x3u, data8);
177  data8 = 0u;
178  dataByte = I165C_DB4;
179  TEST_I165C_ReadDataByte(dataByte, &data8, canMessage);
180  TEST_ASSERT_EQUAL(0x4u, data8);
181 
182  id = 0xA;
183  command = 0xB;
185  /* Test that cmd is written correctly to CAN frame */
186  TEST_I165C_WriteCmd(id, command, &canMessage);
187  TEST_ASSERT_EQUAL(0xAu, canMessage.id);
188  TEST_ASSERT_EQUAL(0xBu, canMessage.data[0u]);
189 
190  /* Check assertion of invalid parameter */
191  canMessage.data[0u] = 0xA;
192  command = 0xA;
194 
195  /* Check that response ID corresponds to awaited acknowledge */
196  canMessage.id = CAN_ID_IMD_RESPONSE;
197  canMessage.data[0u] = 0xA;
198  command = 0xA;
199  TEST_ASSERT_EQUAL(true, TEST_I165C_CheckResponse(command, &canMessage));
200 
201  /* Check that response ID does not correspond to awaited acknowledge */
202  canMessage.id = CAN_ID_IMD_RESPONSE;
203  canMessage.data[0u] = 0xA;
204  command = 0xB;
205  TEST_ASSERT_EQUAL(false, TEST_I165C_CheckResponse(command, &canMessage));
206 
207  /* Check that response failed if ID is not CAN_ID_IMD_RESPONSE, even if response matches command */
208  canMessage.id = CAN_ID_IMD_INFO;
209  canMessage.data[0u] = 0xA;
210  command = 0xA;
211  TEST_ASSERT_EQUAL(false, TEST_I165C_CheckResponse(command, &canMessage));
212 
213  /* Check that response failed if ID is not CAN_ID_IMD_RESPONSE, if respose does not match command */
214  canMessage.id = CAN_ID_IMD_INFO;
215  canMessage.data[0u] = 0xA;
216  command = 0xB;
217  TEST_ASSERT_EQUAL(false, TEST_I165C_CheckResponse(command, &canMessage));
218 
219  canMessage.id = I165C_MESSAGETYPE_IMD_INFO;
221  /* Test that an IMD_info frame was received on CAN */
222  TEST_ASSERT_EQUAL(true, TEST_I165C_GetImdInfo(&canMessage));
223  canMessage.id = I165C_MESSAGETYPE_IMD_INFO + 1u;
224  TEST_ASSERT_EQUAL(false, TEST_I165C_GetImdInfo(&canMessage));
225 
226  /* Test if CAN data indicated that iso165c is not initialized */
227  for (uint8_t i = 0u; i < 8u; i++) {
228  canMessage.data[i] = 0u;
229  }
230  TEST_ASSERT_EQUAL(false, TEST_I165C_IsSelfTestFinished(canMessage));
231 
232  /* Test if CAN data indicated that iso165c is not initialized */
233  for (uint8_t i = 0u; i < 8u; i++) {
234  canMessage.data[i] = 0x00u;
235  }
236  /*
237  * D_IMC_STATUS is located in byte 2 and byte 3 of CAN message:
238  * Bit 4: Self test running -> set to 1 */
239  canMessage.data[2u] |= (1u << I165C_SELFTEST_RUNNING_SHIFT);
240  /* D_VIFC_STATUS is located in byte 4 and byte 5 of CAN message
241  * Bit 0: Insulation measurement active -> set to 0
242  * Bit 12: Self-test long executed -> set to 0
243  * Bit 13: Self-test short executed -> set to 0
244  */
245  canMessage.data[4u] |= (0u << I165C_INSULATION_MEASUREMENT_STATUS_SHIFT);
246  canMessage.data[5u] |=
247  (0u << (I165C_IMC_SELFTEST_OVERALL_SCENARIO_SHIFT - 8u)); /* Subtract 8 because upper byte is used */
248  canMessage.data[5u] |=
249  (0u << (I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO_SHIFT - 8u)); /* Subtract 8 because upper byte is used */
250 
251  TEST_ASSERT_EQUAL(true, TEST_I165C_IsSelfTestFinished(canMessage));
252 
253  /* ----------- Test function that waits for acknowledge -----------------*/
254 
255  /* Check for invalid function parameters */
259 
260  /* Acknowledge arrived */
261  canMessage.id = CAN_ID_IMD_RESPONSE;
262  tries = 0u;
263  command = 0xA;
264  canMessage.data[0] = 0xA;
265  bool ackReceived = false;
266 
267  ackReceived = TEST_I165C_CheckAcknowledgeArrived(command, &tries, &canMessage);
268  TEST_ASSERT_EQUAL(true, ackReceived);
269  TEST_ASSERT_EQUAL(0u, tries);
270 
271  /* Acknowledge not arrived, increment try counter */
272  canMessage.id = CAN_ID_IMD_RESPONSE;
273  tries = 0u;
274  command = 0xA;
275  canMessage.data[0] = 0xB;
276 
277  ackReceived = TEST_I165C_CheckAcknowledgeArrived(command, &tries, &canMessage);
278  TEST_ASSERT_EQUAL(1u, tries);
279  TEST_ASSERT_EQUAL(false, ackReceived);
280 
281  /* Acknowledge not arrived, and allowed number of tries made, restart
282  * Initialization (go to self test) */
283  tries = I165C_TRANSMISSION_ATTEMPTS - 1u;
284  command = 0xA;
285  canMessage.data[0] = 0xB;
286 
287  ackReceived = TEST_I165C_CheckAcknowledgeArrived(command, &tries, &canMessage);
288  TEST_ASSERT_EQUAL(I165C_TRANSMISSION_ATTEMPTS, tries);
289  TEST_ASSERT_EQUAL(false, ackReceived);
290 }
bool TEST_I165C_GetImdInfo(CAN_BUFFERELEMENT_s *canMessage)
void TEST_I165C_ResetCanData(CAN_BUFFERELEMENT_s *canMessage)
void TEST_I165C_ReadDataWord(uint8_t dataWord, uint16_t *data, CAN_BUFFERELEMENT_s canMessage)
bool TEST_I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *tries, CAN_BUFFERELEMENT_s *canMessage)
bool TEST_I165C_IsSelfTestFinished(CAN_BUFFERELEMENT_s canMessage)
void TEST_I165C_ReadDataByte(uint8_t dataByte, uint8_t *data, CAN_BUFFERELEMENT_s canMessage)
void TEST_I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *data, CAN_BUFFERELEMENT_s canMessage)
void TEST_I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFERELEMENT_s *canMessage)
bool TEST_I165C_CheckResponse(uint8_t command, CAN_BUFFERELEMENT_s *canMessage)
void TEST_I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFERELEMENT_s *canMessage)
Headers for the driver for the insulation monitoring.
#define I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO_SHIFT
#define I165C_INSULATION_MEASUREMENT_STATUS_SHIFT
#define I165C_DB2
#define I165C_TRANSMISSION_ATTEMPTS
#define I165C_MESSAGETYPE_IMD_INFO
#define I165C_DW2
#define I165C_SELFTEST_RUNNING_SHIFT
#define I165C_DB3
#define I165C_DW1
#define I165C_DB1
#define I165C_IMC_SELFTEST_OVERALL_SCENARIO_SHIFT
#define I165C_DW3
#define I165C_DB4
#define CAN_ID_IMD_INFO
Definition: can_cfg.h:212
#define CAN_ID_IMD_RESPONSE
Definition: can_cfg.h:216
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:76
@ OS_SUCCESS
Definition: os.h:78
uint8_t data[CAN_MAX_DLC]
Definition: can_cfg.h:307
Helper for unit tests.
#define TEST_ASSERT_FAIL_ASSERT(_code_under_test)
assert whether assert macro has failed
volatile bool ftsk_allQueuesCreated
void testMessageComposition(void)
Test function to compose/use CAN messages.
void setUp(void)
void tearDown(void)
QueueHandle_t ftsk_dataQueue
QueueHandle_t ftsk_canRxQueue
QueueHandle_t ftsk_imdCanDataQueue