separate function, code less confusing
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit

This commit is contained in:
Robin Müller 2023-02-20 18:53:56 +01:00
parent 94262a9d04
commit 60b07035b1
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
2 changed files with 67 additions and 58 deletions

View File

@ -146,8 +146,6 @@ ReturnValue_t PdecHandler::irqOperation() {
// Used to unmask IRQ
uint32_t info = 1;
ssize_t nb = 0;
int ret = 0;
interruptWindowCd.resetTimer();
@ -171,62 +169,7 @@ ReturnValue_t PdecHandler::irqOperation() {
state = State::RUNNING;
break;
case State::RUNNING: {
nb = write(fd, &info, sizeof(info));
if (nb != static_cast<ssize_t>(sizeof(info))) {
sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl;
triggerEvent(WRITE_SYSCALL_ERROR_PDEC, errno);
close(fd);
state = State::INIT;
return returnvalue::FAILED;
}
struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0};
ret = poll(&fds, 1, IRQ_TIMEOUT_MS);
if (ret == 0) {
// No TCs for timeout period
checkLocks();
genericCheckCd.resetTimer();
resetIrqLimiters();
} else if (ret >= 1) {
nb = read(fd, &info, sizeof(info));
interruptCounter++;
if (nb == static_cast<ssize_t>(sizeof(info))) {
uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET);
if ((pisr & TC_NEW_MASK) == TC_NEW_MASK) {
// handle TC
handleNewTc();
}
if ((pisr & TC_ABORT_MASK) == TC_ABORT_MASK) {
tcAbortCounter += 1;
}
if ((pisr & NEW_FAR_MASK) == NEW_FAR_MASK) {
// Read FAR here
CURRENT_FAR = readFar();
checkFrameAna(CURRENT_FAR);
}
if (genericCheckCd.hasTimedOut()) {
checkLocks();
genericCheckCd.resetTimer();
if (interruptWindowCd.timeOut()) {
if (interruptCounter >= MAX_ALLOWED_IRQS_PER_WINDOW) {
sif::error << "PdecHandler::irqOperation: Possible IRQ storm" << std::endl;
triggerEvent(TOO_MANY_IRQS, MAX_ALLOWED_IRQS_PER_WINDOW);
TaskFactory::delayTask(400);
break;
}
resetIrqLimiters();
}
}
// Clear interrupts with dummy read
dummy = *(registerBaseAddress + PDEC_PIR_OFFSET);
}
} else {
sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": "
<< strerror(errno) << std::endl;
triggerEvent(POLL_SYSCALL_ERROR_PDEC, errno);
close(fd);
state = State::INIT;
return returnvalue::FAILED;
}
checkAndHandleIrqs(fd, info);
break;
}
case State::WAIT_FOR_RECOVERY:
@ -244,6 +187,71 @@ ReturnValue_t PdecHandler::irqOperation() {
return returnvalue::OK;
}
ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) {
ssize_t nb = write(fd, &info, sizeof(info));
if (nb != static_cast<ssize_t>(sizeof(info))) {
sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl;
triggerEvent(WRITE_SYSCALL_ERROR_PDEC, errno);
close(fd);
state = State::INIT;
return returnvalue::FAILED;
}
struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0};
int ret = poll(&fds, 1, IRQ_TIMEOUT_MS);
if (ret == 0) {
// No TCs for timeout period
checkLocks();
genericCheckCd.resetTimer();
resetIrqLimiters();
} else if (ret >= 1) {
// Interrupt handling.
nb = read(fd, &info, sizeof(info));
interruptCounter++;
if (nb == static_cast<ssize_t>(sizeof(info))) {
uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET);
if ((pisr & TC_NEW_MASK) == TC_NEW_MASK) {
// handle TC
handleNewTc();
}
if ((pisr & TC_ABORT_MASK) == TC_ABORT_MASK) {
tcAbortCounter += 1;
}
if ((pisr & NEW_FAR_MASK) == NEW_FAR_MASK) {
// Read FAR here
CURRENT_FAR = readFar();
checkFrameAna(CURRENT_FAR);
}
// Clear interrupts with dummy read. Volatile is important here to prevent
// compiler opitmizations in release builds!
volatile uint32_t dummy = *(registerBaseAddress + PDEC_PIR_OFFSET);
static_cast<void>(dummy);
if (genericCheckCd.hasTimedOut()) {
checkLocks();
genericCheckCd.resetTimer();
if (interruptWindowCd.hasTimedOut()) {
if (interruptCounter >= MAX_ALLOWED_IRQS_PER_WINDOW) {
sif::error << "PdecHandler::irqOperation: Possible IRQ storm" << std::endl;
triggerEvent(TOO_MANY_IRQS, MAX_ALLOWED_IRQS_PER_WINDOW);
resetIrqLimiters();
TaskFactory::delayTask(400);
return returnvalue::FAILED;
}
resetIrqLimiters();
}
}
}
} else {
sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": "
<< strerror(errno) << std::endl;
triggerEvent(POLL_SYSCALL_ERROR_PDEC, errno);
close(fd);
state = State::INIT;
return returnvalue::FAILED;
}
return returnvalue::OK;
}
void PdecHandler::readCommandQueue(void) {
CommandMessage commandMessage;
ReturnValue_t result = returnvalue::FAILED;

View File

@ -266,6 +266,7 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
ReturnValue_t polledOperation();
ReturnValue_t irqOperation();
ReturnValue_t checkAndHandleIrqs(int fd, uint32_t& info);
uint32_t readFar();