From de0fb8aa92d369802efd8b5e3641d896a59b6452 Mon Sep 17 00:00:00 2001 From: rusefi Date: Sun, 10 Feb 2019 23:54:41 -0500 Subject: [PATCH] wider usage of PeriodicController --- firmware/config/stm32f4ems/chconf.h | 6 ++++ firmware/controllers/algo/aux_pid.cpp | 27 +++++++------- firmware/controllers/alternatorController.cpp | 29 +++++++-------- firmware/controllers/electronic_throttle.cpp | 4 +-- firmware/controllers/injector_central.cpp | 32 ++++++++--------- .../controllers/malfunction_indicator.cpp | 35 ++++++++++--------- .../controllers/system/PeriodicController.h | 3 ++ 7 files changed, 70 insertions(+), 66 deletions(-) diff --git a/firmware/config/stm32f4ems/chconf.h b/firmware/config/stm32f4ems/chconf.h index 2d56c53427..936af6356b 100644 --- a/firmware/config/stm32f4ems/chconf.h +++ b/firmware/config/stm32f4ems/chconf.h @@ -35,7 +35,12 @@ #define _CHIBIOS_RT_CONF_VER_5_1_ #define PORT_IDLE_THREAD_STACK_SIZE 1024 + +// rusEfi main processing happens on IRQ so PORT_INT_REQUIRED_STACK has to be pretty large. +// see also a strange comment about PORT_INT_REQUIRED_STACK in global_shared.h +// see also http://www.chibios.org/dokuwiki/doku.php?id=chibios:kb:stacks #define PORT_INT_REQUIRED_STACK 768 + #define CHPRINTF_USE_FLOAT TRUE #if !defined(EFI_CLOCK_LOCKS) || defined(__DOXYGEN__) @@ -613,6 +618,7 @@ extern "C" * * @note The default is @p FALSE. */ +// see also CH_DBG_STACK_FILL_VALUE #if !defined(CH_DBG_FILL_THREADS) #define CH_DBG_FILL_THREADS TRUE #endif diff --git a/firmware/controllers/algo/aux_pid.cpp b/firmware/controllers/algo/aux_pid.cpp index 1d3cbc5c63..63b3543344 100644 --- a/firmware/controllers/algo/aux_pid.cpp +++ b/firmware/controllers/algo/aux_pid.cpp @@ -17,6 +17,7 @@ #include "fsio_impl.h" #include "engine_math.h" #include "pin_repository.h" +#include "PeriodicController.h" EXTERN_ENGINE ; @@ -30,8 +31,6 @@ extern fsio8_Map3D_f32t fsioTable1; extern TunerStudioOutputChannels tsOutputChannels; #endif /* EFI_TUNER_STUDIO */ -static THD_WORKING_AREA(auxPidThreadStack, UTILITY_THREAD_STACK_SIZE); - static LocalVersionHolder parametersVersion; static SimplePwm auxPidPwm[AUX_PID_COUNT]; static OutputPin auxPidPin[AUX_PID_COUNT]; @@ -58,11 +57,12 @@ static void pidReset(void) { auxPid.reset(); } -static msg_t auxPidThread(int param) { - UNUSED(param); - chRegSetThreadName("AuxPidController"); - while (true) { - auxPid.sleep(); +class AuxPidController : public PeriodicController { +public: + AuxPidController() : PeriodicController("AuxPidController") { } +private: + void PeriodicTask(efitime_t nowNt) override { + setPeriod(NOT_TOO_OFTEN(10 /* ms */, engineConfiguration->auxPid[0].periodMs)); if (parametersVersion.isOld(engine->getGlobalConfigurationVersion())) { pidReset(); @@ -76,7 +76,7 @@ static msg_t auxPidThread(int param) { if (!enabledAtCurrentRpm) { // we need to avoid accumulating iTerm while engine is not running pidReset(); - continue; + return; } @@ -101,10 +101,9 @@ static msg_t auxPidThread(int param) { } -#if defined __GNUC__ - return -1; -#endif -} +}; + +static AuxPidController instance; static void turnAuxPidOn(int index) { if (!isEnabled(index)) { @@ -135,12 +134,10 @@ void stopAuxPins(void) { } void initAuxPid(Logging *sharedLogger) { - chThdCreateStatic(auxPidThreadStack, sizeof(auxPidThreadStack), LOWPRIO, - (tfunc_t)(void*) auxPidThread, NULL); - logger = sharedLogger; startAuxPins(); + instance.Start(); } #endif diff --git a/firmware/controllers/alternatorController.cpp b/firmware/controllers/alternatorController.cpp index 3b6c7f8681..b10204e08e 100644 --- a/firmware/controllers/alternatorController.cpp +++ b/firmware/controllers/alternatorController.cpp @@ -13,6 +13,7 @@ #include "voltage.h" #include "pid.h" #include "LocalVersionHolder.h" +#include "PeriodicController.h" #if EFI_ALTERNATOR_CONTROL || defined(__DOXYGEN__) #include "pwm_generator.h" @@ -28,8 +29,6 @@ static SimplePwm alternatorControl("alt"); static pid_s *altPidS = &persistentState.persistentConfiguration.engineConfiguration.alternatorControl; static Pid altPid(altPidS); -static THD_WORKING_AREA(alternatorControlThreadStack, UTILITY_THREAD_STACK_SIZE); - static percent_t currentAltDuty; #if EFI_TUNER_STUDIO || defined(__DOXYGEN__) @@ -43,10 +42,13 @@ static void pidReset(void) { altPid.reset(); } -static msg_t AltCtrlThread(int param) { - UNUSED(param); - chRegSetThreadName("AlternatorController"); - while (true) { +class AlternatorController : public PeriodicController { +public: + AlternatorController() : PeriodicController("AlternatorController") { } +private: + void PeriodicTask(efitime_t nowNt) override { + setPeriod(NOT_TOO_OFTEN(10 /* ms */, engineConfiguration->alternatorControl.periodMs)); + #if ! EFI_UNIT_TEST || defined(__DOXYGEN__) if (shouldResetPid) { pidReset(); @@ -54,8 +56,6 @@ static msg_t AltCtrlThread(int param) { } #endif - altPid.sleep(); - if (engineConfiguration->debugMode == DBG_ALTERNATOR_PID) { // this block could be executed even in on/off alternator control mode // but at least we would reflect latest state @@ -71,7 +71,7 @@ static msg_t AltCtrlThread(int param) { if (!engine->isAlternatorControlEnabled) { // we need to avoid accumulating iTerm while engine is not running pidReset(); - continue; + return; } float vBatt = getVBatt(PASS_ENGINE_PARAMETER_SIGNATURE); @@ -88,7 +88,7 @@ static msg_t AltCtrlThread(int param) { #endif /* EFI_TUNER_STUDIO */ } - continue; + return; } @@ -101,11 +101,9 @@ static msg_t AltCtrlThread(int param) { alternatorControl.setSimplePwmDutyCycle(currentAltDuty / 100); } -#if defined __GNUC__ - return -1; -#endif -} +}; +static AlternatorController instance; void showAltInfo(void) { scheduleMsg(logger, "alt=%s @%s t=%dms", boolToString(engineConfiguration->isAlternatorControlEnabled), @@ -169,8 +167,7 @@ void initAlternatorCtrl(Logging *sharedLogger) { &enginePins.alternatorPin, engineConfiguration->alternatorPwmFrequency, 0.1, applyAlternatorPinState); } - chThdCreateStatic(alternatorControlThreadStack, sizeof(alternatorControlThreadStack), LOWPRIO, - (tfunc_t)(void*) AltCtrlThread, NULL); + instance.Start(); } #endif /* EFI_ALTERNATOR_CONTROL */ diff --git a/firmware/controllers/electronic_throttle.cpp b/firmware/controllers/electronic_throttle.cpp index e7917b2823..98b751721b 100644 --- a/firmware/controllers/electronic_throttle.cpp +++ b/firmware/controllers/electronic_throttle.cpp @@ -106,6 +106,8 @@ public: EtbController() : PeriodicController("ETB") { } private: void PeriodicTask(efitime_t nowNt) override { + setPeriod(NOT_TOO_OFTEN(10 /* ms */, engineConfiguration->etb.periodMs)); + // set debug_mode 17 if (engineConfiguration->debugMode == DBG_ELECTRONIC_THROTTLE_PID) { @@ -368,8 +370,6 @@ void initElectronicThrottle(void) { pid.reset(); - int periodMs = maxI(10, engineConfiguration->etb.periodMs); - etbController.setPeriod(periodMs); etbController.Start(); } diff --git a/firmware/controllers/injector_central.cpp b/firmware/controllers/injector_central.cpp index 537e8ec052..948065a230 100644 --- a/firmware/controllers/injector_central.cpp +++ b/firmware/controllers/injector_central.cpp @@ -34,6 +34,7 @@ #include "efiGpio.h" #include "settings.h" #include "idle_thread.h" +#include "PeriodicController.h" EXTERN_ENGINE ; @@ -214,25 +215,22 @@ void dizzyBench(void) { pinbench("300", "5", "400", "3", &enginePins.dizzyOutput, engineConfiguration->dizzySparkOutputPin); } +class BenchController : public PeriodicController { +public: + BenchController() : PeriodicController("BenchThread") { } +private: + void PeriodicTask(efitime_t nowNt) override { + setPeriod(NOT_TOO_OFTEN(10 /* ms */, engineConfiguration->auxPid[0].periodMs)); -static THD_WORKING_AREA(benchThreadStack, UTILITY_THREAD_STACK_SIZE); - -static msg_t benchThread(int param) { - (void) param; - chRegSetThreadName("BenchThread"); - - while (true) { // naive inter-thread communication - waiting for a flag - while (!isBenchTestPending) { - chThdSleepMilliseconds(200); + if (isBenchTestPending) { + isBenchTestPending = false; + runBench(brainPin, pinX, delayMs, onTime, offTime, count); } - isBenchTestPending = false; - runBench(brainPin, pinX, delayMs, onTime, offTime, count); } -#if defined __GNUC__ - return 0; -#endif -} +}; + +static BenchController instance; void OutputPin::unregisterOutput(brain_pin_e oldPin, brain_pin_e newPin) { if (oldPin != GPIO_UNASSIGNED && oldPin != newPin) { @@ -276,7 +274,6 @@ void runBenchTest(uint16_t subsystem, uint16_t index) { void initInjectorCentral(Logging *sharedLogger) { logger = sharedLogger; - chThdCreateStatic(benchThreadStack, sizeof(benchThreadStack), NORMALPRIO, (tfunc_t)(void*) benchThread, NULL); for (int i = 0; i < INJECTION_PIN_COUNT; i++) { is_injector_enabled[i] = true; @@ -301,6 +298,9 @@ void initInjectorCentral(Logging *sharedLogger) { addConsoleActionSSSSS("fuelbench2", fuelbench2); addConsoleActionSSSSS("sparkbench2", sparkbench2); + + instance.setPeriod(200 /*ms*/); + instance.Start(); } #endif diff --git a/firmware/controllers/malfunction_indicator.cpp b/firmware/controllers/malfunction_indicator.cpp index e450c2b1e7..21bd7f14a1 100644 --- a/firmware/controllers/malfunction_indicator.cpp +++ b/firmware/controllers/malfunction_indicator.cpp @@ -30,9 +30,12 @@ #include "malfunction_central.h" #include "malfunction_indicator.h" #include "efiGpio.h" +#include "PeriodicController.h" #if EFI_MALFUNCTION_INDICATOR || defined(__DOXYGEN__) +#define TEST_MIL_CODE FALSE + EXTERN_ENGINE; #define MFI_LONG_BLINK 1500 @@ -40,8 +43,6 @@ EXTERN_ENGINE; #define MFI_BLINK_SEPARATOR 400 #define MFI_CHECKENGINE_LIGHT 10000 -static THD_WORKING_AREA(mfiThreadStack, UTILITY_THREAD_STACK_SIZE); // declare thread - static void blink_digits(int digit, int duration) { for (int iter = 0; iter < digit; iter++) { enginePins.checkEnginePin.setValue(0); @@ -78,18 +79,12 @@ static void DisplayErrorCode(int length, int code) { } } -// our main thread for show check engine error -#if defined __GNUC__ -__attribute__((noreturn)) static msg_t mfiThread(void) -#else - static msg_t mfiThread(void) -#endif - { - chRegSetThreadName("MFIndicator"); - error_codes_set_s localErrorCopy; - - while (true) { - chThdSleepSeconds(10); +class MILController : public PeriodicController { +public: + MILController() : PeriodicController("MFIndicator") { } +private: + void PeriodicTask(efitime_t nowNt) override { + static error_codes_set_s localErrorCopy; getErrorCodes(&localErrorCopy); for (int p = 0; p < localErrorCopy.count; p++) { @@ -98,12 +93,16 @@ __attribute__((noreturn)) static msg_t mfiThread(void) DisplayErrorCode(DigitLength(code), code); } } -} +}; +static MILController instance; + +#if TEST_MIL_CODE static void testMil(void) { addError(OBD_Engine_Coolant_Temperature_Circuit_Malfunction); addError(OBD_Intake_Air_Temperature_Circuit_Malfunction); } +#endif /* TEST_MIL_CODE */ bool isMilEnabled() { return CONFIGB(malfunctionIndicatorPin) != GPIO_UNASSIGNED; @@ -113,10 +112,12 @@ void initMalfunctionIndicator(void) { if (!isMilEnabled()) { return; } - // create static thread - chThdCreateStatic(mfiThreadStack, sizeof(mfiThreadStack), LOWPRIO, (tfunc_t)(void*) mfiThread, NULL); + instance.setPeriod(10); + instance.Start(); +#if TEST_MIL_CODE addConsoleAction("testmil", testMil); +#endif /* TEST_MIL_CODE */ } #endif /* EFI_MALFUNCTION_INDICATOR */ diff --git a/firmware/controllers/system/PeriodicController.h b/firmware/controllers/system/PeriodicController.h index 500b8d9012..7bc43657d2 100644 --- a/firmware/controllers/system/PeriodicController.h +++ b/firmware/controllers/system/PeriodicController.h @@ -98,3 +98,6 @@ public: this->m_period = CH_CFG_ST_FREQUENCY / frequencyHz; } }; + +// let's make sure period is not below specified threshold +#define NOT_TOO_OFTEN(threshold, value) maxI(threshold, value)