Compare commits

..

7 Commits

46 changed files with 742 additions and 1140 deletions

View File

@ -19,16 +19,3 @@ enum ServiceIds : uint8_t {
PUS_SERVICE_200 = 200
};
}
namespace common {
/**
* The APID is a 14 bit identifier which can be used to distinguish processes and applications
* on a spacecraft. For more details, see the related ECSS/CCSDS standards.
* For this example, we are going to use a constant APID
*/
static constexpr uint16_t COMMON_PUS_APID = 0xEF;
static constexpr uint16_t COMMON_CFDP_APID = 0xF0;
static constexpr uint16_t COMMON_CFDP_CLIENT_ENTITY_ID = 0x01;
} // namespace common

View File

@ -6,8 +6,8 @@
namespace CLASS_ID {
enum commonClassIds : uint8_t {
COMMON_CLASS_ID_START = FW_CLASS_ID_COUNT,
DUMMY_HANDLER, // DDH
COMMON_CLASS_ID_END // [EXPORT] : [END]
DUMMY_HANDLER, // DDH
COMMON_CLASS_ID_END // [EXPORT] : [END]
};
}

View File

@ -6,7 +6,7 @@
#include <cstdint>
#cmakedefine01 FSFW_ADD_FMT_TESTS
#cmakedefine01 OBSW_ADD_FMT_TESTS
//! Specify the debug output verbose level
#define OBSW_VERBOSE_LEVEL 1
@ -18,7 +18,6 @@
//! Add core components for the FSFW and for TMTC communication
#define OBSW_ADD_CORE_COMPONENTS 1
#define OBSW_ADD_CFDP_COMPONENTS 1
//! Add the PUS service stack
#define OBSW_ADD_PUS_STACK 1
@ -36,8 +35,21 @@
#define OBSW_ADD_CONTROLLER_DEMO 1
#define OBSW_CONTROLLER_PRINTOUT 1
/**
* The APID is a 14 bit identifier which can be used to distinguish processes and applications
* on a spacecraft. For more details, see the related ECSS/CCSDS standards.
* For this example, we are going to use a constant APID
*/
static const uint16_t COMMON_APID = 0xEF;
#ifdef __cplusplus
namespace cfg {
static constexpr uint32_t OBSW_MAX_SCHEDULED_TCS = @OBSW_MAX_SCHEDULED_TCS@;
}
#endif /* __cplusplus */
#endif /* COMMON_COMMONCONFIG_H_ */

View File

@ -25,10 +25,6 @@ enum commonObjects : object_id_t {
CCSDS_DISTRIBUTOR = 0x63000000,
PUS_DISTRIBUTOR = 0x63000001,
TM_FUNNEL = 0x63000002,
CFDP_DISTRIBUTOR = 0x63000003,
CFDP_HANDLER = 0x63000004,
PUS_TM_FUNNEL = 0x63000005,
CFDP_TM_FUNNEL = 0x64000006,
/* 0x74 ('t') for test and example objects */
TEST_TASK = 0x7400CAFE,

View File

@ -1,4 +1,5 @@
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
#include "example/test/FsfwExampleTask.h"
@ -8,9 +9,12 @@
ReturnValue_t pst::pollingSequenceExamples(FixedTimeslotTaskIF *thisSequence) {
uint32_t length = thisSequence->getPeriodMs();
thisSequence->addSlot(objects::TEST_DUMMY_1, length * 0, FsfwExampleTask::OpCodes::SEND_RAND_NUM);
thisSequence->addSlot(objects::TEST_DUMMY_2, length * 0, FsfwExampleTask::OpCodes::SEND_RAND_NUM);
thisSequence->addSlot(objects::TEST_DUMMY_3, length * 0, FsfwExampleTask::OpCodes::SEND_RAND_NUM);
thisSequence->addSlot(objects::TEST_DUMMY_1, length * 0,
FsfwExampleTask::OpCodes::SEND_RAND_NUM);
thisSequence->addSlot(objects::TEST_DUMMY_2, length * 0,
FsfwExampleTask::OpCodes::SEND_RAND_NUM);
thisSequence->addSlot(objects::TEST_DUMMY_3, length * 0,
FsfwExampleTask::OpCodes::SEND_RAND_NUM);
thisSequence->addSlot(objects::TEST_DUMMY_1, length * 0.2,
FsfwExampleTask::OpCodes::RECEIVE_RAND_NUM);
@ -19,48 +23,53 @@ ReturnValue_t pst::pollingSequenceExamples(FixedTimeslotTaskIF *thisSequence) {
thisSequence->addSlot(objects::TEST_DUMMY_3, length * 0.2,
FsfwExampleTask::OpCodes::RECEIVE_RAND_NUM);
thisSequence->addSlot(objects::TEST_DUMMY_1, length * 0.5, FsfwExampleTask::OpCodes::DELAY_SHORT);
thisSequence->addSlot(objects::TEST_DUMMY_2, length * 0.5, FsfwExampleTask::OpCodes::DELAY_SHORT);
thisSequence->addSlot(objects::TEST_DUMMY_3, length * 0.5, FsfwExampleTask::OpCodes::DELAY_SHORT);
thisSequence->addSlot(objects::TEST_DUMMY_1, length * 0.5,
FsfwExampleTask::OpCodes::DELAY_SHORT);
thisSequence->addSlot(objects::TEST_DUMMY_2, length * 0.5,
FsfwExampleTask::OpCodes::DELAY_SHORT);
thisSequence->addSlot(objects::TEST_DUMMY_3, length * 0.5,
FsfwExampleTask::OpCodes::DELAY_SHORT);
if (thisSequence->checkSequence() == returnvalue::OK) {
return returnvalue::OK;
if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) {
return HasReturnvaluesIF::RETURN_OK;
} else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "pst::pollingSequenceInitFunction: Initialization errors!" << std::endl;
#else
sif::printError("pst::pollingSequenceInitFunction: Initialization errors!\n");
#endif
return returnvalue::OK;
FSFW_LOGE("pst::pollingSequenceInitFunction: Initialization errors\n");
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t pst::pollingSequenceDevices(FixedTimeslotTaskIF *thisSequence) {
uint32_t length = thisSequence->getPeriodMs();
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.3 * length, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.3 * length, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.3 * length,
DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.3 * length,
DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.45 * length, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.45 * length, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.45 * length,
DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.45 * length,
DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.6 * length, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.6 * length, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.6 * length,
DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.6 * length,
DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.8 * length, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.8 * length, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.8 * length,
DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.8 * length,
DeviceHandlerIF::GET_READ);
if (thisSequence->checkSequence() == returnvalue::OK) {
return returnvalue::OK;
if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) {
return HasReturnvaluesIF::RETURN_OK;
} else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "pst::pollingSequenceTestFunction: Initialization errors!" << std::endl;
#else
sif::printError("pst::pollingSequenceTestFunction: Initialization errors!\n");
#endif
return returnvalue::OK;
FSFW_LOGE("pst::pollingSequenceTestFunction: Initialization errors\n");
return HasReturnvaluesIF::RETURN_FAILED;
}
}

View File

@ -3,4 +3,3 @@ add_subdirectory(core)
add_subdirectory(devices)
add_subdirectory(test)
add_subdirectory(utility)
add_subdirectory(cfdp)

View File

@ -1 +0,0 @@

View File

@ -1,59 +0,0 @@
#ifndef FSFW_EXAMPLE_HOSTED_CONFIG_H
#define FSFW_EXAMPLE_HOSTED_CONFIG_H
#include "fsfw/cfdp.h"
namespace cfdp {
extern PacketInfoListBase* PACKET_LIST_PTR;
extern LostSegmentsListBase* LOST_SEGMENTS_PTR;
class ExampleUserHandler : public UserBase {
public:
explicit ExampleUserHandler(HasFileSystemIF& vfs) : cfdp::UserBase(vfs) {}
void transactionIndication(const cfdp::TransactionId& id) override {}
void eofSentIndication(const cfdp::TransactionId& id) override {}
void transactionFinishedIndication(const cfdp::TransactionFinishedParams& params) override {
sif::info << "File transaction finished for transaction with " << params.id << std::endl;
}
void metadataRecvdIndication(const cfdp::MetadataRecvdParams& params) override {
sif::info << "Metadata received for transaction with " << params.id << std::endl;
}
void fileSegmentRecvdIndication(const cfdp::FileSegmentRecvdParams& params) override {}
void reportIndication(const cfdp::TransactionId& id, cfdp::StatusReportIF& report) override {}
void suspendedIndication(const cfdp::TransactionId& id, cfdp::ConditionCode code) override {}
void resumedIndication(const cfdp::TransactionId& id, size_t progress) override {}
void faultIndication(const cfdp::TransactionId& id, cfdp::ConditionCode code,
size_t progress) override {}
void abandonedIndication(const cfdp::TransactionId& id, cfdp::ConditionCode code,
size_t progress) override {}
void eofRecvIndication(const cfdp::TransactionId& id) override {
sif::info << "EOF PDU received for transaction with " << id << std::endl;
}
};
class ExampleFaultHandler : public cfdp::FaultHandlerBase {
public:
void noticeOfSuspensionCb(cfdp::TransactionId& id, cfdp::ConditionCode code) override {
sif::warning << "Notice of suspension detected for transaction " << id
<< " with condition code: " << cfdp::getConditionCodeString(code) << std::endl;
}
void noticeOfCancellationCb(cfdp::TransactionId& id, cfdp::ConditionCode code) override {
sif::warning << "Notice of suspension detected for transaction " << id
<< " with condition code: " << cfdp::getConditionCodeString(code) << std::endl;
}
void abandonCb(cfdp::TransactionId& id, cfdp::ConditionCode code) override {
sif::warning << "Transaction " << id
<< " was abandoned, condition code : " << cfdp::getConditionCodeString(code)
<< std::endl;
}
void ignoreCb(cfdp::TransactionId& id, cfdp::ConditionCode code) override {
sif::warning << "Fault ignored for transaction " << id
<< ", condition code: " << cfdp::getConditionCodeString(code) << std::endl;
}
};
} // namespace cfdp
#endif // FSFW_EXAMPLE_HOSTED_CONFIG_H

View File

@ -2,23 +2,22 @@
#include <fsfw/datapool/PoolReadGuard.h>
FsfwTestController::FsfwTestController(object_id_t objectId, object_id_t device0,
object_id_t device1, uint8_t verboseLevel)
: TestController(objectId, objects::NO_OBJECT, 5),
device0Id(device0),
device1Id(device1),
deviceDataset0(device0),
deviceDataset1(device1) {}
FsfwTestController::FsfwTestController(object_id_t objectId,
object_id_t device0, object_id_t device1,
uint8_t verboseLevel)
: TestController(objectId, objects::NO_OBJECT, 5), device0Id(device0),
device1Id(device1), deviceDataset0(device0), deviceDataset1(device1) {}
FsfwTestController::~FsfwTestController() = default;
FsfwTestController::~FsfwTestController() {}
ReturnValue_t FsfwTestController::handleCommandMessage(CommandMessage *message) {
return returnvalue::OK;
ReturnValue_t
FsfwTestController::handleCommandMessage(CommandMessage *message) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t FsfwTestController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
return returnvalue::OK;
ReturnValue_t FsfwTestController::initializeLocalDataPool(
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
return HasReturnvaluesIF::RETURN_OK;
}
void FsfwTestController::performControlOperation() {
@ -33,24 +32,15 @@ void FsfwTestController::performControlOperation() {
}
case (TRACE_DEV_0_UINT8): {
if (traceCounter == 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "Tracing finished" << std::endl;
#else
sif::printInfo("Tracing finished\n");
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
FSFW_LOGI("Tracing finished\n");
traceVariable = false;
traceCounter = traceCycles;
currentTraceType = TraceTypes::NONE;
break;
}
PoolReadGuard readHelper(&deviceDataset0.testUint8Var);
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "Tracing device 0 variable 0 (UINT8), current value: "
<< static_cast<int>(deviceDataset0.testUint8Var.value) << std::endl;
#else
sif::printInfo("Tracing device 0 variable 0 (UINT8), current value: %d\n",
deviceDataset0.testUint8Var.value);
#endif
FSFW_LOGI("Tracing device 0 variable 0 (UINT8), current value: {}",
static_cast<int>(deviceDataset0.testUint8Var.value));
traceCounter--;
break;
}
@ -64,102 +54,76 @@ void FsfwTestController::performControlOperation() {
ReturnValue_t FsfwTestController::initializeAfterTaskCreation() {
namespace td = testdevice;
ReturnValue_t result = TestController::initializeAfterTaskCreation();
if (result != returnvalue::OK) {
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
auto *device0 =
auto* device0 =
ObjectManager::instance()->get<HasLocalDataPoolIF>(deviceDataset0.getCreatorObjectId());
if (device0 == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TestController::initializeAfterTaskCreation: Test device handler 0 "
"handle invalid!"
<< std::endl;
#else
sif::printWarning(
"TestController::initializeAfterTaskCreation: Test device handler 0 "
"handle invalid!");
#endif
FSFW_LOGW("initializeAfterTaskCreation: Test device handler 0 handle invalid\n");
return ObjectManagerIF::CHILD_INIT_FAILED;
}
ProvidesDataPoolSubscriptionIF *subscriptionIF = device0->getSubscriptionInterface();
ProvidesDataPoolSubscriptionIF *subscriptionIF =
device0->getSubscriptionInterface();
if (subscriptionIF != nullptr) {
/* For DEVICE_0, we only subscribe for notifications */
subscriptionIF->subscribeForSetUpdateMessage(td::TEST_SET_ID, getObjectId(), getCommandQueue(),
false);
subscriptionIF->subscribeForVariableUpdateMessage(td::PoolIds::TEST_UINT8_ID, getObjectId(),
getCommandQueue(), false);
subscriptionIF->subscribeForSetUpdateMessage(td::TEST_SET_ID, getObjectId(),
getCommandQueue(), false);
subscriptionIF->subscribeForVariableUpdateMessage(
td::PoolIds::TEST_UINT8_ID, getObjectId(), getCommandQueue(), false);
}
auto *device1 =
auto* device1 =
ObjectManager::instance()->get<HasLocalDataPoolIF>(deviceDataset0.getCreatorObjectId());
if (device1 == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TestController::initializeAfterTaskCreation: Test device handler 1 "
"handle invalid!"
<< std::endl;
#else
sif::printWarning(
"TestController::initializeAfterTaskCreation: Test device handler 1 "
"handle invalid!");
#endif
FSFW_LOGW("initializeAfterTaskCreation: Test device handler 1 handle invalid\n");
}
subscriptionIF = device1->getSubscriptionInterface();
if (subscriptionIF != nullptr) {
/* For DEVICE_1, we will subscribe for snapshots */
subscriptionIF->subscribeForSetUpdateMessage(td::TEST_SET_ID, getObjectId(), getCommandQueue(),
true);
subscriptionIF->subscribeForVariableUpdateMessage(td::PoolIds::TEST_UINT8_ID, getObjectId(),
getCommandQueue(), true);
subscriptionIF->subscribeForSetUpdateMessage(td::TEST_SET_ID, getObjectId(),
getCommandQueue(), true);
subscriptionIF->subscribeForVariableUpdateMessage(
td::PoolIds::TEST_UINT8_ID, getObjectId(), getCommandQueue(), true);
}
return result;
}
LocalPoolDataSetBase *FsfwTestController::getDataSetHandle(sid_t sid) { return nullptr; }
ReturnValue_t FsfwTestController::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) {
return returnvalue::OK;
LocalPoolDataSetBase *FsfwTestController::getDataSetHandle(sid_t sid) {
return nullptr;
}
void FsfwTestController::handleChangedDataset(sid_t sid, store_address_t storeId,
ReturnValue_t FsfwTestController::checkModeCommand(Mode_t mode,
Submode_t submode,
uint32_t *msToReachTheMode) {
return HasReturnvaluesIF::RETURN_OK;
}
void FsfwTestController::handleChangedDataset(sid_t sid,
store_address_t storeId,
bool *clearMessage) {
using namespace std;
if (verboseLevel >= 1) {
char const *printout = nullptr;
if (storeId == store_address_t::invalid()) {
if (storeId == storeId::INVALID_STORE_ADDRESS) {
printout = "Notification";
} else {
printout = "Snapshot";
}
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "FsfwTestController::handleChangedDataset: " << printout
<< " update"
"from object ID "
<< setw(8) << setfill('0') << hex << sid.objectId << " and set ID " << sid.ownerSetId
<< dec << setfill(' ') << endl;
#else
sif::printInfo(
"FsfwTestController::handleChangedPoolVariable: %s update from"
"object ID 0x%08x and set ID %lu\n",
printout, sid.objectId, sid.ownerSetId);
#endif
FSFW_LOGI("handleChangedDataset: {} update from object ID {:#010x} and set ID {}\n", printout,
sid.objectId, sid.ownerSetId);
if (storeId == store_address_t::invalid()) {
if (storeId == storeId::INVALID_STORE_ADDRESS) {
if (sid.objectId == device0Id) {
PoolReadGuard readHelper(&deviceDataset0.testFloat3Vec);
float floatVec[3];
floatVec[0] = deviceDataset0.testFloat3Vec.value[0];
floatVec[1] = deviceDataset0.testFloat3Vec.value[1];
floatVec[2] = deviceDataset0.testFloat3Vec.value[2];
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "Current float vector (3) values: [" << floatVec[0] << ", " << floatVec[1]
<< ", " << floatVec[2] << "]" << std::endl;
#else
sif::printInfo("Current float vector (3) values: [%f, %f, %f]\n", floatVec[0], floatVec[1],
floatVec[2]);
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
FSFW_LOGI("Current float vector (3) values: [{},{},{}]\n", floatVec[0], floatVec[1],
floatVec[2]);
}
}
}
@ -172,42 +136,29 @@ void FsfwTestController::handleChangedDataset(sid_t sid, store_address_t storeId
}
}
void FsfwTestController::handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId,
void FsfwTestController::handleChangedPoolVariable(gp_id_t globPoolId,
store_address_t storeId,
bool *clearMessage) {
using namespace std;
if (verboseLevel >= 1) {
char const *printout = nullptr;
if (storeId == store_address_t::invalid()) {
if (storeId == storeId::INVALID_STORE_ADDRESS) {
printout = "Notification";
} else {
printout = "Snapshot";
}
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "TestController::handleChangedPoolVariable: " << printout
<< " update from object "
"ID 0x"
<< setw(8) << setfill('0') << hex << globPoolId.objectId << " and local pool ID "
<< globPoolId.localPoolId << dec << setfill(' ') << endl;
#else
sif::printInfo(
"TestController::handleChangedPoolVariable: %s update from "
"object ID 0x%08x and "
"local pool ID %lu\n",
FSFW_LOGI(
"TestController::handleChangedPoolVariable: {} update from object "
"ID {:#010x} and LPID {}\n",
printout, globPoolId.objectId, globPoolId.localPoolId);
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
if (storeId == store_address_t::invalid()) {
if (storeId == storeId::INVALID_STORE_ADDRESS) {
if (globPoolId.objectId == device0Id) {
PoolReadGuard readHelper(&deviceDataset0.testUint8Var);
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "Current test variable 0 (UINT8) value: "
<< static_cast<int>(deviceDataset0.testUint8Var.value) << std::endl;
#else
sif::printInfo("Current test variable 0 (UINT8) value %d\n",
deviceDataset0.testUint8Var.value);
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
FSFW_LOGI("Current test variable 0 (UINT8) value: {}",
static_cast<int>(deviceDataset0.testUint8Var.value));
}
}
}

View File

@ -5,9 +5,9 @@
#include "fsfw_tests/integration/controller/TestController.h"
class FsfwTestController : public TestController {
public:
FsfwTestController(object_id_t objectId, object_id_t device0, object_id_t device1,
uint8_t verboseLevel = 0);
public:
FsfwTestController(object_id_t objectId, object_id_t device0,
object_id_t device1, uint8_t verboseLevel = 0);
virtual ~FsfwTestController();
ReturnValue_t handleCommandMessage(CommandMessage *message) override;
@ -16,7 +16,7 @@ class FsfwTestController : public TestController {
*/
void performControlOperation() override;
private:
private:
object_id_t device0Id;
object_id_t device1Id;
testdevice::TestDataSet deviceDataset0;
@ -31,11 +31,13 @@ class FsfwTestController : public TestController {
TraceTypes currentTraceType = TraceTypes::NONE;
ReturnValue_t initializeAfterTaskCreation() override;
void handleChangedDataset(sid_t sid, store_address_t storeId, bool *clearMessage) override;
void handleChangedDataset(sid_t sid, store_address_t storeId,
bool *clearMessage) override;
void handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId,
bool *clearMessage) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
ReturnValue_t
initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) override;

View File

@ -1,20 +1,15 @@
#include "GenericFactory.h"
#include "OBSWConfig.h"
#include "common/definitions.h"
#include "definitions.h"
#include "example/cfdp/Config.h"
#include "example/test/FsfwExampleTask.h"
#include "example/test/FsfwReaderTask.h"
#include "example/utility/CfdpTmFunnel.h"
#include "example/utility/TmFunnel.h"
#include "fsfw/FSFW.h"
#include "fsfw/cfdp.h"
#include "fsfw/cfdp/CfdpDistributor.h"
#include "fsfw/devicehandlers/CookieIF.h"
#include "fsfw/events/EventManager.h"
#include "fsfw/health/HealthTable.h"
#include "fsfw/internalerror/InternalErrorReporter.h"
#include "fsfw/ipc/QueueFactory.h"
#include "fsfw/pus/CService200ModeCommanding.h"
#include "fsfw/pus/Service11TelecommandScheduling.h"
#include "fsfw/pus/Service17Test.h"
@ -25,11 +20,10 @@
#include "fsfw/pus/Service5EventReporting.h"
#include "fsfw/pus/Service8FunctionManagement.h"
#include "fsfw/pus/Service9TimeManagement.h"
#include "fsfw/tcdistribution/CcsdsDistributor.h"
#include "fsfw/tcdistribution/PusDistributor.h"
#include "fsfw/timemanager/CdsShortTimeStamper.h"
#include "fsfw/tmtcservices/VerificationReporter.h"
#include "fsfw_hal/host/HostFilesystem.h"
#include "fsfw/tcdistribution/CCSDSDistributor.h"
#include "fsfw/tcdistribution/PUSDistributor.h"
#include "fsfw/timemanager/TimeStamper.h"
#include "fsfw/tmtcpacket/pus/tm.h"
#include "fsfw_tests/integration/assemblies/TestAssembly.h"
#include "fsfw_tests/integration/controller/TestController.h"
#include "fsfw_tests/integration/devices/TestCookie.h"
@ -37,63 +31,47 @@
#include "fsfw_tests/integration/devices/TestEchoComIF.h"
#include "fsfw_tests/internal/InternalUnitTester.h"
#include "objects/systemObjectList.h"
#include "tmtc/apid.h"
#if OBSW_ADD_CFDP_COMPONENTS == 1
namespace cfdp {
EntityId REMOTE_CFDP_ID(cfdp::WidthInBytes::TWO_BYTES, common::COMMON_CFDP_CLIENT_ENTITY_ID);
RemoteEntityCfg GROUND_REMOTE_CFG(REMOTE_CFDP_ID);
OneRemoteConfigProvider REMOTE_CFG_PROVIDER(GROUND_REMOTE_CFG);
HostFilesystem HOST_FS;
ExampleUserHandler USER_HANDLER(HOST_FS);
ExampleFaultHandler EXAMPLE_FAULT_HANDLER;
} // namespace cfdp
#endif
void ObjectFactory::produceGenericObjects(PusTmFunnel **pusFunnel,
const AcceptsTelemetryIF &tmtcBridge,
CcsdsDistributor **ccsdsDistrib,
StorageManagerIF &tcStore, StorageManagerIF &tmStore) {
void ObjectFactory::produceGenericObjects() {
#if OBSW_ADD_CORE_COMPONENTS == 1
/* Framework objects */
new EventManager(objects::EVENT_MANAGER);
new HealthTable(objects::HEALTH_TABLE);
new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER);
auto *stamperAndReader = new CdsShortTimeStamper(objects::TIME_STAMPER);
new VerificationReporter();
*ccsdsDistrib =
new CcsdsDistributor(common::COMMON_PUS_APID, objects::CCSDS_DISTRIBUTOR, &tcStore);
new PusDistributor(common::COMMON_PUS_APID, objects::PUS_DISTRIBUTOR, *ccsdsDistrib);
*pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, tmtcBridge, *stamperAndReader, tmStore);
auto *cfdpFunnel =
new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, common::COMMON_CFDP_APID, tmtcBridge, tmStore);
new TmFunnel(objects::TM_FUNNEL, **pusFunnel, *cfdpFunnel);
new TimeStamper(objects::TIME_STAMPER);
auto *ccsdsDistrib =
new CCSDSDistributor(apid::APID, objects::CCSDS_DISTRIBUTOR);
new PUSDistributor(apid::APID, objects::PUS_DISTRIBUTOR,
objects::CCSDS_DISTRIBUTOR);
new TmFunnel(objects::TM_FUNNEL);
#endif /* OBSW_ADD_CORE_COMPONENTS == 1 */
/* PUS stack */
#if OBSW_ADD_PUS_STACK == 1
new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION, common::COMMON_PUS_APID,
pus::PUS_SERVICE_1, objects::PUS_TM_FUNNEL, 5);
new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, common::COMMON_PUS_APID,
new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION,
apid::APID, pus::PUS_SERVICE_1,
objects::TM_FUNNEL, 5);
new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, apid::APID,
pus::PUS_SERVICE_2, 3, 10);
new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, common::COMMON_PUS_APID,
new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, apid::APID,
pus::PUS_SERVICE_3);
new Service5EventReporting(PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING,
common::COMMON_PUS_APID, pus::PUS_SERVICE_5),
20, 40);
new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, common::COMMON_PUS_APID,
pus::PUS_SERVICE_8, 3, 10);
new Service9TimeManagement(
PsbParams(objects::PUS_SERVICE_9_TIME_MGMT, common::COMMON_PUS_APID, pus::PUS_SERVICE_9));
new Service17Test(
PsbParams(objects::PUS_SERVICE_17_TEST, common::COMMON_PUS_APID, pus::PUS_SERVICE_17));
new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS, common::COMMON_PUS_APID,
pus::PUS_SERVICE_20);
new Service5EventReporting(objects::PUS_SERVICE_5_EVENT_REPORTING, apid::APID,
pus::PUS_SERVICE_5, 50);
new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT,
apid::APID, pus::PUS_SERVICE_8, 3, 10);
new Service9TimeManagement(objects::PUS_SERVICE_9_TIME_MGMT, apid::APID,
pus::PUS_SERVICE_9);
new Service17Test(objects::PUS_SERVICE_17_TEST, apid::APID,
pus::PUS_SERVICE_17);
new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS,
apid::APID, pus::PUS_SERVICE_20);
#if OBSW_ADD_CORE_COMPONENTS == 1
new Service11TelecommandScheduling<cfg::OBSW_MAX_SCHEDULED_TCS>(
PsbParams(objects::PUS_SERVICE_11_TC_SCHEDULER, common::COMMON_PUS_APID, pus::PUS_SERVICE_11),
*ccsdsDistrib);
objects::PUS_SERVICE_11_TC_SCHEDULER, apid::APID, pus::PUS_SERVICE_11,
ccsdsDistrib);
#endif
new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, common::COMMON_PUS_APID,
new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, apid::APID,
pus::PUS_SERVICE_200);
#endif /* OBSW_ADD_PUS_STACK == 1 */
@ -120,17 +98,22 @@ void ObjectFactory::produceGenericObjects(PusTmFunnel **pusFunnel,
/* Demo device handler object */
size_t expectedMaxReplyLen = 64;
CookieIF *testCookie = new TestCookie(static_cast<address_t>(testdevice::DeviceIndex::DEVICE_0),
expectedMaxReplyLen);
CookieIF *testCookie =
new TestCookie(static_cast<address_t>(testdevice::DeviceIndex::DEVICE_0),
expectedMaxReplyLen);
new TestEchoComIF(objects::TEST_ECHO_COM_IF);
new TestDevice(objects::TEST_DEVICE_HANDLER_0, objects::TEST_ECHO_COM_IF, testCookie,
testdevice::DeviceIndex::DEVICE_0, enableInfoPrintout);
testCookie = new TestCookie(static_cast<address_t>(testdevice::DeviceIndex::DEVICE_1),
expectedMaxReplyLen);
new TestDevice(objects::TEST_DEVICE_HANDLER_1, objects::TEST_ECHO_COM_IF, testCookie,
testdevice::DeviceIndex::DEVICE_1, enableInfoPrintout);
new TestDevice(objects::TEST_DEVICE_HANDLER_0, objects::TEST_ECHO_COM_IF,
testCookie, testdevice::DeviceIndex::DEVICE_0,
enableInfoPrintout);
testCookie =
new TestCookie(static_cast<address_t>(testdevice::DeviceIndex::DEVICE_1),
expectedMaxReplyLen);
new TestDevice(objects::TEST_DEVICE_HANDLER_1, objects::TEST_ECHO_COM_IF,
testCookie, testdevice::DeviceIndex::DEVICE_1,
enableInfoPrintout);
new TestAssembly(objects::TEST_ASSEMBLY, objects::NO_OBJECT, objects::TEST_DEVICE_HANDLER_0,
new TestAssembly(objects::TEST_ASSEMBLY, objects::NO_OBJECT,
objects::TEST_DEVICE_HANDLER_0,
objects::TEST_DEVICE_HANDLER_1);
#endif /* OBSW_ADD_DEVICE_HANDLER_DEMO == 1 */
@ -154,34 +137,6 @@ void ObjectFactory::produceGenericObjects(PusTmFunnel **pusFunnel,
InternalUnitTester unittester;
unittester.performTests(testCfg);
#endif /* OBSW_PERFORM_INTERNAL_UNITTEST == 1 */
#if OBSW_ADD_CFDP_COMPONENTS == 1
using namespace cfdp;
MessageQueueIF *cfdpMsgQueue = QueueFactory::instance()->createMessageQueue(32);
CfdpDistribCfg cfg(objects::CFDP_DISTRIBUTOR, tcStore, cfdpMsgQueue);
new CfdpDistributor(cfg);
auto *msgQueue = QueueFactory::instance()->createMessageQueue(32);
UnsignedByteField<uint16_t> remoteEntityId(common::COMMON_CFDP_CLIENT_ENTITY_ID);
cfdp::EntityId remoteId(remoteEntityId);
cfdp::RemoteEntityCfg remoteCfg(remoteId);
remoteCfg.defaultChecksum = cfdp::ChecksumType::CRC_32;
FsfwHandlerParams params(objects::CFDP_HANDLER, HOST_FS, *cfdpFunnel, tcStore, tmStore,
*msgQueue);
cfdp::IndicationCfg indicationCfg;
UnsignedByteField<uint16_t> apid(common::COMMON_CFDP_APID);
cfdp::EntityId localId(apid);
GROUND_REMOTE_CFG.defaultChecksum = cfdp::ChecksumType::CRC_32;
if (PACKET_LIST_PTR == nullptr or LOST_SEGMENTS_PTR == nullptr) {
sif::error << "CFDP: No packet list or lost segments container set" << std::endl;
}
CfdpHandlerCfg cfdpCfg(localId, indicationCfg, USER_HANDLER, EXAMPLE_FAULT_HANDLER,
*PACKET_LIST_PTR, *LOST_SEGMENTS_PTR, REMOTE_CFG_PROVIDER);
auto *cfdpHandler = new CfdpHandler(params, cfdpCfg);
CcsdsDistributorIF::DestInfo info("CFDP Destination", common::COMMON_CFDP_APID,
cfdpHandler->getRequestQueue(), true);
(*ccsdsDistrib)->registerApplication(info);
#endif
}
void Factory::setStaticFrameworkObjectIds() {
@ -192,11 +147,17 @@ void Factory::setStaticFrameworkObjectIds() {
MonitoringReportContent<int16_t>::timeStamperId = objects::TIME_STAMPER;
MonitoringReportContent<uint16_t>::timeStamperId = objects::TIME_STAMPER;
PusServiceBase::PUS_DISTRIBUTOR = objects::PUS_DISTRIBUTOR;
PusServiceBase::PACKET_DESTINATION = objects::PUS_TM_FUNNEL;
TmFunnel::downlinkDestination = objects::DOWNLINK_DESTINATION;
// No storage object for now.
TmFunnel::storageDestination = objects::NO_OBJECT;
PusServiceBase::packetSource = objects::PUS_DISTRIBUTOR;
PusServiceBase::packetDestination = objects::TM_FUNNEL;
CommandingServiceBase::defaultPacketSource = objects::PUS_DISTRIBUTOR;
CommandingServiceBase::defaultPacketDestination = objects::PUS_TM_FUNNEL;
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
VerificationReporter::DEFAULT_RECEIVER = objects::PUS_SERVICE_1_VERIFICATION;
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
TmPacketBase::timeStamperId = objects::TIME_STAMPER;
}

View File

@ -3,24 +3,14 @@
#include <fsfw/objectmanager/SystemObjectIF.h>
#include "OBSWConfig.h"
#include "example/utility/PusTmFunnel.h"
#include "fsfw/cfdp/handler/DestHandler.h"
#include "fsfw/storagemanager/StorageManagerIF.h"
class TmFunnel;
class CcsdsDistributor;
namespace ObjectFactory {
/**
* @brief Produce hardware independant objects. Called by bsp specific
* object factory.
*/
void produceGenericObjects(PusTmFunnel** pusFunnel, const AcceptsTelemetryIF& tmtcBridge,
CcsdsDistributor** ccsdsDistributor, StorageManagerIF& tcStore,
StorageManagerIF& tmStore);
void produceGenericObjects();
} // namespace ObjectFactory
} // namespace ObjectFactory
#endif /* MISSION_CORE_GENERICFACTORY_H_ */

View File

@ -1,6 +1,8 @@
target_sources(${TARGET_NAME} PRIVATE FsfwReaderTask.cpp FsfwExampleTask.cpp
MutexExample.cpp FsfwTestTask.cpp)
if(FSFW_ADD_FMT_TESTS)
target_sources(${TARGET_NAME} PRIVATE testFmt.cpp)
if(OBSW_ADD_FMT_TESTS)
target_sources(${TARGET_NAME} PRIVATE
testFmt.cpp
)
endif()

View File

@ -3,7 +3,7 @@
#include <fsfw/ipc/CommandMessage.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/objectmanager/ObjectManager.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/serviceinterface.h>
#include <fsfw/tasks/TaskFactory.h>
#include "OBSWConfig.h"
@ -11,11 +11,11 @@
#include "objects/systemObjectList.h"
FsfwExampleTask::FsfwExampleTask(object_id_t objectId)
: SystemObject(objectId),
poolManager(this, nullptr),
demoSet(this),
monitor(objectId, MONITOR_ID, gp_id_t(objectId, FsfwDemoSet::VARIABLE_LIMIT), 30, 10) {
commandQueue = QueueFactory::instance()->createMessageQueue(10, CommandMessage::MAX_MESSAGE_SIZE);
: SystemObject(objectId), poolManager(this, nullptr), demoSet(this),
monitor(objectId, MONITOR_ID,
gp_id_t(objectId, FsfwDemoSet::VARIABLE_LIMIT), 30, 10) {
commandQueue = QueueFactory::instance()->createMessageQueue(
10, CommandMessage::MAX_MESSAGE_SIZE);
}
FsfwExampleTask::~FsfwExampleTask() {}
@ -27,13 +27,13 @@ ReturnValue_t FsfwExampleTask::performOperation(uint8_t operationCode) {
// TODO: Move this to new test controller?
ReturnValue_t result = performMonitoringDemo();
if (result != returnvalue::OK) {
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (operationCode == OpCodes::SEND_RAND_NUM) {
result = performSendOperation();
if (result != returnvalue::OK) {
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
@ -47,59 +47,51 @@ ReturnValue_t FsfwExampleTask::performOperation(uint8_t operationCode) {
object_id_t FsfwExampleTask::getNextRecipient() {
switch (this->getObjectId()) {
case (objects::TEST_DUMMY_1): {
return objects::TEST_DUMMY_2;
}
case (objects::TEST_DUMMY_2): {
return objects::TEST_DUMMY_3;
}
case (objects::TEST_DUMMY_3): {
return objects::TEST_DUMMY_1;
}
default:
return objects::TEST_DUMMY_1;
case (objects::TEST_DUMMY_1): {
return objects::TEST_DUMMY_2;
}
case (objects::TEST_DUMMY_2): {
return objects::TEST_DUMMY_3;
}
case (objects::TEST_DUMMY_3): {
return objects::TEST_DUMMY_1;
}
default:
return objects::TEST_DUMMY_1;
}
}
object_id_t FsfwExampleTask::getSender() {
switch (this->getObjectId()) {
case (objects::TEST_DUMMY_1): {
return objects::TEST_DUMMY_3;
}
case (objects::TEST_DUMMY_2): {
return objects::TEST_DUMMY_1;
}
case (objects::TEST_DUMMY_3): {
return objects::TEST_DUMMY_2;
}
default:
return objects::TEST_DUMMY_1;
case (objects::TEST_DUMMY_1): {
return objects::TEST_DUMMY_3;
}
case (objects::TEST_DUMMY_2): {
return objects::TEST_DUMMY_1;
}
case (objects::TEST_DUMMY_3): {
return objects::TEST_DUMMY_2;
}
default:
return objects::TEST_DUMMY_1;
}
}
ReturnValue_t FsfwExampleTask::initialize() {
// Get the dataset of the sender. Will be cached for later checks.
object_id_t sender = getSender();
auto *senderIF = ObjectManager::instance()->get<HasLocalDataPoolIF>(sender);
auto* senderIF = ObjectManager::instance()->get<HasLocalDataPoolIF>(sender);
if (senderIF == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "FsfwDemoTask::initialize: Sender object invalid!" << std::endl;
#else
sif::printError("FsfwDemoTask::initialize: Sender object invalid!\n");
#endif
return returnvalue::FAILED;
FSFW_LOGE("initialize: Sender object invalid\n");
return HasReturnvaluesIF::RETURN_FAILED;
}
// we need a private copy of the previous dataset.. or we use the shared
// dataset.
senderSet = new FsfwDemoSet(senderIF);
if (senderSet == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "FsfwDemoTask::initialize: Sender dataset invalid!" << std::endl;
#else
sif::printError("FsfwDemoTask::initialize: Sender dataset invalid!\n");
#endif
return returnvalue::FAILED;
FSFW_LOGE("initialize: Sender dataset invalid\n");
return HasReturnvaluesIF::RETURN_FAILED;
}
return poolManager.initialize(commandQueue);
}
@ -108,32 +100,40 @@ ReturnValue_t FsfwExampleTask::initializeAfterTaskCreation() {
return poolManager.initializeAfterTaskCreation();
}
object_id_t FsfwExampleTask::getObjectId() const { return SystemObject::getObjectId(); }
object_id_t FsfwExampleTask::getObjectId() const {
return SystemObject::getObjectId();
}
MessageQueueId_t FsfwExampleTask::getMessageQueueId() { return commandQueue->getId(); }
MessageQueueId_t FsfwExampleTask::getMessageQueueId() {
return commandQueue->getId();
}
void FsfwExampleTask::setTaskIF(PeriodicTaskIF *task) { this->task = task; }
LocalPoolDataSetBase *FsfwExampleTask::getDataSetHandle(sid_t sid) { return &demoSet; }
LocalPoolDataSetBase *FsfwExampleTask::getDataSetHandle(sid_t sid) {
return &demoSet;
}
uint32_t FsfwExampleTask::getPeriodicOperationFrequency() const { return task->getPeriodMs(); }
uint32_t FsfwExampleTask::getPeriodicOperationFrequency() const {
return task->getPeriodMs();
}
ReturnValue_t FsfwExampleTask::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(FsfwDemoSet::PoolIds::VARIABLE, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(FsfwDemoSet::PoolIds::VARIABLE_LIMIT, new PoolEntry<uint16_t>({0}));
return returnvalue::OK;
ReturnValue_t
FsfwExampleTask::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(FsfwDemoSet::PoolIds::VARIABLE,
new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(FsfwDemoSet::PoolIds::VARIABLE_LIMIT,
new PoolEntry<uint16_t>({0}));
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t FsfwExampleTask::performMonitoringDemo() {
ReturnValue_t result = demoSet.variableLimit.read(MutexIF::TimeoutType::WAITING, 20);
if (result != returnvalue::OK) {
ReturnValue_t result =
demoSet.variableLimit.read(MutexIF::TimeoutType::WAITING, 20);
if (result != HasReturnvaluesIF::RETURN_OK) {
/* Configuration error */
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "DummyObject::performOperation: Could not read variableLimit!" << std::endl;
#else
sif::printError("DummyObject::performOperation: Could not read variableLimit!\n");
#endif
FSFW_LOGE("DummyObject::performOperation: Could not read variableLimit\n");
return result;
}
if (this->getObjectId() == objects::TEST_DUMMY_5) {
@ -141,23 +141,19 @@ ReturnValue_t FsfwExampleTask::performMonitoringDemo() {
demoSet.variableLimit.value = 0;
}
demoSet.variableLimit.value++;
demoSet.variableLimit.commit(20);
demoSet.variableLimit.commit(true);
monitor.check();
}
return returnvalue::OK;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t FsfwExampleTask::performSendOperation() {
object_id_t nextRecipient = getNextRecipient();
auto *target = ObjectManager::instance()->get<FsfwExampleTask>(nextRecipient);
auto* target = ObjectManager::instance()->get<FsfwExampleTask>(nextRecipient);
if (target == nullptr) {
/* Configuration error */
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "DummyObject::performOperation: Next recipient does not exist!" << std::endl;
#else
sif::printError("DummyObject::performOperation: Next recipient does not exist!\n");
#endif
return returnvalue::FAILED;
FSFW_LOGE("performSendOperation: Next recipient does not exist\n");
return HasReturnvaluesIF::RETURN_FAILED;
}
uint32_t randomNumber = rand() % 100;
@ -167,73 +163,65 @@ ReturnValue_t FsfwExampleTask::performSendOperation() {
/* Send message using own message queue */
ReturnValue_t result = commandQueue->sendMessage(target->getMessageQueueId(), &message);
if (result != returnvalue::OK && result != MessageQueueIF::FULL) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "FsfwDemoTask::performSendOperation: Send failed with " << result << std::endl;
#else
sif::printError("FsfwDemoTask::performSendOperation: Send failed with %hu\n", result);
#endif
if (result != HasReturnvaluesIF::RETURN_OK && result != MessageQueueIF::FULL) {
FSFW_LOGE("performSendOperation: Send failed with {:#06x}\n", result);
}
/* Send message without via MessageQueueSenderIF */
result = MessageQueueSenderIF::sendMessage(target->getMessageQueueId(), &message,
commandQueue->getId());
if (result != returnvalue::OK && result != MessageQueueIF::FULL) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "FsfwDemoTask::performSendOperation: Send failed with " << result << std::endl;
#else
sif::printError("FsfwDemoTask::performSendOperation: Send failed with %hu\n", result);
#endif
if (result != HasReturnvaluesIF::RETURN_OK && result != MessageQueueIF::FULL) {
FSFW_LOGE("performSendOperation: Send failed with {:#06x}\n", result);
}
demoSet.variableWrite.value = randomNumber;
result = demoSet.variableWrite.commit(20);
result = demoSet.variableWrite.commit(true);
return result;
}
ReturnValue_t FsfwExampleTask::performReceiveOperation() {
ReturnValue_t result = returnvalue::OK;
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
while (result != MessageQueueIF::EMPTY) {
CommandMessage receivedMessage;
result = commandQueue->receiveMessage(&receivedMessage);
if (result != returnvalue::OK && result != MessageQueueIF::EMPTY) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "Receive failed with " << result << std::endl;
#endif
if (result != HasReturnvaluesIF::RETURN_OK && result != MessageQueueIF::EMPTY) {
FSFW_LOGD("performReceiveOperation: Receive failed with {}\n", result);
break;
}
if (result != MessageQueueIF::EMPTY) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
#if OBSW_VERBOSE_LEVEL >= 2
sif::debug << "Message Received by " << getObjectId() << " from Queue "
<< receivedMessage.getSender() << " ObjectId " << receivedMessage.getParameter()
<< " Queue " << receivedMessage.getParameter2() << std::endl;
<< receivedMessage.getSender() << " ObjectId "
<< receivedMessage.getParameter() << " Queue "
<< receivedMessage.getParameter2() << std::endl;
#endif
#endif
if (senderSet == nullptr) {
return returnvalue::FAILED;
return HasReturnvaluesIF::RETURN_FAILED;
}
result = senderSet->variableRead.read(MutexIF::TimeoutType::WAITING, 20);
if (result != returnvalue::OK) {
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (senderSet->variableRead.value != receivedMessage.getParameter()) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "FsfwDemoTask::performReceiveOperation: Variable " << std::hex << "0x"
<< senderSet->variableRead.getDataPoolId() << std::dec << " has wrong value."
<< std::endl;
sif::error << "Value: " << demoSet.variableRead.value
<< ", expected: " << receivedMessage.getParameter() << std::endl;
#endif
FSFW_LOGE(
"FsfwDemoTask::performReceiveOperation: Variable {} has wrong value {}, expected {}\n",
senderSet->variableRead.getDataPoolId(), demoSet.variableRead.value,
receivedMessage.getParameter());
}
}
}
return result;
}
MessageQueueId_t FsfwExampleTask::getCommandQueue() const { return commandQueue->getId(); }
MessageQueueId_t FsfwExampleTask::getCommandQueue() const {
return commandQueue->getId();
}
LocalDataPoolManager *FsfwExampleTask::getHkManagerHandle() { return &poolManager; }
LocalDataPoolManager *FsfwExampleTask::getHkManagerHandle() {
return &poolManager;
}

View File

@ -24,8 +24,10 @@ class PeriodicTaskIF;
* value directly from the sender via the local data pool interface.
* If the timing is set up correctly, the values will always be the same.
*/
class FsfwExampleTask : public ExecutableObjectIF, public SystemObject, public HasLocalDataPoolIF {
public:
class FsfwExampleTask : public ExecutableObjectIF,
public SystemObject,
public HasLocalDataPoolIF {
public:
enum OpCodes { SEND_RAND_NUM, RECEIVE_RAND_NUM, DELAY_SHORT };
static constexpr uint8_t MONITOR_ID = 2;
@ -78,7 +80,7 @@ class FsfwExampleTask : public ExecutableObjectIF, public SystemObject, public H
MessageQueueId_t getMessageQueueId();
private:
private:
LocalDataPoolManager poolManager;
FsfwDemoSet *senderSet = nullptr;
FsfwDemoSet demoSet;
@ -90,8 +92,9 @@ class FsfwExampleTask : public ExecutableObjectIF, public SystemObject, public H
MessageQueueId_t getCommandQueue() const override;
LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override;
uint32_t getPeriodicOperationFrequency() const override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
ReturnValue_t
initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
LocalDataPoolManager *getHkManagerHandle() override;
object_id_t getNextRecipient();

View File

@ -2,15 +2,14 @@
#include <OBSWConfig.h>
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/serviceinterface.h>
#include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
FsfwReaderTask::FsfwReaderTask(object_id_t objectId, bool enablePrintout)
: SystemObject(objectId),
printoutEnabled(enablePrintout),
opDivider(10),
readSet(this->getObjectId(), gp_id_t(objects::TEST_DUMMY_1, FsfwDemoSet::PoolIds::VARIABLE),
: SystemObject(objectId), printoutEnabled(enablePrintout), opDivider(10),
readSet(this->getObjectId(),
gp_id_t(objects::TEST_DUMMY_1, FsfwDemoSet::PoolIds::VARIABLE),
gp_id_t(objects::TEST_DUMMY_2, FsfwDemoSet::PoolIds::VARIABLE),
gp_id_t(objects::TEST_DUMMY_3, FsfwDemoSet::PoolIds::VARIABLE)) {
/* Special protection for set reading because each variable is read from a
@ -18,12 +17,12 @@ FsfwReaderTask::FsfwReaderTask(object_id_t objectId, bool enablePrintout)
readSet.setReadCommitProtectionBehaviour(true);
}
FsfwReaderTask::~FsfwReaderTask() = default;
FsfwReaderTask::~FsfwReaderTask() {}
ReturnValue_t FsfwReaderTask::initializeAfterTaskCreation() {
/* Give other task some time to set up local data pools. */
TaskFactory::delayTask(20);
return returnvalue::OK;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t FsfwReaderTask::performOperation(uint8_t operationCode) {
@ -33,23 +32,11 @@ ReturnValue_t FsfwReaderTask::performOperation(uint8_t operationCode) {
uint32_t variable2 = readSet.variable2.value;
uint32_t variable3 = readSet.variable3.value;
#if OBSW_VERBOSE_LEVEL >= 1
if (opDivider.checkAndIncrement() and printoutEnabled) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "FsfwPeriodicTask::performOperation: Reading variables." << std::endl;
sif::info << "Variable read from demo object 1: " << variable1 << std::endl;
sif::info << "Variable read from demo object 2: " << variable2 << std::endl;
sif::info << "Variable read from demo object 3: " << variable3 << std::endl;
#else
sif::printInfo("FsfwPeriodicTask::performOperation: Reading variables.\n\r");
sif::printInfo("Variable read from demo object 1: %d\n\r", variable1);
sif::printInfo("Variable read from demo object 2: %d\n\r", variable2);
sif::printInfo("Variable read from demo object 3: %d\n\r", variable3);
#endif
FSFW_LOGI(
"FsfwPeriodicTask::performOperation: Reading variables from Demo "
"Object 1,2,3\n1 {} | 2 {} | 3 {}\n",
variable1, variable2, variable3);
}
#else
if (variable1 and variable2 and variable3) {
};
#endif
return returnvalue::OK;
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -8,14 +8,14 @@
#include "testdefinitions/demoDefinitions.h"
class FsfwReaderTask : public ExecutableObjectIF, public SystemObject {
public:
public:
FsfwReaderTask(object_id_t objectId, bool enablePrintout);
~FsfwReaderTask() override;
ReturnValue_t initializeAfterTaskCreation() override;
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
private:
private:
bool printoutEnabled = false;
PeriodicOperationDivider opDivider;
CompleteDemoReadSet readSet;

View File

@ -2,13 +2,13 @@
#include <commonConfig.h>
#if FSFW_ADD_FMT_TESTS == 1
#if OBSW_ADD_FMT_TESTS == 1
#include "testFmt.h"
#endif
FsfwTestTask::FsfwTestTask(object_id_t objectId, bool periodicEvent)
: TestTask(objectId), periodicEvent(periodicEvent) {
#if FSFW_ADD_FMT_TESTS == 1
#if OBSW_ADD_FMT_TESTS == 1
fmtTests();
#endif
}
@ -17,5 +17,5 @@ ReturnValue_t FsfwTestTask::performPeriodicAction() {
if (periodicEvent) {
triggerEvent(TEST_EVENT, 0x1234, 0x4321);
}
return returnvalue::OK;
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -6,15 +6,16 @@
#include "fsfw_tests/integration/task/TestTask.h"
class FsfwTestTask : public TestTask {
public:
public:
FsfwTestTask(object_id_t objectId, bool periodicEvent);
ReturnValue_t performPeriodicAction() override;
private:
private:
bool periodicEvent = false;
static constexpr uint8_t subsystemId = SUBSYSTEM_ID::TEST_TASK_ID;
static constexpr Event TEST_EVENT = event::makeEvent(subsystemId, 0, severity::INFO);
static constexpr Event TEST_EVENT =
event::makeEvent(subsystemId, 0, severity::INFO);
};
#endif /* EXAMPLE_COMMON_EXAMPLE_TEST_FSFWTESTTASK_H_ */

View File

@ -1,45 +1,30 @@
#include "MutexExample.h"
#include <fsfw/ipc/MutexFactory.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/serviceinterface.h>
void MutexExample::example() {
MutexIF *mutex = MutexFactory::instance()->createMutex();
MutexIF *mutex2 = MutexFactory::instance()->createMutex();
ReturnValue_t result = mutex->lockMutex(MutexIF::TimeoutType::WAITING, 2 * 60 * 1000);
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MutexExample::example: Lock Failed with " << result << std::endl;
#else
sif::printError("MutexExample::example: Lock Failed with %hu\n", result);
#endif
ReturnValue_t result =
mutex->lockMutex(MutexIF::TimeoutType::WAITING, 2 * 60 * 1000);
if (result != HasReturnvaluesIF::RETURN_OK) {
FSFW_LOGET("MutexExample::example: Lock Failed with {}\n", result);
}
result = mutex2->lockMutex(MutexIF::TimeoutType::BLOCKING);
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MutexExample::example: Lock Failed with " << result << std::endl;
#else
sif::printError("MutexExample::example: Lock Failed with %hu\n", result);
#endif
if (result != HasReturnvaluesIF::RETURN_OK) {
FSFW_LOGET("MutexExample::example: Lock Failed with {}\n", result);
}
result = mutex->unlockMutex();
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MutexExample::example: Unlock Failed with " << result << std::endl;
#else
sif::printError("MutexExample::example: Unlock Failed with %hu\n", result);
#endif
if (result != HasReturnvaluesIF::RETURN_OK) {
FSFW_LOGET("MutexExample::example: Unlock Failed with {}\n", result);
}
result = mutex2->unlockMutex();
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MutexExample::example: Unlock Failed with " << result << std::endl;
#else
sif::printError("MutexExample::example: Unlock Failed with %hu\n", result);
#endif
if (result != HasReturnvaluesIF::RETURN_OK) {
FSFW_LOGET("MutexExample::example: Unlock Failed with {}\n", result);
}
}

View File

@ -1,14 +1,20 @@
#include "testFmt.h"
#include "fsfw/serviceinterface/fmtWrapper.h"
void fmtTests() {
sif::fdebug(__FILENAME__, __LINE__, "Hello {} {}", "World\n");
sif::fdebug_t(__FILENAME__, __LINE__, "Hallo\n");
sif::initialize();
sif::debug_s(__FILENAME__, __LINE__, "Hello {}", "World\n");
sif::debug_st(__FILENAME__, __LINE__, "Hallo\n");
FSFW_LOGD("{}", "Hallo\n");
// MY_LOG("{}", "test\n");
// sif::finfo_t("Hallo\n");
// sif::finfo("Hallo\n");
// sif::fwarning("Hello\n");
// sif::fwarning_t("Hello\n");
// sif::ferror("Hello\n");
// sif::ferror_t("Hello\n");
sif::info_t("Hallo\n");
sif::info("Hallo\n");
sif::warning_s(__FILENAME__, __LINE__, "Hello\n");
sif::warning_st(__FILENAME__, __LINE__, "Hello\n");
FSFW_LOGW("Hello World\n");
FSFW_LOGW("{} World\n", "Hello");
uint8_t test0 = 5;
float test1 = 12.0;
uint32_t test2 = 0x00ff11ff;
FSFW_LOGW("Test 0 {} | Test 1 {:.3f} | Test 2 {:#010x}\n", test0, test1, test2);
sif::error_s(__FILENAME__, __LINE__, "Hello\n");
sif::error_st(__FILENAME__, __LINE__, "Hello\n");
}

View File

@ -1,162 +1,3 @@
#ifndef FSFW_EXAMPLE_HOSTED_TESTFMT_H
#define FSFW_EXAMPLE_HOSTED_TESTFMT_H
#include <fmt/chrono.h>
#include <fmt/color.h>
#include <fmt/compile.h>
#include <fmt/core.h>
#include <array>
#include <cstdint>
#include "fsfw/ipc/MutexFactory.h"
#include "fsfw/ipc/MutexGuard.h"
#include "fsfw/ipc/MutexIF.h"
#include "fsfw/timemanager/Clock.h"
#define __FILENAME_REL__ (((const char *)__FILE__ + SOURCE_PATH_SIZE))
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#pragma once
void fmtTests();
namespace sif {
static std::array<char, 524> PRINT_BUF = {};
static const char INFO_PREFIX[] = "INFO";
static const char DEBUG_PREFIX[] = "DEBUG";
static const char WARNING_PREFIX[] = "WARNING";
static const char ERROR_PREFIX[] = "ERROR";
enum class LogLevel : unsigned int { DEBUG = 0, INFO = 1, WARNING = 2, ERROR = 3 };
static const char *PREFIX_ARR[4] = {DEBUG_PREFIX, INFO_PREFIX, WARNING_PREFIX, ERROR_PREFIX};
static const std::array<fmt::color, 4> LOG_COLOR_ARR = {
fmt::color::deep_sky_blue, fmt::color::forest_green, fmt::color::orange_red, fmt::color::red};
static MutexIF *PRINT_MUTEX = MutexFactory::instance()->createMutex();
static size_t writeTypePrefix(LogLevel level) {
auto idx = static_cast<unsigned int>(level);
const auto result =
fmt::format_to_n(PRINT_BUF.begin(), PRINT_BUF.size() - 1,
fmt::runtime(fmt::format(fg(LOG_COLOR_ARR[idx]), PREFIX_ARR[idx])));
return result.size;
}
template <typename... T>
size_t logTraced(LogLevel level, const char *file, unsigned int line, bool timed,
fmt::format_string<T...> fmt, T &&...args) noexcept {
try {
MutexGuard mg(PRINT_MUTEX);
size_t bufPos = writeTypePrefix(level);
auto currentIter = PRINT_BUF.begin() + bufPos;
if (timed) {
Clock::TimeOfDay_t logTime;
Clock::getDateAndTime(&logTime);
const auto result = fmt::format_to_n(currentIter, PRINT_BUF.size() - 1 - bufPos,
" | {}[l.{}] | {:02}:{:02}:{:02}.{:03} | {}", file, line,
logTime.hour, logTime.minute, logTime.second,
logTime.usecond / 1000, fmt::format(fmt, args...));
*result.out = '\0';
bufPos += result.size;
} else {
const auto result =
fmt::format_to_n(currentIter, PRINT_BUF.size() - 1 - bufPos, " | {}[l.{}] | {}", file,
line, fmt::format(fmt, args...));
*result.out = '\0';
bufPos += result.size;
}
fmt::print(fmt::runtime(PRINT_BUF.data()));
return bufPos;
} catch (const fmt::v8::format_error &e) {
fmt::print("Printing failed with error: {}\n", e.what());
return 0;
}
}
template <typename... T>
size_t log(LogLevel level, bool timed, fmt::format_string<T...> fmt, T &&...args) noexcept {
try {
MutexGuard mg(PRINT_MUTEX);
size_t bufPos = writeTypePrefix(level);
auto currentIter = PRINT_BUF.begin() + bufPos;
if (timed) {
Clock::TimeOfDay_t logTime;
Clock::getDateAndTime(&logTime);
const auto result = fmt::format_to_n(
currentIter, PRINT_BUF.size() - bufPos, " | {:02}:{:02}:{:02}.{:03} | {}", logTime.hour,
logTime.minute, logTime.second, logTime.usecond / 1000, fmt::format(fmt, args...));
bufPos += result.size;
}
fmt::print(fmt::runtime(PRINT_BUF.data()));
return bufPos;
} catch (const fmt::v8::format_error &e) {
fmt::print("Printing failed with error: {}\n", e.what());
return 0;
}
}
template <typename... T>
void fdebug(const char *file, unsigned int line, fmt::format_string<T...> fmt,
T &&...args) noexcept {
logTraced(LogLevel::DEBUG, file, line, false, fmt, args...);
}
template <typename... T>
void fdebug_t(const char *file, unsigned int line, fmt::format_string<T...> fmt,
T &&...args) noexcept {
logTraced(LogLevel::DEBUG, file, line, true, fmt, args...);
}
template <typename... T>
void finfo_t(fmt::format_string<T...> fmt, T &&...args) {
log(LogLevel::INFO, true, fmt, args...);
}
template <typename... T>
void finfo(fmt::format_string<T...> fmt, T &&...args) {
log(LogLevel::INFO, false, fmt, args...);
}
template <typename... T>
void fwarning(const char *file, unsigned int line, fmt::format_string<T...> fmt, T &&...args) {
logTraced(LogLevel::WARNING, file, line, false, fmt, args...);
}
template <typename... T>
void fwarning_t(const char *file, unsigned int line, fmt::format_string<T...> fmt, T &&...args) {
logTraced(LogLevel::WARNING, file, line, true, fmt, args...);
}
template <typename... T>
void ferror(const char *file, unsigned int line, fmt::format_string<T...> fmt, T &&...args) {
logTraced(LogLevel::ERROR, file, line, false, fmt, args...);
}
template <typename... T>
void ferror_t(const char *file, unsigned int line, fmt::format_string<T...> fmt, T &&...args) {
logTraced(LogLevel::ERROR, file, line, true, fmt, args...);
}
} // namespace sif
#define FSFW_LOGI(format, ...) finfo(FMT_STRING(format), __VA_ARGS__)
#define FSFW_LOGIT(format, ...) finfo_t(FMT_STRING(format), __VA_ARGS__)
#define FSFW_LOGD(format, ...) sif::fdebug(__FILENAME__, __LINE__, FMT_STRING(format), __VA_ARGS__)
#define FSFW_LOGDT(format, ...) fdebug_t(__FILENAME__, __LINE__, FMT_STRING(format), __VA_ARGS__)
#define FSFW_LOGW(format, ...) fdebug(__FILENAME__, __LINE__, FMT_STRING(format), __VA_ARGS__)
#define FSFW_LOGWT(format, ...) fdebug_t(__FILENAME__, __LINE__, FMT_STRING(format), __VA_ARGS__)
#define FSFW_LOGE(format, ...) fdebug(__FILENAME__, __LINE__, FMT_STRING(format), __VA_ARGS__)
#define FSFW_LOGET(format, ...) fdebug_t(__FILENAME__, __LINE__, FMT_STRING(format), __VA_ARGS__)
#endif // FSFW_EXAMPLE_HOSTED_TESTFMT_H

View File

@ -12,21 +12,22 @@
* pool variables (for read and write access respectively).
*/
class FsfwDemoSet : public StaticLocalDataSet<3> {
public:
public:
static constexpr uint32_t DEMO_SET_ID = 0;
enum PoolIds { VARIABLE, VARIABLE_LIMIT };
FsfwDemoSet(HasLocalDataPoolIF *hkOwner) : StaticLocalDataSet(hkOwner, DEMO_SET_ID) {}
FsfwDemoSet(HasLocalDataPoolIF *hkOwner)
: StaticLocalDataSet(hkOwner, DEMO_SET_ID) {}
lp_var_t<uint32_t> variableRead =
lp_var_t<uint32_t>(sid.objectId, PoolIds::VARIABLE, this, pool_rwm_t::VAR_READ);
lp_var_t<uint32_t> variableWrite =
lp_var_t<uint32_t>(sid.objectId, PoolIds::VARIABLE, this, pool_rwm_t::VAR_WRITE);
lp_var_t<uint32_t> variableRead = lp_var_t<uint32_t>(
sid.objectId, PoolIds::VARIABLE, this, pool_rwm_t::VAR_READ);
lp_var_t<uint32_t> variableWrite = lp_var_t<uint32_t>(
sid.objectId, PoolIds::VARIABLE, this, pool_rwm_t::VAR_WRITE);
lp_var_t<uint16_t> variableLimit =
lp_var_t<uint16_t>(sid.objectId, PoolIds::VARIABLE_LIMIT, this);
private:
private:
};
/**
@ -35,10 +36,11 @@ class FsfwDemoSet : public StaticLocalDataSet<3> {
* which reads multiple sensor values at once.
*/
class CompleteDemoReadSet : public StaticLocalDataSet<3> {
public:
public:
static constexpr uint32_t DEMO_SET_ID = 0;
CompleteDemoReadSet(object_id_t owner, gp_id_t variable1, gp_id_t variable2, gp_id_t variable3)
CompleteDemoReadSet(object_id_t owner, gp_id_t variable1, gp_id_t variable2,
gp_id_t variable3)
: StaticLocalDataSet(sid_t(owner, DEMO_SET_ID)),
variable1(variable1, this, pool_rwm_t::VAR_READ),
variable2(variable2, this, pool_rwm_t::VAR_READ),
@ -48,7 +50,7 @@ class CompleteDemoReadSet : public StaticLocalDataSet<3> {
lp_var_t<uint32_t> variable2;
lp_var_t<uint32_t> variable3;
private:
private:
};
#endif /* MISSION_DEMO_DEMODEFINITIONS_H_ */

View File

@ -1,2 +1 @@
target_sources(${TARGET_NAME} PRIVATE utility.cpp TmFunnel.cpp PusTmFunnel.cpp
CfdpTmFunnel.cpp)
target_sources(${TARGET_NAME} PRIVATE utility.cpp TmFunnel.cpp)

View File

@ -1,84 +0,0 @@
#include "CfdpTmFunnel.h"
#include "fsfw/ipc/QueueFactory.h"
#include "fsfw/tmtcpacket/ccsds/SpacePacketCreator.h"
#include "fsfw/tmtcservices/TmTcMessage.h"
CfdpTmFunnel::CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid,
const AcceptsTelemetryIF& downlinkDestination, StorageManagerIF& tmStore)
: SystemObject(objectId), cfdpInCcsdsApid(cfdpInCcsdsApid), tmStore(tmStore) {
msgQueue = QueueFactory::instance()->createMessageQueue(5);
msgQueue->setDefaultDestination(downlinkDestination.getReportReceptionQueue());
}
const char* CfdpTmFunnel::getName() const { return "CFDP TM Funnel"; }
MessageQueueId_t CfdpTmFunnel::getReportReceptionQueue(uint8_t virtualChannel) const {
return msgQueue->getId();
}
ReturnValue_t CfdpTmFunnel::performOperation(uint8_t) {
TmTcMessage currentMessage;
ReturnValue_t status = msgQueue->receiveMessage(&currentMessage);
while (status == returnvalue::OK) {
status = handlePacket(currentMessage);
if (status != returnvalue::OK) {
sif::warning << "CfdpTmFunnel packet handling failed" << std::endl;
break;
}
status = msgQueue->receiveMessage(&currentMessage);
}
if (status == MessageQueueIF::EMPTY) {
return returnvalue::OK;
}
return status;
}
ReturnValue_t CfdpTmFunnel::initialize() { return returnvalue::OK; }
ReturnValue_t CfdpTmFunnel::handlePacket(TmTcMessage& msg) {
const uint8_t* cfdpPacket = nullptr;
size_t cfdpPacketLen = 0;
ReturnValue_t result = tmStore.getData(msg.getStorageId(), &cfdpPacket, &cfdpPacketLen);
if (result != returnvalue::OK) {
return result;
}
auto spacePacketHeader =
SpacePacketCreator(ccsds::PacketType::TM, false, cfdpInCcsdsApid,
ccsds::SequenceFlags::UNSEGMENTED, sourceSequenceCount++, 0);
sourceSequenceCount = sourceSequenceCount & ccsds::LIMIT_SEQUENCE_COUNT;
spacePacketHeader.setCcsdsLenFromTotalDataFieldLen(cfdpPacketLen);
uint8_t* newPacketData = nullptr;
store_address_t newStoreId{};
result =
tmStore.getFreeElement(&newStoreId, spacePacketHeader.getFullPacketLen(), &newPacketData);
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "CfdpTmFunnel::handlePacket: Error getting TM store element of size "
<< spacePacketHeader.getFullPacketLen() << std::endl;
#endif
return result;
}
size_t serSize = 0;
result =
spacePacketHeader.serializeBe(&newPacketData, &serSize, spacePacketHeader.getFullPacketLen());
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "CfdpTmFunnel::handlePacket: Error serializing packet" << std::endl;
#endif
return result;
}
std::memcpy(newPacketData, cfdpPacket, cfdpPacketLen);
// Delete old packet
tmStore.deleteData(msg.getStorageId());
msg.setStorageId(newStoreId);
result = msgQueue->sendToDefault(&msg);
if (result != returnvalue::OK) {
tmStore.deleteData(msg.getStorageId());
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "CfdpTmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl;
#endif
}
return result;
}

View File

@ -1,27 +0,0 @@
#ifndef FSFW_EXAMPLE_COMMON_CFDPTMFUNNEL_H
#define FSFW_EXAMPLE_COMMON_CFDPTMFUNNEL_H
#include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/storagemanager/StorageManagerIF.h"
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
#include "fsfw/tmtcservices/TmTcMessage.h"
class CfdpTmFunnel : public AcceptsTelemetryIF, public SystemObject {
public:
CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid,
const AcceptsTelemetryIF& downlinkDestination, StorageManagerIF& tmStore);
[[nodiscard]] const char* getName() const override;
[[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override;
ReturnValue_t performOperation(uint8_t opCode);
ReturnValue_t initialize() override;
private:
ReturnValue_t handlePacket(TmTcMessage& msg);
uint16_t sourceSequenceCount = 0;
uint16_t cfdpInCcsdsApid;
MessageQueueIF* msgQueue;
StorageManagerIF& tmStore;
};
#endif // FSFW_EXAMPLE_COMMON_CFDPTMFUNNEL_H

View File

@ -9,7 +9,7 @@
#define MISSION_UTILITY_PUSPACKETCREATOR_H_
class PusPacketCreator {
public:
public:
static void createPusPacketAndPrint();
};

View File

@ -1,68 +0,0 @@
#include "PusTmFunnel.h"
#include "fsfw/ipc/QueueFactory.h"
#include "fsfw/objectmanager.h"
#include "fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h"
PusTmFunnel::PusTmFunnel(object_id_t objectId, const AcceptsTelemetryIF &downlinkDestination,
TimeReaderIF &timeReader, StorageManagerIF &tmStore, uint32_t messageDepth)
: SystemObject(objectId), timeReader(timeReader), tmStore(tmStore) {
tmQueue = QueueFactory::instance()->createMessageQueue(messageDepth,
MessageQueueMessage::MAX_MESSAGE_SIZE);
tmQueue->setDefaultDestination(downlinkDestination.getReportReceptionQueue());
}
PusTmFunnel::~PusTmFunnel() = default;
MessageQueueId_t PusTmFunnel::getReportReceptionQueue(uint8_t virtualChannel) const {
return tmQueue->getId();
}
ReturnValue_t PusTmFunnel::performOperation(uint8_t) {
TmTcMessage currentMessage;
ReturnValue_t status = tmQueue->receiveMessage(&currentMessage);
while (status == returnvalue::OK) {
status = handlePacket(currentMessage);
if (status != returnvalue::OK) {
sif::warning << "TmFunnel packet handling failed" << std::endl;
break;
}
status = tmQueue->receiveMessage(&currentMessage);
}
if (status == MessageQueueIF::EMPTY) {
return returnvalue::OK;
}
return status;
}
ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) {
uint8_t *packetData = nullptr;
size_t size = 0;
ReturnValue_t result = tmStore.modifyData(message.getStorageId(), &packetData, &size);
if (result != returnvalue::OK) {
return result;
}
PusTmZeroCopyWriter packet(timeReader, packetData, size);
result = packet.parseDataWithoutCrcCheck();
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "PusTmFunnel::handlePacket: Error parsing received PUS packet" << std::endl;
#endif
return result;
}
packet.setSequenceCount(sourceSequenceCount++);
sourceSequenceCount = sourceSequenceCount % ccsds::LIMIT_SEQUENCE_COUNT;
packet.updateErrorControl();
result = tmQueue->sendToDefault(&message);
if (result != returnvalue::OK) {
tmStore.deleteData(message.getStorageId());
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PusTmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl;
#endif
}
return result;
}
const char *PusTmFunnel::getName() const { return "PUS TM Funnel"; }

View File

@ -1,39 +0,0 @@
#ifndef FSFW_EXAMPLE_COMMON_PUSTMFUNNEL_H
#define FSFW_EXAMPLE_COMMON_PUSTMFUNNEL_H
#include <fsfw/ipc/MessageQueueIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
#include <fsfw/tmtcservices/TmTcMessage.h>
#include "fsfw/timemanager/TimeReaderIF.h"
/**
* @brief TM Recipient.
* @details
* Main telemetry receiver. All generated telemetry is funneled into
* this object.
* @ingroup utility
* @author J. Meier
*/
class PusTmFunnel : public AcceptsTelemetryIF, public SystemObject {
public:
explicit PusTmFunnel(object_id_t objectId, const AcceptsTelemetryIF &downlinkDestination,
TimeReaderIF &timeReader, StorageManagerIF &tmStore,
uint32_t messageDepth = 20);
[[nodiscard]] const char *getName() const override;
~PusTmFunnel() override;
[[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override;
ReturnValue_t performOperation(uint8_t operationCode);
private:
uint16_t sourceSequenceCount = 0;
TimeReaderIF &timeReader;
StorageManagerIF &tmStore;
MessageQueueIF *tmQueue = nullptr;
ReturnValue_t handlePacket(TmTcMessage &message);
};
#endif // FSFW_EXAMPLE_COMMON_PUSTMFUNNEL_H

View File

@ -2,20 +2,14 @@
#define MISSION_UTILITY_TASKCREATION_H_
#include <fsfw/objectmanager/SystemObjectIF.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/serviceinterface.h>
namespace task {
void printInitError(const char *objName, object_id_t objectId) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "InitMission: Adding object " << objName << "(" << std::setw(8) << std::setfill('0')
<< std::hex << objectId << std::dec << ") failed." << std::endl;
#else
sif::printError("InitMission: Adding object %s (0x%08x) failed.\n", objName,
static_cast<unsigned int>(objectId));
#endif
void printInitError(const char* objName, object_id_t objectId) {
FSFW_LOGW("InitMission: Adding object {} ({:#010x}) failed\n", objName, objectId);
}
} // namespace task
} // namespace task
#endif /* MISSION_UTILITY_TASKCREATION_H_ */

View File

@ -1,16 +1,109 @@
#include "TmFunnel.h"
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/objectmanager/ObjectManager.h>
#include <fsfw/serviceinterface.h>
#include <fsfw/tmtcpacket/pus/tm.h>
TmFunnel::TmFunnel(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel)
: SystemObject(objectId), pusFunnel(pusFunnel), cfdpFunnel(cfdpFunnel) {}
object_id_t TmFunnel::downlinkDestination = objects::NO_OBJECT;
object_id_t TmFunnel::storageDestination = objects::NO_OBJECT;
TmFunnel::~TmFunnel() = default;
ReturnValue_t TmFunnel::performOperation(uint8_t operationCode) {
pusFunnel.performOperation(operationCode);
cfdpFunnel.performOperation(operationCode);
return returnvalue::OK;
TmFunnel::TmFunnel(object_id_t objectId, uint32_t messageDepth)
: SystemObject(objectId), messageDepth(messageDepth) {
tmQueue = QueueFactory::instance()->createMessageQueue(
messageDepth, MessageQueueMessage::MAX_MESSAGE_SIZE);
storageQueue = QueueFactory::instance()->createMessageQueue(
messageDepth, MessageQueueMessage::MAX_MESSAGE_SIZE);
}
ReturnValue_t TmFunnel::initialize() { return returnvalue::OK; }
TmFunnel::~TmFunnel() {}
MessageQueueId_t TmFunnel::getReportReceptionQueue(uint8_t virtualChannel) {
return tmQueue->getId();
}
ReturnValue_t TmFunnel::performOperation(uint8_t operationCode) {
TmTcMessage currentMessage;
ReturnValue_t status = tmQueue->receiveMessage(&currentMessage);
while (status == HasReturnvaluesIF::RETURN_OK) {
status = handlePacket(&currentMessage);
if (status != HasReturnvaluesIF::RETURN_OK) {
break;
}
status = tmQueue->receiveMessage(&currentMessage);
}
if (status == MessageQueueIF::EMPTY) {
return HasReturnvaluesIF::RETURN_OK;
} else {
return status;
}
}
ReturnValue_t TmFunnel::handlePacket(TmTcMessage *message) {
uint8_t *packetData = nullptr;
size_t size = 0;
ReturnValue_t result =
tmPool->modifyData(message->getStorageId(), &packetData, &size);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
TmPacketPusC packet(packetData);
packet.setPacketSequenceCount(this->sourceSequenceCount);
sourceSequenceCount++;
sourceSequenceCount =
sourceSequenceCount % SpacePacketBase::LIMIT_SEQUENCE_COUNT;
packet.setErrorControl();
result = tmQueue->sendToDefault(message);
if (result != HasReturnvaluesIF::RETURN_OK) {
tmPool->deleteData(message->getStorageId());
FSFW_LOGET("handlePacket: Error sending to downlink handler\n");
return result;
}
if (storageDestination != objects::NO_OBJECT) {
result = storageQueue->sendToDefault(message);
if (result != HasReturnvaluesIF::RETURN_OK) {
tmPool->deleteData(message->getStorageId());
FSFW_LOGET("handlePacket: Error sending to storage handler\n");
return result;
}
}
return result;
}
ReturnValue_t TmFunnel::initialize() {
tmPool = ObjectManager::instance()->get<StorageManagerIF>(objects::TM_STORE);
if (tmPool == nullptr) {
FSFW_LOGE("{}",
"initialize: TM store not set\n"
"Make sure the tm store is set up properly and implements StorageManagerIF");
return ObjectManagerIF::CHILD_INIT_FAILED;
}
auto* tmTarget = ObjectManager::instance()->get<AcceptsTelemetryIF>(downlinkDestination);
if (tmTarget == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
FSFW_LOGE("{}",
"initialize: Downlink Destination not set. Make sure the downlink destination "
"object is set up properly and implements AcceptsTelemetryIF\n");
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
}
tmQueue->setDefaultDestination(tmTarget->getReportReceptionQueue());
// Storage destination is optional.
if (storageDestination == objects::NO_OBJECT) {
return SystemObject::initialize();
}
AcceptsTelemetryIF *storageTarget =
ObjectManager::instance()->get<AcceptsTelemetryIF>(storageDestination);
if (storageTarget != nullptr) {
storageQueue->setDefaultDestination(
storageTarget->getReportReceptionQueue());
}
return SystemObject::initialize();
}

View File

@ -7,9 +7,9 @@
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
#include <fsfw/tmtcservices/TmTcMessage.h>
#include "CfdpTmFunnel.h"
#include "PusTmFunnel.h"
#include "fsfw/timemanager/TimeReaderIF.h"
namespace Factory {
void setStaticFrameworkObjectIds();
}
/**
* @brief TM Recipient.
@ -19,17 +19,33 @@
* @ingroup utility
* @author J. Meier
*/
class TmFunnel : public ExecutableObjectIF, public SystemObject {
public:
TmFunnel(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel);
~TmFunnel() override;
class TmFunnel : public AcceptsTelemetryIF,
public ExecutableObjectIF,
public SystemObject {
friend void(Factory::setStaticFrameworkObjectIds)();
ReturnValue_t performOperation(uint8_t operationCode) override;
ReturnValue_t initialize() override;
public:
TmFunnel(object_id_t objectId, uint32_t messageDepth = 20);
virtual ~TmFunnel();
private:
PusTmFunnel& pusFunnel;
CfdpTmFunnel& cfdpFunnel;
virtual MessageQueueId_t
getReportReceptionQueue(uint8_t virtualChannel = 0) override;
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
virtual ReturnValue_t initialize() override;
protected:
static object_id_t downlinkDestination;
static object_id_t storageDestination;
private:
uint16_t sourceSequenceCount = 0;
MessageQueueIF *tmQueue = nullptr;
MessageQueueIF *storageQueue = nullptr;
StorageManagerIF *tmPool = nullptr;
uint32_t messageDepth = 0;
ReturnValue_t handlePacket(TmTcMessage *message);
};
#endif /* MISSION_UTILITY_TMFUNNEL_H_ */

View File

@ -39,19 +39,19 @@
#define CONV_STR2DEC_4(str, i) (CONV_STR2DEC_3(str, i) * 10 + str[i + 3] - '0')
// Custom "glue logic" to convert the month name to a usable number
#define GET_MONTH(str, i) \
(str[i] == 'J' && str[i + 1] == 'a' && str[i + 2] == 'n' ? 1 \
: str[i] == 'F' && str[i + 1] == 'e' && str[i + 2] == 'b' ? 2 \
: str[i] == 'M' && str[i + 1] == 'a' && str[i + 2] == 'r' ? 3 \
: str[i] == 'A' && str[i + 1] == 'p' && str[i + 2] == 'r' ? 4 \
: str[i] == 'M' && str[i + 1] == 'a' && str[i + 2] == 'y' ? 5 \
: str[i] == 'J' && str[i + 1] == 'u' && str[i + 2] == 'n' ? 6 \
: str[i] == 'J' && str[i + 1] == 'u' && str[i + 2] == 'l' ? 7 \
: str[i] == 'A' && str[i + 1] == 'u' && str[i + 2] == 'g' ? 8 \
: str[i] == 'S' && str[i + 1] == 'e' && str[i + 2] == 'p' ? 9 \
: str[i] == 'O' && str[i + 1] == 'c' && str[i + 2] == 't' ? 10 \
: str[i] == 'N' && str[i + 1] == 'o' && str[i + 2] == 'v' ? 11 \
: str[i] == 'D' && str[i + 1] == 'e' && str[i + 2] == 'c' ? 12 \
#define GET_MONTH(str, i) \
(str[i] == 'J' && str[i + 1] == 'a' && str[i + 2] == 'n' ? 1 \
: str[i] == 'F' && str[i + 1] == 'e' && str[i + 2] == 'b' ? 2 \
: str[i] == 'M' && str[i + 1] == 'a' && str[i + 2] == 'r' ? 3 \
: str[i] == 'A' && str[i + 1] == 'p' && str[i + 2] == 'r' ? 4 \
: str[i] == 'M' && str[i + 1] == 'a' && str[i + 2] == 'y' ? 5 \
: str[i] == 'J' && str[i + 1] == 'u' && str[i + 2] == 'n' ? 6 \
: str[i] == 'J' && str[i + 1] == 'u' && str[i + 2] == 'l' ? 7 \
: str[i] == 'A' && str[i + 1] == 'u' && str[i + 2] == 'g' ? 8 \
: str[i] == 'S' && str[i + 1] == 'e' && str[i + 2] == 'p' ? 9 \
: str[i] == 'O' && str[i + 1] == 'c' && str[i + 2] == 't' ? 10 \
: str[i] == 'N' && str[i + 1] == 'o' && str[i + 2] == 'v' ? 11 \
: str[i] == 'D' && str[i + 1] == 'e' && str[i + 2] == 'c' ? 12 \
: 0)
// extract the information from the time string given by __TIME__ and __DATE__
@ -63,30 +63,37 @@
#define __TIME_YEARS__ CONV_STR2DEC_4(__DATE__, 7)
// Days in February
#define _UNIX_TIMESTAMP_FDAY(year) \
(((year) % 400) == 0UL ? 29UL \
: (((year) % 100) == 0UL ? 28UL : (((year) % 4) == 0UL ? 29UL : 28UL)))
#define _UNIX_TIMESTAMP_FDAY(year) \
(((year) % 400) == 0UL \
? 29UL \
: (((year) % 100) == 0UL ? 28UL : (((year) % 4) == 0UL ? 29UL : 28UL)))
// Days in the year
#define _UNIX_TIMESTAMP_YDAY(year, month, day) \
(/* January */ day /* February */ + (month >= 2 ? 31UL : 0UL) /* March */ + \
(month >= 3 ? _UNIX_TIMESTAMP_FDAY(year) : 0UL) /* April */ + \
(month >= 4 ? 31UL : 0UL) /* May */ + (month >= 5 ? 30UL : 0UL) /* June */ + \
(month >= 6 ? 31UL : 0UL) /* July */ + (month >= 7 ? 30UL : 0UL) /* August */ + \
(month >= 8 ? 31UL : 0UL) /* September */ + (month >= 9 ? 31UL : 0UL) /* October */ + \
(month >= 10 ? 30UL : 0UL) /* November */ + (month >= 11 ? 31UL : 0UL) /* December */ + \
(month >= 12 ? 30UL : 0UL))
#define _UNIX_TIMESTAMP_YDAY(year, month, day) \
(/* January */ day /* February */ + (month >= 2 ? 31UL : 0UL) /* March */ + \
(month >= 3 ? _UNIX_TIMESTAMP_FDAY(year) : 0UL) /* April */ + \
(month >= 4 ? 31UL : 0UL) /* May */ + \
(month >= 5 ? 30UL : 0UL) /* June */ + \
(month >= 6 ? 31UL : 0UL) /* July */ + \
(month >= 7 ? 30UL : 0UL) /* August */ + \
(month >= 8 ? 31UL : 0UL) /* September */ + \
(month >= 9 ? 31UL : 0UL) /* October */ + \
(month >= 10 ? 30UL : 0UL) /* November */ + \
(month >= 11 ? 31UL : 0UL) /* December */ + (month >= 12 ? 30UL : 0UL))
// get the UNIX timestamp from a digits representation
#define _UNIX_TIMESTAMP(year, month, day, hour, minute, second) \
(/* time */ second + minute * SEC_PER_MIN + hour * SEC_PER_HOUR + \
/* year day (month + day) */ (_UNIX_TIMESTAMP_YDAY(year, month, day) - 1) * SEC_PER_DAY + \
/* year */ (year - 1970UL) * SEC_PER_YEAR + ((year - 1969UL) / 4UL) * SEC_PER_DAY - \
((year - 1901UL) / 100UL) * SEC_PER_DAY + ((year - 1601UL) / 400UL) * SEC_PER_DAY)
#define _UNIX_TIMESTAMP(year, month, day, hour, minute, second) \
(/* time */ second + minute * SEC_PER_MIN + hour * SEC_PER_HOUR + \
/* year day (month + day) */ (_UNIX_TIMESTAMP_YDAY(year, month, day) - 1) * \
SEC_PER_DAY + \
/* year */ (year - 1970UL) * SEC_PER_YEAR + \
((year - 1969UL) / 4UL) * SEC_PER_DAY - \
((year - 1901UL) / 100UL) * SEC_PER_DAY + \
((year - 1601UL) / 400UL) * SEC_PER_DAY)
// the UNIX timestamp
#define UNIX_TIMESTAMP \
(_UNIX_TIMESTAMP(__TIME_YEARS__, __TIME_MONTH__, __TIME_DAYS__, __TIME_HOURS__, \
__TIME_MINUTES__, __TIME_SECONDS__))
#define UNIX_TIMESTAMP \
(_UNIX_TIMESTAMP(__TIME_YEARS__, __TIME_MONTH__, __TIME_DAYS__, \
__TIME_HOURS__, __TIME_MINUTES__, __TIME_SECONDS__))
#endif

View File

@ -1,22 +1,16 @@
#include "utility.h"
#include <FSFWConfig.h>
#include <OBSWVersion.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include "fsfw/serviceinterface.h"
void utility::commonInitPrint(const char *const os, const char *const board) {
if (os == nullptr or board == nullptr) {
return;
}
#if FSFW_CPP_OSTREAM_ENABLED == 1
std::cout << "-- FSFW Example (" << os << ") v" << FSFW_EXAMPLE_VERSION << "."
<< FSFW_EXAMPLE_SUBVERSION << "." << FSFW_EXAMPLE_REVISION << " --" << std::endl;
std::cout << "-- Compiled for " << board << " --" << std::endl;
std::cout << "-- Compiled on " << __DATE__ << " " << __TIME__ << " --" << std::endl;
#else
printf("\n\r-- FSFW Example (%s) v%d.%d.%d --\n", os, FSFW_EXAMPLE_VERSION,
FSFW_EXAMPLE_SUBVERSION, FSFW_EXAMPLE_REVISION);
printf("-- Compiled for %s --\n", board);
printf("-- Compiled on %s %s --\n", __DATE__, __TIME__);
#endif
fmt::print("-- FSFW Example ({}) v{}.{}.{} --\n", os, FSFW_EXAMPLE_VERSION,
FSFW_EXAMPLE_SUBVERSION, FSFW_EXAMPLE_REVISION);
fmt::print("-- Compiled for {}\n", board);
fmt::print("-- Compiled on {} {}\n", __DATE__, __TIME__);
sif::initialize();
}

View File

@ -3,7 +3,8 @@
#include "OBSWConfig.h"
#include "stm32h7xx_nucleo.h"
STM32TestTask::STM32TestTask(object_id_t objectId, bool enablePrintout, bool blinkyLed)
STM32TestTask::STM32TestTask(object_id_t objectId, bool enablePrintout,
bool blinkyLed)
: TestTask(objectId), blinkyLed(blinkyLed) {
BSP_LED_Init(LED1);
BSP_LED_Init(LED2);
@ -20,7 +21,7 @@ ReturnValue_t STM32TestTask::initialize() {
ReturnValue_t STM32TestTask::performPeriodicAction() {
if (blinkyLed) {
#if OBSW_ETHERNET_USE_LED1_LED2 == 0
#if OBSW_ETHERNET_USE_LED1_LED2 == 0
BSP_LED_Toggle(LED1);
BSP_LED_Toggle(LED2);
#endif

View File

@ -5,13 +5,14 @@
#include "fsfw_tests/integration/task/TestTask.h"
class STM32TestTask : public TestTask {
public:
STM32TestTask(object_id_t objectId, bool enablePrintout, bool blinkyLed = true);
public:
STM32TestTask(object_id_t objectId, bool enablePrintout,
bool blinkyLed = true);
ReturnValue_t initialize() override;
ReturnValue_t performPeriodicAction() override;
private:
private:
SpiComIF *spiComIF = nullptr;
SpiTest *spiTest = nullptr;

View File

@ -1,5 +1,6 @@
#include "TmTcLwIpUdpBridge.h"
#include <fsfw/ipc/MutexGuard.h>
#include <fsfw/serialize/EndianConverter.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
@ -7,8 +8,10 @@
#include "app_ethernet.h"
#include "udp_config.h"
TmTcLwIpUdpBridge::TmTcLwIpUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor,
object_id_t tmStoreId, object_id_t tcStoreId)
TmTcLwIpUdpBridge::TmTcLwIpUdpBridge(object_id_t objectId,
object_id_t ccsdsPacketDistributor,
object_id_t tmStoreId,
object_id_t tcStoreId)
: TmTcBridge(objectId, ccsdsPacketDistributor, tmStoreId, tcStoreId) {
TmTcLwIpUdpBridge::lastAdd.addr = IPADDR_TYPE_ANY;
}
@ -37,7 +40,8 @@ ReturnValue_t TmTcLwIpUdpBridge::udp_server_init() {
if (err == ERR_OK) {
/* Set a receive callback for the upcb */
udp_recv(TmTcLwIpUdpBridge::upcb, &udp_server_receive_callback, (void *)this);
udp_recv(TmTcLwIpUdpBridge::upcb, &udp_server_receive_callback,
(void *)this);
return RETURN_OK;
} else {
udp_remove(TmTcLwIpUdpBridge::upcb);
@ -60,13 +64,15 @@ ReturnValue_t TmTcLwIpUdpBridge::performOperation(uint8_t operationCode) {
int ipAddress4 = ipAddress & 0xFF;
#if OBSW_VERBOSE_LEVEL == 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::info << "TmTcLwIpUdpBridge: Client IP Address " << std::dec << ipAddress4 << "."
<< ipAddress3 << "." << ipAddress2 << "." << ipAddress1 << std::endl;
sif::info << "TmTcLwIpUdpBridge: Client IP Address " << std::dec
<< ipAddress4 << "." << ipAddress3 << "." << ipAddress2 << "."
<< ipAddress1 << std::endl;
uint16_t portSwapped = EndianConverter::convertBigEndian(lastPort);
sif::info << "TmTcLwIpUdpBridge: Client IP Port " << (int)portSwapped << std::endl;
sif::info << "TmTcLwIpUdpBridge: Client IP Port " << (int)portSwapped
<< std::endl;
#else
sif::printInfo("TmTcLwIpUdpBridge: Client IP Address %d.%d.%d.%d\n", ipAddress4, ipAddress3,
ipAddress2, ipAddress1);
sif::printInfo("TmTcLwIpUdpBridge: Client IP Address %d.%d.%d.%d\n",
ipAddress4, ipAddress3, ipAddress2, ipAddress1);
uint16_t portSwapped = EndianConverter::convertBigEndian(lastPort);
sif::printInfo("TmTcLwIpUdpBridge: Client IP Port: %d\n", portSwapped);
#endif
@ -80,7 +86,8 @@ ReturnValue_t TmTcLwIpUdpBridge::performOperation(uint8_t operationCode) {
ReturnValue_t TmTcLwIpUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
struct pbuf *p_tx = pbuf_alloc(PBUF_TRANSPORT, dataLen, PBUF_RAM);
if ((p_tx != nullptr) && (lastAdd.addr != IPADDR_TYPE_ANY) && (upcb != nullptr)) {
if ((p_tx != nullptr) && (lastAdd.addr != IPADDR_TYPE_ANY) &&
(upcb != nullptr)) {
/* copy data to pbuf */
err_t err = pbuf_take(p_tx, (const char *)data, dataLen);
if (err != ERR_OK) {
@ -108,18 +115,20 @@ ReturnValue_t TmTcLwIpUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
return RETURN_OK;
}
void TmTcLwIpUdpBridge::udp_server_receive_callback(void *arg, struct udp_pcb *upcb_,
struct pbuf *p, const ip_addr_t *addr,
void TmTcLwIpUdpBridge::udp_server_receive_callback(void *arg,
struct udp_pcb *upcb_,
struct pbuf *p,
const ip_addr_t *addr,
u16_t port) {
auto udpBridge = reinterpret_cast<TmTcLwIpUdpBridge *>(arg);
if (udpBridge == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TmTcLwIpUdpBridge::udp_server_receive_callback: Invalid UDP bridge!"
<< std::endl;
sif::warning
<< "TmTcLwIpUdpBridge::udp_server_receive_callback: Invalid UDP bridge!"
<< std::endl;
#else
sif::printWarning(
"TmTcLwIpUdpBridge::udp_server_receive_callback: Invalid "
"UDP bridge!\n");
sif::printWarning("TmTcLwIpUdpBridge::udp_server_receive_callback: Invalid "
"UDP bridge!\n");
#endif
}
/* allocate pbuf from RAM*/
@ -150,8 +159,8 @@ void TmTcLwIpUdpBridge::udp_server_receive_callback(void *arg, struct udp_pcb *u
#endif
store_address_t storeId;
ReturnValue_t returnValue =
udpBridge->tcStore->addData(&storeId, reinterpret_cast<uint8_t *>(p->payload), p->len);
ReturnValue_t returnValue = udpBridge->tcStore->addData(
&storeId, reinterpret_cast<uint8_t *>(p->payload), p->len);
if (returnValue != RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UDP Server: Data storage failed" << std::endl;

View File

@ -1,12 +1,12 @@
#ifndef BSP_STM32_RTEMS_NETWORKING_TMTCUDPBRIDGE_H_
#define BSP_STM32_RTEMS_NETWORKING_TMTCUDPBRIDGE_H_
#include "fsfw/tmtcservices/TmTcBridge.h"
#include "commonConfig.h"
#include <lwip/ip_addr.h>
#include <lwip/udp.h>
#include "commonConfig.h"
#include "fsfw/tmtcservices/TmTcBridge.h"
/**
* This bridge is used to forward TMTC packets received via LwIP UDP to the
* internal software bus.
@ -14,9 +14,9 @@
class TmTcLwIpUdpBridge : public TmTcBridge {
friend class UdpTcLwIpPollingTask;
public:
TmTcLwIpUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor, object_id_t tmStoreId,
object_id_t tcStoreId);
public:
TmTcLwIpUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor,
object_id_t tmStoreId, object_id_t tcStoreId);
~TmTcLwIpUdpBridge() override;
ReturnValue_t initialize() override;
@ -45,8 +45,9 @@ class TmTcLwIpUdpBridge : public TmTcBridge {
* @param addr Source address which will be bound to TmTcUdpBridge::lastAdd
* @param port
*/
static void udp_server_receive_callback(void *arg, struct udp_pcb *upcb_, struct pbuf *p,
const ip_addr_t *addr, u16_t port);
static void udp_server_receive_callback(void *arg, struct udp_pcb *upcb_,
struct pbuf *p, const ip_addr_t *addr,
u16_t port);
/**
* Check whether the communication link is up.
@ -55,7 +56,7 @@ class TmTcLwIpUdpBridge : public TmTcBridge {
*/
[[nodiscard]] bool comLinkUp() const;
private:
private:
struct udp_pcb *upcb = nullptr;
ip_addr_t lastAdd{};
u16_t lastPort = 0;

View File

@ -10,9 +10,11 @@
#include "lwip/timeouts.h"
#include "networking.h"
UdpTcLwIpPollingTask::UdpTcLwIpPollingTask(object_id_t objectId, object_id_t bridgeId,
UdpTcLwIpPollingTask::UdpTcLwIpPollingTask(object_id_t objectId,
object_id_t bridgeId,
struct netif *gnetif)
: SystemObject(objectId), periodicHandleCounter(0), bridgeId(bridgeId), gnetif(gnetif) {}
: SystemObject(objectId), periodicHandleCounter(0), bridgeId(bridgeId),
gnetif(gnetif) {}
UdpTcLwIpPollingTask::~UdpTcLwIpPollingTask() = default;
@ -45,7 +47,8 @@ ReturnValue_t UdpTcLwIpPollingTask::performOperation(uint8_t operationCode) {
/* In case ethernet cable is disconnected */
if (not networking::getEthCableConnected() and udpBridge->comLinkUp()) {
udpBridge->physicalConnectStatusChange(false);
} else if (networking::getEthCableConnected() and not udpBridge->comLinkUp()) {
} else if (networking::getEthCableConnected() and
not udpBridge->comLinkUp()) {
udpBridge->physicalConnectStatusChange(true);
}
}

View File

@ -14,8 +14,9 @@ class TmTcLwIpUdpBridge;
class UdpTcLwIpPollingTask : public SystemObject,
public ExecutableObjectIF,
public HasReturnvaluesIF {
public:
UdpTcLwIpPollingTask(object_id_t objectId, object_id_t bridgeId, struct netif *gnetif);
public:
UdpTcLwIpPollingTask(object_id_t objectId, object_id_t bridgeId,
struct netif *gnetif);
~UdpTcLwIpPollingTask() override;
ReturnValue_t initialize() override;
@ -27,7 +28,7 @@ class UdpTcLwIpPollingTask : public SystemObject,
*/
ReturnValue_t performOperation(uint8_t operationCode) override;
private:
private:
static const uint8_t PERIODIC_HANDLE_TRIGGER = 5;
uint8_t periodicHandleCounter;
object_id_t bridgeId = 0;

View File

@ -24,22 +24,22 @@ void handle_dhcp_down(struct netif *netif);
void DHCP_Process(struct netif *netif) {
struct dhcp *dhcp = nullptr;
switch (DHCP_state) {
case DHCP_START: {
handle_dhcp_start(netif);
break;
}
case DHCP_WAIT_ADDRESS: {
handle_dhcp_wait(netif, &dhcp);
break;
}
case DHCP_START: {
handle_dhcp_start(netif);
break;
}
case DHCP_WAIT_ADDRESS: {
handle_dhcp_wait(netif, &dhcp);
break;
}
case DHCP_LINK_DOWN: {
handle_dhcp_down(netif);
break;
}
default: {
break;
}
case DHCP_LINK_DOWN: {
handle_dhcp_down(netif);
break;
}
default: {
break;
}
}
}
@ -107,7 +107,8 @@ void handle_dhcp_start(struct netif *netif) {
void handle_dhcp_wait(struct netif *netif, struct dhcp **dhcp) {
if (dhcp_supplied_address(netif)) {
DHCP_state = DHCP_ADDRESS_ASSIGNED;
printf("IP address assigned by a DHCP server: %s\n\r", ip4addr_ntoa(netif_ip4_addr(netif)));
printf("IP address assigned by a DHCP server: %s\n\r",
ip4addr_ntoa(netif_ip4_addr(netif)));
printf("Listener port: %d\n\r", UDP_SERVER_PORT);
#if OBSW_ETHERNET_TMTC_COMMANDING == 1
#if OBSW_ETHERNET_USE_LED1_LED2 == 1
@ -116,8 +117,8 @@ void handle_dhcp_wait(struct netif *netif, struct dhcp **dhcp) {
#endif
#endif
} else {
*dhcp =
static_cast<struct dhcp *>(netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP));
*dhcp = static_cast<struct dhcp *>(netif_get_client_data(
netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP));
/* DHCP timeout */
if ((*dhcp)->tries > MAX_DHCP_TRIES) {

View File

@ -47,8 +47,8 @@ void handle_status_change(struct netif *netif, bool link_up) {
#else
uint8_t iptxt[20];
sprintf((char *)iptxt, "%s", ip4addr_ntoa(netif_ip4_addr(netif)));
printf("\rNetwork cable connected. Static IP address: %s | Port: %d\n\r", iptxt,
UDP_SERVER_PORT);
printf("\rNetwork cable connected. Static IP address: %s | Port: %d\n\r",
iptxt, UDP_SERVER_PORT);
#if OBSW_ETHERNET_USE_LED1_LED2 == 1
BSP_LED_On(LED1);
BSP_LED_Off(LED2);

View File

@ -65,7 +65,7 @@ namespace networking {
void ethernetLinkStatusUpdated(struct netif *netif);
void ethernetLinkPeriodicHandle(struct netif *netif);
} // namespace networking
} // namespace networking
#ifdef __cplusplus
}

View File

@ -44,18 +44,17 @@
*/
/* Includes ------------------------------------------------------------------*/
#include "ethernetif.h"
#include <stdbool.h>
#include <string.h>
#include "fsfw/FSFW.h"
#include "lan8742.h"
#include "lwip/netif.h"
#include "stm32h7xx_hal.h"
#include "lwip/opt.h"
#include "lwip/timeouts.h"
#include "lwip/netif.h"
#include "netif/etharp.h"
#include "stm32h7xx_hal.h"
#include "ethernetif.h"
#include "lan8742.h"
#include <string.h>
#include <stdbool.h>
#include "fsfw/FSFW.h"
#ifdef FSFW_OSAL_RTEMS
#include <rtems.h>
@ -67,11 +66,11 @@
#define IFNAME0 's'
#define IFNAME1 't'
#define ETH_DMA_TRANSMIT_TIMEOUT (20U)
#define ETH_DMA_TRANSMIT_TIMEOUT (20U)
#define ETH_RX_BUFFER_SIZE 1536U
#define ETH_RX_BUFFER_CNT 12U
#define ETH_TX_BUFFER_MAX ((ETH_TX_DESC_CNT)*2U)
#define ETH_RX_BUFFER_SIZE 1536U
#define ETH_RX_BUFFER_CNT 12U
#define ETH_TX_BUFFER_MAX ((ETH_TX_DESC_CNT) * 2U)
#define DMA_DESCRIPTOR_ALIGNMENT 0x20
@ -94,47 +93,49 @@ stack they will return back to DMA after been processed by the stack.
2.b. Rx Buffers must have the same size: ETH_RX_BUFFER_SIZE, this value must
passed to ETH DMA in the init field (EthHandle.Init.RxBuffLen)
*/
typedef enum { RX_ALLOC_OK = 0x00, RX_ALLOC_ERROR = 0x01 } RxAllocStatusTypeDef;
typedef enum
{
RX_ALLOC_OK = 0x00,
RX_ALLOC_ERROR = 0x01
} RxAllocStatusTypeDef;
typedef struct {
typedef struct
{
struct pbuf_custom pbuf_custom;
uint8_t buff[(ETH_RX_BUFFER_SIZE + 31) & ~31] __ALIGNED(32);
} RxBuff_t;
#if defined(__ICCARM__) /*!< IAR Compiler */
#pragma location = 0x30000000
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
#pragma location = 0x30000200
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
#pragma location=0x30000000
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
#pragma location=0x30000200
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
#elif defined(__CC_ARM) /* MDK ARM Compiler */
__attribute__((section(".RxDecripSection")))
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
__attribute__((section(".TxDecripSection")))
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
__attribute__((section(".RxDecripSection"))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
__attribute__((section(".TxDecripSection"))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
#elif defined(__GNUC__) /* GNU Compiler */
#ifdef FSFW_OSAL_RTEMS
/* Put into special RTEMS section and align correctly */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]
__attribute__((section(".bsp_nocache"),
__aligned__(DMA_DESCRIPTOR_ALIGNMENT))); /* Ethernet Rx DMA Descriptors */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((
section(".bsp_nocache"),
__aligned__(DMA_DESCRIPTOR_ALIGNMENT))); /* Ethernet Rx DMA Descriptors */
/* Put into special RTEMS section and align correctly */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]
__attribute__((section(".bsp_nocache"),
__aligned__(DMA_DESCRIPTOR_ALIGNMENT))); /* Ethernet Tx DMA Descriptors */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((
section(".bsp_nocache"),
__aligned__(DMA_DESCRIPTOR_ALIGNMENT))); /* Ethernet Tx DMA Descriptors */
/* Ethernet Receive Buffers. Just place somewhere is BSS instead of explicitely
* placing it */
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE];
#elif defined FSFW_OSAL_FREERTOS
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]
__attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]
__attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */
#endif /* FSFW_OSAL_RTEMS */
@ -143,14 +144,14 @@ ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]
/* Memory Pool Declaration */
LWIP_MEMPOOL_DECLARE(RX_POOL, ETH_RX_BUFFER_CNT, sizeof(RxBuff_t), "Zero-copy RX PBUF pool");
#if defined(__ICCARM__) /*!< IAR Compiler */
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma location = 0x30000400
extern u8_t memp_memory_RX_POOL_base[];
#elif defined(__CC_ARM) /* MDK ARM Compiler */
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
#elif defined(__GNUC__) /* GNU Compiler */
#elif defined ( __GNUC__ ) /* GNU Compiler */
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
#endif
@ -169,14 +170,17 @@ ETH_TxPacketConfig TxConfig;
u32_t sys_now(void);
extern void Error_Handler(void);
int32_t ETH_PHY_IO_Init(void);
int32_t ETH_PHY_IO_DeInit(void);
int32_t ETH_PHY_IO_DeInit (void);
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal);
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal);
int32_t ETH_PHY_IO_GetTick(void);
lan8742_Object_t LAN8742;
lan8742_IOCtx_t LAN8742_IOCtx = {ETH_PHY_IO_Init, ETH_PHY_IO_DeInit, ETH_PHY_IO_WriteReg,
ETH_PHY_IO_ReadReg, ETH_PHY_IO_GetTick};
lan8742_IOCtx_t LAN8742_IOCtx = {ETH_PHY_IO_Init,
ETH_PHY_IO_DeInit,
ETH_PHY_IO_WriteReg,
ETH_PHY_IO_ReadReg,
ETH_PHY_IO_GetTick};
/* Private functions ---------------------------------------------------------*/
void pbuf_free_custom(struct pbuf *p);
@ -191,8 +195,7 @@ void pbuf_free_custom(struct pbuf *p);
* for this ethernetif
*/
static void low_level_init(struct netif *netif) {
uint8_t macaddress[6] = {ETH_MAC_ADDR0, ETH_MAC_ADDR1, ETH_MAC_ADDR2,
ETH_MAC_ADDR3, ETH_MAC_ADDR4, ETH_MAC_ADDR5};
uint8_t macaddress[6]= {ETH_MAC_ADDR0, ETH_MAC_ADDR1, ETH_MAC_ADDR2, ETH_MAC_ADDR3, ETH_MAC_ADDR4, ETH_MAC_ADDR5};
EthHandle.Instance = ETH;
EthHandle.Init.MACAddr = macaddress;
@ -208,12 +211,12 @@ static void low_level_init(struct netif *netif) {
netif->hwaddr_len = ETH_HWADDR_LEN;
/* set MAC hardware address */
netif->hwaddr[0] = ETH_MAC_ADDR0;
netif->hwaddr[1] = ETH_MAC_ADDR1;
netif->hwaddr[2] = ETH_MAC_ADDR2;
netif->hwaddr[3] = ETH_MAC_ADDR3;
netif->hwaddr[4] = ETH_MAC_ADDR4;
netif->hwaddr[5] = ETH_MAC_ADDR5;
netif->hwaddr[0] = ETH_MAC_ADDR0;
netif->hwaddr[1] = ETH_MAC_ADDR1;
netif->hwaddr[2] = ETH_MAC_ADDR2;
netif->hwaddr[3] = ETH_MAC_ADDR3;
netif->hwaddr[4] = ETH_MAC_ADDR4;
netif->hwaddr[5] = ETH_MAC_ADDR5;
/* maximum transfer unit */
netif->mtu = ETH_MAX_PAYLOAD;
@ -226,7 +229,7 @@ static void low_level_init(struct netif *netif) {
LWIP_MEMPOOL_INIT(RX_POOL);
/* Set Tx packet config common parameters */
memset(&TxConfig, 0, sizeof(ETH_TxPacketConfig));
memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig));
TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
@ -262,19 +265,23 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p) {
err_t errval = ERR_OK;
ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT] = {0};
memset(Txbuffer, 0, ETH_TX_DESC_CNT * sizeof(ETH_BufferTypeDef));
memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef));
for (q = p; q != NULL; q = q->next) {
if (i >= ETH_TX_DESC_CNT) return ERR_IF;
for(q = p; q != NULL; q = q->next)
{
if(i >= ETH_TX_DESC_CNT)
return ERR_IF;
Txbuffer[i].buffer = q->payload;
Txbuffer[i].len = q->len;
if (i > 0) {
Txbuffer[i - 1].next = &Txbuffer[i];
if(i>0)
{
Txbuffer[i-1].next = &Txbuffer[i];
}
if (q->next == NULL) {
if(q->next == NULL)
{
Txbuffer[i].next = NULL;
}
@ -287,7 +294,8 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p) {
HAL_StatusTypeDef ret = HAL_ETH_Transmit(&EthHandle, &TxConfig, ETH_DMA_TRANSMIT_TIMEOUT);
if (ret != HAL_OK) {
printf("low_level_output: Could not transmit ethernet packet, code %d!\n\r", ret);
printf("low_level_output: Could not transmit ethernet packet, code %d!\n\r",
ret);
}
return errval;
}
@ -303,7 +311,8 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p) {
static struct pbuf *low_level_input(struct netif *netif) {
struct pbuf *p = NULL;
if (RxAllocStatus == RX_ALLOC_OK) {
if(RxAllocStatus == RX_ALLOC_OK)
{
HAL_ETH_ReadData(&EthHandle, (void **)&p);
}
@ -322,15 +331,19 @@ static struct pbuf *low_level_input(struct netif *netif) {
void ethernetif_input(struct netif *netif) {
struct pbuf *p = NULL;
do {
p = low_level_input(netif);
if (p != NULL) {
if (netif->input(p, netif) != ERR_OK) {
do
{
p = low_level_input( netif );
if (p != NULL)
{
if (netif->input( p, netif) != ERR_OK )
{
pbuf_free(p);
}
}
} while (p != NULL);
} while(p!=NULL);
}
/**
@ -375,11 +388,12 @@ err_t ethernetif_init(struct netif *netif) {
* @retval None
*/
void pbuf_free_custom(struct pbuf *p) {
struct pbuf_custom *custom_pbuf = (struct pbuf_custom *)p;
struct pbuf_custom* custom_pbuf = (struct pbuf_custom*)p;
LWIP_MEMPOOL_FREE(RX_POOL, custom_pbuf);
/* If the Rx Buffer Pool was exhausted, signal the ethernetif_input task to
* call HAL_ETH_GetRxDataBuffer to rebuild the Rx descriptors. */
if (RxAllocStatus == RX_ALLOC_ERROR) {
if (RxAllocStatus == RX_ALLOC_ERROR)
{
RxAllocStatus = RX_ALLOC_OK;
}
}
@ -491,8 +505,10 @@ int32_t ETH_PHY_IO_DeInit(void) { return 0; }
* @param pRegVal: pointer to hold the register value
* @retval 0 if OK -1 if Error
*/
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal) {
if (HAL_ETH_ReadPHYRegister(&EthHandle, DevAddr, RegAddr, pRegVal) != HAL_OK) {
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr,
uint32_t *pRegVal) {
if (HAL_ETH_ReadPHYRegister(&EthHandle, DevAddr, RegAddr, pRegVal) !=
HAL_OK) {
return -1;
}
@ -506,8 +522,10 @@ int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal
* @param RegVal: Value to be written
* @retval 0 if OK -1 if Error
*/
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal) {
if (HAL_ETH_WritePHYRegister(&EthHandle, DevAddr, RegAddr, RegVal) != HAL_OK) {
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr,
uint32_t RegVal) {
if (HAL_ETH_WritePHYRegister(&EthHandle, DevAddr, RegAddr, RegVal) !=
HAL_OK) {
return -1;
}
@ -531,37 +549,42 @@ void ethernet_link_check_state(struct netif *netif) {
PHYLinkState = LAN8742_GetLinkState(&LAN8742);
if (netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN)) {
if(netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN))
{
HAL_ETH_Stop_IT(&EthHandle);
netif_set_down(netif);
netif_set_link_down(netif);
} else if (!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN)) {
switch (PHYLinkState) {
case LAN8742_STATUS_100MBITS_FULLDUPLEX:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_100M;
linkchanged = 1;
break;
case LAN8742_STATUS_100MBITS_HALFDUPLEX:
duplex = ETH_HALFDUPLEX_MODE;
speed = ETH_SPEED_100M;
linkchanged = 1;
break;
case LAN8742_STATUS_10MBITS_FULLDUPLEX:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_10M;
linkchanged = 1;
break;
case LAN8742_STATUS_10MBITS_HALFDUPLEX:
duplex = ETH_HALFDUPLEX_MODE;
speed = ETH_SPEED_10M;
linkchanged = 1;
break;
default:
break;
}
else if(!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN))
{
switch (PHYLinkState)
{
case LAN8742_STATUS_100MBITS_FULLDUPLEX:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_100M;
linkchanged = 1;
break;
case LAN8742_STATUS_100MBITS_HALFDUPLEX:
duplex = ETH_HALFDUPLEX_MODE;
speed = ETH_SPEED_100M;
linkchanged = 1;
break;
case LAN8742_STATUS_10MBITS_FULLDUPLEX:
duplex = ETH_FULLDUPLEX_MODE;
speed = ETH_SPEED_10M;
linkchanged = 1;
break;
case LAN8742_STATUS_10MBITS_HALFDUPLEX:
duplex = ETH_HALFDUPLEX_MODE;
speed = ETH_SPEED_10M;
linkchanged = 1;
break;
default:
break;
}
if (linkchanged) {
if(linkchanged)
{
/* Get MAC Config MAC */
HAL_ETH_GetMACConfig(&EthHandle, &MACConf);
MACConf.DuplexMode = duplex;
@ -574,23 +597,28 @@ void ethernet_link_check_state(struct netif *netif) {
}
}
void HAL_ETH_RxAllocateCallback(uint8_t **buff) {
void HAL_ETH_RxAllocateCallback(uint8_t **buff)
{
struct pbuf_custom *p = LWIP_MEMPOOL_ALLOC(RX_POOL);
if (p) {
if (p)
{
/* Get the buff from the struct pbuf address. */
*buff = (uint8_t *)p + offsetof(RxBuff_t, buff);
p->custom_free_function = pbuf_free_custom;
/* Initialize the struct pbuf.
* This must be performed whenever a buffer's allocated because it may be
* changed by lwIP or the app, e.g., pbuf_free decrements ref. */
* This must be performed whenever a buffer's allocated because it may be
* changed by lwIP or the app, e.g., pbuf_free decrements ref. */
pbuf_alloced_custom(PBUF_RAW, 0, PBUF_REF, p, *buff, ETH_RX_BUFFER_SIZE);
} else {
}
else
{
RxAllocStatus = RX_ALLOC_ERROR;
*buff = NULL;
}
}
void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length) {
void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length)
{
struct pbuf **ppStart = (struct pbuf **)pStart;
struct pbuf **ppEnd = (struct pbuf **)pEnd;
struct pbuf *p = NULL;
@ -602,18 +630,22 @@ void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t
p->len = Length;
/* Chain the buffer. */
if (!*ppStart) {
if (!*ppStart)
{
/* The first buffer of the packet. */
*ppStart = p;
} else {
}
else
{
/* Chain the buffer to the end of the packet. */
(*ppEnd)->next = p;
}
*ppEnd = p;
*ppEnd = p;
/* Update the total length of all the buffers of the chain. Each pbuf in the chain should have its
* tot_len set to its own length, plus the length of all the following pbufs in the chain. */
for (p = *ppStart; p != NULL; p = p->next) {
/* Update the total length of all the buffers of the chain. Each pbuf in the chain should have its tot_len
* set to its own length, plus the length of all the following pbufs in the chain. */
for (p = *ppStart; p != NULL; p = p->next)
{
p->tot_len += Length;
}
@ -621,7 +653,10 @@ void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t
SCB_InvalidateDCache_by_Addr((uint32_t *)buff, Length);
}
void HAL_ETH_TxFreeCallback(uint32_t *buff) { pbuf_free((struct pbuf *)buff); }
void HAL_ETH_TxFreeCallback(uint32_t * buff)
{
pbuf_free((struct pbuf *)buff);
}
ETH_HandleTypeDef *getEthernetHandle() { return &EthHandle; }

View File

@ -4,11 +4,14 @@
bool ethernetCableConnected = false;
void networking::setEthCableConnected(bool status) { ethernetCableConnected = status; }
void networking::setEthCableConnected(bool status) {
ethernetCableConnected = status;
}
bool networking::getEthCableConnected() { return ethernetCableConnected; }
void networking::setLwipAddresses(ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw) {
void networking::setLwipAddresses(ip_addr_t *ipaddr, ip_addr_t *netmask,
ip_addr_t *gw) {
IP4_ADDR(ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
IP4_ADDR(netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);

View File

@ -9,6 +9,6 @@ void setEthCableConnected(bool status);
bool getEthCableConnected();
void setLwipAddresses(ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw);
} // namespace networking
} // namespace networking
#endif /* BSP_STM32H7_RTEMS_NETWORKING_NETWORKING_H_ */