linux working

This commit is contained in:
2020-09-16 16:22:36 +02:00
parent 6f6eceef6f
commit ffcb6e0213
47 changed files with 1926 additions and 6 deletions

View File

@ -0,0 +1,3 @@
CXXSRC += $(wildcard $(CURRENTPATH)/testdevices/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/testinterfaces/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/testtasks/*.cpp)

View File

@ -0,0 +1,41 @@
/*
* MutextestTask.cpp
*
* Created on: 19.07.2018
* Author: mohr
*/
#include <test/testtasks/MutextestTask.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
MutexIF * MutextestTask::mutex = nullptr;
MutextestTask::MutextestTask(const char *name, object_id_t setObjectId) :
SystemObject(setObjectId), name(name), locked(false) {
if (mutex == NULL) {
mutex = MutexFactory::instance()->createMutex();
}
}
ReturnValue_t MutextestTask::performOperation(uint8_t operationCode) {
if (!locked){
sif::info << name << ": locking..." << std::endl;
ReturnValue_t result = mutex->lockMutex(MutexIF::BLOCKING);
sif::info << name << ": locked with " << (int) result << std::endl;
if (result == HasReturnvaluesIF::RETURN_OK){
locked = true;
}
} else {
sif::info << name << ": releasing" << std::endl;
mutex->unlockMutex();
locked = false;
}
return HasReturnvaluesIF::RETURN_OK;
}
MutextestTask::~MutextestTask() {
// TODO Auto-generated destructor stub
}

View File

@ -0,0 +1,32 @@
/*
* MutextestTask.h
*
* Created on: 19.07.2018
* Author: mohr
*/
#ifndef MISSION_MUTEXTESTTASK_H_
#define MISSION_MUTEXTESTTASK_H_
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/ipc/MutexFactory.h>
/**
* Start two of them with a little time difference and different periods to see mutex in action
*/
class MutextestTask: public SystemObject, public ExecutableObjectIF {
public:
virtual ReturnValue_t performOperation(uint8_t operationCode = 0);
MutextestTask(const char *name, object_id_t setObjectId);
virtual ~MutextestTask();
private:
static MutexIF *mutex;
const char * name;
bool locked;
};
#endif /* MISSION_MUTEXTESTTASK_H_ */

View File

@ -0,0 +1,67 @@
#include <test/testtasks/PusTcInjector.h>
#include <fsfw/objectmanager/ObjectManagerIF.h>
#include <fsfw/tmtcservices/AcceptsTelecommandsIF.h>
#include <fsfw/tmtcservices/TmTcMessage.h>
#include <fsfw/tmtcpacket/pus/TcPacketBase.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/globalfunctions/arrayprinter.h>
#include <fsfw/tmtcpacket/pus/TcPacketStored.h>
PusTcInjector::PusTcInjector(object_id_t objectId, object_id_t destination,
object_id_t tcStore, uint16_t defaultApid): SystemObject(objectId),
defaultApid(defaultApid), destination(destination), tcStoreId(tcStore) {
}
PusTcInjector::~PusTcInjector() {
}
//ReturnValue_t PusTcInjector::injectPusTelecommand(uint8_t service,
// uint8_t subservice,const uint8_t* appData, size_t appDataLen) {
// return injectPusTelecommand(service, subservice, defaultApid, appData,
// appDataLen);
//}
// TODO: ACK flags
//ReturnValue_t PusTcInjector::injectPusTelecommand(uint8_t service,
// uint8_t subservice,uint16_t apid, const uint8_t* appData,
// size_t appDataLen) {
// // Prepare TC packet. Store into TC store immediately.
// TcPacketStored tcPacket(service, subservice, apid, sequenceCount++);
//
// const uint8_t* packetPtr = nullptr;
// size_t packetSize = 0;
// tcPacket.getData(&packetPtr, &packetSize);
// //arrayprinter::print(packetPtr, packetSize, OutputType::BIN);
//
// // Send TC packet.
// TmTcMessage tcMessage(tcPacket.getStoreAddress());
// ReturnValue_t result = injectionQueue->sendToDefault(&tcMessage);
// if(result != HasReturnvaluesIF::RETURN_OK) {
// sif::warning << "PusTcInjector: Sending TMTC message failed!" << std::endl;
// }
// return result;
//}
ReturnValue_t PusTcInjector::initialize() {
// Prepare message queue which is used to send telecommands.
injectionQueue = QueueFactory::instance()->
createMessageQueue(INJECTION_QUEUE_DEPTH);
AcceptsTelecommandsIF* targetQueue = objectManager->
get<AcceptsTelecommandsIF>(destination);
if(targetQueue == nullptr) {
sif::error << "PusTcInjector: CCSDS distributor not initialized yet!" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
else {
injectionQueue->setDefaultDestination(targetQueue->getRequestQueue());
}
// Prepare store used to store TC messages
tcStore = objectManager->get<StorageManagerIF>(tcStoreId);
if(tcStore == nullptr) {
sif::error << "PusTcInjector: TC Store not initialized!" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -0,0 +1,72 @@
#ifndef TEST_TESTTASKS_PUSTCINJECTOR_H_
#define TEST_TESTTASKS_PUSTCINJECTOR_H_
#include <fsfw/ipc/MessageQueueIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/storagemanager/StorageManagerIF.h>
#include <array>
class PusTcInjector: public SystemObject {
public:
static constexpr uint8_t INJECTION_QUEUE_DEPTH = 10;
const uint16_t defaultApid;
/**
* Initialize a software telecommand injector by supplying object IDs to
* various helper objects which must exist before calling initialiez()
* @param objectId ID of PUS telecommand injector
* @param destination ID of destination, which has to implement
* AcceptsTelecommandIF.
* @param tcStore ID of telecommand store, which has to implement
* StorageManagerIF.
* @param defaultApid Default APID which will be used if an injection
* without an APID is requested.
*/
PusTcInjector(object_id_t objectId, object_id_t destination,
object_id_t tcStore, uint16_t defaultApid);
/**
* This has to be called before using the PusTcInjector.
* Call Not necessary when using a factory and the object manager.
* @return -@c RETURN_OK for successfull init
* -@c ObjectManagerIF::CHILD_INIT_FAILED otherwise
*/
ReturnValue_t initialize() override;
virtual~ PusTcInjector();
/**
* Can be used to inject a telecommand by supplying service, subservice
* and optional application data and its length.
* Default APID will be used.
* @param service PUS service type
* @param subservice PUS subservice type
* @param appData Pointer to application data
* @param appDataLen Length of application data
* @return
*/
//ReturnValue_t injectPusTelecommand(uint8_t service, uint8_t subservice,
// const uint8_t* appData = nullptr, size_t appDataLen = 0);
/**
* Provides the same functionality while also setting a user defined APID.
* @param service PUS service type
* @param subservice PUS subservice type
* @param apid Custom APID to,
* @param appData Pointer to application data
* @param appDataLen Length of application data
* @return
*/
//ReturnValue_t injectPusTelecommand(uint8_t service, uint8_t subservice,
// uint16_t apid, const uint8_t* appData = nullptr,
// size_t appDataLen = 0);
private:
MessageQueueIF* injectionQueue = nullptr;
StorageManagerIF *tcStore = nullptr;
/* Cached for initialize function */
object_id_t destination = 0;
object_id_t tcStoreId = 0;
uint16_t sequenceCount = 0;
};
#endif /* TEST_TESTTASKS_PUSTCINJECTOR_H_ */

View File

@ -0,0 +1,74 @@
#include "logicalAddresses.h"
#include "apid.h"
#include <test/testtasks/TestTask.h>
#include <test/testtasks/PusTcInjector.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <fsfw/timemanager/Stopwatch.h>
#include <fsfw/globalfunctions/arrayprinter.h>
#include <etl/vector.h>
#include <array>
#include <cstring>
bool TestTask::oneShotAction = true;
MutexIF* TestTask::testLock = nullptr;
TestTask::TestTask(object_id_t objectId_):
SystemObject(objectId_), testMode(testModes::A) {
if(testLock == nullptr) {
testLock = MutexFactory::instance()->createMutex();
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
}
TestTask::~TestTask() {
}
ReturnValue_t TestTask::performOperation(uint8_t operationCode) {
ReturnValue_t result = RETURN_OK;
testLock ->lockMutex(MutexIF::TimeoutType::WAITING, 20);
if(oneShotAction) {
// Add code here which should only be run once
performOneShotAction();
oneShotAction = false;
}
testLock->unlockMutex();
// Add code here which should only be run once per performOperation
performPeriodicAction();
// Add code here which should only be run on alternating cycles.
if(testMode == testModes::A) {
performActionA();
testMode = testModes::B;
}
else if(testMode == testModes::B) {
performActionB();
testMode = testModes::A;
}
return result;
}
ReturnValue_t TestTask::performOneShotAction() {
// Everything here will only be performed once.
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t TestTask::performPeriodicAction() {
ReturnValue_t result = RETURN_OK;
return result;
}
ReturnValue_t TestTask::performActionA() {
ReturnValue_t result = RETURN_OK;
// Add periodically executed code here
return result;
}
ReturnValue_t TestTask::performActionB() {
ReturnValue_t result = RETURN_OK;
// Add periodically executed code here
return result;
}

57
test/testtasks/TestTask.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef TEST_TESTTASK_H_
#define TEST_TESTTASK_H_
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/parameters/HasParametersIF.h>
#include <fsfw/serialize/SerialBufferAdapter.h>
#include <fsfw/serialize/SerializeElement.h>
#include <fsfw/serialize/SerialLinkedListAdapter.h>
#include <fsfw/storagemanager/StorageManagerIF.h>
#include <cstddef>
/**
* @brief Test class for general C++ testing.
* @details
* Should not be used for board specific
* tests. Instead, a derived board test class should be used.
*/
class TestTask : public SystemObject,
public ExecutableObjectIF,
public HasReturnvaluesIF {
public:
TestTask(object_id_t objectId);
virtual ~TestTask();
virtual ReturnValue_t performOperation(uint8_t operationCode = 0);
protected:
virtual ReturnValue_t performOneShotAction();
virtual ReturnValue_t performPeriodicAction();
virtual ReturnValue_t performActionA();
virtual ReturnValue_t performActionB();
enum testModes: uint8_t {
A,
B
};
testModes testMode;
bool testFlag = false;
uint8_t counter { 1 };
uint8_t counterTrigger { 3 };
void performPusInjectorTest();
void examplePacketTest();
private:
// Actually, to be really thread-safe, a mutex should be used as well
// Let's keep it simple for now.
static bool oneShotAction;
static MutexIF* testLock;
StorageManagerIF* IPCStore;
};
#endif /* TESTTASK_H_ */