FSIO testability and test-driven development
This commit is contained in:
parent
35ed0fc2a3
commit
8beae89bcb
|
@ -111,10 +111,7 @@ void Engine::periodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
checkShutdown();
|
||||
|
||||
#if EFI_FSIO || defined(__DOXYGEN__)
|
||||
// todo: enable this for unit tests
|
||||
#if ! EFI_UNIT_TEST
|
||||
runFsio(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
#endif
|
||||
#endif /* EFI_PROD_CODE && EFI_FSIO */
|
||||
|
||||
cylinderCleanupControl(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
|
@ -375,3 +372,9 @@ void Engine::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
engine->m.fuelCalcTime = GET_TIMESTAMP() - engine->m.beforeFuelCalc;
|
||||
|
||||
}
|
||||
|
||||
void doScheduleStopEngine(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||
engine->stopEngineRequestTimeNt = getTimeNowNt();
|
||||
// let's close injectors or else if these happen to be open right now
|
||||
enginePins.stopPins();
|
||||
}
|
||||
|
|
|
@ -94,6 +94,9 @@ public:
|
|||
* values are in Celsius
|
||||
*/
|
||||
float iat;
|
||||
#if EFI_UNIT_TEST
|
||||
float mockClt = NAN;
|
||||
#endif
|
||||
float clt;
|
||||
|
||||
/**
|
||||
|
@ -310,6 +313,7 @@ public:
|
|||
float fsioTimingAdjustment;
|
||||
float fsioIdleTargetRPMAdjustment;
|
||||
float servoValues[SERVO_COUNT];
|
||||
float fsioLastValue[FSIO_COMMAND_COUNT];
|
||||
|
||||
#if EFI_ENABLE_ENGINE_WARNING
|
||||
/**
|
||||
|
@ -364,8 +368,6 @@ public:
|
|||
FuelSchedule injectionEvents;
|
||||
#endif /* EFI_ENGINE_CONTROL */
|
||||
|
||||
float fsioLastValue[FSIO_COMMAND_COUNT];
|
||||
|
||||
WallFuel wallFuel;
|
||||
bool needToStopEngine(efitick_t nowNt);
|
||||
bool etbAutoTune;
|
||||
|
@ -592,5 +594,6 @@ void applyNonPersistentConfiguration(Logging * logger DECLARE_ENGINE_PARAMETER_S
|
|||
void prepareOutputSignals(DECLARE_ENGINE_PARAMETER_SIGNATURE);
|
||||
|
||||
void validateConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE);
|
||||
void doScheduleStopEngine(DECLARE_ENGINE_PARAMETER_SIGNATURE);
|
||||
|
||||
#endif /* H_ENGINE_H_ */
|
||||
|
|
|
@ -113,6 +113,11 @@ EngineState::EngineState() {
|
|||
void EngineState::updateSlowSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||
engine->sensors.iat = getIntakeAirTemperature(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
engine->sensors.clt = getCoolantTemperature(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
#if EFI_UNIT_TEST
|
||||
if (!cisnan(engine->sensors.mockClt)) {
|
||||
engine->sensors.clt = engine->sensors.mockClt;
|
||||
}
|
||||
#endif
|
||||
engine->sensors.oilPressure = getOilPressure(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
|
||||
warmupTargetAfr = interpolate2d("warm", engine->sensors.clt, engineConfiguration->warmupTargetAfrBins,
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
*/
|
||||
#define NO_PWM 0
|
||||
|
||||
#define MAGIC_OFFSET_FOR_ENGINE_WARNING 4
|
||||
#define MAGIC_OFFSET_FOR_CRITICAL_ENGINE 5
|
||||
|
||||
// see useFSIO15ForIdleRpmAdjustment
|
||||
#define MAGIC_OFFSET_FOR_IDLE_TARGET_RPM 14
|
||||
// see useFSIO16ForTimingAdjustment
|
||||
|
@ -322,7 +319,7 @@ float getFsioOutputValue(int index DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
|||
warning(CUSTOM_NO_FSIO, "no FSIO for #%d %s", index + 1, hwPortname(CONFIGB(fsioOutputPins)[index]));
|
||||
return NAN;
|
||||
} else {
|
||||
return calc.getValue2(engine->fsioLastValue[index], state.fsioLogics[index] PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
return calc.getValue2(engine->fsioState.fsioLastValue[index], state.fsioLogics[index] PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,14 +328,14 @@ float getFsioOutputValue(int index DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
|||
*/
|
||||
static void handleFsio(int index DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
if (CONFIGB(fsioOutputPins)[index] == GPIO_UNASSIGNED) {
|
||||
engine->fsioLastValue[index] = NAN;
|
||||
engine->fsioState.fsioLastValue[index] = NAN;
|
||||
return;
|
||||
}
|
||||
|
||||
bool isPwmMode = CONFIGB(fsioFrequency)[index] != NO_PWM;
|
||||
|
||||
float fvalue = getFsioOutputValue(index PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
engine->fsioLastValue[index] = fvalue;
|
||||
engine->fsioState.fsioLastValue[index] = fvalue;
|
||||
|
||||
if (isPwmMode) {
|
||||
fsioPwm[index].setSimplePwmDutyCycle(fvalue);
|
||||
|
@ -495,9 +492,7 @@ void runFsio(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
if (engineConfiguration->useFSIO5ForCriticalIssueEngineStop) {
|
||||
bool changed = updateValueOrWarning(MAGIC_OFFSET_FOR_CRITICAL_ENGINE, "eng critical", &ENGINE(fsioState.isCriticalEngineCondition) PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
if (changed && float2bool(ENGINE(fsioState.isCriticalEngineCondition))) {
|
||||
#if EFI_PROD_CODE || EFI_SIMULATOR
|
||||
scheduleStopEngine();
|
||||
#endif
|
||||
doScheduleStopEngine(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
}
|
||||
}
|
||||
#endif /* EFI_ENABLE_CRITICAL_ENGINE_STOP */
|
||||
|
@ -569,7 +564,7 @@ static void showFsioInfo(void) {
|
|||
*/
|
||||
scheduleMsg(logger, "FSIO #%d [%s] at %s@%dHz value=%.2f", (i + 1), exp,
|
||||
hwPortname(CONFIGB(fsioOutputPins)[i]), CONFIGB(fsioFrequency)[i],
|
||||
engine->fsioLastValue[i]);
|
||||
engine->fsioState.fsioLastValue[i]);
|
||||
// scheduleMsg(logger, "user-defined #%d value=%.2f", i, engine->engineConfigurationPtr2->fsioLastValue[i]);
|
||||
showFsio(NULL, state.fsioLogics[i]);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
typedef Map3D<FSIO_TABLE_8, FSIO_TABLE_8, float> fsio8_Map3D_f32t;
|
||||
typedef Map3D<FSIO_TABLE_8, FSIO_TABLE_8, uint8_t> fsio8_Map3D_u8t;
|
||||
|
||||
#define MAGIC_OFFSET_FOR_ENGINE_WARNING 4
|
||||
#define MAGIC_OFFSET_FOR_CRITICAL_ENGINE 5
|
||||
|
||||
float getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX);
|
||||
void setFsio(int index, brain_pin_e pin, const char * exp DECLARE_ENGINE_PARAMETER_SUFFIX);
|
||||
|
|
|
@ -975,9 +975,7 @@ static void disableSpi(int index) {
|
|||
* weird: we stop pins from here? we probably should stop engine from the code which is actually stopping engine?
|
||||
*/
|
||||
void scheduleStopEngine(void) {
|
||||
engine->stopEngineRequestTimeNt = getTimeNowNt();
|
||||
// let's close injectors or else if these happen to be open right now
|
||||
enginePins.stopPins();
|
||||
doScheduleStopEngine(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
}
|
||||
|
||||
static void printAllInfo(void) {
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
// Human-readable: vbatt < 14.5
|
||||
#define ALTERNATOR_LOGIC "vbatt 14.5 <"
|
||||
|
||||
// Human-readable: coolant > 120 (Celsius)
|
||||
#define TOO_HOT_LOGIC "coolant 120 >"
|
||||
|
||||
// Human-readable: ac_on_switch
|
||||
#define AC_RELAY_LOGIC "ac_on_switch"
|
||||
// Combined RPM, CLT and VBATT warning light
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
#include "engine_test_helper.h"
|
||||
#include "event_queue.h"
|
||||
#include "tps.h"
|
||||
#include "fsio_impl.h"
|
||||
|
||||
TEST(fuelCut, coasting) {
|
||||
printf("*************************************************** testCoastingFuelCut\r\n");
|
||||
|
||||
EngineTestHelper eth(TEST_ENGINE);
|
||||
EXPAND_EngineTestHelper
|
||||
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
||||
|
||||
// configure coastingFuelCut
|
||||
engineConfiguration->bc.coastingFuelCutEnabled = true;
|
||||
|
@ -95,3 +95,30 @@ TEST(fuelCut, coasting) {
|
|||
// Fuel cut-off is active again!
|
||||
assertEqualsM("inj dur#7 cut", 0.0f, ENGINE(injectionDuration));
|
||||
}
|
||||
|
||||
|
||||
TEST(fuelCut, criticalEngineTemperature) {
|
||||
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
||||
|
||||
setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð);
|
||||
|
||||
engineConfiguration->useFSIO5ForCriticalIssueEngineStop = true;
|
||||
setFsio(MAGIC_OFFSET_FOR_CRITICAL_ENGINE, GPIOD_7, TOO_HOT_LOGIC PASS_ENGINE_PARAMETER_SUFFIX);
|
||||
applyFsioConfiguration(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
|
||||
// we need some non-zero time as getTimeNow() which would become stopEngineRequestTimeNt
|
||||
eth.moveTimeForwardUs(1000);
|
||||
|
||||
engine->rpmCalculator.mockRpm = 2000;
|
||||
eth.engine.periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
eth.engine.periodicSlowCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
ASSERT_EQ(engine->stopEngineRequestTimeNt, 0);
|
||||
|
||||
ASSERT_FALSE(engine->stopEngineRequestTimeNt > 0);
|
||||
|
||||
engine->sensors.mockClt = 200; // 200C is really hot!
|
||||
eth.engine.periodicFastCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
eth.engine.periodicSlowCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
|
||||
ASSERT_TRUE(engine->stopEngineRequestTimeNt > 0);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
#define TEST_POOL_SIZE 256
|
||||
|
||||
static float mockCoolant;
|
||||
static float mockFan;
|
||||
static float mockRpm;
|
||||
static float mockCrankingRpm;
|
||||
|
@ -25,7 +24,7 @@ float getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
|||
case LE_METHOD_FAN:
|
||||
return mockFan;
|
||||
case LE_METHOD_COOLANT:
|
||||
return mockCoolant;
|
||||
return engine->sensors.clt;
|
||||
case LE_METHOD_RPM:
|
||||
return mockRpm;
|
||||
case LE_METHOD_CRANKING_RPM:
|
||||
|
@ -36,6 +35,8 @@ float getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
|||
return 0;
|
||||
case LE_METHOD_FAN_OFF_SETTING:
|
||||
return 0;
|
||||
case LE_METHOD_VBATT:
|
||||
return 12;
|
||||
default:
|
||||
firmwareError(OBD_PCM_Processor_Fault, "No mock value for %d", action);
|
||||
return NAN;
|
||||
|
@ -87,7 +88,7 @@ static void testParsing(void) {
|
|||
ASSERT_TRUE(element == NULL);
|
||||
}
|
||||
|
||||
static void testExpression2(float selfValue, const char *line, float expected) {
|
||||
static void testExpression2(float selfValue, const char *line, float expected, Engine *engine) {
|
||||
LEElement thepool[TEST_POOL_SIZE];
|
||||
LEElementPool pool(thepool, TEST_POOL_SIZE);
|
||||
LEElement * element = pool.parseExpression(line);
|
||||
|
@ -95,9 +96,14 @@ static void testExpression2(float selfValue, const char *line, float expected) {
|
|||
ASSERT_TRUE(element != NULL) << "Not NULL expected";
|
||||
LECalculator c;
|
||||
|
||||
WITH_ENGINE_TEST_HELPER(FORD_INLINE_6_1995);
|
||||
EXPAND_Engine;
|
||||
|
||||
assertEqualsM(line, expected, c.getValue2(selfValue, element PASS_ENGINE_PARAMETER_SUFFIX));
|
||||
ASSERT_EQ(expected, c.getValue2(selfValue, element PASS_ENGINE_PARAMETER_SUFFIX)) << line;
|
||||
}
|
||||
|
||||
static void testExpression2(float selfValue, const char *line, float expected) {
|
||||
WITH_ENGINE_TEST_HELPER(FORD_INLINE_6_1995);
|
||||
testExpression2(selfValue, line, expected, engine);
|
||||
}
|
||||
|
||||
static void testExpression(const char *line, float expected) {
|
||||
|
@ -108,6 +114,7 @@ TEST(misc, testLogicExpressions) {
|
|||
printf("*************************************************** testLogicExpressions\r\n");
|
||||
|
||||
testParsing();
|
||||
{
|
||||
|
||||
WITH_ENGINE_TEST_HELPER(FORD_INLINE_6_1995);
|
||||
|
||||
|
@ -163,17 +170,20 @@ TEST(misc, testLogicExpressions) {
|
|||
element = pool.parseExpression("fan no_such_method");
|
||||
ASSERT_TRUE(element == NULL) << "NULL expected";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* fan = (not fan && coolant > 90) OR (fan && coolant > 85)
|
||||
* fan = fan NOT coolant 90 AND more fan coolant 85 more AND OR
|
||||
*/
|
||||
|
||||
|
||||
mockFan = 0;
|
||||
mockCoolant = 100;
|
||||
|
||||
testExpression("coolant", 100);
|
||||
{
|
||||
WITH_ENGINE_TEST_HELPER(FORD_INLINE_6_1995);
|
||||
engine->sensors.mockClt = 100;
|
||||
engine->periodicSlowCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
testExpression2(0, "coolant 1 +", 101, engine);
|
||||
}
|
||||
testExpression("fan", 0);
|
||||
testExpression("fan not", 1);
|
||||
testExpression("coolant 90 >", 1);
|
||||
|
@ -186,6 +196,7 @@ TEST(misc, testLogicExpressions) {
|
|||
|
||||
testExpression("fan NOT coolant 90 > AND fan coolant 85 > AND OR", 1);
|
||||
{
|
||||
WITH_ENGINE_TEST_HELPER(FORD_INLINE_6_1995);
|
||||
LEElement thepool[TEST_POOL_SIZE];
|
||||
LEElementPool pool(thepool, TEST_POOL_SIZE);
|
||||
LEElement * element = pool.parseExpression("fan NOT coolant 90 > AND fan coolant 85 > AND OR");
|
||||
|
@ -198,7 +209,6 @@ TEST(misc, testLogicExpressions) {
|
|||
ASSERT_EQ(0, c.calcLogValue[0]);
|
||||
}
|
||||
|
||||
testExpression("coolant", 100);
|
||||
testExpression("fan_off_setting", 0);
|
||||
testExpression("coolant fan_off_setting >", 1);
|
||||
|
||||
|
|
Loading…
Reference in New Issue