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, periodNt != 0, "period not initialized");
|
||||||
efiAssertVoid(CUSTOM_ERR_6580, iterationLimit > 0, "iterationLimit invalid");
|
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
|
* period length has changed - we need to reset internal state
|
||||||
*/
|
*/
|
||||||
safe.startNt = getTimeNowNt();
|
safe.startNt = getTimeNowNt();
|
||||||
safe.iteration = 0;
|
safe.iteration = 0;
|
||||||
safe.periodNt = periodNt;
|
safe.periodNt = periodNt;
|
||||||
|
|
||||||
|
forceCycleStart = false;
|
||||||
#if DEBUG_PWM
|
#if DEBUG_PWM
|
||||||
scheduleMsg(&logger, "state reset start=%d iteration=%d", state->safe.start, state->safe.iteration);
|
scheduleMsg(&logger, "state reset start=%d iteration=%d", state->safe.start, state->safe.iteration);
|
||||||
#endif
|
#endif
|
||||||
|
@ -225,10 +227,18 @@ efitick_t PwmConfig::togglePwmState() {
|
||||||
scheduleMsg(&logger, "%s: nextSwitchTime %d", state->name, nextSwitchTime);
|
scheduleMsg(&logger, "%s: nextSwitchTime %d", state->name, nextSwitchTime);
|
||||||
#endif /* DEBUG_PWM */
|
#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++;
|
safe.phaseIndex++;
|
||||||
if (safe.phaseIndex == phaseCount || mode != PM_NORMAL) {
|
if (isVeryBehindSchedule || safe.phaseIndex == phaseCount || mode != PM_NORMAL) {
|
||||||
safe.phaseIndex = 0; // restart
|
safe.phaseIndex = 0; // restart
|
||||||
safe.iteration++;
|
safe.iteration++;
|
||||||
|
|
||||||
|
if (isVeryBehindSchedule) {
|
||||||
|
forceCycleStart = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if EFI_UNIT_TEST
|
#if EFI_UNIT_TEST
|
||||||
printf("PWM: nextSwitchTimeNt=%d phaseIndex=%d iteration=%d\r\n", nextSwitchTimeNt,
|
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
|
* PWM generation is not happening while this value is NAN
|
||||||
*/
|
*/
|
||||||
float periodNt;
|
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;
|
struct hardware_pwm;
|
||||||
|
|
|
@ -123,16 +123,21 @@ void SingleTimerExecutor::executeAllPendingActions() {
|
||||||
* TODO: add a counter & figure out a limit of iterations?
|
* 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;
|
bool didExecute;
|
||||||
do {
|
do {
|
||||||
efitick_t nowNt = getTimeNowNt();
|
efitick_t nowNt = getTimeNowNt();
|
||||||
didExecute = queue.executeOne(nowNt);
|
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);
|
} while (didExecute);
|
||||||
|
|
||||||
maxExecuteCounter = maxI(maxExecuteCounter, executeCounter);
|
maxExecuteCounter = maxI(maxExecuteCounter, executeCounter);
|
||||||
|
|
||||||
if (!isLocked()) {
|
if (!isLocked()) {
|
||||||
|
@ -169,7 +174,7 @@ void initSingleTimerExecutorHardware(void) {
|
||||||
|
|
||||||
void executorStatistics() {
|
void executorStatistics() {
|
||||||
if (engineConfiguration->debugMode == DBG_EXECUTOR) {
|
if (engineConfiguration->debugMode == DBG_EXECUTOR) {
|
||||||
#if EFI_TUNER_STUDIO && EFI_SIGNAL_EXECUTOR_ONE_TIMER
|
#if EFI_TUNER_STUDIO
|
||||||
tsOutputChannels.debugIntField1 = ___engine.executor.timerCallbackCounter;
|
tsOutputChannels.debugIntField1 = ___engine.executor.timerCallbackCounter;
|
||||||
tsOutputChannels.debugIntField2 = ___engine.executor.executeAllPendingActionsInvocationCounter;
|
tsOutputChannels.debugIntField2 = ___engine.executor.executeAllPendingActionsInvocationCounter;
|
||||||
tsOutputChannels.debugIntField3 = ___engine.executor.scheduleCounter;
|
tsOutputChannels.debugIntField3 = ___engine.executor.scheduleCounter;
|
||||||
|
|
Loading…
Reference in New Issue