Merge remote-tracking branch 'origin/develop' into refactoring_syrlinks_com_if
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
#include <fsfw_hal/linux/uio/UioMapper.h>
|
||||
#include <linux/ipcore/PapbVcInterface.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
@ -15,47 +16,67 @@ PapbVcInterface::~PapbVcInterface() {}
|
||||
|
||||
ReturnValue_t PapbVcInterface::initialize() {
|
||||
UioMapper uioMapper(uioFile, mapNum);
|
||||
return uioMapper.getMappedAdress(&vcBaseReg, UioMapper::Permissions::WRITE_ONLY);
|
||||
uint32_t* baseReg;
|
||||
ReturnValue_t result = uioMapper.getMappedAdress(&baseReg, UioMapper::Permissions::WRITE_ONLY);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
vcBaseReg = baseReg;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
|
||||
if (pollPapbBusySignal() == returnvalue::OK) {
|
||||
if (pollPapbBusySignal(0, 0) == returnvalue::OK) {
|
||||
startPacketTransfer();
|
||||
} else {
|
||||
return DirectTmSinkIF::IS_BUSY;
|
||||
}
|
||||
for (size_t idx = 0; idx < size; idx++) {
|
||||
if (pollPapbBusySignal() == returnvalue::OK) {
|
||||
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(*(data + idx));
|
||||
if (pollPapbBusySignal(10, 10) == returnvalue::OK) {
|
||||
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[idx]);
|
||||
} else {
|
||||
sif::warning << "PapbVcInterface::write: Only written " << idx << " of " << size << " data"
|
||||
<< std::endl;
|
||||
abortPacketTransfer();
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
if (pollPapbBusySignal() == returnvalue::OK) {
|
||||
endPacketTransfer();
|
||||
if (pollPapbBusySignal(10, 10) == returnvalue::OK) {
|
||||
completePacketTransfer();
|
||||
} else {
|
||||
abortPacketTransfer();
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; }
|
||||
|
||||
void PapbVcInterface::endPacketTransfer() { *vcBaseReg = CONFIG_END; }
|
||||
void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; }
|
||||
|
||||
ReturnValue_t PapbVcInterface::pollPapbBusySignal() const {
|
||||
ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries,
|
||||
uint32_t retryDelayUs) const {
|
||||
gpio::Levels papbBusyState = gpio::Levels::LOW;
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
ReturnValue_t result;
|
||||
uint32_t busyIdx = 0;
|
||||
|
||||
/** Check if PAPB interface is ready to receive data */
|
||||
result = gpioComIF->readGpio(papbBusyId, papbBusyState);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "PapbVcInterface::pollPapbBusySignal: Failed to read papb busy signal"
|
||||
<< std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (papbBusyState == gpio::Levels::LOW) {
|
||||
return PAPB_BUSY;
|
||||
}
|
||||
while (true) {
|
||||
/** Check if PAPB interface is ready to receive data */
|
||||
result = gpioComIF->readGpio(papbBusyId, papbBusyState);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "PapbVcInterface::pollPapbBusySignal: Failed to read papb busy signal"
|
||||
<< std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (papbBusyState == gpio::Levels::HIGH) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
busyIdx++;
|
||||
if (busyIdx >= maxPollRetries) {
|
||||
return PAPB_BUSY;
|
||||
}
|
||||
|
||||
usleep(retryDelayUs);
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -79,7 +100,9 @@ void PapbVcInterface::isVcInterfaceBufferEmpty() {
|
||||
return;
|
||||
}
|
||||
|
||||
bool PapbVcInterface::isBusy() const { return pollPapbBusySignal() == PAPB_BUSY; }
|
||||
bool PapbVcInterface::isBusy() const { return pollPapbBusySignal(0, 0) == PAPB_BUSY; }
|
||||
|
||||
void PapbVcInterface::cancelTransfer() { abortPacketTransfer(); }
|
||||
|
||||
ReturnValue_t PapbVcInterface::sendTestFrame() {
|
||||
/** Size of one complete transfer frame data field amounts to 1105 bytes */
|
||||
@ -97,3 +120,5 @@ ReturnValue_t PapbVcInterface::sendTestFrame() {
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void PapbVcInterface::abortPacketTransfer() { *vcBaseReg = CONFIG_ABORT; }
|
||||
|
@ -41,6 +41,8 @@ class PapbVcInterface : public VirtualChannelIF {
|
||||
*/
|
||||
ReturnValue_t write(const uint8_t* data, size_t size) override;
|
||||
|
||||
void cancelTransfer() override;
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
private:
|
||||
@ -51,16 +53,21 @@ class PapbVcInterface : public VirtualChannelIF {
|
||||
/**
|
||||
* Configuration bits:
|
||||
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
||||
* bit[2]: Set this bit to 1 to abort a transfered packet
|
||||
* bit[2]: Set this bit to 1 to abort a transferred packet
|
||||
* bit[3]: Signals to VcInterface the start of a new telemetry packet
|
||||
*/
|
||||
static const uint32_t CONFIG_START = 0x8;
|
||||
static constexpr uint32_t CONFIG_START = 0b00001000;
|
||||
|
||||
/**
|
||||
* Abort a transferred packet.
|
||||
*/
|
||||
static constexpr uint32_t CONFIG_ABORT = 0b00000100;
|
||||
|
||||
/**
|
||||
* Writing this word to the VcInterface base address signals to the virtual channel interface
|
||||
* that a complete tm packet has been transferred.
|
||||
*/
|
||||
static const uint32_t CONFIG_END = 0x0;
|
||||
static constexpr uint32_t CONFIG_END = 0x0;
|
||||
|
||||
/**
|
||||
* Writing to this offset within the memory space of a virtual channel will insert data for
|
||||
@ -79,7 +86,7 @@ class PapbVcInterface : public VirtualChannelIF {
|
||||
std::string uioFile;
|
||||
int mapNum = 0;
|
||||
|
||||
uint32_t* vcBaseReg = nullptr;
|
||||
volatile uint32_t* vcBaseReg = nullptr;
|
||||
|
||||
uint32_t vcOffset = 0;
|
||||
|
||||
@ -89,11 +96,13 @@ class PapbVcInterface : public VirtualChannelIF {
|
||||
*/
|
||||
void startPacketTransfer();
|
||||
|
||||
void abortPacketTransfer();
|
||||
|
||||
/**
|
||||
* @brief This function sends the config byte to the virtual channel interface of the PTME
|
||||
* IP Core to signal the end of a packet transfer.
|
||||
*/
|
||||
void endPacketTransfer();
|
||||
void completePacketTransfer();
|
||||
|
||||
/**
|
||||
* @brief This function reads the papb busy signal indicating whether the virtual channel
|
||||
@ -102,7 +111,7 @@ class PapbVcInterface : public VirtualChannelIF {
|
||||
*
|
||||
* @return returnvalue::OK when ready to receive data else PAPB_BUSY.
|
||||
*/
|
||||
ReturnValue_t pollPapbBusySignal() const;
|
||||
ReturnValue_t pollPapbBusySignal(uint32_t maxPollRetries, uint32_t retryDelayUs) const;
|
||||
|
||||
/**
|
||||
* @brief This function can be used for debugging to check whether there are packets in
|
||||
|
@ -20,7 +20,6 @@ ReturnValue_t Ptme::initialize() {
|
||||
}
|
||||
|
||||
ReturnValue_t Ptme::writeToVc(uint8_t vcId, const uint8_t* data, size_t size) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
VcInterfaceMapIter vcInterfaceMapIter = vcInterfaceMap.find(vcId);
|
||||
if (vcInterfaceMapIter == vcInterfaceMap.end()) {
|
||||
sif::warning << "Ptme::writeToVc: No virtual channel interface found for the virtual "
|
||||
@ -28,8 +27,7 @@ ReturnValue_t Ptme::writeToVc(uint8_t vcId, const uint8_t* data, size_t size) {
|
||||
<< static_cast<unsigned int>(vcId) << std::endl;
|
||||
return UNKNOWN_VC_ID;
|
||||
}
|
||||
result = vcInterfaceMapIter->second->write(data, size);
|
||||
return result;
|
||||
return vcInterfaceMapIter->second->write(data, size);
|
||||
}
|
||||
|
||||
void Ptme::addVcInterface(VcId_t vcId, VirtualChannelIF* vc) {
|
||||
@ -62,3 +60,11 @@ bool Ptme::isBusy(uint8_t vcId) const {
|
||||
}
|
||||
return vcInterfaceMapIter->second->isBusy();
|
||||
}
|
||||
|
||||
void Ptme::cancelTransfer(uint8_t vcId) {
|
||||
VcInterfaceMapIter vcInterfaceMapIter = vcInterfaceMap.find(vcId);
|
||||
if (vcInterfaceMapIter == vcInterfaceMap.end()) {
|
||||
return;
|
||||
}
|
||||
return vcInterfaceMapIter->second->cancelTransfer();
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ class Ptme : public PtmeIF, public SystemObject {
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) override;
|
||||
bool isBusy(uint8_t vcId) const override;
|
||||
void cancelTransfer(uint8_t vcId) override;
|
||||
|
||||
/**
|
||||
* @brief This function adds the reference to a virtual channel interface to the vcInterface
|
||||
|
@ -23,6 +23,7 @@ class PtmeIF {
|
||||
*/
|
||||
virtual ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) = 0;
|
||||
virtual bool isBusy(uint8_t vcId) const = 0;
|
||||
virtual void cancelTransfer(uint8_t vcId) = 0;
|
||||
};
|
||||
|
||||
#endif /* LINUX_OBC_PTMEIF_H_ */
|
||||
|
@ -18,6 +18,7 @@ class VirtualChannelIF : public DirectTmSinkIF {
|
||||
virtual ~VirtualChannelIF(){};
|
||||
|
||||
virtual ReturnValue_t initialize() = 0;
|
||||
virtual void cancelTransfer() = 0;
|
||||
};
|
||||
|
||||
#endif /* LINUX_OBC_VCINTERFACEIF_H_ */
|
||||
|
@ -8,6 +8,9 @@
|
||||
#include "ObjectFactory.h"
|
||||
#include "eive/objects.h"
|
||||
|
||||
PosixThreadArgs scheduling::RR_SCHEDULING = {.policy = SchedulingPolicy::RR};
|
||||
PosixThreadArgs scheduling::NORMAL_SCHEDULING;
|
||||
|
||||
void scheduling::scheduleScexReader(TaskFactory& factory, PeriodicTaskIF*& scexReaderTask) {
|
||||
using namespace scheduling;
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
@ -18,8 +21,9 @@ void scheduling::scheduleScexReader(TaskFactory& factory, PeriodicTaskIF*& scexR
|
||||
#endif
|
||||
|
||||
result = returnvalue::OK;
|
||||
scexReaderTask = factory.createPeriodicTask(
|
||||
"SCEX_UART_READER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||
scexReaderTask =
|
||||
factory.createPeriodicTask("SCEX_UART_READER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0,
|
||||
missedDeadlineFunc, &NORMAL_SCHEDULING);
|
||||
result = scexReaderTask->addComponent(objects::SCEX_UART_READER);
|
||||
if (result != returnvalue::OK) {
|
||||
printAddObjectError("SCEX_UART_READER", objects::SCEX_UART_READER);
|
||||
|
@ -1,8 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/osal/linux/PosixThread.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
|
||||
namespace scheduling {
|
||||
|
||||
extern PosixThreadArgs RR_SCHEDULING;
|
||||
extern PosixThreadArgs NORMAL_SCHEDULING;
|
||||
|
||||
void scheduleScexDev(PeriodicTaskIF*& scexDevHandler);
|
||||
void scheduleScexReader(TaskFactory& factory, PeriodicTaskIF*& scexReaderTask);
|
||||
void addMpsocSupvHandlers(PeriodicTaskIF* task);
|
||||
|
Reference in New Issue
Block a user