auto-sync

This commit is contained in:
rusEfi 2014-11-08 00:05:46 -06:00
parent 3fbeeec2e9
commit c081381455
10 changed files with 81 additions and 63 deletions

View File

@ -18,6 +18,8 @@
class FuelSchedule { class FuelSchedule {
public: public:
FuelSchedule();
void clear();
ActuatorEventList events; ActuatorEventList events;
void addFuelEvents(trigger_shape_s *s, void addFuelEvents(trigger_shape_s *s,
@ -25,6 +27,8 @@ public:
void registerInjectionEvent(trigger_shape_s *s, void registerInjectionEvent(trigger_shape_s *s,
io_pin_e pin, float angle DECLATE_ENGINE_PARAMETER); io_pin_e pin, float angle DECLATE_ENGINE_PARAMETER);
uint8_t hasEvents[PWM_PHASE_MAX_COUNT];
}; };
/** /**

View File

@ -110,6 +110,7 @@ void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs) {
return; return;
} }
efiAssertVoid(signal!=NULL, "signal is NULL");
int index = getRevolutionCounter() % 2; int index = getRevolutionCounter() % 2;
scheduling_s * sUp = &signal->signalTimerUp[index]; scheduling_s * sUp = &signal->signalTimerUp[index];
scheduling_s * sDown = &signal->signalTimerDown[index]; scheduling_s * sDown = &signal->signalTimerDown[index];

View File

@ -173,14 +173,6 @@ void initializeIgnitionActions(float advance, float dwellAngle,
} }
} }
static void registerActuatorEventExt(trigger_shape_s * s, ActuatorEvent *ev,
OutputSignal *actuator, float angle DECLATE_ENGINE_PARAMETER) {
findTriggerPosition(s, &ev->position, angle PASS_ENGINE_PARAMETER);
}
void FuelSchedule::registerInjectionEvent(trigger_shape_s *s, void FuelSchedule::registerInjectionEvent(trigger_shape_s *s,
io_pin_e pin, float angle DECLATE_ENGINE_PARAMETER) { io_pin_e pin, float angle DECLATE_ENGINE_PARAMETER) {
ActuatorEventList *list = &events; ActuatorEventList *list = &events;
@ -201,7 +193,16 @@ void FuelSchedule::registerInjectionEvent(trigger_shape_s *s,
} }
ev->actuator = actuator; ev->actuator = actuator;
registerActuatorEventExt(s, ev, actuator, angle PASS_ENGINE_PARAMETER); findTriggerPosition(s, &ev->position, angle PASS_ENGINE_PARAMETER);
hasEvents[ev->position.eventIndex] = true;
}
FuelSchedule::FuelSchedule() {
clear();
}
void FuelSchedule::clear() {
memset(hasEvents, 0, sizeof(hasEvents));
} }
void FuelSchedule::addFuelEvents(trigger_shape_s *s, void FuelSchedule::addFuelEvents(trigger_shape_s *s,

View File

@ -16,13 +16,14 @@
EventQueue::EventQueue() { EventQueue::EventQueue() {
head = NULL; head = NULL;
setLateDelay(100);
} }
bool EventQueue::checkIfPending(scheduling_s *scheduling) { bool EventQueue::checkIfPending(scheduling_s *scheduling) {
return assertNotInList<scheduling_s>(head, scheduling); return assertNotInList<scheduling_s>(head, scheduling);
} }
void EventQueue::insertTask(scheduling_s *scheduling, uint64_t timeUs, schfunc_t callback, void *param) { void EventQueue::insertTask(scheduling_s *scheduling, uint64_t timeX, schfunc_t callback, void *param) {
if (callback == NULL) if (callback == NULL)
firmwareError("NULL callback"); firmwareError("NULL callback");
@ -30,7 +31,7 @@ void EventQueue::insertTask(scheduling_s *scheduling, uint64_t timeUs, schfunc_t
if (alreadyPending) if (alreadyPending)
return; return;
scheduling->momentUs = timeUs; scheduling->momentX = timeX;
scheduling->callback = callback; scheduling->callback = callback;
scheduling->param = param; scheduling->param = param;
@ -42,12 +43,13 @@ void EventQueue::insertTask(scheduling_s *scheduling, uint64_t timeUs, schfunc_t
//} //}
/** /**
* On this layer it does not matter which units are used - us, ms ot nt.
* Get the timestamp of the soonest pending action * Get the timestamp of the soonest pending action
*/ */
uint64_t EventQueue::getNextEventTime(uint64_t nowUs) { uint64_t EventQueue::getNextEventTime(uint64_t nowX) {
scheduling_s * current; scheduling_s * current;
// this is a large value which is expected to be larger than any real time // this is a large value which is expected to be larger than any real time
uint64_t result = EMPTY_QUEUE; uint64_t nextTimeUs = EMPTY_QUEUE;
int counter = 0; int counter = 0;
LL_FOREACH(head, current) LL_FOREACH(head, current)
@ -56,20 +58,20 @@ uint64_t EventQueue::getNextEventTime(uint64_t nowUs) {
firmwareError("Is this list looped #2?"); firmwareError("Is this list looped #2?");
return EMPTY_QUEUE; return EMPTY_QUEUE;
} }
if (current->momentUs <= nowUs) { if (current->momentX <= nowX) {
/** /**
* looks like we end up here after 'writeconfig' (which freezes the firmware) - we are late * looks like we end up here after 'writeconfig' (which freezes the firmware) - we are late
* for the next scheduled event * for the next scheduled event
*/ */
uint64_t mock = nowUs + 100; uint64_t mock = nowX + lateDelay;
if (mock < result) if (mock < nextTimeUs)
result = mock; nextTimeUs = mock;
} else { } else {
if (current->momentUs < result) if (current->momentX < nextTimeUs)
result = current->momentUs; nextTimeUs = current->momentX;
} }
} }
return result; return nextTimeUs;
} }
/** /**
@ -90,7 +92,7 @@ bool EventQueue::executeAll(uint64_t now) {
firmwareError("Is this list looped?"); firmwareError("Is this list looped?");
return false; return false;
} }
if (current->momentUs <= now) { if (current->momentX <= now) {
LL_DELETE(head, current); LL_DELETE(head, current);
LL_PREPEND(executionList, current); LL_PREPEND(executionList, current);
} }
@ -115,6 +117,10 @@ int EventQueue::size(void) {
return result; return result;
} }
void EventQueue::setLateDelay(int value) {
lateDelay = value;
}
scheduling_s *EventQueue::getForUnitText(int index) { scheduling_s *EventQueue::getForUnitText(int index) {
scheduling_s * current; scheduling_s * current;

View File

@ -38,7 +38,7 @@ class EventQueue {
public: public:
EventQueue(); EventQueue();
void insertTask(scheduling_s *scheduling, uint64_t timeUs, schfunc_t callback, void *param); void insertTask(scheduling_s *scheduling, uint64_t timeX, schfunc_t callback, void *param);
bool executeAll(uint64_t now); bool executeAll(uint64_t now);
@ -46,9 +46,11 @@ public:
void clear(void); void clear(void);
int size(void); int size(void);
scheduling_s *getForUnitText(int index); scheduling_s *getForUnitText(int index);
void setLateDelay(int value);
private: private:
bool checkIfPending(scheduling_s *scheduling); bool checkIfPending(scheduling_s *scheduling);
scheduling_s *head; scheduling_s *head;
uint64_t lateDelay;
}; };
#endif /* EVENT_SCHEDULER_H_ */ #endif /* EVENT_SCHEDULER_H_ */

View File

@ -17,7 +17,7 @@ struct scheduling_struct {
VirtualTimer timer; VirtualTimer timer;
#endif /* EFI_SIGNAL_EXECUTOR_SLEEP */ #endif /* EFI_SIGNAL_EXECUTOR_SLEEP */
volatile uint64_t momentUs; volatile uint64_t momentX;
schfunc_t callback; schfunc_t callback;
void *param; void *param;
scheduling_s *next; scheduling_s *next;

View File

@ -54,7 +54,8 @@
#include "event_queue.h" #include "event_queue.h"
#include "engine.h" #include "engine.h"
EXTERN_ENGINE; EXTERN_ENGINE
;
static LocalVersionHolder localVersion; static LocalVersionHolder localVersion;
@ -114,11 +115,17 @@ static INLINE void handleFuel(uint32_t eventIndex, int rpm DECLATE_ENGINE_PARAME
*/ */
FuelSchedule *fs = FuelSchedule *fs =
isCrankingR(rpm) ? isCrankingR(rpm) ?
&engine->engineConfiguration2->crankingInjectionEvents : &engine->engineConfiguration2->crankingInjectionEvents : &engine->engineConfiguration2->injectionEvents;
&engine->engineConfiguration2->injectionEvents;
ActuatorEventList *source = &fs->events; ActuatorEventList *source = &fs->events;
/**
* This is a performance optimization for https://sourceforge.net/p/rusefi/tickets/64/
* TODO: better data structure? better algorithm?
*/
if (!fs->hasEvents[eventIndex])
return;
for (int i = 0; i < source->size; i++) { for (int i = 0; i < source->size; i++) {
ActuatorEvent *event = &source->events[i]; ActuatorEvent *event = &source->events[i];
if (event->position.eventIndex != eventIndex) if (event->position.eventIndex != eventIndex)
@ -127,8 +134,7 @@ static INLINE void handleFuel(uint32_t eventIndex, int rpm DECLATE_ENGINE_PARAME
} }
} }
static INLINE void handleSparkEvent(uint32_t eventIndex, IgnitionEvent *iEvent, static INLINE void handleSparkEvent(uint32_t eventIndex, IgnitionEvent *iEvent, int rpm DECLATE_ENGINE_PARAMETER) {
int rpm DECLATE_ENGINE_PARAMETER) {
engine_configuration2_s *engineConfiguration2 = engine->engineConfiguration2; engine_configuration2_s *engineConfiguration2 = engine->engineConfiguration2;
float dwellMs = getSparkDwellMsT(rpm PASS_ENGINE_PARAMETER); float dwellMs = getSparkDwellMsT(rpm PASS_ENGINE_PARAMETER);
@ -191,8 +197,7 @@ static INLINE void handleSparkEvent(uint32_t eventIndex, IgnitionEvent *iEvent,
} }
} }
static INLINE void handleSpark(uint32_t eventIndex, int rpm, static INLINE void handleSpark(uint32_t eventIndex, int rpm, IgnitionEventList *list DECLATE_ENGINE_PARAMETER) {
IgnitionEventList *list DECLATE_ENGINE_PARAMETER) {
if (!isValidRpm(rpm) || !engine->engineConfiguration->isIgnitionEnabled) if (!isValidRpm(rpm) || !engine->engineConfiguration->isIgnitionEnabled)
return; // this might happen for instance in case of a single trigger event after a pause return; // this might happen for instance in case of a single trigger event after a pause
@ -239,7 +244,7 @@ void showMainHistogram(void) {
* Both injection and ignition are controlled from this method. * Both injection and ignition are controlled from this method.
*/ */
void onTriggerEvent(trigger_event_e ckpSignalType, uint32_t eventIndex, MainTriggerCallback *mtc) { void onTriggerEvent(trigger_event_e ckpSignalType, uint32_t eventIndex, MainTriggerCallback *mtc) {
if(hasFirmwareError()) { if (hasFirmwareError()) {
/** /**
* In case on a major error we should not process any more events. * In case on a major error we should not process any more events.
* TODO: add 'pin shutdown' invocation somewhere * TODO: add 'pin shutdown' invocation somewhere
@ -249,8 +254,7 @@ void onTriggerEvent(trigger_event_e ckpSignalType, uint32_t eventIndex, MainTrig
Engine *engine = mtc->engine; Engine *engine = mtc->engine;
(void) ckpSignalType; (void) ckpSignalType;
efiAssertVoid(eventIndex < 2 * engine->engineConfiguration2->triggerShape.shaftPositionEventCount, efiAssertVoid(eventIndex < 2 * engine->engineConfiguration2->triggerShape.shaftPositionEventCount, "event index");
"event index");
efiAssertVoid(getRemainingStack(chThdSelf()) > 64, "lowstck#2"); efiAssertVoid(getRemainingStack(chThdSelf()) > 64, "lowstck#2");
// todo: remove these local variables soon? // todo: remove these local variables soon?
@ -306,20 +310,18 @@ void onTriggerEvent(trigger_event_e ckpSignalType, uint32_t eventIndex, MainTrig
float dwellAngle = dwellMs / getOneDegreeTimeMs(rpm); float dwellAngle = dwellMs / getOneDegreeTimeMs(rpm);
initializeIgnitionActions(advance, dwellAngle, initializeIgnitionActions(advance, dwellAngle, engine->engineConfiguration2,
engine->engineConfiguration2,
&engine->engineConfiguration2->ignitionEvents[revolutionIndex] PASS_ENGINE_PARAMETER); &engine->engineConfiguration2->ignitionEvents[revolutionIndex] PASS_ENGINE_PARAMETER);
} }
triggerEventsQueue.executeAll(getCrankEventCounter()); triggerEventsQueue.executeAll(getCrankEventCounter());
handleFuel(eventIndex, rpm PASS_ENGINE_PARAMETER); handleFuel(eventIndex, rpm PASS_ENGINE_PARAMETER);
handleSpark(eventIndex, rpm, handleSpark(eventIndex, rpm, &engine->engineConfiguration2->ignitionEvents[revolutionIndex] PASS_ENGINE_PARAMETER);
&engine->engineConfiguration2->ignitionEvents[revolutionIndex] PASS_ENGINE_PARAMETER);
#if EFI_HISTOGRAMS && EFI_PROD_CODE #if EFI_HISTOGRAMS && EFI_PROD_CODE
int diff = hal_lld_get_counter_value() - beforeCallback; int diff = hal_lld_get_counter_value() - beforeCallback;
if (diff > 0) if (diff > 0)
hsAdd(&mainLoopHisto, diff); hsAdd(&mainLoopHisto, diff);
#endif /* EFI_HISTOGRAMS */ #endif /* EFI_HISTOGRAMS */
} }
@ -355,7 +357,7 @@ void initMainEventListener(Engine *engine, engine_configuration2_s *engineConfig
#if EFI_PROD_CODE || defined(__DOXYGEN__) #if EFI_PROD_CODE || defined(__DOXYGEN__)
addConsoleAction("performanceinfo", showTriggerHistogram); addConsoleAction("performanceinfo", showTriggerHistogram);
addConsoleActionP("maininfo", (VoidPtr)showMainInfo, engine); addConsoleActionP("maininfo", (VoidPtr) showMainInfo, engine);
initLogging(&logger, "main event handler"); initLogging(&logger, "main event handler");
printMsg(&logger, "initMainLoop: %d", currentTimeMillis()); printMsg(&logger, "initMainLoop: %d", currentTimeMillis());

View File

@ -250,5 +250,5 @@ void firmwareError(const char *fmt, ...) {
} }
int getRusEfiVersion(void) { int getRusEfiVersion(void) {
return 20141107; return 20141108;
} }

View File

@ -39,10 +39,14 @@ void testFuelMap(void) {
printf("*************************************************** initThermistors\r\n"); printf("*************************************************** initThermistors\r\n");
initThermistors(&eth.engine); Engine *engine = &eth.engine;
engine_configuration_s *engineConfiguration = engine->engineConfiguration;
initThermistors(engine);
printf("*** getInjectorLag\r\n"); printf("*** getInjectorLag\r\n");
assertEquals(1.0, getInjectorLag(eth.engine.engineConfiguration, 12)); assertEquals(1.0, getInjectorLag(12 PASS_ENGINE_PARAMETER));
eth.engine.engineConfiguration->injectorLag = 0.5; eth.engine.engineConfiguration->injectorLag = 0.5;
@ -55,7 +59,7 @@ void testFuelMap(void) {
// because all the correction tables are zero // because all the correction tables are zero
printf("*************************************************** getRunningFuel 1\r\n"); printf("*************************************************** getRunningFuel 1\r\n");
float baseFuel = getBaseTableFuel(eth.engine.engineConfiguration, 5, getEngineLoadT(&eth.engine)); float baseFuel = getBaseTableFuel(eth.engine.engineConfiguration, 5, getEngineLoadT(&eth.engine));
assertEqualsM("base fuel", 5.0, getRunningFuel(baseFuel, &eth.engine, 5)); assertEqualsM("base fuel", 5.0, getRunningFuel(baseFuel, 5 PASS_ENGINE_PARAMETER));
printf("*************************************************** setting IAT table\r\n"); printf("*************************************************** setting IAT table\r\n");
for (int i = 0; i < IAT_CURVE_SIZE; i++) { for (int i = 0; i < IAT_CURVE_SIZE; i++) {
@ -71,14 +75,12 @@ void testFuelMap(void) {
} }
eth.engine.engineConfiguration->injectorLag = 0; eth.engine.engineConfiguration->injectorLag = 0;
engine_configuration_s *engineConfiguration = eth.engine.engineConfiguration;
assertEquals(NAN, getIntakeAirTemperature(&eth.engine)); assertEquals(NAN, getIntakeAirTemperature(&eth.engine));
float iatCorrection = getIatCorrection(engineConfiguration, -KELV); float iatCorrection = getIatCorrection(-KELV PASS_ENGINE_PARAMETER);
assertEqualsM("IAT", 2, iatCorrection); assertEqualsM("IAT", 2, iatCorrection);
float cltCorrection = getCltCorrection(engineConfiguration, getCoolantTemperature(&eth.engine)); float cltCorrection = getCltCorrection(getCoolantTemperature(&eth.engine) PASS_ENGINE_PARAMETER);
assertEqualsM("CLT", 1, cltCorrection); assertEqualsM("CLT", 1, cltCorrection);
float injectorLag = getInjectorLag(engineConfiguration, getVBatt(engineConfiguration)); float injectorLag = getInjectorLag(getVBatt(engineConfiguration) PASS_ENGINE_PARAMETER);
assertEquals(0, injectorLag); assertEquals(0, injectorLag);
testMafValue = 5; testMafValue = 5;
@ -86,7 +88,7 @@ void testFuelMap(void) {
// 1005 * 2 for IAT correction // 1005 * 2 for IAT correction
printf("*************************************************** getRunningFuel 2\r\n"); printf("*************************************************** getRunningFuel 2\r\n");
baseFuel = getBaseTableFuel(eth.engine.engineConfiguration, 5, getEngineLoadT(&eth.engine)); baseFuel = getBaseTableFuel(eth.engine.engineConfiguration, 5, getEngineLoadT(&eth.engine));
assertEqualsM("v1", 30150, getRunningFuel(baseFuel, &eth.engine, 5)); assertEqualsM("v1", 30150, getRunningFuel(baseFuel, 5 PASS_ENGINE_PARAMETER));
testMafValue = 0; testMafValue = 0;

View File

@ -429,8 +429,8 @@ static void testRpmCalculator(void) {
eth.triggerCentral.handleShaftSignal(&eth.engine, SHAFT_PRIMARY_UP); eth.triggerCentral.handleShaftSignal(&eth.engine, SHAFT_PRIMARY_UP);
assertEqualsM("index #2", 0, eth.triggerCentral.triggerState.getCurrentIndex()); assertEqualsM("index #2", 0, eth.triggerCentral.triggerState.getCurrentIndex());
assertEqualsM("queue size", 6, schedulingQueue.size()); assertEqualsM("queue size", 6, schedulingQueue.size());
assertEqualsM("ev 1", 246444, schedulingQueue.getForUnitText(0)->momentUs); assertEqualsM("ev 1", 246444, schedulingQueue.getForUnitText(0)->momentX);
assertEqualsM("ev 2", 245944, schedulingQueue.getForUnitText(1)->momentUs); assertEqualsM("ev 2", 245944, schedulingQueue.getForUnitText(1)->momentX);
schedulingQueue.clear(); schedulingQueue.clear();
timeNow += 5000; timeNow += 5000;
@ -441,10 +441,10 @@ static void testRpmCalculator(void) {
eth.triggerCentral.handleShaftSignal(&eth.engine, SHAFT_PRIMARY_DOWN); eth.triggerCentral.handleShaftSignal(&eth.engine, SHAFT_PRIMARY_DOWN);
assertEqualsM("index #3", 3, eth.triggerCentral.triggerState.getCurrentIndex()); assertEqualsM("index #3", 3, eth.triggerCentral.triggerState.getCurrentIndex());
assertEqualsM("queue size 3", 6, schedulingQueue.size()); assertEqualsM("queue size 3", 6, schedulingQueue.size());
assertEqualsM("ev 3", 259777, schedulingQueue.getForUnitText(0)->momentUs); assertEqualsM("ev 3", 259777, schedulingQueue.getForUnitText(0)->momentX);
assertEquals(259277, schedulingQueue.getForUnitText(1)->momentUs); assertEquals(259277, schedulingQueue.getForUnitText(1)->momentX);
assertEqualsM("ev 5", 261333, schedulingQueue.getForUnitText(2)->momentUs); assertEqualsM("ev 5", 261333, schedulingQueue.getForUnitText(2)->momentX);
assertEqualsM("3/3", 258333, schedulingQueue.getForUnitText(3)->momentUs); assertEqualsM("3/3", 258333, schedulingQueue.getForUnitText(3)->momentX);
schedulingQueue.clear(); schedulingQueue.clear();
timeNow += 5000; timeNow += 5000;
@ -455,7 +455,7 @@ static void testRpmCalculator(void) {
eth.triggerCentral.handleShaftSignal(&eth.engine, SHAFT_PRIMARY_UP); eth.triggerCentral.handleShaftSignal(&eth.engine, SHAFT_PRIMARY_UP);
assertEqualsM("index #4", 6, eth.triggerCentral.triggerState.getCurrentIndex()); assertEqualsM("index #4", 6, eth.triggerCentral.triggerState.getCurrentIndex());
assertEqualsM("queue size 4", 6, schedulingQueue.size()); assertEqualsM("queue size 4", 6, schedulingQueue.size());
assertEqualsM("4/0", 273111, schedulingQueue.getForUnitText(0)->momentUs); assertEqualsM("4/0", 273111, schedulingQueue.getForUnitText(0)->momentX);
schedulingQueue.clear(); schedulingQueue.clear();
timeNow += 5000; timeNow += 5000;
@ -467,9 +467,9 @@ static void testRpmCalculator(void) {
timeNow += 5000; // 5ms timeNow += 5000; // 5ms
eth.triggerCentral.handleShaftSignal(&eth.engine, SHAFT_PRIMARY_UP); eth.triggerCentral.handleShaftSignal(&eth.engine, SHAFT_PRIMARY_UP);
assertEqualsM("queue size 6", 6, schedulingQueue.size()); assertEqualsM("queue size 6", 6, schedulingQueue.size());
assertEqualsM("6/0", 286444, schedulingQueue.getForUnitText(0)->momentUs); assertEqualsM("6/0", 286444, schedulingQueue.getForUnitText(0)->momentX);
assertEqualsM("6/1", 285944, schedulingQueue.getForUnitText(1)->momentUs); assertEqualsM("6/1", 285944, schedulingQueue.getForUnitText(1)->momentX);
assertEqualsM("6/2", 288000, schedulingQueue.getForUnitText(2)->momentUs); assertEqualsM("6/2", 288000, schedulingQueue.getForUnitText(2)->momentX);
schedulingQueue.clear(); schedulingQueue.clear();
timeNow += 5000; timeNow += 5000;
@ -480,10 +480,10 @@ static void testRpmCalculator(void) {
timeNow += 5000; // 5ms timeNow += 5000; // 5ms
eth.triggerCentral.handleShaftSignal(&eth.engine, SHAFT_PRIMARY_UP); eth.triggerCentral.handleShaftSignal(&eth.engine, SHAFT_PRIMARY_UP);
assertEqualsM("queue size 8", 6, schedulingQueue.size()); assertEqualsM("queue size 8", 6, schedulingQueue.size());
assertEqualsM("8/0", 299777, schedulingQueue.getForUnitText(0)->momentUs); assertEqualsM("8/0", 299777, schedulingQueue.getForUnitText(0)->momentX);
assertEqualsM("8/1", 299277, schedulingQueue.getForUnitText(1)->momentUs); assertEqualsM("8/1", 299277, schedulingQueue.getForUnitText(1)->momentX);
assertEqualsM("8/2", 301333, schedulingQueue.getForUnitText(2)->momentUs); assertEqualsM("8/2", 301333, schedulingQueue.getForUnitText(2)->momentX);
assertEqualsM("8/3", 298333, schedulingQueue.getForUnitText(3)->momentUs); assertEqualsM("8/3", 298333, schedulingQueue.getForUnitText(3)->momentX);
schedulingQueue.clear(); schedulingQueue.clear();
timeNow += 5000; timeNow += 5000;