rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Functions
engine_controller.h File Reference

Detailed Description

Controllers package entry point header.

Date
Feb 7, 2013
Author
Andrey Belomutskiy, (c) 2012-2020

Definition in file engine_controller.h.

Functions

bool validateConfigOnStartUpOrBurn ()
 
chargetPinNameByAdcChannel (const char *msg, adc_channel_e hwChannel, char *buffer, size_t bufferSize)
 
void initPeriodicEvents ()
 
void initRealHardwareEngineController ()
 
void commonEarlyInit ()
 
void commonInitEngineController ()
 
void initStartStopButton ()
 
void initWarningRunningPins ()
 
void initDataStructures ()
 
void slowStartStopButtonCallback ()
 

Function Documentation

◆ commonEarlyInit()

void commonEarlyInit ( )

Initialize hardware drivers

Definition at line 712 of file engine_controller.cpp.

712 {
713 // Start this early - it will start LED blinking and such
715
716#if EFI_SHAFT_POSITION_INPUT
717 // todo: figure out better startup logic
719#endif /* EFI_SHAFT_POSITION_INPUT */
720
721 /**
722 * Initialize hardware drivers
723 */
724 initHardware();
725
727
728#if EFI_FILE_LOGGING
729 initMmcCard();
730#endif /* EFI_FILE_LOGGING */
731
732#if EFI_ENGINE_EMULATOR
734#endif
735
736#if EFI_LUA
737 startLua();
738#endif // EFI_LUA
739
740#if EFI_CAN_SERIAL
741 // needs to be called after initCan() inside initHardware()
743#endif /* EFI_CAN_SERIAL */
744
745}
void initQcBenchControls()
void initEngineEmulator()
void initHardware()
Definition hardware.cpp:540
void startLua()
Definition lua.cpp:281
void initMmcCard()
void startStatusThreads()
void initTriggerCentral()
void startCanConsole()

Referenced by initEfiWithConfig().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ commonInitEngineController()

void commonInitEngineController ( )

This has to go after 'enginePins.startPins()' in order to properly detect un-assigned output pins

Definition at line 386 of file engine_controller.cpp.

386 {
387#if EFI_PROD_CODE
388 addConsoleAction("sensorinfo", printSensorInfo);
389 addConsoleAction("reset_accel", resetAccel);
390#endif /* EFI_PROD_CODE */
391
392#if EFI_SIMULATOR || EFI_UNIT_TEST
393 printf("commonInitEngineController\n");
394#endif
395
396#if !EFI_UNIT_TEST
398#endif /* EFI_UNIT_TEST */
399
400#if EFI_ENGINE_CONTROL
401 /**
402 * This has to go after 'enginePins.startPins()' in order to
403 * properly detect un-assigned output pins
404 */
406
408#endif // EFI_ENGINE_CONTROL
409
410
411#if EFI_PROD_CODE || EFI_SIMULATOR
412 initSettings();
413
414 if (hasFirmwareError()) {
415 return;
416 }
417#endif
418
419#if ! EFI_UNIT_TEST && EFI_ENGINE_CONTROL
421#endif /* ! EFI_UNIT_TEST && EFI_ENGINE_CONTROL */
422
423#if EFI_ALTERNATOR_CONTROL
425#endif /* EFI_ALTERNATOR_CONTROL */
426
427#if EFI_VVT_PID
429#endif /* EFI_VVT_PID */
430
431#if EFI_MALFUNCTION_INDICATOR
433#endif /* EFI_MALFUNCTION_INDICATOR */
434
435#if !EFI_UNIT_TEST
436 // This is tested independently - don't configure sensors for tests.
437 // This lets us selectively mock them for each test.
439#endif /* EFI_UNIT_TEST */
440
441 initSensors();
442
444
446
447 initGpPwm();
448
449#if EFI_IDLE_CONTROL
451#endif /* EFI_IDLE_CONTROL */
452
453#if EFI_TCU
455#endif
456
458
459#if EFI_ELECTRONIC_THROTTLE_BODY
461#endif /* EFI_ELECTRONIC_THROTTLE_BODY */
462
463#if EFI_MAP_AVERAGING && defined (MODULE_MAP_AVERAGING)
464 engine->module<MapAveragingModule>()->init();
465#else
466 efiPrintf("No MapAveraging support!");
467#endif /* EFI_MAP_AVERAGING */
468
469#if EFI_BOOST_CONTROL
471#endif /* EFI_BOOST_CONTROL */
472
473#if EFI_LAUNCH_CONTROL
475#endif
476
478
479#if EFI_UNIT_TEST
481#endif /* EFI_UNIT_TEST */
482
483#if EFI_AUX_VALVES
485#endif /* EFI_AUX_VALVES */
486
487#ifdef MODULE_TACHOMETER
488 engine->module<TachometerModule>()->init();
489#endif
490
492
493 initStft();
494#if EFI_LTFT_CONTROL
495 initLtft();
496#endif
497}
void initAccelEnrichment()
void initIgnitionAdvanceControl()
void initSensors()
void initAlternatorCtrl()
void initAuxValves()
void initBenchTest()
void initBoostCtrl()
FuelSchedule injectionEvents
Definition engine.h:288
RpmCalculator rpmCalculator
Definition engine.h:306
constexpr auto & module()
Definition engine.h:200
bool Register()
Definition sensor.cpp:131
void addConsoleAction(const char *token, Void callback)
Register console action without parameters.
void initStft(void)
void initButtonDebounce()
void initElectronicThrottle()
void prepareOutputSignals()
Engine * engine
static void printSensorInfo()
static void initConfigActions()
static void resetAccel()
void initGearController()
void initGpPwm()
Definition gppwm.cpp:31
void startIdleThread()
void initNewSensors()
void initLaunchControl()
void initLtft()
void initMalfunctionIndicator(void)
void initScriptImpl()
void initSettings()
Definition settings.cpp:637
void initSpeedometer()
printf("\n")
void initVvtActuators()
Definition vvt.cpp:190

Referenced by initRealHardwareEngineController().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getPinNameByAdcChannel()

char * getPinNameByAdcChannel ( const char msg,
adc_channel_e  hwChannel,
char buffer,
size_t  bufferSize 
)

Definition at line 212 of file engine_controller.cpp.

212 {
213#if HAL_USE_ADC
214 if (!isAdcChannelValid(hwChannel)) {
215 snprintf(buffer, bufferSize, "NONE");
216 } else {
217 const char *name = portname(getAdcChannelPort(msg, hwChannel));
218 snprintf(buffer, bufferSize, "%s%d", name ? name : "null", getAdcChannelPin(hwChannel));
219 }
220#else
221 snprintf(buffer, bufferSize, "NONE");
222#endif /* HAL_USE_ADC */
223 return buffer;
224}
bool isAdcChannelValid(adc_channel_e hwChannel)
Definition adc_inputs.h:23
int getAdcChannelPin(adc_channel_e hwChannel)
ioportid_t getAdcChannelPort(const char *msg, adc_channel_e hwChannel)
const char * portname(ioportid_t GPIOx)
static BigBufferHandle buffer

Referenced by AdcSubscription::PrintInfo(), and printMAPInfo().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initDataStructures()

void initDataStructures ( )

Definition at line 102 of file engine_controller.cpp.

102 {
103#if EFI_ENGINE_CONTROL
104 initFuelMap();
107 for (size_t i=0;i<efi::size(events.elements);i++) {
108 // above-zero value helps distinguish events
110 }
111 // above-zero value helps distinguish events
113#endif // EFI_ENGINE_CONTROL
114}
IgnitionEventList ignitionEvents
Definition engine.h:289
EngineState engineState
Definition engine.h:344
uint32_t sparkCounter
IgnitionEvent elements[MAX_CYLINDER_COUNT]
void initFuelMap()
Initialize fuel map data structure.
void initSpeedDensity()
static std::vector< CompositeEvent > events

Referenced by runRusEfi().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initPeriodicEvents()

void initPeriodicEvents ( )

Definition at line 207 of file engine_controller.cpp.

207 {
208 slowController.start();
209 fastController.start();
210}
static PeriodicFastController fastController
static PeriodicSlowController slowController

Referenced by runRusEfi().

Here is the caller graph for this function:

◆ initRealHardwareEngineController()

void initRealHardwareEngineController ( )

Definition at line 748 of file engine_controller.cpp.

748 {
751
752#if EFI_LOGIC_ANALYZER
753 if (engineConfiguration->isWaveAnalyzerEnabled) {
755 }
756#endif /* EFI_LOGIC_ANALYZER */
757
758 if (hasFirmwareError()) {
759 return;
760 }
761
763
765}
static constexpr engine_configuration_s * engineConfiguration
static EngineStateBlinkingTask engineStateBlinkingTask
void commonInitEngineController()
void initWaveAnalyzer()
void initWarningRunningPins()
void initVrThresholdPwm()
Definition vr_pwm.cpp:39

Referenced by initEfiWithConfig().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initStartStopButton()

void initStartStopButton ( )

See test_start_stop.cpp

Definition at line 11 of file start_stop.cpp.

11 {
12 /* startCrankingDuration is efitimesec_t, so we need to multiply it by 1000 to get milliseconds*/
14 engineConfiguration->startStopButtonPin,
15 engineConfiguration->startStopButtonMode,
16 engineConfiguration->startRequestPinInverted);
17}
void init(efitimems_t threshold, brain_pin_e &pin, pin_input_mode_e &mode, bool inverted=false)
Definition debounce.cpp:23
StartStopState startStopState
Definition engine.h:106
static EngineAccessor engine
Definition engine.h:413
ButtonDebounce startStopButtonDebounce
Definition start_stop.h:6

Referenced by startHardware().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initWarningRunningPins()

void initWarningRunningPins ( )

Definition at line 226 of file status_loop.cpp.

226 {
227#if EFI_PROD_CODE
228 // open question if we need warningLedPin and runningLedPin at all!
229 enginePins.warningLedPin.initPin("led: warning status", getWarningLedPin(), LED_PIN_MODE, true);
230 enginePins.runningLedPin.initPin("led: running status", getRunningLedPin(), LED_PIN_MODE, true);
231#endif /* EFI_PROD_CODE */
232}
Gpio getWarningLedPin()
Gpio getRunningLedPin()
OutputPin runningLedPin
Definition efi_gpio.h:108
OutputPin warningLedPin
Definition efi_gpio.h:107
void initPin(const char *msg, brain_pin_e brainPin, pin_output_mode_e outputMode, bool forceInitWithFatalError=false)
Definition efi_gpio.cpp:711
EnginePins enginePins
Definition efi_gpio.cpp:24

Referenced by initRealHardwareEngineController().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ slowStartStopButtonCallback()

void slowStartStopButtonCallback ( )

Definition at line 60 of file start_stop.cpp.

60 {
61 if (!isIgnVoltage()) {
62 // nothing to crank if we are powered only via USB
64 return;
65 } else if (engine->startStopState.isFirstTime) {
66 // initialize when first time with proper power
69 }
70
71 if (engine->startStopState.timeSinceIgnitionPower.getElapsedUs() < MS2US(engineConfiguration->startButtonSuppressOnStartUpMs)) {
72 // where are odd cases of start button combined with ECU power source button we do not want to crank right on start
73 return;
74 }
75
77 if (engineConfiguration->crankingCondition == CC_BRAKE && !engine->brakePedalSwitchedState) {
78 return;
79 }
80 if (engineConfiguration->crankingCondition == CC_CLUTCH && !engine->clutchUpSwitchedState) {
81 return;
82 }
83
85 return;
86 }
87 }
88
90
92 // we are here on transition from 0 to 1
94 }
95 // todo: we shall extract start_stop.txt from engine_state.txt
98
99 bool isStarterEngaged = enginePins.starterControl.getLogicValue();
100
101 if (isStarterEngaged) {
103 }
104}
bool readPinEvent()
bool getPhysicalState()
SwitchedState brakePedalSwitchedState
Definition engine.h:215
SwitchedState clutchUpSwitchedState
Definition engine.h:214
RegisteredOutputPin starterControl
Definition efi_gpio.h:82
bool getLogicValue() const
Definition efi_gpio.cpp:667
bool isStopped() const override
bool isIgnVoltage()
startStopState("startStopState", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1380, 1.0, -1.0, -1.0, "")
PUBLIC_API_WEAK bool isCrankingSuppressed()
static void disengageStarterIfNeeded()
void startStopButtonToggle()
Timer timeSinceIgnitionPower
Definition start_stop.h:7

Referenced by doPeriodicSlowCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validateConfigOnStartUpOrBurn()

bool validateConfigOnStartUpOrBurn ( )

Definition at line 519 of file engine_controller.cpp.

519 {
520 if (!validateBoardConfig()) {
521 return false;
522 }
523#if defined(HW_HELLEN_UAEFI)
524 // todo: make this board-specific validation callback!
526#endif
527 if (!validateGdi()) {
528 return false;
529 }
530 if (engineConfiguration->etbMinimumPosition + 1 >= engineConfiguration->etbMaximumPosition) {
531 criticalError("Broken ETB min/max %d %d",
532 engineConfiguration->etbMinimumPosition,
533 engineConfiguration->etbMaximumPosition);
534 return false;
535 }
536
538 if (engineConfiguration->cylindersCount > MAX_CYLINDER_COUNT) {
539 criticalError("Invalid cylinder count: %d", engineConfiguration->cylindersCount);
540 return false;
541 }
542#if EFI_PROD_CODE && (BOARD_MC33810_COUNT > 0)
543 float maxConfiguredCorr = config->dwellVoltageCorrValues[0];
544 for (size_t i = 0;i<efi::size(config->dwellVoltageCorrValues);i++) {
545 maxConfiguredCorr = std::max(maxConfiguredCorr, (float)config->dwellVoltageCorrValues[i]);
546 }
547 float maxConfiguredDwell = config->sparkDwellValues[0];
548 for (size_t i = 0;i<efi::size(config->sparkDwellValues);i++) {
549 maxConfiguredDwell = std::max(maxConfiguredDwell, (float)config->sparkDwellValues[i]);
550 }
551 int maxAllowedDwell = getMc33810maxDwellTimer(engineConfiguration->mc33810maxDwellTimer);
552 if (maxConfiguredCorr * maxConfiguredDwell > maxAllowedDwell) {
553 criticalError("Dwell=%.2f/corr=%.2f while 33810 limit %d", maxConfiguredDwell, maxConfiguredCorr, maxAllowedDwell);
554 }
555
556#endif // EFI_PROD_CODE && (BOARD_MC33810_COUNT > 0)
557 if (engineConfiguration->adcVcc > 5.0f || engineConfiguration->adcVcc < 1.0f) {
558 criticalError("Invalid adcVcc: %f", engineConfiguration->adcVcc);
559 return false;
560 }
561
562 ensureArrayIsAscending("Injector deadtime vBATT", engineConfiguration->injector.battLagCorrBattBins);
563 ensureArrayIsAscending("Injector deadtime Pressure", engineConfiguration->injector.battLagCorrPressBins);
564
565#if EFI_ENGINE_CONTROL
566 // Fueling
567 {
568 ensureArrayIsAscending("VE load", config->veLoadBins);
569 ensureArrayIsAscending("VE RPM", config->veRpmBins);
570
571 ensureArrayIsAscending("Lambda/AFR load", config->lambdaLoadBins);
572 ensureArrayIsAscending("Lambda/AFR RPM", config->lambdaRpmBins);
573
574 ensureArrayIsAscending("Fuel CLT mult", config->cltFuelCorrBins);
575 ensureArrayIsAscending("Fuel IAT mult", config->iatFuelCorrBins);
576
577 ensureArrayIsAscendingOrDefault("Boost CLT mult", config->cltBoostCorrBins);
578 ensureArrayIsAscendingOrDefault("Boost IAT mult", config->iatBoostCorrBins);
579
580 ensureArrayIsAscending("Injection phase load", config->injPhaseLoadBins);
581 ensureArrayIsAscending("Injection phase RPM", config->injPhaseRpmBins);
582
583 ensureArrayIsAscendingOrDefault("Fuel Level Sensor", config->fuelLevelBins);
584
585 ensureArrayIsAscendingOrDefault("STFT Rpm", config->fuelTrimRpmBins);
586 ensureArrayIsAscendingOrDefault("STFT Load", config->fuelTrimLoadBins);
587
588 ensureArrayIsAscendingOrDefault("TC slip", engineConfiguration->tractionControlSlipBins);
589 ensureArrayIsAscendingOrDefault("TC speed", engineConfiguration->tractionControlSpeedBins);
590
591 ensureArrayIsAscending("TPS/TPS AE from", config->tpsTpsAccelFromRpmBins);
592 ensureArrayIsAscending("TPS/TPS AE to", config->tpsTpsAccelToRpmBins);
593
594 ensureArrayIsAscendingOrDefault("TPS TPS RPM correction", config->tpsTspCorrValuesBins);
595
596 ensureArrayIsAscendingOrDefault("Staging Load", config->injectorStagingLoadBins);
597 ensureArrayIsAscendingOrDefault("Staging RPM", config->injectorStagingRpmBins);
598 }
599
600 // Ignition
601 {
602 ensureArrayIsAscending("Dwell RPM", config->sparkDwellRpmBins);
603
604 ensureArrayIsAscending("Ignition load", config->ignitionLoadBins);
605 ensureArrayIsAscending("Ignition RPM", config->ignitionRpmBins);
606 ensureArrayIsAscendingOrDefault("Ign Trim Rpm", config->ignTrimRpmBins);
607 ensureArrayIsAscendingOrDefault("Ign Trim Load", config->ignTrimLoadBins);
608
609 ensureArrayIsAscending("Ignition CLT corr CLT", config->ignitionCltCorrTempBins);
610 ensureArrayIsAscending("Ignition CLT corr Load", config->ignitionCltCorrLoadBins);
611
612 ensureArrayIsAscending("Ignition IAT corr IAT", config->ignitionIatCorrTempBins);
613 ensureArrayIsAscending("Ignition IAT corr Load", config->ignitionIatCorrLoadBins);
614 }
615
616 ensureArrayIsAscendingOrDefault("Map estimate TPS", config->mapEstimateTpsBins);
617 ensureArrayIsAscendingOrDefault("Map estimate RPM", config->mapEstimateRpmBins);
618#endif // EFI_ENGINE_CONTROL
619
620 ensureArrayIsAscendingOrDefault("Script Curve 1", config->scriptCurve1Bins);
621 ensureArrayIsAscendingOrDefault("Script Curve 2", config->scriptCurve2Bins);
622 ensureArrayIsAscendingOrDefault("Script Curve 3", config->scriptCurve3Bins);
623 ensureArrayIsAscendingOrDefault("Script Curve 4", config->scriptCurve4Bins);
624 ensureArrayIsAscendingOrDefault("Script Curve 5", config->scriptCurve5Bins);
625 ensureArrayIsAscendingOrDefault("Script Curve 6", config->scriptCurve6Bins);
626
627// todo: huh? why does this not work on CI? ensureArrayIsAscendingOrDefault("Dwell Correction Voltage", engineConfiguration->dwellVoltageCorrVoltBins);
628
629 ensureArrayIsAscending("MAF transfer function", config->mafDecodingBins);
630
631 // Cranking tables
632 ensureArrayIsAscending("Cranking fuel mult", config->crankingFuelBins);
633 ensureArrayIsAscending("Cranking duration", config->crankingCycleBins);
634 ensureArrayIsAscending("Cranking Fuel CLT", config->crankingCycleFuelCltBins);
635 ensureArrayIsAscending("Cranking TPS", config->crankingTpsBins);
636
637 // Idle tables
638 ensureArrayIsAscending("Idle target RPM", config->cltIdleRpmBins);
639 ensureArrayIsAscending("Idle warmup mult CLT", config->cltIdleCorrBins);
640 ensureArrayIsAscending("Idle warmup mult RPM", config->rpmIdleCorrBins);
641 ensureArrayIsAscendingOrDefault("Idle coasting RPM", config->iacCoastingRpmBins);
642 ensureArrayIsAscendingOrDefault("Idle VE RPM", config->idleVeRpmBins);
643 ensureArrayIsAscendingOrDefault("Idle VE Load", config->idleVeLoadBins);
644 ensureArrayIsAscendingOrDefault("Idle timing", config->idleAdvanceBins);
645
646 for (size_t index = 0; index < efi::size(engineConfiguration->vrThreshold); index++) {
647 auto& cfg = engineConfiguration->vrThreshold[index];
648
649 if (cfg.pin == Gpio::Unassigned) {
650 continue;
651 }
652 ensureArrayIsAscending("VR threshold", cfg.rpmBins);
653 }
654
655#if EFI_BOOST_CONTROL
656 // Boost
657 ensureArrayIsAscending("Boost control Load [open loop]", config->boostOpenLoopLoadBins);
658 ensureArrayIsAscending("Boost control Load [closed loop]", config->boostClosedLoopLoadBins);
659 ensureArrayIsAscending("Boost control RPM [open+closed loop]", config->boostRpmBins);
660#endif // EFI_BOOST_CONTROL
661
662#if EFI_ANTILAG_SYSTEM
663 // ALS
664 ensureArrayIsAscendingOrDefault("ign ALS TPS", config->alsIgnRetardLoadBins);
665 ensureArrayIsAscendingOrDefault("ign ALS RPM", config->alsIgnRetardrpmBins);
666 ensureArrayIsAscendingOrDefault("fuel ALS TPS", config->alsFuelAdjustmentLoadBins);
667 ensureArrayIsAscendingOrDefault("fuel ALS RPM", config->alsFuelAdjustmentrpmBins);
668#endif // EFI_ANTILAG_SYSTEM
669
670#if EFI_ELECTRONIC_THROTTLE_BODY
671 // ETB
672 ensureArrayIsAscending("Pedal map pedal", config->pedalToTpsPedalBins);
673 ensureArrayIsAscending("Pedal map RPM", config->pedalToTpsRpmBins);
674#endif // EFI_ELECTRONIC_THROTTLE_BODY
675
676 if (isGdiEngine()) {
677 ensureArrayIsAscending("HPFP compensation", config->hpfpCompensationRpmBins);
678 ensureArrayIsAscending("HPFP deadtime", config->hpfpDeadtimeVoltsBins);
679 ensureArrayIsAscending("HPFP lobe profile", config->hpfpLobeProfileQuantityBins);
680 ensureArrayIsAscending("HPFP target rpm", config->hpfpTargetRpmBins);
681 ensureArrayIsAscending("HPFP target load", config->hpfpTargetLoadBins);
682
683 ensureArrayIsAscending("HPFP fuel mass compensation fuel pressure", config->hpfpFuelMassCompensationFuelPressure);
684 ensureArrayIsAscending("HPFP fuel mass compensation fuel mass", config->hpfpFuelMassCompensationFuelMass);
685
686 }
687
688 // VVT
689 if (isBrainPinValid(engineConfiguration->camInputs[0])) {
690 ensureArrayIsAscending("VVT intake load", config->vvtTable1LoadBins);
691 ensureArrayIsAscending("VVT intake RPM", config->vvtTable1RpmBins);
692 }
693
694#if CAM_INPUTS_COUNT != 1
695 if (isBrainPinValid(engineConfiguration->camInputs[1])) {
696 ensureArrayIsAscending("VVT exhaust load", config->vvtTable2LoadBins);
697 ensureArrayIsAscending("VVT exhaust RPM", config->vvtTable2RpmBins);
698 }
699#endif
700
701 if (engineConfiguration->enableOilPressureProtect) {
702 ensureArrayIsAscending("Oil pressure protection", config->minimumOilPressureBins);
703 }
704
706
707 return true;
708}
static void onConfigOnStartUpOrBurn()
@ Unassigned
void defaultsOrFixOnBurn()
void ensureArrayIsAscendingOrDefault(const char *msg, const TValue(&values)[TSize])
void ensureArrayIsAscending(const char *msg, const TValue(&values)[TSize])
void pickEtbOrStepper()
static constexpr persistent_config_s * config
PUBLIC_API_WEAK bool validateBoardConfig()
static bool validateGdi()
bool isGdiEngine()
int getMc33810maxDwellTimer(mc33810maxDwellTimer_e value)
Definition mc33810.cpp:1003
bool isBrainPinValid(brain_pin_e brainPin)

Referenced by handleBurnCommand(), and initEfiWithConfig().

Here is the call graph for this function:
Here is the caller graph for this function:

Go to the source code of this file.