linux working
This commit is contained in:
@ -0,0 +1,3 @@
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/testdevices/*.cpp)
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/testinterfaces/*.cpp)
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/testtasks/*.cpp)
|
41
test/testtasks/MutextestTask.cpp
Normal file
41
test/testtasks/MutextestTask.cpp
Normal 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
|
||||
}
|
||||
|
32
test/testtasks/MutextestTask.h
Normal file
32
test/testtasks/MutextestTask.h
Normal 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_ */
|
67
test/testtasks/PusTcInjector.cpp
Normal file
67
test/testtasks/PusTcInjector.cpp
Normal 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;
|
||||
}
|
72
test/testtasks/PusTcInjector.h
Normal file
72
test/testtasks/PusTcInjector.h
Normal 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_ */
|
74
test/testtasks/TestTask.cpp
Normal file
74
test/testtasks/TestTask.cpp
Normal 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
57
test/testtasks/TestTask.h
Normal 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_ */
|
Reference in New Issue
Block a user