From 41e49ff53c917c20b301757c4da73f7d976d497d Mon Sep 17 00:00:00 2001 From: GitHub set-date Action Date: Mon, 5 Oct 2020 00:50:15 +0000 Subject: [PATCH 1/4] Update date --- firmware/controllers/date_stamp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/controllers/date_stamp.h b/firmware/controllers/date_stamp.h index 89fcfb9ca5..f984a24482 100644 --- a/firmware/controllers/date_stamp.h +++ b/firmware/controllers/date_stamp.h @@ -1,2 +1,2 @@ #pragma once -#define VCS_DATE 20201004 +#define VCS_DATE 20201005 From da3242f2fc9645f849c6dc92e2142289df1ff1dc Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Sun, 4 Oct 2020 18:33:54 -0700 Subject: [PATCH 2/4] missing iat (#1854) --- firmware/controllers/core/fsio_impl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/controllers/core/fsio_impl.cpp b/firmware/controllers/core/fsio_impl.cpp index 3c7bd2847d..196b3f3b0f 100644 --- a/firmware/controllers/core/fsio_impl.cpp +++ b/firmware/controllers/core/fsio_impl.cpp @@ -54,6 +54,7 @@ static LENameOrdinalPair leMap(LE_METHOD_MAP, "map"); static LENameOrdinalPair leVBatt(LE_METHOD_VBATT, "vbatt"); static LENameOrdinalPair leFan(LE_METHOD_FAN, "fan"); static LENameOrdinalPair leCoolant(LE_METHOD_COOLANT, "coolant"); +static LENameOrdinalPair leIntakeTemp(LE_METHOD_INTAKE_AIR, "iat"); static LENameOrdinalPair leIsCoolantBroken(LE_METHOD_IS_COOLANT_BROKEN, "is_clt_broken"); // @returns boolean state of A/C toggle switch static LENameOrdinalPair leAcToggle(LE_METHOD_AC_TOGGLE, "ac_on_switch"); From 04ae4ee347aa0540e0fd68cd268b00cf2120dc89 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Mon, 5 Oct 2020 05:23:30 -0700 Subject: [PATCH 3/4] pwm perf (#1858) * pwm perf * this trace is now redundant --- .../system/timer/pwm_generator_logic.cpp | 20 ++----------------- firmware/development/perf_trace.h | 2 +- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/firmware/controllers/system/timer/pwm_generator_logic.cpp b/firmware/controllers/system/timer/pwm_generator_logic.cpp index ccc07bc90d..2f228647e4 100644 --- a/firmware/controllers/system/timer/pwm_generator_logic.cpp +++ b/firmware/controllers/system/timer/pwm_generator_logic.cpp @@ -21,7 +21,7 @@ * We need to limit the number of iterations in order to avoid precision loss while calculating * next toggle time */ -#define ITERATION_LIMIT 1000 +#define ITERATION_LIMIT 100 // 1% duty cycle #define ZERO_PWM_THRESHOLD 0.01 @@ -123,7 +123,7 @@ static efitick_t getNextSwitchTimeNt(PwmConfig *state) { * Once 'iteration' gets relatively high, we might lose calculation precision here. * This is addressed by ITERATION_LIMIT */ - efitick_t timeToSwitchNt = (efitick_t) ((iteration + switchTime) * periodNt); + uint32_t timeToSwitchNt = (uint32_t)((iteration + switchTime) * periodNt); #if DEBUG_PWM scheduleMsg(&logger, "start=%d timeToSwitch=%d", state->safe.start, timeToSwitch); @@ -175,8 +175,6 @@ void PwmConfig::handleCycleStart() { * @return Next time for signal toggle */ efitick_t PwmConfig::togglePwmState() { - ScopePerf perf(PE::PwmConfigTogglePwmState); - if (isStopRequested) { return 0; } @@ -224,20 +222,6 @@ efitick_t PwmConfig::togglePwmState() { #if DEBUG_PWM scheduleMsg(&logger, "%s: nextSwitchTime %d", state->name, nextSwitchTime); #endif /* DEBUG_PWM */ - // signed value is needed here -// int64_t timeToSwitch = nextSwitchTimeUs - getTimeNowUs(); -// if (timeToSwitch < 1) { -// /** -// * We are here if we are late for a state transition. -// * At 12000RPM=200Hz with a 60 toothed wheel we need to change state every -// * 1000000 / 200 / 120 = ~41 uS. We are kind of OK. -// * -// * We are also here after a flash write. Flash write freezes the whole chip for a couple of seconds, -// * so PWM generation and trigger simulation generation would have to recover from this time lag. -// */ -// //todo: introduce error and test this error handling warning(OBD_PCM_Processor_Fault, "PWM: negative switch time"); -// timeToSwitch = 10; -// } safe.phaseIndex++; if (safe.phaseIndex == phaseCount || mode != PM_NORMAL) { diff --git a/firmware/development/perf_trace.h b/firmware/development/perf_trace.h index d1bca96f34..79e4a3a6b1 100644 --- a/firmware/development/perf_trace.h +++ b/firmware/development/perf_trace.h @@ -51,7 +51,7 @@ enum class PE : uint8_t { EventQueueExecuteCallback, PwmGeneratorCallback, TunerStudioHandleCrcCommand, - PwmConfigTogglePwmState, + Unused, PwmConfigStateChangeCallback, Temporary1, Temporary2, From 60329b55a5e619ff7bb7f53558339fd15f790250 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Mon, 5 Oct 2020 05:57:00 -0700 Subject: [PATCH 4/4] we don't need two loops (#1855) --- .../controllers/system/timer/event_queue.cpp | 78 ++++++++++--------- .../controllers/system/timer/event_queue.h | 1 + .../system/timer/single_timer_executor.cpp | 19 ++--- .../controllers/trigger/trigger_central.cpp | 2 - 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/firmware/controllers/system/timer/event_queue.cpp b/firmware/controllers/system/timer/event_queue.cpp index 7275fc8d77..ad59c547c0 100644 --- a/firmware/controllers/system/timer/event_queue.cpp +++ b/firmware/controllers/system/timer/event_queue.cpp @@ -120,57 +120,63 @@ int EventQueue::executeAll(efitime_t now) { assertListIsSorted(); #endif - while (true) { - // Read the head every time - a previously executed event could - // have inserted something new at the head - scheduling_s* current = head; + bool didExecute; + do { + didExecute = executeOne(now); + executionCounter += didExecute ? 1 : 0; + } while (didExecute); - // Queue is empty - bail - if (!current) { - break; - } + return executionCounter; +} - // If the next event is far in the future, we'll reschedule - // and execute it next time. - // We do this when the next event is close enough that the overhead of - // resetting the timer and scheduling an new interrupt is greater than just - // waiting for the time to arrive. On current CPUs, this is reasonable to set - // around 10 microseconds. - if (current->momentX > now + lateDelay) { - break; - } +bool EventQueue::executeOne(efitime_t now) { + // Read the head every time - a previously executed event could + // have inserted something new at the head + scheduling_s* current = head; - // near future - spin wait for the event to happen and avoid the - // overhead of rescheduling the timer. - // yes, that's a busy wait but that's what we need here - while (current->momentX > getTimeNowNt()) { - UNIT_TEST_BUSY_WAIT_CALLBACK(); - } + // Queue is empty - bail + if (!current) { + return false; + } - executionCounter++; + // If the next event is far in the future, we'll reschedule + // and execute it next time. + // We do this when the next event is close enough that the overhead of + // resetting the timer and scheduling an new interrupt is greater than just + // waiting for the time to arrive. On current CPUs, this is reasonable to set + // around 10 microseconds. + if (current->momentX > now + lateDelay) { + return false; + } - // step the head forward, unlink this element, clear scheduled flag - head = current->nextScheduling_s; - current->nextScheduling_s = nullptr; - current->isScheduled = false; + // near future - spin wait for the event to happen and avoid the + // overhead of rescheduling the timer. + // yes, that's a busy wait but that's what we need here + while (current->momentX > getTimeNowNt()) { + UNIT_TEST_BUSY_WAIT_CALLBACK(); + } + + // step the head forward, unlink this element, clear scheduled flag + head = current->nextScheduling_s; + current->nextScheduling_s = nullptr; + current->isScheduled = false; #if EFI_UNIT_TEST - printf("QUEUE: execute current=%d param=%d\r\n", (long)current, (long)current->action.getArgument()); + printf("QUEUE: execute current=%d param=%d\r\n", (long)current, (long)current->action.getArgument()); #endif - // Execute the current element - { - ScopePerf perf2(PE::EventQueueExecuteCallback); - current->action.execute(); - } + // Execute the current element + { + ScopePerf perf2(PE::EventQueueExecuteCallback); + current->action.execute(); + } #if EFI_UNIT_TEST // (tests only) Ensure we didn't break anything assertListIsSorted(); #endif - } - return executionCounter; + return true; } int EventQueue::size(void) const { diff --git a/firmware/controllers/system/timer/event_queue.h b/firmware/controllers/system/timer/event_queue.h index f16939e7e9..88c1c7657e 100644 --- a/firmware/controllers/system/timer/event_queue.h +++ b/firmware/controllers/system/timer/event_queue.h @@ -56,6 +56,7 @@ public: bool insertTask(scheduling_s *scheduling, efitime_t timeX, action_s action); int executeAll(efitime_t now); + bool executeOne(efitime_t now); efitime_t getNextEventTime(efitime_t nowUs) const; void clear(void); diff --git a/firmware/controllers/system/timer/single_timer_executor.cpp b/firmware/controllers/system/timer/single_timer_executor.cpp index 89a99dfbc3..e4fd913d9e 100644 --- a/firmware/controllers/system/timer/single_timer_executor.cpp +++ b/firmware/controllers/system/timer/single_timer_executor.cpp @@ -41,7 +41,6 @@ EXTERN_ENGINE; static efitime_t nextEventTimeNt = 0; uint32_t hwSetTimerDuration; -uint32_t lastExecutionCount; void globalTimerCallback() { efiAssertVoid(CUSTOM_ERR_6624, getCurrentRemainingStack() > EXPECTED_REMAINING_STACK, "lowstck#2y"); @@ -131,16 +130,13 @@ void SingleTimerExecutor::executeAllPendingActions() { * next listeners. * TODO: add a counter & figure out a limit of iterations? */ - int totalExecuted = 0; - while (shouldExecute > 0) { - /** - * It's worth noting that that the actions might be adding new actions into the queue - */ + + bool didExecute; + do { efitick_t nowNt = getTimeNowNt(); - shouldExecute = queue.executeAll(nowNt); - totalExecuted += shouldExecute; - } - lastExecutionCount = totalExecuted; + didExecute = queue.executeOne(nowNt); + } while (didExecute); + if (!isLocked()) { firmwareError(CUSTOM_ERR_LOCK_ISSUE, "Someone has stolen my lock"); return; @@ -162,10 +158,9 @@ void SingleTimerExecutor::scheduleTimerCallback() { efiAssertVoid(CUSTOM_ERR_6625, nextEventTimeNt > nowNt, "setTimer constraint"); if (nextEventTimeNt == EMPTY_QUEUE) return; // no pending events in the queue + int32_t hwAlarmTime = NT2US((int32_t)nextEventTimeNt - (int32_t)nowNt); - uint32_t beforeHwSetTimer = getTimeNowLowerNt(); setHardwareUsTimer(hwAlarmTime == 0 ? 1 : hwAlarmTime); - hwSetTimerDuration = getTimeNowLowerNt() - beforeHwSetTimer; } void initSingleTimerExecutorHardware(void) { diff --git a/firmware/controllers/trigger/trigger_central.cpp b/firmware/controllers/trigger/trigger_central.cpp index 0184b704a2..c9b9cd5416 100644 --- a/firmware/controllers/trigger/trigger_central.cpp +++ b/firmware/controllers/trigger/trigger_central.cpp @@ -603,7 +603,6 @@ extern PwmConfig triggerSignal; #endif /* #if EFI_PROD_CODE */ extern uint32_t hipLastExecutionCount; -extern uint32_t hwSetTimerDuration; extern uint32_t maxLockedDuration; extern uint32_t maxEventCallbackDuration; @@ -737,7 +736,6 @@ void triggerInfo(void) { #if EFI_HIP_9011 scheduleMsg(logger, "hipLastExecutionCount=%d", hipLastExecutionCount); #endif /* EFI_HIP_9011 */ - scheduleMsg(logger, "hwSetTimerDuration=%d", hwSetTimerDuration); scheduleMsg(logger, "totalTriggerHandlerMaxTime=%d", triggerMaxDuration); scheduleMsg(logger, "maxPrecisionCallbackDuration=%d", maxPrecisionCallbackDuration);