Skip to content

Commit 58123c1

Browse files
committed
Test config layout
1 parent c70f2c5 commit 58123c1

4 files changed

Lines changed: 232 additions & 7 deletions

File tree

firmware/heater_thread.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static void HeaterThread(void*)
7474
// immediately think we overshot the target temperature
7575
chThdSleepMilliseconds(1000);
7676

77-
struct HeaterConfig configuration = GetConfiguration()->heaterConfig;
77+
struct HeaterConfig* configuration = &GetConfiguration()->heaterConfig;
7878

7979
// Configure heater controllers for sensor type
8080
for (int i = 0; i < AFR_CHANNELS; i++)
@@ -84,14 +84,14 @@ static void HeaterThread(void*)
8484
switch (GetSensorType())
8585
{
8686
case SensorType::LSU42:
87-
h.Configure(730, 80, &configuration);
87+
h.Configure(730, 80, configuration);
8888
break;
8989
case SensorType::LSUADV:
90-
h.Configure(785, 300, &configuration);
90+
h.Configure(785, 300, configuration);
9191
break;
9292
case SensorType::LSU49:
9393
default:
94-
h.Configure(780, 300, &configuration);
94+
h.Configure(780, 300, configuration);
9595
break;
9696
}
9797
}

test/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ CPPSRC += \
3030
test_stubs.cpp \
3131
tests/test_sampler.cpp \
3232
tests/test_heater.cpp \
33+
tests/test_config.cpp \
3334

3435
INCDIR += \
3536
$(PROJECT_DIR)/googletest/googlemock/ \

test/tests/test_config.cpp

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
#include <gtest/gtest.h>
2+
#include <gmock/gmock.h>
3+
4+
#include <cstring>
5+
#include "fixed_point.h"
6+
#include "port.h"
7+
8+
#pragma GCC diagnostic push
9+
#pragma GCC diagnostic ignored "-Wunused-const-variable"
10+
namespace ConfigSizes {
11+
constexpr size_t TAG = 4;
12+
constexpr size_t NO_LONGER_USED_0 = 1;
13+
constexpr size_t AUX_OUT_BINS = 64;
14+
constexpr size_t AUX_OUT_VALUES = 64;
15+
constexpr size_t AUX_OUTPUT_SOURCE = 2;
16+
constexpr size_t SENSOR_TYPE = 1;
17+
constexpr size_t AFR_CHANNEL = 8;
18+
constexpr size_t AFR_SETTINGS = AFR_CHANNEL * 2;
19+
constexpr size_t EGT_CHANNEL = 8;
20+
constexpr size_t EGT_SETTINGS = EGT_CHANNEL * 2;
21+
constexpr size_t HEATER_CONFIG = 8;
22+
}
23+
#pragma GCC diagnostic pop
24+
25+
template<typename T>
26+
void WriteAtOffset(Configuration& config, size_t offset, T value) {
27+
uint8_t* bytes = reinterpret_cast<uint8_t*>(&config);
28+
std::memcpy(bytes + offset, &value, sizeof(T));
29+
}
30+
31+
TEST(ConfigLayout, BinaryCompatibility_NoLongerUsed0) {
32+
Configuration config = {};
33+
34+
size_t offset = ConfigSizes::TAG;
35+
uint8_t expectedValue = 0x42;
36+
WriteAtOffset(config, offset, expectedValue);
37+
38+
EXPECT_EQ(config.NoLongerUsed0, expectedValue);
39+
}
40+
41+
TEST(ConfigLayout, BinaryCompatibility_AuxOutBins) {
42+
Configuration config = {};
43+
44+
size_t offset = ConfigSizes::TAG
45+
+ ConfigSizes::NO_LONGER_USED_0;
46+
47+
// Test auxOutBins[0]
48+
for (int i = 0; i < 8; i++) {
49+
float testValue = 10.0f + i;
50+
WriteAtOffset(config, offset + i * sizeof(float), testValue);
51+
}
52+
53+
for (int i = 0; i < 8; i++) {
54+
EXPECT_FLOAT_EQ(config.auxOutBins[0][i], 10.0f + i);
55+
}
56+
57+
// Test auxOutBins[1]
58+
offset += 8 * sizeof(float);
59+
for (int i = 0; i < 8; i++) {
60+
float testValue = 20.0f + i;
61+
WriteAtOffset(config, offset + i * sizeof(float), testValue);
62+
}
63+
64+
for (int i = 0; i < 8; i++) {
65+
EXPECT_FLOAT_EQ(config.auxOutBins[1][i], 20.0f + i);
66+
}
67+
}
68+
69+
TEST(ConfigLayout, BinaryCompatibility_AuxOutValues) {
70+
Configuration config = {};
71+
72+
size_t offset = ConfigSizes::TAG
73+
+ ConfigSizes::NO_LONGER_USED_0
74+
+ ConfigSizes::AUX_OUT_BINS;
75+
76+
for (int j = 0; j < 2; j++) {
77+
for (int i = 0; i < 8; i++) {
78+
float testValue = 100.0f + j * 10 + i;
79+
WriteAtOffset(config, offset + (j * 8 + i) * sizeof(float), testValue);
80+
}
81+
}
82+
83+
for (int j = 0; j < 2; j++) {
84+
for (int i = 0; i < 8; i++) {
85+
EXPECT_FLOAT_EQ(config.auxOutValues[j][i], 100.0f + j * 10 + i);
86+
}
87+
}
88+
}
89+
90+
TEST(ConfigLayout, BinaryCompatibility_AuxOutputSource) {
91+
Configuration config = {};
92+
93+
size_t offset = ConfigSizes::TAG
94+
+ ConfigSizes::NO_LONGER_USED_0
95+
+ ConfigSizes::AUX_OUT_BINS
96+
+ ConfigSizes::AUX_OUT_VALUES;
97+
98+
WriteAtOffset(config, offset, static_cast<uint8_t>(AuxOutputMode::Lambda0));
99+
WriteAtOffset(config, offset + 1, static_cast<uint8_t>(AuxOutputMode::Egt1));
100+
101+
EXPECT_EQ(config.auxOutputSource[0], AuxOutputMode::Lambda0);
102+
EXPECT_EQ(config.auxOutputSource[1], AuxOutputMode::Egt1);
103+
}
104+
105+
TEST(ConfigLayout, BinaryCompatibility_SensorType) {
106+
Configuration config = {};
107+
108+
size_t offset = ConfigSizes::TAG
109+
+ ConfigSizes::NO_LONGER_USED_0
110+
+ ConfigSizes::AUX_OUT_BINS
111+
+ ConfigSizes::AUX_OUT_VALUES
112+
+ ConfigSizes::AUX_OUTPUT_SOURCE;
113+
114+
WriteAtOffset(config, offset, static_cast<uint8_t>(SensorType::LSU42));
115+
116+
EXPECT_EQ(config.sensorType, SensorType::LSU42);
117+
}
118+
119+
TEST(ConfigLayout, BinaryCompatibility_AfrChannelSettings) {
120+
Configuration config = {};
121+
122+
size_t offset = ConfigSizes::TAG
123+
+ ConfigSizes::NO_LONGER_USED_0
124+
+ ConfigSizes::AUX_OUT_BINS
125+
+ ConfigSizes::AUX_OUT_VALUES
126+
+ ConfigSizes::AUX_OUTPUT_SOURCE
127+
+ ConfigSizes::SENSOR_TYPE;
128+
129+
// Write first AFR channel
130+
uint8_t bitfield0 = 0b00000111; // RusEfiTx=1, RusEfiTxDiag=1, AemNetTx=1
131+
WriteAtOffset(config, offset, bitfield0);
132+
WriteAtOffset(config, offset + 1, static_cast<uint8_t>(5)); // RusEfiIdx
133+
WriteAtOffset(config, offset + 2, static_cast<uint8_t>(10)); // AemNetIdOffset
134+
135+
EXPECT_TRUE(config.afr[0].RusEfiTx);
136+
EXPECT_TRUE(config.afr[0].RusEfiTxDiag);
137+
EXPECT_TRUE(config.afr[0].AemNetTx);
138+
EXPECT_EQ(config.afr[0].RusEfiIdx, 5);
139+
EXPECT_EQ(config.afr[0].AemNetIdOffset, 10);
140+
141+
// Write second AFR channel
142+
offset += ConfigSizes::AFR_CHANNEL;
143+
uint8_t bitfield1 = 0b00000010; // RusEfiTx=0, RusEfiTxDiag=1, AemNetTx=0
144+
WriteAtOffset(config, offset, bitfield1);
145+
WriteAtOffset(config, offset + 1, static_cast<uint8_t>(7)); // RusEfiIdx
146+
WriteAtOffset(config, offset + 2, static_cast<uint8_t>(15)); // AemNetIdOffset
147+
148+
EXPECT_FALSE(config.afr[1].RusEfiTx);
149+
EXPECT_TRUE(config.afr[1].RusEfiTxDiag);
150+
EXPECT_FALSE(config.afr[1].AemNetTx);
151+
EXPECT_EQ(config.afr[1].RusEfiIdx, 7);
152+
EXPECT_EQ(config.afr[1].AemNetIdOffset, 15);
153+
}
154+
155+
TEST(ConfigLayout, BinaryCompatibility_EgtChannelSettings) {
156+
Configuration config = {};
157+
158+
size_t offset = ConfigSizes::TAG
159+
+ ConfigSizes::NO_LONGER_USED_0
160+
+ ConfigSizes::AUX_OUT_BINS
161+
+ ConfigSizes::AUX_OUT_VALUES
162+
+ ConfigSizes::AUX_OUTPUT_SOURCE
163+
+ ConfigSizes::SENSOR_TYPE
164+
+ ConfigSizes::AFR_SETTINGS;
165+
166+
// Write first EGT channel
167+
uint8_t bitfield0 = 0b00000101; // RusEfiTx=1, RusEfiTxDiag=0, AemNetTx=1
168+
WriteAtOffset(config, offset, bitfield0);
169+
WriteAtOffset(config, offset + 1, static_cast<uint8_t>(3)); // RusEfiIdx
170+
WriteAtOffset(config, offset + 2, static_cast<uint8_t>(8)); // AemNetIdOffset
171+
172+
EXPECT_TRUE(config.egt[0].RusEfiTx);
173+
EXPECT_FALSE(config.egt[0].RusEfiTxDiag);
174+
EXPECT_TRUE(config.egt[0].AemNetTx);
175+
EXPECT_EQ(config.egt[0].RusEfiIdx, 3);
176+
EXPECT_EQ(config.egt[0].AemNetIdOffset, 8);
177+
178+
// Write second EGT channel
179+
offset += ConfigSizes::EGT_CHANNEL;
180+
uint8_t bitfield1 = 0b00000010; // RusEfiTx=0, RusEfiTxDiag=1, AemNetTx=0
181+
WriteAtOffset(config, offset, bitfield1);
182+
WriteAtOffset(config, offset + 1, static_cast<uint8_t>(7)); // RusEfiIdx
183+
WriteAtOffset(config, offset + 2, static_cast<uint8_t>(15)); // AemNetIdOffset
184+
185+
EXPECT_FALSE(config.egt[1].RusEfiTx);
186+
EXPECT_TRUE(config.egt[1].RusEfiTxDiag);
187+
EXPECT_FALSE(config.egt[1].AemNetTx);
188+
EXPECT_EQ(config.egt[1].RusEfiIdx, 7);
189+
EXPECT_EQ(config.egt[1].AemNetIdOffset, 15);
190+
}
191+
192+
TEST(ConfigLayout, BinaryCompatibility_HeaterConfig) {
193+
Configuration config = {};
194+
195+
size_t offset = ConfigSizes::TAG
196+
+ ConfigSizes::NO_LONGER_USED_0
197+
+ ConfigSizes::AUX_OUT_BINS
198+
+ ConfigSizes::AUX_OUT_VALUES
199+
+ ConfigSizes::AUX_OUTPUT_SOURCE
200+
+ ConfigSizes::SENSOR_TYPE
201+
+ ConfigSizes::AFR_SETTINGS
202+
+ ConfigSizes::EGT_SETTINGS;
203+
204+
WriteAtOffset(config, offset, static_cast<uint8_t>(120)); // HeaterSupplyOffVoltage
205+
WriteAtOffset(config, offset + 1, static_cast<uint8_t>(135)); // HeaterSupplyOnVoltage
206+
WriteAtOffset(config, offset + 2, static_cast<uint8_t>(50)); // HeaterBatteryStabTime
207+
WriteAtOffset(config, offset + 3, static_cast<uint16_t>(180)); // PreheatTimeSec
208+
WriteAtOffset(config, offset + 5, static_cast<uint16_t>(240)); // WarmupTimeSec
209+
210+
EXPECT_FLOAT_EQ(config.heaterConfig.HeaterSupplyOffVoltage.getValue(), 12.0f);
211+
EXPECT_FLOAT_EQ(config.heaterConfig.HeaterSupplyOnVoltage.getValue(), 13.5f);
212+
EXPECT_FLOAT_EQ(config.heaterConfig.HeaterBatteryStabTime.getValue(), 5.0f);
213+
EXPECT_EQ(config.heaterConfig.PreheatTimeSec, 180);
214+
EXPECT_EQ(config.heaterConfig.WarmupTimeSec, 240);
215+
}
216+
217+
TEST(ConfigLayout, SizeVerification) {
218+
// Verify the total size is exactly 256 bytes
219+
EXPECT_EQ(sizeof(Configuration), 256UL);
220+
221+
// Verify union size
222+
Configuration config;
223+
EXPECT_EQ(sizeof(config.pad), 252UL); // 256 - 4 (Tag size)
224+
}

test/tests/test_heater.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
struct MockConfiguration {
88
struct HeaterConfig heaterConfig {
9-
.HeaterSupplyOffVoltage = 6,
10-
.HeaterSupplyOnVoltage = 11,
11-
.HeaterBatteryStabTime = 20,
9+
.HeaterSupplyOffVoltage = { 60 }, // 6.0V
10+
.HeaterSupplyOnVoltage = { 110 }, // 11.0V
11+
.HeaterBatteryStabTime = { 20 }, // 2.0s
1212
.PreheatTimeSec = 5,
1313
.WarmupTimeSec = 10,
1414
.pad = {0},

0 commit comments

Comments
 (0)