separate function, code less confusing
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
This commit is contained in:
parent
94262a9d04
commit
60b07035b1
@ -146,8 +146,6 @@ ReturnValue_t PdecHandler::irqOperation() {
|
|||||||
|
|
||||||
// Used to unmask IRQ
|
// Used to unmask IRQ
|
||||||
uint32_t info = 1;
|
uint32_t info = 1;
|
||||||
ssize_t nb = 0;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
interruptWindowCd.resetTimer();
|
interruptWindowCd.resetTimer();
|
||||||
|
|
||||||
@ -171,7 +169,26 @@ ReturnValue_t PdecHandler::irqOperation() {
|
|||||||
state = State::RUNNING;
|
state = State::RUNNING;
|
||||||
break;
|
break;
|
||||||
case State::RUNNING: {
|
case State::RUNNING: {
|
||||||
nb = write(fd, &info, sizeof(info));
|
checkAndHandleIrqs(fd, info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case State::WAIT_FOR_RECOVERY:
|
||||||
|
TaskFactory::delayTask(400);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Should never happen.
|
||||||
|
sif::error << "PdecHandler::performOperation: Invalid state" << std::endl;
|
||||||
|
TaskFactory::delayTask(400);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// To avoid compiler warning
|
||||||
|
static_cast<void>(dummy);
|
||||||
|
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))) {
|
if (nb != static_cast<ssize_t>(sizeof(info))) {
|
||||||
sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl;
|
sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl;
|
||||||
triggerEvent(WRITE_SYSCALL_ERROR_PDEC, errno);
|
triggerEvent(WRITE_SYSCALL_ERROR_PDEC, errno);
|
||||||
@ -180,13 +197,14 @@ ReturnValue_t PdecHandler::irqOperation() {
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0};
|
struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0};
|
||||||
ret = poll(&fds, 1, IRQ_TIMEOUT_MS);
|
int ret = poll(&fds, 1, IRQ_TIMEOUT_MS);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
// No TCs for timeout period
|
// No TCs for timeout period
|
||||||
checkLocks();
|
checkLocks();
|
||||||
genericCheckCd.resetTimer();
|
genericCheckCd.resetTimer();
|
||||||
resetIrqLimiters();
|
resetIrqLimiters();
|
||||||
} else if (ret >= 1) {
|
} else if (ret >= 1) {
|
||||||
|
// Interrupt handling.
|
||||||
nb = read(fd, &info, sizeof(info));
|
nb = read(fd, &info, sizeof(info));
|
||||||
interruptCounter++;
|
interruptCounter++;
|
||||||
if (nb == static_cast<ssize_t>(sizeof(info))) {
|
if (nb == static_cast<ssize_t>(sizeof(info))) {
|
||||||
@ -203,21 +221,25 @@ ReturnValue_t PdecHandler::irqOperation() {
|
|||||||
CURRENT_FAR = readFar();
|
CURRENT_FAR = readFar();
|
||||||
checkFrameAna(CURRENT_FAR);
|
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()) {
|
if (genericCheckCd.hasTimedOut()) {
|
||||||
checkLocks();
|
checkLocks();
|
||||||
genericCheckCd.resetTimer();
|
genericCheckCd.resetTimer();
|
||||||
if (interruptWindowCd.timeOut()) {
|
if (interruptWindowCd.hasTimedOut()) {
|
||||||
if (interruptCounter >= MAX_ALLOWED_IRQS_PER_WINDOW) {
|
if (interruptCounter >= MAX_ALLOWED_IRQS_PER_WINDOW) {
|
||||||
sif::error << "PdecHandler::irqOperation: Possible IRQ storm" << std::endl;
|
sif::error << "PdecHandler::irqOperation: Possible IRQ storm" << std::endl;
|
||||||
triggerEvent(TOO_MANY_IRQS, MAX_ALLOWED_IRQS_PER_WINDOW);
|
triggerEvent(TOO_MANY_IRQS, MAX_ALLOWED_IRQS_PER_WINDOW);
|
||||||
|
resetIrqLimiters();
|
||||||
TaskFactory::delayTask(400);
|
TaskFactory::delayTask(400);
|
||||||
break;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
resetIrqLimiters();
|
resetIrqLimiters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Clear interrupts with dummy read
|
|
||||||
dummy = *(registerBaseAddress + PDEC_PIR_OFFSET);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": "
|
sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": "
|
||||||
@ -227,20 +249,6 @@ ReturnValue_t PdecHandler::irqOperation() {
|
|||||||
state = State::INIT;
|
state = State::INIT;
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
case State::WAIT_FOR_RECOVERY:
|
|
||||||
TaskFactory::delayTask(400);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// Should never happen.
|
|
||||||
sif::error << "PdecHandler::performOperation: Invalid state" << std::endl;
|
|
||||||
TaskFactory::delayTask(400);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// To avoid compiler warning
|
|
||||||
static_cast<void>(dummy);
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,6 +266,7 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
|
|||||||
|
|
||||||
ReturnValue_t polledOperation();
|
ReturnValue_t polledOperation();
|
||||||
ReturnValue_t irqOperation();
|
ReturnValue_t irqOperation();
|
||||||
|
ReturnValue_t checkAndHandleIrqs(int fd, uint32_t& info);
|
||||||
|
|
||||||
uint32_t readFar();
|
uint32_t readFar();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user