auto-sync

This commit is contained in:
rusEfi 2014-11-08 00:05:46 -06:00
parent 51a379a6b1
commit 6496c12f93
10 changed files with 81 additions and 63 deletions

View File

@ -18,6 +18,8 @@
class FuelSchedule {
public:
FuelSchedule();
void clear();
ActuatorEventList events;
void addFuelEvents(trigger_shape_s *s,
@ -25,6 +27,8 @@ public:
void registerInjectionEvent(trigger_shape_s *s,
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;
}
efiAssertVoid(signal!=NULL, "signal is NULL");
int index = getRevolutionCounter() % 2;
scheduling_s * sUp = &signal->signalTimerUp[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,
io_pin_e pin, float angle DECLATE_ENGINE_PARAMETER) {
ActuatorEventList *list = &events;
@ -201,7 +193,16 @@ void FuelSchedule::registerInjectionEvent(trigger_shape_s *s,
}
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,

View File

@ -16,13 +16,14 @@
EventQueue::EventQueue() {
head = NULL;
setLateDelay(100);
}
bool EventQueue::checkIfPending(scheduling_s *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)
firmwareError("NULL callback");
@ -30,7 +31,7 @@ void EventQueue::insertTask(scheduling_s *scheduling, uint64_t timeUs, schfunc_t
if (alreadyPending)
return;
scheduling->momentUs = timeUs;
scheduling->momentX = timeX;
scheduling->callback = callback;
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
*/
uint64_t EventQueue::getNextEventTime(uint64_t nowUs) {
uint64_t EventQueue::getNextEventTime(uint64_t nowX) {
scheduling_s * current;
// 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;
LL_FOREACH(head, current)
@ -56,20 +58,20 @@ uint64_t EventQueue::getNextEventTime(uint64_t nowUs) {
firmwareError("Is this list looped #2?");
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
* for the next scheduled event
*/
uint64_t mock = nowUs + 100;
if (mock < result)
result = mock;
uint64_t mock = nowX + lateDelay;
if (mock < nextTimeUs)
nextTimeUs = mock;
} else {
if (current->momentUs < result)
result = current->momentUs;
if (current->momentX < nextTimeUs)
nextTimeUs = current->momentX;
}
}
return result;
return nextTimeUs;
}
/**
@ -90,7 +92,7 @@ bool EventQueue::executeAll(uint64_t now) {
firmwareError("Is this list looped?");
return false;
}
if (current->momentUs <= now) {
if (current->momentX <= now) {
LL_DELETE(head, current);
LL_PREPEND(executionList, current);
}
@ -115,6 +117,10 @@ int EventQueue::size(void) {
return result;
}
void EventQueue::setLateDelay(int value) {
lateDelay = value;
}
scheduling_s *EventQueue::getForUnitText(int index) {
scheduling_s * current;

View File

@ -38,7 +38,7 @@ class EventQueue {
public:
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);
@ -46,9 +46,11 @@ public:
void clear(void);
int size(void);
scheduling_s *getForUnitText(int index);
void setLateDelay(int value);
private:
bool checkIfPending(scheduling_s *scheduling);
scheduling_s *head;
uint64_t lateDelay;
};
#endif /* EVENT_SCHEDULER_H_ */

View File

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

View File

@ -54,7 +54,8 @@
#include "event_queue.h"
#include "engine.h"
EXTERN_ENGINE;
EXTERN_ENGINE
;
static LocalVersionHolder localVersion;
@ -114,11 +115,17 @@ static INLINE void handleFuel(uint32_t eventIndex, int rpm DECLATE_ENGINE_PARAME
*/
FuelSchedule *fs =
isCrankingR(rpm) ?
&engine->engineConfiguration2->crankingInjectionEvents :
&engine->engineConfiguration2->injectionEvents;
&engine->engineConfiguration2->crankingInjectionEvents : &engine->engineConfiguration2->injectionEvents;
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++) {
ActuatorEvent *event = &source->events[i];
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,
int rpm DECLATE_ENGINE_PARAMETER) {
static INLINE void handleSparkEvent(uint32_t eventIndex, IgnitionEvent *iEvent, int rpm DECLATE_ENGINE_PARAMETER) {
engine_configuration2_s *engineConfiguration2 = engine->engineConfiguration2;
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,
IgnitionEventList *list DECLATE_ENGINE_PARAMETER) {
static INLINE void handleSpark(uint32_t eventIndex, int rpm, IgnitionEventList *list DECLATE_ENGINE_PARAMETER) {
if (!isValidRpm(rpm) || !engine->engineConfiguration->isIgnitionEnabled)
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.
*/
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.
* TODO: add 'pin shutdown' invocation somewhere
@ -249,8 +254,7 @@ void onTriggerEvent(trigger_event_e ckpSignalType, uint32_t eventIndex, MainTrig
Engine *engine = mtc->engine;
(void) ckpSignalType;
efiAssertVoid(eventIndex < 2 * engine->engineConfiguration2->triggerShape.shaftPositionEventCount,
"event index");
efiAssertVoid(eventIndex < 2 * engine->engineConfiguration2->triggerShape.shaftPositionEventCount, "event index");
efiAssertVoid(getRemainingStack(chThdSelf()) > 64, "lowstck#2");
// 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);
initializeIgnitionActions(advance, dwellAngle,
engine->engineConfiguration2,
initializeIgnitionActions(advance, dwellAngle, engine->engineConfiguration2,
&engine->engineConfiguration2->ignitionEvents[revolutionIndex] PASS_ENGINE_PARAMETER);
}
triggerEventsQueue.executeAll(getCrankEventCounter());
handleFuel(eventIndex, rpm PASS_ENGINE_PARAMETER);
handleSpark(eventIndex, rpm,
&engine->engineConfiguration2->ignitionEvents[revolutionIndex] PASS_ENGINE_PARAMETER);
handleSpark(eventIndex, rpm, &engine->engineConfiguration2->ignitionEvents[revolutionIndex] PASS_ENGINE_PARAMETER);
#if EFI_HISTOGRAMS && EFI_PROD_CODE
int diff = hal_lld_get_counter_value() - beforeCallback;
if (diff > 0)
hsAdd(&mainLoopHisto, diff);
hsAdd(&mainLoopHisto, diff);
#endif /* EFI_HISTOGRAMS */
}
@ -355,7 +357,7 @@ void initMainEventListener(Engine *engine, engine_configuration2_s *engineConfig
#if EFI_PROD_CODE || defined(__DOXYGEN__)
addConsoleAction("performanceinfo", showTriggerHistogram);
addConsoleActionP("maininfo", (VoidPtr)showMainInfo, engine);
addConsoleActionP("maininfo", (VoidPtr) showMainInfo, engine);
initLogging(&logger, "main event handler");
printMsg(&logger, "initMainLoop: %d", currentTimeMillis());

View File

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

View File

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

View File

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