Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | /* | |||
2 | * @file logicdata_csv_reader.cpp | |||
3 | * | |||
4 | * @date Jun 26, 2021 | |||
5 | * @author Andrey Belomutskiy, (c) 2012-2021 | |||
6 | */ | |||
7 | ||||
8 | #include "pch.h" | |||
9 | #include "logicdata_csv_reader.h" | |||
10 | #include "unit_test_logger.h" | |||
11 | ||||
12 | 852829 | static char* trim(char *str) { | ||
13 |
3/4✓ Branch 0 taken 980287 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 127458 times.
✓ Branch 3 taken 852829 times.
|
0/1? Decision couldn't be analyzed.
|
980287 | while (str != nullptr && str[0] == ' ') { |
14 | 127458 | str++; | ||
15 | } | |||
16 | 852829 | return str; | ||
17 | } | |||
18 | ||||
19 | 67 | CsvReader::~CsvReader() { | ||
20 |
1/2✓ Branch 0 taken 67 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 67 times.
✗ Decision 'false' not taken.
|
67 | if (fp) { |
21 | 67 | fclose(fp); | ||
22 | } | |||
23 | 67 | } | ||
24 | ||||
25 | 67 | void CsvReader::open(const char *fileName, const int* triggerColumnIndeces, const int *vvtColumnIndeces) { | ||
26 | 67 | printf("Reading from %s\r\n", fileName); | ||
27 | 67 | fp = fopen(fileName, "r"); | ||
28 | 67 | this->triggerColumnIndeces = triggerColumnIndeces; | ||
29 | 67 | this->vvtColumnIndeces = vvtColumnIndeces; | ||
30 |
2/8✗ Branch 5 not taken.
✓ Branch 6 taken 67 times.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✓ Branch 30 taken 67 times.
✗ Branch 31 not taken.
|
67 | ASSERT_TRUE(fp != nullptr); | |
31 | } | |||
32 | ||||
33 | 416308 | bool CsvReader::haveMore() { | ||
34 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 416308 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 416308 times.
|
416308 | if (fp == nullptr) { |
35 | ✗ | throw std::runtime_error("No file"); | ||
36 | } | |||
37 | 416308 | bool result = fgets(buffer, sizeof(buffer), fp) != nullptr; | ||
38 | 416308 | m_lineIndex++; | ||
39 |
2/2✓ Branch 0 taken 67 times.
✓ Branch 1 taken 416241 times.
|
2/2✓ Decision 'true' taken 67 times.
✓ Decision 'false' taken 416241 times.
|
416308 | if (m_lineIndex == 0) { |
40 | // skip header | |||
41 | 67 | return haveMore(); | ||
42 | } | |||
43 | ||||
44 | 416241 | return result; | ||
45 | } | |||
46 | ||||
47 | static const char COMMA_SEPARATOR[2] = ","; | |||
48 | ||||
49 | #define readFirstTokenAndRememberInputString(input) trim(strtok(input, COMMA_SEPARATOR)) | |||
50 | #define readNextToken() trim(strtok(nullptr, COMMA_SEPARATOR)) | |||
51 | ||||
52 | /** | |||
53 | * @param values reference of values array to modify | |||
54 | * @return timestamp of current line | |||
55 | */ | |||
56 | 355156 | double CsvReader::readTimestampAndValues(double *values) { | ||
57 | 355156 | char *timeStampstr = readFirstTokenAndRememberInputString(buffer); | ||
58 |
2/2✓ Branch 3 taken 355156 times.
✓ Branch 6 taken 355156 times.
|
1065468 | double timeStamp = std::stod(timeStampstr); | |
59 | ||||
60 |
2/2✓ Branch 0 taken 355156 times.
✓ Branch 1 taken 355156 times.
|
2/2✓ Decision 'true' taken 355156 times.
✓ Decision 'false' taken 355156 times.
|
710312 | for (size_t i = 0; i < m_triggerCount; i++) { |
61 | 355156 | char *triggerToken = readNextToken(); | ||
62 |
2/2✓ Branch 3 taken 355156 times.
✓ Branch 6 taken 355156 times.
|
1065468 | values[i] = std::stod(triggerToken); | |
63 | } | |||
64 | ||||
65 | 355156 | return timeStamp; | ||
66 | } | |||
67 | ||||
68 | // this is about TS logs generated during trigger tests and viewing these files by humans. | |||
69 | // Emulate 500Hz refresh rate | |||
70 | #define TIME_DELTA (1.0/500.0) | |||
71 | ||||
72 | // todo: separate trigger handling from csv file processing, maybe reuse 'readTimestampAndValues'? | |||
73 | 61018 | void CsvReader::processLine(EngineTestHelper *eth) { | ||
74 | 61018 | Engine *engine = ð->engine; | ||
75 | ||||
76 | 61018 | const char s[2] = ","; | ||
77 | 61018 | char *timeStampstr = readFirstTokenAndRememberInputString(buffer); | ||
78 | ||||
79 |
2/2✓ Branch 0 taken 976 times.
✓ Branch 1 taken 61018 times.
|
2/2✓ Decision 'true' taken 976 times.
✓ Decision 'false' taken 61018 times.
|
61994 | for (int i = 0;i<readingOffset;i++) { |
80 | 976 | readNextToken(); | ||
81 | } | |||
82 | ||||
83 | 61018 | bool newTriggerState[TRIGGER_INPUT_PIN_COUNT]; | ||
84 | 61018 | bool newVvtState[CAM_INPUTS_COUNT]; | ||
85 | ||||
86 |
2/2✓ Branch 0 taken 62105 times.
✓ Branch 1 taken 61018 times.
|
2/2✓ Decision 'true' taken 62105 times.
✓ Decision 'false' taken 61018 times.
|
123123 | for (size_t i = 0;i<m_triggerCount;i++) { |
87 | 62105 | char * triggerToken = readNextToken(); | ||
88 | 62105 | newTriggerState[triggerColumnIndeces[i]] = triggerToken[0] == '1'; | ||
89 | } | |||
90 | ||||
91 |
2/2✓ Branch 0 taken 18418 times.
✓ Branch 1 taken 61018 times.
|
2/2✓ Decision 'true' taken 18418 times.
✓ Decision 'false' taken 61018 times.
|
79436 | for (size_t i = 0;i<m_vvtCount;i++) { |
92 | 18418 | char *vvtToken = readNextToken(); | ||
93 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18418 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 18418 times.
|
18418 | if (vvtToken == nullptr) { |
94 | ✗ | criticalError("Null token in [%s]", buffer); | ||
95 | } | |||
96 | 18418 | bool state = vvtToken[0] == '1'; | ||
97 | 18418 | newVvtState[vvtColumnIndeces[i]] = state; | ||
98 | } | |||
99 | ||||
100 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 61018 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 61018 times.
|
61018 | if (timeStampstr == nullptr) { |
101 | ✗ | criticalError("End of File"); | ||
102 | ✗ | return; | ||
103 | } | |||
104 | ||||
105 |
2/2✓ Branch 3 taken 61018 times.
✓ Branch 6 taken 61018 times.
|
183054 | double timeStamp = std::stod(timeStampstr); | |
106 | 61018 | history.add(timeStamp); | ||
107 | ||||
108 | 61018 | timeStamp += m_timestampOffset; | ||
109 | ||||
110 | #ifdef TIME_DELTA | |||
111 | // Fill the gap | |||
112 |
2/2✓ Branch 0 taken 461936 times.
✓ Branch 1 taken 61018 times.
|
2/2✓ Decision 'true' taken 461936 times.
✓ Decision 'false' taken 61018 times.
|
522954 | while (lastTimeStamp + TIME_DELTA < timeStamp) { |
113 | 461936 | lastTimeStamp += TIME_DELTA; | ||
114 |
1/1✓ Branch 1 taken 461936 times.
|
461936 | eth->setTimeAndInvokeEventsUs(1'000'000 * lastTimeStamp); | |
115 |
1/1✓ Branch 1 taken 461936 times.
|
461936 | writeUnitTestLogLine(); | |
116 | } | |||
117 | #endif | |||
118 | ||||
119 |
1/1✓ Branch 1 taken 61018 times.
|
61018 | eth->setTimeAndInvokeEventsUs(1'000'000 * timeStamp); | |
120 |
2/2✓ Branch 0 taken 62105 times.
✓ Branch 1 taken 61018 times.
|
2/2✓ Decision 'true' taken 62105 times.
✓ Decision 'false' taken 61018 times.
|
123123 | for (size_t index = 0; index < m_triggerCount; index++) { |
121 |
2/2✓ Branch 2 taken 5637 times.
✓ Branch 3 taken 56468 times.
|
2/2✓ Decision 'true' taken 5637 times.
✓ Decision 'false' taken 56468 times.
|
62105 | if (currentState[index] == newTriggerState[index]) { |
122 | 5637 | continue; | ||
123 | } | |||
124 | ||||
125 |
1/1✓ Branch 1 taken 56468 times.
|
56468 | efitick_t nowNt = getTimeNowNt(); | |
126 | 56468 | bool state = newTriggerState[index] ^ flipOnRead; | ||
127 |
1/1✓ Branch 1 taken 56468 times.
|
56468 | hwHandleShaftSignal(index, state, nowNt); | |
128 | ||||
129 | 56468 | currentState[index] = newTriggerState[index]; | ||
130 | } | |||
131 | ||||
132 |
2/2✓ Branch 0 taken 18418 times.
✓ Branch 1 taken 61018 times.
|
2/2✓ Decision 'true' taken 18418 times.
✓ Decision 'false' taken 61018 times.
|
79436 | for (size_t vvtIndex = 0; vvtIndex < m_vvtCount ; vvtIndex++) { |
133 |
2/2✓ Branch 2 taken 15535 times.
✓ Branch 3 taken 2883 times.
|
2/2✓ Decision 'true' taken 15535 times.
✓ Decision 'false' taken 2883 times.
|
18418 | if (currentVvtState[vvtIndex] == newVvtState[vvtIndex]) { |
134 | 15535 | continue; | ||
135 | } | |||
136 | ||||
137 |
1/1✓ Branch 1 taken 2883 times.
|
2883 | efitick_t nowNt = getTimeNowNt(); | |
138 | 2883 | bool state = newVvtState[vvtIndex] ^ flipVvtOnRead; | ||
139 | ||||
140 | // todo: configurable selection of vvt mode - dual bank or dual cam single bank | |||
141 | int bankIndex; | |||
142 | int camIndex; | |||
143 |
2/2✓ Branch 0 taken 2467 times.
✓ Branch 1 taken 416 times.
|
2/2✓ Decision 'true' taken 2467 times.
✓ Decision 'false' taken 416 times.
|
2883 | if (twoBanksSingleCamMode) { |
144 | 2467 | bankIndex = vvtIndex; | ||
145 | 2467 | camIndex = 0; | ||
146 | } else { | |||
147 | 416 | bankIndex = vvtIndex / 2; | ||
148 | 416 | camIndex = vvtIndex % 2; | ||
149 | } | |||
150 |
1/1✓ Branch 1 taken 2883 times.
|
2883 | hwHandleVvtCamSignal(state, nowNt, bankIndex *2 + camIndex); | |
151 | ||||
152 | 2883 | currentVvtState[vvtIndex] = newVvtState[vvtIndex]; | ||
153 | ||||
154 | } | |||
155 |
1/1✓ Branch 1 taken 61018 times.
|
61018 | writeUnitTestLogLine(); | |
156 | 61018 | lastTimeStamp = timeStamp; | ||
157 | } | |||
158 | ||||
159 | 84 | void CsvReader::readLine(EngineTestHelper *eth) { | ||
160 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 84 times.
|
84 | if (!haveMore()) |
161 | ✗ | return; | ||
162 | 84 | processLine(eth); | ||
163 | 84 | engine->periodicSlowCallback(); | ||
164 | } | |||
165 |