mirror of https://github.com/rusefi/rusefi-1.git
force a pwm cycle start (skip cycles) if late (#2097)
* skip cycles if late * fail at lower count * start at -1
This commit is contained in:
parent
f37c318c04
commit
7277b04039
|
@ -160,13 +160,15 @@ void PwmConfig::handleCycleStart() {
|
|||
|
||||
efiAssertVoid(CUSTOM_ERR_6580, periodNt != 0, "period not initialized");
|
||||
efiAssertVoid(CUSTOM_ERR_6580, iterationLimit > 0, "iterationLimit invalid");
|
||||
if (safe.periodNt != periodNt || safe.iteration == iterationLimit) {
|
||||
if (forceCycleStart || safe.periodNt != periodNt || safe.iteration == iterationLimit) {
|
||||
/**
|
||||
* period length has changed - we need to reset internal state
|
||||
*/
|
||||
safe.startNt = getTimeNowNt();
|
||||
safe.iteration = 0;
|
||||
safe.periodNt = periodNt;
|
||||
|
||||
forceCycleStart = false;
|
||||
#if DEBUG_PWM
|
||||
scheduleMsg(&logger, "state reset start=%d iteration=%d", state->safe.start, state->safe.iteration);
|
||||
#endif
|
||||
|
@ -225,10 +227,18 @@ efitick_t PwmConfig::togglePwmState() {
|
|||
scheduleMsg(&logger, "%s: nextSwitchTime %d", state->name, nextSwitchTime);
|
||||
#endif /* DEBUG_PWM */
|
||||
|
||||
// If we're very far behind schedule, restart the cycle fresh to avoid scheduling a huge pile of events all at once
|
||||
// This can happen during config write or debugging where CPU is halted for multiple seconds
|
||||
bool isVeryBehindSchedule = nextSwitchTimeNt < getTimeNowNt() - MS2NT(10);
|
||||
|
||||
safe.phaseIndex++;
|
||||
if (safe.phaseIndex == phaseCount || mode != PM_NORMAL) {
|
||||
if (isVeryBehindSchedule || safe.phaseIndex == phaseCount || mode != PM_NORMAL) {
|
||||
safe.phaseIndex = 0; // restart
|
||||
safe.iteration++;
|
||||
|
||||
if (isVeryBehindSchedule) {
|
||||
forceCycleStart = true;
|
||||
}
|
||||
}
|
||||
#if EFI_UNIT_TEST
|
||||
printf("PWM: nextSwitchTimeNt=%d phaseIndex=%d iteration=%d\r\n", nextSwitchTimeNt,
|
||||
|
|
|
@ -110,6 +110,9 @@ private:
|
|||
* PWM generation is not happening while this value is NAN
|
||||
*/
|
||||
float periodNt;
|
||||
|
||||
// Set if we are very far behind schedule and need to reset back to the beginning of a cycle to find our way
|
||||
bool forceCycleStart = true;
|
||||
};
|
||||
|
||||
struct hardware_pwm;
|
||||
|
|
|
@ -123,16 +123,21 @@ void SingleTimerExecutor::executeAllPendingActions() {
|
|||
* TODO: add a counter & figure out a limit of iterations?
|
||||
*/
|
||||
|
||||
executeCounter = 0;
|
||||
// starts at -1 because do..while will run a minimum of once
|
||||
executeCounter = -1;
|
||||
|
||||
bool didExecute;
|
||||
do {
|
||||
efitick_t nowNt = getTimeNowNt();
|
||||
didExecute = queue.executeOne(nowNt);
|
||||
if (executeCounter++ == 10000) {
|
||||
firmwareError(CUSTOM_ERR_LOCK_ISSUE, "Looks like firmware is really busy");
|
||||
|
||||
// if we're stuck in a loop executing lots of events, panic!
|
||||
if (executeCounter++ == 500) {
|
||||
firmwareError(CUSTOM_ERR_LOCK_ISSUE, "Maximum scheduling run length exceeded - CPU load too high");
|
||||
}
|
||||
|
||||
} while (didExecute);
|
||||
|
||||
maxExecuteCounter = maxI(maxExecuteCounter, executeCounter);
|
||||
|
||||
if (!isLocked()) {
|
||||
|
@ -169,7 +174,7 @@ void initSingleTimerExecutorHardware(void) {
|
|||
|
||||
void executorStatistics() {
|
||||
if (engineConfiguration->debugMode == DBG_EXECUTOR) {
|
||||
#if EFI_TUNER_STUDIO && EFI_SIGNAL_EXECUTOR_ONE_TIMER
|
||||
#if EFI_TUNER_STUDIO
|
||||
tsOutputChannels.debugIntField1 = ___engine.executor.timerCallbackCounter;
|
||||
tsOutputChannels.debugIntField2 = ___engine.executor.executeAllPendingActionsInvocationCounter;
|
||||
tsOutputChannels.debugIntField3 = ___engine.executor.scheduleCounter;
|
||||
|
|
Loading…
Reference in New Issue