diff --git a/firmware/controllers/algo/engine.cpp b/firmware/controllers/algo/engine.cpp index 2f0e2c2c57..578cfebaec 100644 --- a/firmware/controllers/algo/engine.cpp +++ b/firmware/controllers/algo/engine.cpp @@ -382,3 +382,13 @@ void doScheduleStopEngine(DECLARE_ENGINE_PARAMETER_SIGNATURE) { // let's close injectors or else if these happen to be open right now enginePins.stopPins(); } + +void action_s::setAction(schfunc_t callback, void *param) { + this->callback = callback; + this->param = param; +} + +void action_s::execute() { + efiAssertVoid(CUSTOM_ERR_ASSERT, callback != NULL, "callback==null1"); + callback(param); +} diff --git a/firmware/controllers/scheduling/event_queue.cpp b/firmware/controllers/scheduling/event_queue.cpp index 4974a0379e..d631c7aff7 100644 --- a/firmware/controllers/scheduling/event_queue.cpp +++ b/firmware/controllers/scheduling/event_queue.cpp @@ -57,8 +57,7 @@ bool EventQueue::insertTask(scheduling_s *scheduling, efitime_t timeX, schfunc_t } scheduling->momentX = timeX; - scheduling->callback = callback; - scheduling->param = param; + scheduling->action.setAction(callback, param); scheduling->isScheduled = true; if (head == NULL || timeX < head->momentX) { @@ -134,7 +133,6 @@ int EventQueue::executeAll(efitime_t now) { // we need safe iteration because we are removing elements inside the loop LL_FOREACH_SAFE2(head, current, tmp, nextScheduling_s) { - efiAssert(CUSTOM_ERR_ASSERT, current->callback != NULL, "callback==null1", 0); if (++listIterationCounter > QUEUE_LENGTH_LIMIT) { firmwareError(CUSTOM_LIST_LOOP, "Is this list looped?"); return false; @@ -167,20 +165,18 @@ int EventQueue::executeAll(efitime_t now) { * we need safe iteration here because 'callback' might change change 'current->next' * while re-inserting it into the queue from within the callback */ - LL_FOREACH_SAFE2(executionList, current, tmp, nextScheduling_s) - { - efiAssert(CUSTOM_ERR_ASSERT, current->callback != NULL, "callback==null2", 0); + LL_FOREACH_SAFE2(executionList, current, tmp, nextScheduling_s) { uint32_t before = getTimeNowLowerNt(); current->isScheduled = false; uint32_t howFarOff = now - current->momentX; maxSchedulingPrecisionLoss = maxI(maxSchedulingPrecisionLoss, howFarOff); #if EFI_UNIT_TEST - printf("QUEUE: execute current=%d param=%d\r\n", (long)current, (long)current->param); + printf("QUEUE: execute current=%d param=%d\r\n", (long)current, (long)current->action.param); #endif { ScopePerf perf2(PE::EventQueueExecuteCallback); - current->callback(current->param); + current->action.execute(); } // even with overflow it's safe to subtract here diff --git a/firmware/controllers/scheduling/scheduler.h b/firmware/controllers/scheduling/scheduler.h index 77a0b71029..06676d3d66 100644 --- a/firmware/controllers/scheduling/scheduler.h +++ b/firmware/controllers/scheduling/scheduler.h @@ -2,7 +2,7 @@ * @file scheduler.h * * @date May 18, 2014 - * @author Andrey Belomutskiy, (c) 2012-2017 + * @author Andrey Belomutskiy, (c) 2012-2019 */ #pragma once @@ -10,6 +10,18 @@ typedef void (*schfunc_t)(void *); +class action_s { +public: + void setAction(schfunc_t callback, void *param); + void execute(); + +#if EFI_PROD_CODE +private: +#endif /* EFI_PROD_CODE */ + schfunc_t callback = nullptr; + void *param = nullptr; +}; + /** * This structure holds information about an event scheduled in the future: when to execute what callback with what parameters */ @@ -30,8 +42,7 @@ public: */ scheduling_s *nextScheduling_s = nullptr; - schfunc_t callback = nullptr; - void *param = nullptr; + action_s action; }; class ExecutorInterface { diff --git a/firmware/controllers/scheduling/signal_executor_sleep.cpp b/firmware/controllers/scheduling/signal_executor_sleep.cpp index be5af50a9c..663e938f55 100644 --- a/firmware/controllers/scheduling/signal_executor_sleep.cpp +++ b/firmware/controllers/scheduling/signal_executor_sleep.cpp @@ -39,16 +39,15 @@ void SleepExecutor::scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t ti static void timerCallback(scheduling_s *scheduling) { #if EFI_PRINTF_FUEL_DETAILS - if (scheduling->callback == (schfunc_t)&seTurnPinLow) { - printf("executing cb=seTurnPinLow p=%d sch=%d now=%d\r\n", (int)scheduling->param, (int)scheduling, + if (scheduling->action.callback == (schfunc_t)&seTurnPinLow) { + printf("executing cb=seTurnPinLow p=%d sch=%d now=%d\r\n", (int)scheduling->action.param, (int)scheduling, (int)getTimeNowUs()); } else { // printf("exec cb=%d p=%d\r\n", (int)scheduling->callback, (int)scheduling->param); } #endif /* EFI_SIMULATOR */ - scheduling->callback(scheduling->param); - + scheduling->action.execute(); } static void doScheduleForLater(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param) { @@ -62,8 +61,7 @@ static void doScheduleForLater(scheduling_s *scheduling, int delayUs, schfunc_t } bool alreadyLocked = lockAnyContext(); - scheduling->callback = callback; - scheduling->param = param; + scheduling->action.setAction(callback, param); int isArmed = chVTIsArmedI(&scheduling->timer); if (isArmed) { /** diff --git a/unit_tests/engine_test_helper.cpp b/unit_tests/engine_test_helper.cpp index 8ead564a2c..4566b93f86 100644 --- a/unit_tests/engine_test_helper.cpp +++ b/unit_tests/engine_test_helper.cpp @@ -165,7 +165,7 @@ scheduling_s * EngineTestHelper::assertEvent5(const char *msg, int index, void * TestExecutor *executor = &engine.executor; EXPECT_TRUE(executor->size() > index) << msg; scheduling_s *event = executor->getForUnitTest(index); - assertEqualsM4(msg, " up/down", (void*)event->callback == (void*) callback, 1); + assertEqualsM4(msg, " up/down", (void*)event->action.callback == (void*) callback, 1); efitime_t start = getTimeNowUs(); assertEqualsM(msg, expectedTimestamp, event->momentX - start); return event; @@ -174,7 +174,7 @@ scheduling_s * EngineTestHelper::assertEvent5(const char *msg, int index, void * void EngineTestHelper::assertEvent(const char *msg, int index, void *callback, efitime_t momentX, InjectionEvent *expectedEvent) { scheduling_s *event = assertEvent5(msg, index, callback, momentX); - InjectionEvent *actualEvent = (InjectionEvent *)event->param; + InjectionEvent *actualEvent = (InjectionEvent *)event->action.param; assertEqualsLM(msg, expectedEvent->outputs[0], (long)actualEvent->outputs[0]); // but this would not work assertEqualsLM(msg, expectedPair, (long)eventPair); diff --git a/unit_tests/tests/test_trigger_decoder.cpp b/unit_tests/tests/test_trigger_decoder.cpp index 4bb2a7cc68..1efe4ce7e2 100644 --- a/unit_tests/tests/test_trigger_decoder.cpp +++ b/unit_tests/tests/test_trigger_decoder.cpp @@ -359,14 +359,14 @@ TEST(misc, testRpmCalculator) { { scheduling_s *ev0 = engine->executor.getForUnitTest(0); - assertREqualsM("Call@0", (void*)ev0->callback, (void*)turnSparkPinHigh); + assertREqualsM("Call@0", (void*)ev0->action.callback, (void*)turnSparkPinHigh); assertEqualsM("ev 0", start + 944, ev0->momentX); - assertEqualsLM("coil 0", (long)&enginePins.coils[0], (long)((IgnitionEvent*)ev0->param)->outputs[0]); + assertEqualsLM("coil 0", (long)&enginePins.coils[0], (long)((IgnitionEvent*)ev0->action.param)->outputs[0]); scheduling_s *ev1 = engine->executor.getForUnitTest(1); - assertREqualsM("Call@1", (void*)ev1->callback, (void*)fireSparkAndPrepareNextSchedule); + assertREqualsM("Call@1", (void*)ev1->action.callback, (void*)fireSparkAndPrepareNextSchedule); assertEqualsM("ev 1", start + 1444, ev1->momentX); - assertEqualsLM("coil 1", (long)&enginePins.coils[0], (long)((IgnitionEvent*)ev1->param)->outputs[0]); + assertEqualsLM("coil 1", (long)&enginePins.coils[0], (long)((IgnitionEvent*)ev1->action.param)->outputs[0]); }