various improvements
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good

This commit is contained in:
Robin Müller 2023-06-27 17:36:52 +02:00
parent 47ff8a418e
commit 15a67b81f9
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
6 changed files with 92 additions and 49 deletions

View File

@ -27,6 +27,12 @@ will consitute of a breaking change warranting a new major release:
- Internal error reporter set is now enabled by default and generated every 120 seconds. - Internal error reporter set is now enabled by default and generated every 120 seconds.
- Persistent TM store dumps are now performed in chronological order. - Persistent TM store dumps are now performed in chronological order.
## Fixed
- Various robustness improvements for the heater handler. The heater handler will now only
process the command queue if it is not busy with switch commanding which reduced the amount
of possible bugs.
# [v5.0.0] 2023-06-26 # [v5.0.0] 2023-06-26
v3.3.1 and all following version will now be moved to v5.0.0 with the additional changes listed v3.3.1 and all following version will now be moved to v5.0.0 with the additional changes listed

View File

@ -33,8 +33,8 @@ void ObjectFactory::produce(void* args) {
PersistentTmStores stores; PersistentTmStores stores;
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel, ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
*SdCardManager::instance(), &ipcStore, &tmStore, stores, *SdCardManager::instance(), &ipcStore, &tmStore, stores, 200,
200, true); true);
LinuxLibgpioIF* gpioComIF = nullptr; LinuxLibgpioIF* gpioComIF = nullptr;
SerialComIF* uartComIF = nullptr; SerialComIF* uartComIF = nullptr;

View File

@ -15,7 +15,7 @@ TemperatureSensorInserter::TemperatureSensorInserter(object_id_t objectId,
tmp1075DummyMap(std::move(tempTmpSensorDummies_)) {} tmp1075DummyMap(std::move(tempTmpSensorDummies_)) {}
ReturnValue_t TemperatureSensorInserter::initialize() { ReturnValue_t TemperatureSensorInserter::initialize() {
testCase = TestCase::NONE; testCase = TestCase::COLD_PLOC_CONSECUTIVE;
return returnvalue::OK; return returnvalue::OK;
} }
@ -96,6 +96,25 @@ ReturnValue_t TemperatureSensorInserter::performOperation(uint8_t opCode) {
} }
break; break;
} }
case (TestCase::COLD_PLOC_CONSECUTIVE): {
if (cycles == 15) {
sif::debug << "Setting cold PLOC temperature" << std::endl;
max31865DummyMap[objects::RTD_0_IC3_PLOC_HEATSPREADER]->setTemperature(-15, true);
}
if (cycles == 30) {
sif::debug << "Setting warmer PLOC temperature" << std::endl;
max31865DummyMap[objects::RTD_0_IC3_PLOC_HEATSPREADER]->setTemperature(0, true);
}
if (cycles == 45) {
sif::debug << "Setting cold PLOC temperature again" << std::endl;
max31865DummyMap[objects::RTD_0_IC3_PLOC_HEATSPREADER]->setTemperature(-15, true);
}
if (cycles == 60) {
sif::debug << "Setting warmer PLOC temperature again" << std::endl;
max31865DummyMap[objects::RTD_0_IC3_PLOC_HEATSPREADER]->setTemperature(0, true);
}
break;
}
case (TestCase::COLD_CAMERA): { case (TestCase::COLD_CAMERA): {
if (cycles == 15) { if (cycles == 15) {
sif::debug << "Setting cold CAM temperature" << std::endl; sif::debug << "Setting cold CAM temperature" << std::endl;

View File

@ -32,6 +32,7 @@ class TemperatureSensorInserter : public ExecutableObjectIF, public SystemObject
COLD_STR = 4, COLD_STR = 4,
COLD_STR_CONSECUTIVE = 5, COLD_STR_CONSECUTIVE = 5,
COLD_CAMERA = 6, COLD_CAMERA = 6,
COLD_PLOC_CONSECUTIVE = 7,
}; };
int iteration = 0; int iteration = 0;
uint32_t cycles = 0; uint32_t cycles = 0;

View File

@ -51,9 +51,13 @@ ReturnValue_t HeaterHandler::performOperation(uint8_t operationCode) {
if (mainLineSwitcher->getSwitchState(mainLineSwitch) == SWITCH_OFF) { if (mainLineSwitcher->getSwitchState(mainLineSwitch) == SWITCH_OFF) {
waitForSwitchOff = false; waitForSwitchOff = false;
mode = MODE_OFF; mode = MODE_OFF;
busyWithSwitchCommanding = false;
modeHelper.modeChanged(mode, submode); modeHelper.modeChanged(mode, submode);
} }
} }
if (busyWithSwitchCommanding and heaterCmdBusyCd.hasTimedOut()) {
busyWithSwitchCommanding = false;
}
} catch (const std::out_of_range& e) { } catch (const std::out_of_range& e) {
sif::warning << "HeaterHandler::performOperation: " sif::warning << "HeaterHandler::performOperation: "
"Out of range error | " "Out of range error | "
@ -102,6 +106,7 @@ void HeaterHandler::readCommandQueue() {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
CommandMessage command; CommandMessage command;
do { do {
if (not busyWithSwitchCommanding) {
result = commandQueue->receiveMessage(&command); result = commandQueue->receiveMessage(&command);
if (result == MessageQueueIF::EMPTY) { if (result == MessageQueueIF::EMPTY) {
break; break;
@ -109,13 +114,14 @@ void HeaterHandler::readCommandQueue() {
sif::warning << "HeaterHandler::readCommandQueue: Message reception error" << std::endl; sif::warning << "HeaterHandler::readCommandQueue: Message reception error" << std::endl;
break; break;
} }
result = modeHelper.handleModeCommand(&command);
if (result == returnvalue::OK) {
continue;
}
result = actionHelper.handleActionMessage(&command); result = actionHelper.handleActionMessage(&command);
if (result == returnvalue::OK) { if (result == returnvalue::OK) {
continue; continue;
} }
result = modeHelper.handleModeCommand(&command);
if (result == returnvalue::OK) {
continue;
} }
} while (result == returnvalue::OK); } while (result == returnvalue::OK);
} }
@ -167,6 +173,8 @@ ReturnValue_t HeaterHandler::executeAction(ActionId_t actionId, MessageQueueId_t
heater.action = action; heater.action = action;
heater.cmdActive = true; heater.cmdActive = true;
heater.replyQueue = commandedBy; heater.replyQueue = commandedBy;
busyWithSwitchCommanding = true;
heaterCmdBusyCd.resetTimer();
return returnvalue::OK; return returnvalue::OK;
} }
@ -249,6 +257,7 @@ void HeaterHandler::handleSwitchOnCommand(heater::Switch heaterIdx) {
sif::error << "HeaterHandler::handleSwitchOnCommand: Main switch setting on timeout" sif::error << "HeaterHandler::handleSwitchOnCommand: Main switch setting on timeout"
<< std::endl; << std::endl;
heater.cmdActive = false; heater.cmdActive = false;
busyWithSwitchCommanding = false;
heater.waitMainSwitchOn = false; heater.waitMainSwitchOn = false;
if (heater.replyQueue != commandQueue->getId()) { if (heater.replyQueue != commandQueue->getId()) {
actionHelper.finish(false, heater.replyQueue, heater.action, MAIN_SWITCH_SET_TIMEOUT); actionHelper.finish(false, heater.replyQueue, heater.action, MAIN_SWITCH_SET_TIMEOUT);
@ -259,27 +268,30 @@ void HeaterHandler::handleSwitchOnCommand(heater::Switch heaterIdx) {
// Check state of main line switch // Check state of main line switch
ReturnValue_t mainSwitchState = mainLineSwitcher->getSwitchState(mainLineSwitch); ReturnValue_t mainSwitchState = mainLineSwitcher->getSwitchState(mainLineSwitch);
if (mainSwitchState == PowerSwitchIF::SWITCH_ON) { if (mainSwitchState == PowerSwitchIF::SWITCH_ON) {
if (getSwitchState(heaterIdx) == SwitchState::OFF) {
gpioId_t gpioId = heater.gpioId; gpioId_t gpioId = heater.gpioId;
result = gpioInterface->pullHigh(gpioId); result = gpioInterface->pullHigh(gpioId);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::error << "HeaterHandler::handleSwitchOnCommand: Failed to pull gpio with id " << gpioId sif::error << "HeaterHandler::handleSwitchOnCommand: Failed to pull GPIO with ID " << gpioId
<< " high" << std::endl; << " high" << std::endl;
triggerEvent(GPIO_PULL_HIGH_FAILED, result); triggerEvent(GPIO_PULL_HIGH_FAILED, result);
} else { }
if (result == returnvalue::OK) {
if (getSwitchState(heaterIdx) == SwitchState::OFF) {
triggerEvent(HEATER_WENT_ON, heaterIdx, 0); triggerEvent(HEATER_WENT_ON, heaterIdx, 0);
EventManagerIF::triggerEvent(helper.heaters[heaterIdx].first->getObjectId(), MODE_INFO,
MODE_ON, 0);
{ {
MutexGuard mg(handlerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); MutexGuard mg(handlerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
heater.switchState = ON; heater.switchState = ON;
} }
}
} else { } else {
triggerEvent(SWITCH_ALREADY_ON, heaterIdx); triggerEvent(SWITCH_ALREADY_ON, heaterIdx);
} }
EventManagerIF::triggerEvent(helper.heaters[heaterIdx].first->getObjectId(), MODE_INFO,
MODE_ON, 0);
busyWithSwitchCommanding = false;
mode = HasModesIF::MODE_ON; mode = HasModesIF::MODE_ON;
modeHelper.modeChanged(mode, submode); modeHelper.modeChanged(mode, submode);
}
// There is no need to send action finish replies if the sender was the // There is no need to send action finish replies if the sender was the
// HeaterHandler itself // HeaterHandler itself
if (heater.replyQueue != commandQueue->getId()) { if (heater.replyQueue != commandQueue->getId()) {
@ -312,30 +324,33 @@ void HeaterHandler::handleSwitchOnCommand(heater::Switch heaterIdx) {
void HeaterHandler::handleSwitchOffCommand(heater::Switch heaterIdx) { void HeaterHandler::handleSwitchOffCommand(heater::Switch heaterIdx) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
auto& heater = heaterVec.at(heaterIdx); auto& heater = heaterVec.at(heaterIdx);
// Check whether switch is already off
if (getSwitchState(heaterIdx)) {
gpioId_t gpioId = heater.gpioId; gpioId_t gpioId = heater.gpioId;
result = gpioInterface->pullLow(gpioId); result = gpioInterface->pullLow(gpioId);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::error << "HeaterHandler::handleSwitchOffCommand: Failed to pull gpio with id" << gpioId sif::error << "HeaterHandler::handleSwitchOffCommand: Failed to pull gpio with id" << gpioId
<< " low" << std::endl; << " low" << std::endl;
triggerEvent(GPIO_PULL_LOW_FAILED, result); triggerEvent(GPIO_PULL_LOW_FAILED, result);
} else { }
if (result == returnvalue::OK) {
// Check whether switch is already off
if (getSwitchState(heaterIdx) == SwitchState::ON) {
{ {
MutexGuard mg(handlerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); MutexGuard mg(handlerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
heater.switchState = OFF; heater.switchState = OFF;
} }
triggerEvent(HEATER_WENT_OFF, heaterIdx, 0); triggerEvent(HEATER_WENT_OFF, heaterIdx, 0);
} else {
triggerEvent(SWITCH_ALREADY_OFF, heaterIdx);
}
EventManagerIF::triggerEvent(helper.heaters[heaterIdx].first->getObjectId(), MODE_INFO, EventManagerIF::triggerEvent(helper.heaters[heaterIdx].first->getObjectId(), MODE_INFO,
MODE_OFF, 0); MODE_OFF, 0);
// When all switches are off, also main line switch will be turned off // When all switches are off, also main line switch will be turned off
if (allSwitchesOff()) { if (allSwitchesOff()) {
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
waitForSwitchOff = true; waitForSwitchOff = true;
}
}
} else { } else {
triggerEvent(SWITCH_ALREADY_OFF, heaterIdx); busyWithSwitchCommanding = false;
}
} }
if (heater.replyQueue != NO_COMMANDER) { if (heater.replyQueue != NO_COMMANDER) {
// Report back switch command reply if necessary // Report back switch command reply if necessary

View File

@ -148,6 +148,7 @@ class HeaterHandler : public ExecutableObjectIF,
/** Size of command queue */ /** Size of command queue */
size_t cmdQueueSize = 20; size_t cmdQueueSize = 20;
bool waitForSwitchOff = true; bool waitForSwitchOff = true;
bool busyWithSwitchCommanding = false;
GpioIF* gpioInterface = nullptr; GpioIF* gpioInterface = nullptr;
@ -163,6 +164,7 @@ class HeaterHandler : public ExecutableObjectIF,
power::Switch_t mainLineSwitch; power::Switch_t mainLineSwitch;
ActionHelper actionHelper; ActionHelper actionHelper;
Countdown heaterCmdBusyCd = Countdown(2000);
StorageManagerIF* ipcStore = nullptr; StorageManagerIF* ipcStore = nullptr;