Merge branch 'development' into mueller/LocalPoolRefactoring
This commit is contained in:
commit
24ba716ab2
@ -1,10 +1,11 @@
|
|||||||
#ifndef FSFW_DEFAULTCFG_VERSION_H_
|
#ifndef FSFW_DEFAULTCFG_VERSION_H_
|
||||||
#define FSFW_DEFAULTCFG_VERSION_H_
|
#define FSFW_DEFAULTCFG_VERSION_H_
|
||||||
|
|
||||||
const char* const FSFW_VERSION_NAME = "fsfw";
|
const char* const FSFW_VERSION_NAME = "ASTP";
|
||||||
|
|
||||||
#define FSFW_VERSION 0
|
#define FSFW_VERSION 0
|
||||||
#define FSFW_SUBVERSION 0
|
#define FSFW_SUBVERSION 0
|
||||||
|
#define FSFW_REVISION 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
157
README.md
157
README.md
@ -1,4 +1,159 @@
|
|||||||
Flight Software Framework (FSFW)
|
Flight Software Framework (FSFW)
|
||||||
======
|
======
|
||||||
|
|
||||||
I want to be written!
|
The Flight Software Framework is a C++ Object Oriented Framework for unmanned,
|
||||||
|
automated systems like Satellites.
|
||||||
|
|
||||||
|
The initial version of the Flight Software Framework was developed during
|
||||||
|
the Flying Laptop Project by the University of Stuttgart in cooperation
|
||||||
|
with Airbus Defence and Space GmbH.
|
||||||
|
|
||||||
|
## Intended Use
|
||||||
|
|
||||||
|
The framework is designed for systems, which communicate with external devices, perform control loops, receive telecommands and send telemetry, and need to maintain a high level of availability.
|
||||||
|
Therefore, a mode and health system provides control over the states of the software and the controlled devices.
|
||||||
|
In addition, a simple mechanism of event based fault detection, isolation and recovery is implemented as well.
|
||||||
|
|
||||||
|
The recommended hardware is a microprocessor with more than 2 MB of RAM and 1 MB of non-volatile Memory.
|
||||||
|
For reference, current Applications use a Cobham Gaisler UT699 (LEON3FT), a ISISPACE IOBC or a Zynq-7020 SoC.
|
||||||
|
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
The general structure is driven by the usage of interfaces provided by objects. The FSFW uses C++11 as baseline. The intention behind this is that this C++ Standard should be widely available, even with older compilers.
|
||||||
|
The FSFW uses dynamic allocation during the initialization but provides static containers during runtime.
|
||||||
|
This simplifies the instantiation of objects and allows the usage of some standard containers.
|
||||||
|
Dynamic Allocation after initialization is discouraged and different solutions are provided in the FSFW to achieve that.
|
||||||
|
The fsfw uses Run-time type information.
|
||||||
|
Exceptions are not allowed.
|
||||||
|
|
||||||
|
### Failure Handling
|
||||||
|
|
||||||
|
Functions should return a defined ReturnValue_t to signal to the caller that something is gone wrong.
|
||||||
|
Returnvalues must be unique. For this the function HasReturnvaluesIF::makeReturnCode or the Macro MAKE_RETURN can be used.
|
||||||
|
The CLASS_ID is a unique id for that type of object. See returnvalues/FwClassIds.
|
||||||
|
|
||||||
|
### OSAL
|
||||||
|
The FSFW provides operation system abstraction layers for Linux, FreeRTOS and RTEMS. A independent OSAL called "host" is currently not finished. This aims to be running on windows as well.
|
||||||
|
The OSAL provides periodic tasks, message queues, clocks and Semaphores as well as Mutexes.
|
||||||
|
|
||||||
|
### Core Components
|
||||||
|
|
||||||
|
Clock:
|
||||||
|
* This is a class of static functions that can be used at anytime
|
||||||
|
* Leap Seconds must be set if any time conversions from UTC to other times is used
|
||||||
|
|
||||||
|
ObjectManager (must be created):
|
||||||
|
|
||||||
|
* The component which handles all references. All SystemObjects register at this component.
|
||||||
|
* Any SystemObject needs to have a unique ObjectId. Those can be managed like objects::framework_objects.
|
||||||
|
* A reference to an object can be get by calling the following function. T must be the specific Interface you want to call.
|
||||||
|
A nullptr check of the returning Pointer must be done. This function is based on Run-time type information.
|
||||||
|
|
||||||
|
``` c++
|
||||||
|
template <typename T> T* ObjectManagerIF::get( object_id_t id )
|
||||||
|
|
||||||
|
```
|
||||||
|
* A typical way to create all objects on startup is a handing a static produce function to the ObjectManager on creation.
|
||||||
|
By calling objectManager->initialize() the produce function will be called and all SystemObjects will be initialized afterwards.
|
||||||
|
|
||||||
|
Event Manager:
|
||||||
|
|
||||||
|
* Component which allows routing of events
|
||||||
|
* Other objects can subscribe to specific events, ranges of events or all events of an object.
|
||||||
|
* Subscriptions can be done during runtime but should be done during initialization
|
||||||
|
* Amounts of allowed subscriptions must be configured by setting this parameters:
|
||||||
|
|
||||||
|
``` c++
|
||||||
|
namespace fsfwconfig {
|
||||||
|
//! Configure the allocated pool sizes for the event manager.
|
||||||
|
static constexpr size_t FSFW_EVENTMGMR_MATCHTREE_NODES = 240;
|
||||||
|
static constexpr size_t FSFW_EVENTMGMT_EVENTIDMATCHERS = 120;
|
||||||
|
static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Health Table:
|
||||||
|
|
||||||
|
* A component which holds every health state
|
||||||
|
* Provides a thread safe way to access all health states without the need of message exchanges
|
||||||
|
|
||||||
|
Stores
|
||||||
|
|
||||||
|
* The message based communication can only exchange a few bytes of information inside the message itself. Therefore, additional information can be exchanged with Stores. With this, only the store address must be exchanged in the message.
|
||||||
|
* Internally, the FSFW uses an IPC Store to exchange data between processes. For incoming TCs a TC Store is used. For outgoing TM a TM store is used.
|
||||||
|
* All of them should use the Thread Safe Class storagemanager/PoolManager
|
||||||
|
|
||||||
|
Tasks
|
||||||
|
|
||||||
|
There are two different types of tasks:
|
||||||
|
* The PeriodicTask just executes objects that are of type ExecutableObjectIF in the order of the insertion to the Tasks.
|
||||||
|
* FixedTimeslotTask executes a list of calls in the order of the given list. This is intended for DeviceHandlers, where polling should be in a defined order. An example can be found in defaultcfg/fsfwconfig/pollingSequence
|
||||||
|
|
||||||
|
|
||||||
|
### Static Ids in the framework
|
||||||
|
|
||||||
|
Some parts of the framework use a static routing address for communication.
|
||||||
|
An example setup of ids can be found in the example config in "defaultcft/fsfwconfig/objects/Factory::setStaticFrameworkObjectIds()".
|
||||||
|
|
||||||
|
### Events
|
||||||
|
|
||||||
|
Events are tied to objects. EventIds can be generated by calling the Macro MAKE_EVENT. This works analog to the returnvalues.
|
||||||
|
Every object that needs own EventIds has to get a unique SUBSYSTEM_ID.
|
||||||
|
Every SystemObject can call triggerEvent from the parent class.
|
||||||
|
Therefore, event messages contain the specific EventId and the objectId of the object that has triggered.
|
||||||
|
|
||||||
|
### Internal Communication
|
||||||
|
|
||||||
|
Components communicate mostly over Message through Queues.
|
||||||
|
Those queues are created by calling the singleton QueueFactory::instance()->create().
|
||||||
|
|
||||||
|
### External Communication
|
||||||
|
|
||||||
|
The external communication with the mission control system is mostly up to the user implementation.
|
||||||
|
The FSFW provides PUS Services which can be used to but don't need to be used.
|
||||||
|
The services can be seen as a conversion from a TC to a message based communication and back.
|
||||||
|
|
||||||
|
#### CCSDS Frames, CCSDS Space Packets and PUS
|
||||||
|
|
||||||
|
If the communication is based on CCSDS Frames and Space Packets, several classes can be used to distributed the packets to the corresponding services. Those can be found in tcdistribution.
|
||||||
|
If Space Packets are used, a timestamper must be created.
|
||||||
|
An example can be found in the timemanager folder, this uses CCSDSTime::CDS_short.
|
||||||
|
|
||||||
|
#### DeviceHandling
|
||||||
|
|
||||||
|
DeviceHandlers are a core component of the FSFW.
|
||||||
|
The idea is, to have a software counterpart of every physical device to provide a simple mode, health and commanding interface.
|
||||||
|
By separating the underlying Communication Interface with DeviceCommunicationIF, a DH can be tested on different hardware.
|
||||||
|
The DH has mechanisms to monitor the communication with the physical device which allow for FDIR reaction.
|
||||||
|
A standard FDIR component for the DH will be created automatically but can be overwritten by the user.
|
||||||
|
|
||||||
|
#### Modes, Health
|
||||||
|
|
||||||
|
The two interfaces HasModesIF and HasHealthIF provide access for commanding and monitoring of components.
|
||||||
|
On-board Mode Management is implement in hierarchy system.
|
||||||
|
DeviceHandlers and Controllers are the lowest part of the hierarchy.
|
||||||
|
The next layer are Assemblies. Those assemblies act as a component which handle redundancies of handlers.
|
||||||
|
Assemblies share a common core with the next level which are the Subsystems.
|
||||||
|
|
||||||
|
Those Assemblies are intended to act as auto-generated components from a database which describes the subsystem modes.
|
||||||
|
The definitions contain transition and target tables which contain the DH, Assembly and Controller Modes to be commanded.
|
||||||
|
Transition tables contain as many steps as needed to reach the mode from any other mode, e.g. a switch into any higher AOCS mode might first turn on the sensors, than the actuators and the controller as last component.
|
||||||
|
The target table is used to describe the state that is checked continuously by the subsystem.
|
||||||
|
All of this allows System Modes to be generated as Subsystem object as well from the same database.
|
||||||
|
This System contains list of subsystem modes in the transition and target tables.
|
||||||
|
Therefore, it allows a modular system to create system modes and easy commanding of those, because only the highest components must be commanded.
|
||||||
|
|
||||||
|
The health state represents if the component is able to perform its tasks.
|
||||||
|
This can be used to signal the system to avoid using this component instead of a redundant one.
|
||||||
|
The on-board FDIR uses the health state for isolation and recovery.
|
||||||
|
|
||||||
|
## Example config
|
||||||
|
|
||||||
|
A example config can be found in defaultcfg/fsfwconfig.
|
||||||
|
|
||||||
|
## Unit Tests
|
||||||
|
|
||||||
|
Unit Tests are provided in the unittest folder. Those use the catch2 framework but do not include catch2 itself.
|
||||||
|
See README.md in the unittest Folder.
|
@ -1,5 +1,6 @@
|
|||||||
#include "ActionHelper.h"
|
#include "ActionHelper.h"
|
||||||
#include "HasActionsIF.h"
|
#include "HasActionsIF.h"
|
||||||
|
|
||||||
#include "../ipc/MessageQueueSenderIF.h"
|
#include "../ipc/MessageQueueSenderIF.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef ACTIONMESSAGE_H_
|
#ifndef FSFW_ACTION_ACTIONMESSAGE_H_
|
||||||
#define ACTIONMESSAGE_H_
|
#define FSFW_ACTION_ACTIONMESSAGE_H_
|
||||||
|
|
||||||
#include "../ipc/CommandMessage.h"
|
#include "../ipc/CommandMessage.h"
|
||||||
#include "../objectmanager/ObjectManagerIF.h"
|
#include "../objectmanager/ObjectManagerIF.h"
|
||||||
@ -18,15 +18,19 @@ public:
|
|||||||
static const Command_t COMPLETION_SUCCESS = MAKE_COMMAND_ID(5);
|
static const Command_t COMPLETION_SUCCESS = MAKE_COMMAND_ID(5);
|
||||||
static const Command_t COMPLETION_FAILED = MAKE_COMMAND_ID(6);
|
static const Command_t COMPLETION_FAILED = MAKE_COMMAND_ID(6);
|
||||||
virtual ~ActionMessage();
|
virtual ~ActionMessage();
|
||||||
static void setCommand(CommandMessage* message, ActionId_t fid, store_address_t parameters);
|
static void setCommand(CommandMessage* message, ActionId_t fid,
|
||||||
|
store_address_t parameters);
|
||||||
static ActionId_t getActionId(const CommandMessage* message );
|
static ActionId_t getActionId(const CommandMessage* message );
|
||||||
static store_address_t getStoreId(const CommandMessage* message );
|
static store_address_t getStoreId(const CommandMessage* message );
|
||||||
static void setStepReply(CommandMessage* message, ActionId_t fid, uint8_t step, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
static void setStepReply(CommandMessage* message, ActionId_t fid,
|
||||||
|
uint8_t step, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||||
static uint8_t getStep(const CommandMessage* message );
|
static uint8_t getStep(const CommandMessage* message );
|
||||||
static ReturnValue_t getReturnCode(const CommandMessage* message );
|
static ReturnValue_t getReturnCode(const CommandMessage* message );
|
||||||
static void setDataReply(CommandMessage* message, ActionId_t actionId, store_address_t data);
|
static void setDataReply(CommandMessage* message, ActionId_t actionId,
|
||||||
static void setCompletionReply(CommandMessage* message, ActionId_t fid, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
store_address_t data);
|
||||||
|
static void setCompletionReply(CommandMessage* message, ActionId_t fid,
|
||||||
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||||
static void clear(CommandMessage* message);
|
static void clear(CommandMessage* message);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ACTIONMESSAGE_H_ */
|
#endif /* FSFW_ACTION_ACTIONMESSAGE_H_ */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef COMMANDSACTIONSIF_H_
|
#ifndef FSFW_ACTION_COMMANDSACTIONSIF_H_
|
||||||
#define COMMANDSACTIONSIF_H_
|
#define FSFW_ACTION_COMMANDSACTIONSIF_H_
|
||||||
|
|
||||||
#include "CommandActionHelper.h"
|
#include "CommandActionHelper.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
@ -24,11 +24,14 @@ public:
|
|||||||
virtual MessageQueueIF* getCommandQueuePtr() = 0;
|
virtual MessageQueueIF* getCommandQueuePtr() = 0;
|
||||||
protected:
|
protected:
|
||||||
virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) = 0;
|
virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) = 0;
|
||||||
virtual void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) = 0;
|
virtual void stepFailedReceived(ActionId_t actionId, uint8_t step,
|
||||||
virtual void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) = 0;
|
ReturnValue_t returnCode) = 0;
|
||||||
|
virtual void dataReceived(ActionId_t actionId, const uint8_t* data,
|
||||||
|
uint32_t size) = 0;
|
||||||
virtual void completionSuccessfulReceived(ActionId_t actionId) = 0;
|
virtual void completionSuccessfulReceived(ActionId_t actionId) = 0;
|
||||||
virtual void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) = 0;
|
virtual void completionFailedReceived(ActionId_t actionId,
|
||||||
|
ReturnValue_t returnCode) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* COMMANDSACTIONSIF_H_ */
|
#endif /* FSFW_ACTION_COMMANDSACTIONSIF_H_ */
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <FSFWVersion.h>
|
#include <FSFWVersion.h>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
//! Used to determine whether C++ ostreams are used
|
//! Used to determine whether C++ ostreams are used
|
||||||
//! Those can lead to code bloat.
|
//! Those can lead to code bloat.
|
@ -1,8 +1,8 @@
|
|||||||
#ifndef CONFIG_DEVICES_LOGICALADDRESSES_H_
|
#ifndef CONFIG_DEVICES_LOGICALADDRESSES_H_
|
||||||
#define CONFIG_DEVICES_LOGICALADDRESSES_H_
|
#define CONFIG_DEVICES_LOGICALADDRESSES_H_
|
||||||
|
|
||||||
#include <config/objects/systemObjectList.h>
|
|
||||||
#include <fsfw/devicehandlers/CookieIF.h>
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
|
#include "../objects/systemObjectList.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
/**
|
/**
|
@ -1,4 +1,5 @@
|
|||||||
#include <config/ipc/MissionMessageTypes.h>
|
#include "missionMessageTypes.h"
|
||||||
|
|
||||||
#include <fsfw/ipc/CommandMessageIF.h>
|
#include <fsfw/ipc/CommandMessageIF.h>
|
||||||
|
|
||||||
void messagetypes::clearMissionMessage(CommandMessage* message) {
|
void messagetypes::clearMissionMessage(CommandMessage* message) {
|
@ -11,6 +11,7 @@
|
|||||||
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
||||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||||
#include <fsfw/tmtcservices/PusServiceBase.h>
|
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||||
|
#include <internalError/InternalErrorReporter.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@ -31,15 +32,15 @@ void Factory::produce(void) {
|
|||||||
setStaticFrameworkObjectIds();
|
setStaticFrameworkObjectIds();
|
||||||
new EventManager(objects::EVENT_MANAGER);
|
new EventManager(objects::EVENT_MANAGER);
|
||||||
new HealthTable(objects::HEALTH_TABLE);
|
new HealthTable(objects::HEALTH_TABLE);
|
||||||
//new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER);
|
new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Factory::setStaticFrameworkObjectIds() {
|
void Factory::setStaticFrameworkObjectIds() {
|
||||||
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
PusServiceBase::packetSource = objects::NO_OBJECT;
|
||||||
PusServiceBase::packetDestination = objects::TM_FUNNEL;
|
PusServiceBase::packetDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT;
|
||||||
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
||||||
|
|
||||||
@ -48,7 +49,6 @@ void Factory::setStaticFrameworkObjectIds() {
|
|||||||
|
|
||||||
DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
|
DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
|
||||||
|
|
||||||
TmPacketStored::timeStamperId = objects::PUS_TIME;
|
TmPacketStored::timeStamperId = objects::NO_OBJECT;
|
||||||
//TmFunnel::downlinkDestination = objects::NO_OBJECT;
|
|
||||||
}
|
}
|
||||||
|
|
@ -18,8 +18,6 @@ public:
|
|||||||
static const uint8_t TRANSITION_MODE_CHILD_ACTION_MASK = 0x20;
|
static const uint8_t TRANSITION_MODE_CHILD_ACTION_MASK = 0x20;
|
||||||
static const uint8_t TRANSITION_MODE_BASE_ACTION_MASK = 0x10;
|
static const uint8_t TRANSITION_MODE_BASE_ACTION_MASK = 0x10;
|
||||||
|
|
||||||
static constexpr Command_t NO_COMMAND = 0xffffffff;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the mode the <strong>device handler</strong> is in.
|
* @brief This is the mode the <strong>device handler</strong> is in.
|
||||||
*
|
*
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "fwSubsystemIdRanges.h"
|
#include "fwSubsystemIdRanges.h"
|
||||||
//could be move to more suitable location
|
//could be move to more suitable location
|
||||||
#include <subsystemIdRanges.h>
|
#include <events/subsystemIdRanges.h>
|
||||||
|
|
||||||
typedef uint16_t EventId_t;
|
typedef uint16_t EventId_t;
|
||||||
typedef uint8_t EventSeverity_t;
|
typedef uint8_t EventSeverity_t;
|
||||||
|
2
fsfw.mk
2
fsfw.mk
@ -70,5 +70,3 @@ CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcpacket/packetmatcher/*.cpp)
|
|||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcpacket/pus/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcpacket/pus/*.cpp)
|
||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcservices/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcservices/*.cpp)
|
||||||
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/pus/*.cpp)
|
CXXSRC += $(wildcard $(FRAMEWORK_PATH)/pus/*.cpp)
|
||||||
|
|
||||||
INCLUDES += $(CURRENTPATH)
|
|
||||||
|
@ -33,7 +33,7 @@ ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) {
|
|||||||
while(1) {
|
while(1) {
|
||||||
//! Sender Address is cached here.
|
//! Sender Address is cached here.
|
||||||
struct sockaddr_in senderAddress;
|
struct sockaddr_in senderAddress;
|
||||||
socklen_t senderSockLen = 0;
|
socklen_t senderSockLen = sizeof(senderAddress);
|
||||||
ssize_t bytesReceived = recvfrom(serverUdpSocket,
|
ssize_t bytesReceived = recvfrom(serverUdpSocket,
|
||||||
receptionBuffer.data(), frameSize, receptionFlags,
|
receptionBuffer.data(), frameSize, receptionFlags,
|
||||||
reinterpret_cast<sockaddr*>(&senderAddress), &senderSockLen);
|
reinterpret_cast<sockaddr*>(&senderAddress), &senderSockLen);
|
||||||
|
@ -65,9 +65,13 @@ TmTcUnixUdpBridge::~TmTcUnixUdpBridge() {
|
|||||||
ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
|
ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
|
MutexHelper lock(mutex, MutexIF::TimeoutType::WAITING, 10);
|
||||||
|
|
||||||
|
if(ipAddrAnySet){
|
||||||
clientAddress.sin_addr.s_addr = htons(INADDR_ANY);
|
clientAddress.sin_addr.s_addr = htons(INADDR_ANY);
|
||||||
//clientAddress.sin_addr.s_addr = inet_addr("127.73.73.1");
|
//clientAddress.sin_addr.s_addr = inet_addr("127.73.73.1");
|
||||||
clientAddressLen = sizeof(serverAddress);
|
clientAddressLen = sizeof(serverAddress);
|
||||||
|
}
|
||||||
|
|
||||||
// char ipAddress [15];
|
// char ipAddress [15];
|
||||||
// sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET,
|
// sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET,
|
||||||
@ -85,7 +89,7 @@ ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) {
|
void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) {
|
||||||
MutexHelper lock(mutex, MutexIF::TimeoutType::WAITING, 10);
|
MutexHelper lock(mutex, MutexIF::TimeoutType::WAITING, 10);
|
||||||
|
|
||||||
// char ipAddress [15];
|
// char ipAddress [15];
|
||||||
@ -168,3 +172,7 @@ void TmTcUnixUdpBridge::handleSendError() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TmTcUnixUdpBridge::setClientAddressToAny(bool ipAddrAnySet){
|
||||||
|
this->ipAddrAnySet = ipAddrAnySet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,9 @@ public:
|
|||||||
uint16_t serverPort = 0xFFFF,uint16_t clientPort = 0xFFFF);
|
uint16_t serverPort = 0xFFFF,uint16_t clientPort = 0xFFFF);
|
||||||
virtual~ TmTcUnixUdpBridge();
|
virtual~ TmTcUnixUdpBridge();
|
||||||
|
|
||||||
void checkAndSetClientAddress(sockaddr_in clientAddress);
|
void checkAndSetClientAddress(sockaddr_in& clientAddress);
|
||||||
|
|
||||||
|
void setClientAddressToAny(bool ipAddrAnySet);
|
||||||
protected:
|
protected:
|
||||||
virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override;
|
virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override;
|
||||||
|
|
||||||
@ -36,6 +37,8 @@ private:
|
|||||||
struct sockaddr_in serverAddress;
|
struct sockaddr_in serverAddress;
|
||||||
socklen_t serverAddressLen = 0;
|
socklen_t serverAddressLen = 0;
|
||||||
|
|
||||||
|
bool ipAddrAnySet = false;
|
||||||
|
|
||||||
//! Access to the client address is mutex protected as it is set
|
//! Access to the client address is mutex protected as it is set
|
||||||
//! by another task.
|
//! by another task.
|
||||||
MutexIF* mutex;
|
MutexIF* mutex;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <rtems/score/todimpl.h>
|
#include <rtems/score/todimpl.h>
|
||||||
|
|
||||||
uint16_t Clock::leapSeconds = 0;
|
uint16_t Clock::leapSeconds = 0;
|
||||||
MutexIF* Clock::timeMutex = NULL;
|
MutexIF* Clock::timeMutex = nullptr;
|
||||||
|
|
||||||
uint32_t Clock::getTicksPerSecond(void){
|
uint32_t Clock::getTicksPerSecond(void){
|
||||||
rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second();
|
rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second();
|
||||||
@ -40,7 +40,7 @@ ReturnValue_t Clock::setClock(const timeval* time) {
|
|||||||
//SHOULDDO: Not sure if we need to protect this call somehow (by thread lock or something).
|
//SHOULDDO: Not sure if we need to protect this call somehow (by thread lock or something).
|
||||||
//Uli: rtems docu says you can call this from an ISR, not sure if this means no protetion needed
|
//Uli: rtems docu says you can call this from an ISR, not sure if this means no protetion needed
|
||||||
//TODO Second parameter is ISR_lock_Context
|
//TODO Second parameter is ISR_lock_Context
|
||||||
_TOD_Set(&newTime,NULL);
|
_TOD_Set(&newTime,nullptr);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
|
|||||||
|
|
||||||
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
|
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
|
||||||
//SHOULDDO: works not for dates in the past (might have less leap seconds)
|
//SHOULDDO: works not for dates in the past (might have less leap seconds)
|
||||||
if (timeMutex == NULL) {
|
if (timeMutex == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,40 +157,34 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
|
|||||||
if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){
|
if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT);
|
MutexHelper helper(timeMutex);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
leapSeconds = leapSeconds_;
|
leapSeconds = leapSeconds_;
|
||||||
|
|
||||||
result = timeMutex->unlockMutex();
|
|
||||||
return result;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
|
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
|
||||||
if(timeMutex==NULL){
|
if(timeMutex==nullptr){
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT);
|
MutexHelper helper(timeMutex);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
*leapSeconds_ = leapSeconds;
|
*leapSeconds_ = leapSeconds;
|
||||||
|
|
||||||
result = timeMutex->unlockMutex();
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Clock::checkOrCreateClockMutex(){
|
ReturnValue_t Clock::checkOrCreateClockMutex(){
|
||||||
if(timeMutex==NULL){
|
if(timeMutex==nullptr){
|
||||||
MutexFactory* mutexFactory = MutexFactory::instance();
|
MutexFactory* mutexFactory = MutexFactory::instance();
|
||||||
if (mutexFactory == NULL) {
|
if (mutexFactory == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
timeMutex = mutexFactory->createMutex();
|
timeMutex = mutexFactory->createMutex();
|
||||||
if (timeMutex == NULL) {
|
if (timeMutex == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ uint32_t CpuUsage::ThreadData::getSerializedSize() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer,
|
ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer,
|
||||||
int32_t* size, Endianness streamEndianness) {
|
size_t* size, Endianness streamEndianness) {
|
||||||
ReturnValue_t result = SerializeAdapter::deSerialize(&id, buffer,
|
ReturnValue_t result = SerializeAdapter::deSerialize(&id, buffer,
|
||||||
size, streamEndianness);
|
size, streamEndianness);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
@ -12,8 +12,8 @@ ReturnValue_t InternalErrorCodes::translate(uint8_t code) {
|
|||||||
// return INVALID_WORKSPACE_ADDRESS;
|
// return INVALID_WORKSPACE_ADDRESS;
|
||||||
case INTERNAL_ERROR_TOO_LITTLE_WORKSPACE:
|
case INTERNAL_ERROR_TOO_LITTLE_WORKSPACE:
|
||||||
return TOO_LITTLE_WORKSPACE;
|
return TOO_LITTLE_WORKSPACE;
|
||||||
case INTERNAL_ERROR_WORKSPACE_ALLOCATION:
|
// case INTERNAL_ERROR_WORKSPACE_ALLOCATION:
|
||||||
return WORKSPACE_ALLOCATION;
|
// return WORKSPACE_ALLOCATION;
|
||||||
// case INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL:
|
// case INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL:
|
||||||
// return INTERRUPT_STACK_TOO_SMALL;
|
// return INTERRUPT_STACK_TOO_SMALL;
|
||||||
case INTERNAL_ERROR_THREAD_EXITTED:
|
case INTERNAL_ERROR_THREAD_EXITTED:
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
#include "Interrupt.h"
|
|
||||||
extern "C" {
|
|
||||||
#include <bsp_flp/hw_timer/hw_timer.h>
|
|
||||||
#include <bsp_flp/hw_uart/hw_uart.h>
|
|
||||||
}
|
|
||||||
#include "RtemsBasic.h"
|
|
||||||
|
|
||||||
|
|
||||||
ReturnValue_t Interrupt::enableInterrupt(InterruptNumber_t interruptNumber) {
|
|
||||||
volatile uint32_t* irqMask = hw_irq_mask;
|
|
||||||
uint32_t expectedValue = *irqMask | (1 << interruptNumber);
|
|
||||||
*irqMask = expectedValue;
|
|
||||||
uint32_t tempValue = *irqMask;
|
|
||||||
if (tempValue == expectedValue) {
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
} else {
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t Interrupt::setInterruptServiceRoutine(IsrHandler_t handler,
|
|
||||||
InterruptNumber_t interrupt, IsrHandler_t* oldHandler) {
|
|
||||||
IsrHandler_t oldHandler_local;
|
|
||||||
if (oldHandler == NULL) {
|
|
||||||
oldHandler = &oldHandler_local;
|
|
||||||
}
|
|
||||||
//+ 0x10 comes because of trap type assignment to IRQs in UT699 processor
|
|
||||||
rtems_status_code status = rtems_interrupt_catch(handler, interrupt + 0x10,
|
|
||||||
oldHandler);
|
|
||||||
switch(status){
|
|
||||||
case RTEMS_SUCCESSFUL:
|
|
||||||
//ISR established successfully
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
case RTEMS_INVALID_NUMBER:
|
|
||||||
//illegal vector number
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
case RTEMS_INVALID_ADDRESS:
|
|
||||||
//illegal ISR entry point or invalid old_isr_handler
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
default:
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t Interrupt::disableInterrupt(InterruptNumber_t interruptNumber) {
|
|
||||||
//TODO Not implemented
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//SHOULDDO: Make default values (edge, polarity) settable?
|
|
||||||
ReturnValue_t Interrupt::enableGpioInterrupt(InterruptNumber_t interrupt) {
|
|
||||||
volatile uint32_t* irqMask = hw_irq_mask;
|
|
||||||
uint32_t expectedValue = *irqMask | (1 << interrupt);
|
|
||||||
*irqMask = expectedValue;
|
|
||||||
uint32_t tempValue = *irqMask;
|
|
||||||
if (tempValue == expectedValue) {
|
|
||||||
volatile hw_gpio_port_t* ioPorts = hw_gpio_port;
|
|
||||||
ioPorts->direction &= ~(1 << interrupt); //Direction In
|
|
||||||
ioPorts->interrupt_edge |= 1 << interrupt; //Edge triggered
|
|
||||||
ioPorts->interrupt_polarity |= 1 << interrupt; //Trigger on rising edge
|
|
||||||
ioPorts->interrupt_mask |= 1 << interrupt; //Enable
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
} else {
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t Interrupt::disableGpioInterrupt(InterruptNumber_t interrupt) {
|
|
||||||
volatile uint32_t* irqMask = hw_irq_mask;
|
|
||||||
uint32_t expectedValue = *irqMask & ~(1 << interrupt);
|
|
||||||
*irqMask = expectedValue;
|
|
||||||
uint32_t tempValue = *irqMask;
|
|
||||||
if (tempValue == expectedValue) {
|
|
||||||
//Disable gpio IRQ
|
|
||||||
volatile hw_gpio_port_t* ioPorts = hw_gpio_port;
|
|
||||||
ioPorts->interrupt_mask &= ~(1 << interrupt);
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
} else {
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Interrupt::isInterruptInProgress() {
|
|
||||||
return rtems_interrupt_is_in_progress();
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
#ifndef OS_RTEMS_INTERRUPT_H_
|
|
||||||
#define OS_RTEMS_INTERRUPT_H_
|
|
||||||
|
|
||||||
#include "../../returnvalues/HasReturnvaluesIF.h"
|
|
||||||
#include <cstring>
|
|
||||||
#include <rtems.h>
|
|
||||||
|
|
||||||
typedef rtems_isr_entry IsrHandler_t;
|
|
||||||
typedef rtems_isr IsrReturn_t;
|
|
||||||
typedef rtems_vector_number InterruptNumber_t;
|
|
||||||
|
|
||||||
class Interrupt {
|
|
||||||
public:
|
|
||||||
virtual ~Interrupt(){};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Establishes a new interrupt service routine.
|
|
||||||
* @param handler The service routine to establish
|
|
||||||
* @param interrupt The interrupt (NOT trap type) the routine shall react to.
|
|
||||||
* @return RETURN_OK on success. Otherwise, the OS failure code is returned.
|
|
||||||
*/
|
|
||||||
static ReturnValue_t setInterruptServiceRoutine(IsrHandler_t handler,
|
|
||||||
InterruptNumber_t interrupt, IsrHandler_t *oldHandler = NULL);
|
|
||||||
static ReturnValue_t enableInterrupt(InterruptNumber_t interruptNumber);
|
|
||||||
static ReturnValue_t disableInterrupt(InterruptNumber_t interruptNumber);
|
|
||||||
/**
|
|
||||||
* Enables the interrupt given.
|
|
||||||
* The function tests, if the InterruptMask register was written successfully.
|
|
||||||
* @param interrupt The interrupt to enable.
|
|
||||||
* @return RETURN_OK if the interrupt was set successfully. RETURN_FAILED else.
|
|
||||||
*/
|
|
||||||
static ReturnValue_t enableGpioInterrupt(InterruptNumber_t interrupt);
|
|
||||||
/**
|
|
||||||
* Disables the interrupt given.
|
|
||||||
* @param interrupt The interrupt to disable.
|
|
||||||
* @return RETURN_OK if the interrupt was set successfully. RETURN_FAILED else.
|
|
||||||
*/
|
|
||||||
static ReturnValue_t disableGpioInterrupt(InterruptNumber_t interrupt);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the current executing context is an ISR.
|
|
||||||
* @return true if handling an interrupt, false else.
|
|
||||||
*/
|
|
||||||
static bool isInterruptInProgress();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* OS_RTEMS_INTERRUPT_H_ */
|
|
@ -1,14 +1,15 @@
|
|||||||
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
||||||
|
#include "../../objectmanager/ObjectManagerIF.h"
|
||||||
#include "MessageQueue.h"
|
#include "MessageQueue.h"
|
||||||
#include "RtemsBasic.h"
|
#include "RtemsBasic.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) :
|
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) :
|
||||||
id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(NULL) {
|
id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(nullptr) {
|
||||||
rtems_name name = ('Q' << 24) + (queueCounter++ << 8);
|
rtems_name name = ('Q' << 24) + (queueCounter++ << 8);
|
||||||
rtems_status_code status = rtems_message_queue_create(name, message_depth,
|
rtems_status_code status = rtems_message_queue_create(name, message_depth,
|
||||||
max_message_size, 0, &(this->id));
|
max_message_size, 0, &(this->id));
|
||||||
if (status != RTEMS_SUCCESSFUL) {
|
if (status != RTEMS_SUCCESSFUL) {
|
||||||
error << "MessageQueue::MessageQueue: Creating Queue " << std::hex
|
sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex
|
||||||
<< name << std::dec << " failed with status:"
|
<< name << std::dec << " failed with status:"
|
||||||
<< (uint32_t) status << std::endl;
|
<< (uint32_t) status << std::endl;
|
||||||
this->id = 0;
|
this->id = 0;
|
||||||
@ -20,15 +21,15 @@ MessageQueue::~MessageQueue() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo,
|
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo,
|
||||||
MessageQueueMessage* message, bool ignoreFault) {
|
MessageQueueMessageIF* message, bool ignoreFault) {
|
||||||
return sendMessageFrom(sendTo, message, this->getId(), ignoreFault);
|
return sendMessageFrom(sendTo, message, this->getId(), ignoreFault);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessage* message) {
|
ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) {
|
||||||
return sendToDefaultFrom(message, this->getId());
|
return sendToDefaultFrom(message, this->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) {
|
ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
|
||||||
if (this->lastPartner != 0) {
|
if (this->lastPartner != 0) {
|
||||||
return sendMessage(this->lastPartner, message, this->getId());
|
return sendMessage(this->lastPartner, message, this->getId());
|
||||||
} else {
|
} else {
|
||||||
@ -36,27 +37,29 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message,
|
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t* receivedFrom) {
|
MessageQueueId_t* receivedFrom) {
|
||||||
ReturnValue_t status = this->receiveMessage(message);
|
ReturnValue_t status = this->receiveMessage(message);
|
||||||
*receivedFrom = this->lastPartner;
|
*receivedFrom = this->lastPartner;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
|
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
|
||||||
|
size_t size = 0;
|
||||||
rtems_status_code status = rtems_message_queue_receive(id,
|
rtems_status_code status = rtems_message_queue_receive(id,
|
||||||
message->getBuffer(), &(message->messageSize),
|
message->getBuffer(),&size,
|
||||||
RTEMS_NO_WAIT, 1);
|
RTEMS_NO_WAIT, 1);
|
||||||
if (status == RTEMS_SUCCESSFUL) {
|
if (status == RTEMS_SUCCESSFUL) {
|
||||||
|
message->setMessageSize(size);
|
||||||
this->lastPartner = message->getSender();
|
this->lastPartner = message->getSender();
|
||||||
//Check size of incoming message.
|
//Check size of incoming message.
|
||||||
if (message->messageSize < message->getMinimumMessageSize()) {
|
if (message->getMessageSize() < message->getMinimumMessageSize()) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//No message was received. Keep lastPartner anyway, I might send something later.
|
//No message was received. Keep lastPartner anyway, I might send something later.
|
||||||
//But still, delete packet content.
|
//But still, delete packet content.
|
||||||
memset(message->getData(), 0, message->MAX_DATA_SIZE);
|
memset(message->getData(), 0, message->getMaximumMessageSize());
|
||||||
}
|
}
|
||||||
return convertReturnCode(status);
|
return convertReturnCode(status);
|
||||||
}
|
}
|
||||||
@ -79,20 +82,20 @@ void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
|
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
|
||||||
MessageQueueMessage* message, MessageQueueId_t sentFrom,
|
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||||
bool ignoreFault) {
|
bool ignoreFault) {
|
||||||
|
|
||||||
message->setSender(sentFrom);
|
message->setSender(sentFrom);
|
||||||
rtems_status_code result = rtems_message_queue_send(sendTo,
|
rtems_status_code result = rtems_message_queue_send(sendTo,
|
||||||
message->getBuffer(), message->messageSize);
|
message->getBuffer(), message->getMessageSize());
|
||||||
|
|
||||||
//TODO: Check if we're in ISR.
|
//TODO: Check if we're in ISR.
|
||||||
if (result != RTEMS_SUCCESSFUL && !ignoreFault) {
|
if (result != RTEMS_SUCCESSFUL && !ignoreFault) {
|
||||||
if (internalErrorReporter == NULL) {
|
if (internalErrorReporter == nullptr) {
|
||||||
internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
|
internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
|
||||||
objects::INTERNAL_ERROR_REPORTER);
|
objects::INTERNAL_ERROR_REPORTER);
|
||||||
}
|
}
|
||||||
if (internalErrorReporter != NULL) {
|
if (internalErrorReporter != nullptr) {
|
||||||
internalErrorReporter->queueMessageNotSent();
|
internalErrorReporter->queueMessageNotSent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +108,7 @@ ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
|
|||||||
return returnCode;
|
return returnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessage* message,
|
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
MessageQueueId_t sentFrom, bool ignoreFault) {
|
||||||
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
|
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,5 @@
|
|||||||
/**
|
#ifndef FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
|
||||||
* @file MessageQueue.h
|
#define FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
|
||||||
*
|
|
||||||
* @date 10/02/2012
|
|
||||||
* @author Bastian Baetz
|
|
||||||
*
|
|
||||||
* @brief This file contains the definition of the MessageQueue class.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MESSAGEQUEUE_H_
|
|
||||||
#define MESSAGEQUEUE_H_
|
|
||||||
|
|
||||||
#include "../../internalError/InternalErrorReporterIF.h"
|
#include "../../internalError/InternalErrorReporterIF.h"
|
||||||
#include "../../ipc/MessageQueueIF.h"
|
#include "../../ipc/MessageQueueIF.h"
|
||||||
@ -60,14 +51,14 @@ public:
|
|||||||
* @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full.
|
* @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t sendMessage(MessageQueueId_t sendTo,
|
ReturnValue_t sendMessage(MessageQueueId_t sendTo,
|
||||||
MessageQueueMessage* message, bool ignoreFault = false );
|
MessageQueueMessageIF* message, bool ignoreFault = false );
|
||||||
/**
|
/**
|
||||||
* @brief This operation sends a message to the default destination.
|
* @brief This operation sends a message to the default destination.
|
||||||
* @details As in the sendMessage method, this function uses the sendToDefault call of the
|
* @details As in the sendMessage method, this function uses the sendToDefault call of the
|
||||||
* MessageQueueSender parent class and adds its queue id as "sentFrom" information.
|
* MessageQueueSender parent class and adds its queue id as "sentFrom" information.
|
||||||
* @param message A pointer to a previously created message, which is sent.
|
* @param message A pointer to a previously created message, which is sent.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t sendToDefault( MessageQueueMessage* message );
|
ReturnValue_t sendToDefault( MessageQueueMessageIF* message );
|
||||||
/**
|
/**
|
||||||
* @brief This operation sends a message to the last communication partner.
|
* @brief This operation sends a message to the last communication partner.
|
||||||
* @details This operation simplifies answering an incoming message by using the stored
|
* @details This operation simplifies answering an incoming message by using the stored
|
||||||
@ -75,7 +66,7 @@ public:
|
|||||||
* (i.e. lastPartner is zero), an error code is returned.
|
* (i.e. lastPartner is zero), an error code is returned.
|
||||||
* @param message A pointer to a previously created message, which is sent.
|
* @param message A pointer to a previously created message, which is sent.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t reply( MessageQueueMessage* message );
|
ReturnValue_t reply( MessageQueueMessageIF* message );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function reads available messages from the message queue and returns the sender.
|
* @brief This function reads available messages from the message queue and returns the sender.
|
||||||
@ -84,7 +75,7 @@ public:
|
|||||||
* @param message A pointer to a message in which the received data is stored.
|
* @param message A pointer to a message in which the received data is stored.
|
||||||
* @param receivedFrom A pointer to a queue id in which the sender's id is stored.
|
* @param receivedFrom A pointer to a queue id in which the sender's id is stored.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessage* message,
|
ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t *receivedFrom);
|
MessageQueueId_t *receivedFrom);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,7 +86,7 @@ public:
|
|||||||
* message's content is cleared and the function returns immediately.
|
* message's content is cleared and the function returns immediately.
|
||||||
* @param message A pointer to a message in which the received data is stored.
|
* @param message A pointer to a message in which the received data is stored.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessage* message);
|
ReturnValue_t receiveMessage(MessageQueueMessageIF* message);
|
||||||
/**
|
/**
|
||||||
* Deletes all pending messages in the queue.
|
* Deletes all pending messages in the queue.
|
||||||
* @param count The number of flushed messages.
|
* @param count The number of flushed messages.
|
||||||
@ -121,7 +112,7 @@ public:
|
|||||||
* This variable is set to zero by default.
|
* This variable is set to zero by default.
|
||||||
* \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full.
|
* \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false );
|
virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false );
|
||||||
/**
|
/**
|
||||||
* \brief The sendToDefault method sends a queue message to the default destination.
|
* \brief The sendToDefault method sends a queue message to the default destination.
|
||||||
* \details In all other aspects, it works identical to the sendMessage method.
|
* \details In all other aspects, it works identical to the sendMessage method.
|
||||||
@ -129,7 +120,7 @@ public:
|
|||||||
* \param sentFrom The sentFrom information can be set to inject the sender's queue id into the message.
|
* \param sentFrom The sentFrom information can be set to inject the sender's queue id into the message.
|
||||||
* This variable is set to zero by default.
|
* This variable is set to zero by default.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false );
|
virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false );
|
||||||
/**
|
/**
|
||||||
* \brief This method is a simple setter for the default destination.
|
* \brief This method is a simple setter for the default destination.
|
||||||
*/
|
*/
|
||||||
@ -178,4 +169,4 @@ private:
|
|||||||
static ReturnValue_t convertReturnCode(rtems_status_code inValue);
|
static ReturnValue_t convertReturnCode(rtems_status_code inValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MESSAGEQUEUE_H_ */
|
#endif /* FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_ */
|
||||||
|
@ -30,7 +30,7 @@ ReturnValue_t MultiObjectTask::startTask() {
|
|||||||
rtems_status_code status = rtems_task_start(id, MultiObjectTask::taskEntryPoint,
|
rtems_status_code status = rtems_task_start(id, MultiObjectTask::taskEntryPoint,
|
||||||
rtems_task_argument((void *) this));
|
rtems_task_argument((void *) this));
|
||||||
if (status != RTEMS_SUCCESSFUL) {
|
if (status != RTEMS_SUCCESSFUL) {
|
||||||
error << "ObjectTask::startTask for " << std::hex << this->getId()
|
sif::error << "ObjectTask::startTask for " << std::hex << this->getId()
|
||||||
<< std::dec << " failed." << std::endl;
|
<< std::dec << " failed." << std::endl;
|
||||||
}
|
}
|
||||||
switch(status){
|
switch(status){
|
||||||
@ -63,8 +63,8 @@ void MultiObjectTask::taskFunctionality() {
|
|||||||
char nameSpace[8] = { 0 };
|
char nameSpace[8] = { 0 };
|
||||||
char* ptr = rtems_object_get_name(getId(), sizeof(nameSpace),
|
char* ptr = rtems_object_get_name(getId(), sizeof(nameSpace),
|
||||||
nameSpace);
|
nameSpace);
|
||||||
error << "ObjectTask: " << ptr << " Deadline missed." << std::endl;
|
sif::error << "ObjectTask: " << ptr << " Deadline missed." << std::endl;
|
||||||
if (this->deadlineMissedFunc != NULL) {
|
if (this->deadlineMissedFunc != nullptr) {
|
||||||
this->deadlineMissedFunc();
|
this->deadlineMissedFunc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ void MultiObjectTask::taskFunctionality() {
|
|||||||
ReturnValue_t MultiObjectTask::addComponent(object_id_t object) {
|
ReturnValue_t MultiObjectTask::addComponent(object_id_t object) {
|
||||||
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
|
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
|
||||||
object);
|
object);
|
||||||
if (newObject == NULL) {
|
if (newObject == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
objectList.push_back(newObject);
|
objectList.push_back(newObject);
|
||||||
|
@ -80,7 +80,7 @@ protected:
|
|||||||
/**
|
/**
|
||||||
* @brief The pointer to the deadline-missed function.
|
* @brief The pointer to the deadline-missed function.
|
||||||
* @details This pointer stores the function that is executed if the task's deadline is missed.
|
* @details This pointer stores the function that is executed if the task's deadline is missed.
|
||||||
* So, each may react individually on a timing failure. The pointer may be NULL,
|
* So, each may react individually on a timing failure. The pointer may be nullptr,
|
||||||
* then nothing happens on missing the deadline. The deadline is equal to the next execution
|
* then nothing happens on missing the deadline. The deadline is equal to the next execution
|
||||||
* of the periodic task.
|
* of the periodic task.
|
||||||
*/
|
*/
|
||||||
|
@ -10,7 +10,7 @@ Mutex::Mutex() :
|
|||||||
RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, 0,
|
RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, 0,
|
||||||
&mutexId);
|
&mutexId);
|
||||||
if (status != RTEMS_SUCCESSFUL) {
|
if (status != RTEMS_SUCCESSFUL) {
|
||||||
error << "Mutex: creation with name, id " << mutexName << ", " << mutexId
|
sif::error << "Mutex: creation with name, id " << mutexName << ", " << mutexId
|
||||||
<< " failed with " << status << std::endl;
|
<< " failed with " << status << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,24 +18,25 @@ Mutex::Mutex() :
|
|||||||
Mutex::~Mutex() {
|
Mutex::~Mutex() {
|
||||||
rtems_status_code status = rtems_semaphore_delete(mutexId);
|
rtems_status_code status = rtems_semaphore_delete(mutexId);
|
||||||
if (status != RTEMS_SUCCESSFUL) {
|
if (status != RTEMS_SUCCESSFUL) {
|
||||||
error << "Mutex: deletion for id " << mutexId
|
sif::error << "Mutex: deletion for id " << mutexId
|
||||||
<< " failed with " << status << std::endl;
|
<< " failed with " << status << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType =
|
ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType =
|
||||||
TimeoutType::BLOCKING, uint32_t timeoutMs) {
|
TimeoutType::BLOCKING, uint32_t timeoutMs) {
|
||||||
|
rtems_status_code status = RTEMS_INVALID_ID;
|
||||||
if(timeoutMs == MutexIF::TimeoutType::BLOCKING) {
|
if(timeoutMs == MutexIF::TimeoutType::BLOCKING) {
|
||||||
rtems_status_code status = rtems_semaphore_obtain(mutexId,
|
status = rtems_semaphore_obtain(mutexId,
|
||||||
RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||||
}
|
}
|
||||||
else if(timeoutMs == MutexIF::TimeoutType::POLLING) {
|
else if(timeoutMs == MutexIF::TimeoutType::POLLING) {
|
||||||
timeoutMs = RTEMS_NO_TIMEOUT;
|
timeoutMs = RTEMS_NO_TIMEOUT;
|
||||||
rtems_status_code status = rtems_semaphore_obtain(mutexId,
|
status = rtems_semaphore_obtain(mutexId,
|
||||||
RTEMS_NO_WAIT, 0);
|
RTEMS_NO_WAIT, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rtems_status_code status = rtems_semaphore_obtain(mutexId,
|
status = rtems_semaphore_obtain(mutexId,
|
||||||
RTEMS_WAIT, timeoutMs);
|
RTEMS_WAIT, timeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef FRAMEWORK_OSAL_RTEMS_MUTEX_H_
|
#ifndef FSFW_OSAL_RTEMS_MUTEX_H_
|
||||||
#define FRAMEWORK_OSAL_RTEMS_MUTEX_H_
|
#define FSFW_OSAL_RTEMS_MUTEX_H_
|
||||||
|
|
||||||
#include "../../ipc/MutexIF.h"
|
#include "../../ipc/MutexIF.h"
|
||||||
#include "RtemsBasic.h"
|
#include "RtemsBasic.h"
|
||||||
@ -15,4 +15,4 @@ private:
|
|||||||
static uint8_t count;
|
static uint8_t count;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* OS_RTEMS_MUTEX_H_ */
|
#endif /* FSFW_OSAL_RTEMS_MUTEX_H_ */
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include "Mutex.h"
|
#include "Mutex.h"
|
||||||
#include "RtemsBasic.h"
|
#include "RtemsBasic.h"
|
||||||
|
|
||||||
//TODO: Different variant than the lazy loading in QueueFactory. What's better and why?
|
|
||||||
MutexFactory* MutexFactory::factoryInstance = new MutexFactory();
|
MutexFactory* MutexFactory::factoryInstance = new MutexFactory();
|
||||||
|
|
||||||
MutexFactory::MutexFactory() {
|
MutexFactory::MutexFactory() {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "../../devicehandlers/FixedSequenceSlot.h"
|
#include "../../tasks/FixedSequenceSlot.h"
|
||||||
#include "../../objectmanager/SystemObjectIF.h"
|
#include "../../objectmanager/SystemObjectIF.h"
|
||||||
|
#include "../../objectmanager/ObjectManagerIF.h"
|
||||||
#include "PollingTask.h"
|
#include "PollingTask.h"
|
||||||
#include "RtemsBasic.h"
|
#include "RtemsBasic.h"
|
||||||
#include "../../returnvalues/HasReturnvaluesIF.h"
|
#include "../../returnvalues/HasReturnvaluesIF.h"
|
||||||
@ -34,14 +35,14 @@ rtems_task PollingTask::taskEntryPoint(rtems_task_argument argument) {
|
|||||||
PollingTask *originalTask(reinterpret_cast<PollingTask*>(argument));
|
PollingTask *originalTask(reinterpret_cast<PollingTask*>(argument));
|
||||||
//The task's functionality is called.
|
//The task's functionality is called.
|
||||||
originalTask->taskFunctionality();
|
originalTask->taskFunctionality();
|
||||||
debug << "Polling task " << originalTask->getId()
|
sif::debug << "Polling task " << originalTask->getId()
|
||||||
<< " returned from taskFunctionality." << std::endl;
|
<< " returned from taskFunctionality." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PollingTask::missedDeadlineCounter() {
|
void PollingTask::missedDeadlineCounter() {
|
||||||
PollingTask::deadlineMissedCount++;
|
PollingTask::deadlineMissedCount++;
|
||||||
if (PollingTask::deadlineMissedCount % 10 == 0) {
|
if (PollingTask::deadlineMissedCount % 10 == 0) {
|
||||||
error << "PST missed " << PollingTask::deadlineMissedCount
|
sif::error << "PST missed " << PollingTask::deadlineMissedCount
|
||||||
<< " deadlines." << std::endl;
|
<< " deadlines." << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,7 +51,7 @@ ReturnValue_t PollingTask::startTask() {
|
|||||||
rtems_status_code status = rtems_task_start(id, PollingTask::taskEntryPoint,
|
rtems_status_code status = rtems_task_start(id, PollingTask::taskEntryPoint,
|
||||||
rtems_task_argument((void *) this));
|
rtems_task_argument((void *) this));
|
||||||
if (status != RTEMS_SUCCESSFUL) {
|
if (status != RTEMS_SUCCESSFUL) {
|
||||||
error << "PollingTask::startTask for " << std::hex << this->getId()
|
sif::error << "PollingTask::startTask for " << std::hex << this->getId()
|
||||||
<< std::dec << " failed." << std::endl;
|
<< std::dec << " failed." << std::endl;
|
||||||
}
|
}
|
||||||
switch(status){
|
switch(status){
|
||||||
@ -68,12 +69,13 @@ ReturnValue_t PollingTask::startTask() {
|
|||||||
|
|
||||||
ReturnValue_t PollingTask::addSlot(object_id_t componentId,
|
ReturnValue_t PollingTask::addSlot(object_id_t componentId,
|
||||||
uint32_t slotTimeMs, int8_t executionStep) {
|
uint32_t slotTimeMs, int8_t executionStep) {
|
||||||
if (objectManager->get<ExecutableObjectIF>(componentId) != nullptr) {
|
ExecutableObjectIF* object = objectManager->get<ExecutableObjectIF>(componentId);
|
||||||
pst.addSlot(componentId, slotTimeMs, executionStep, this);
|
if (object != nullptr) {
|
||||||
|
pst.addSlot(componentId, slotTimeMs, executionStep, object, this);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error << "Component " << std::hex << componentId <<
|
sif::error << "Component " << std::hex << componentId <<
|
||||||
" not found, not adding it to pst" << std::endl;
|
" not found, not adding it to pst" << std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
@ -90,11 +92,10 @@ ReturnValue_t PollingTask::checkSequence() const {
|
|||||||
|
|
||||||
void PollingTask::taskFunctionality() {
|
void PollingTask::taskFunctionality() {
|
||||||
// A local iterator for the Polling Sequence Table is created to find the start time for the first entry.
|
// A local iterator for the Polling Sequence Table is created to find the start time for the first entry.
|
||||||
std::list<FixedSequenceSlot*>::iterator it = pst.current;
|
FixedSlotSequence::SlotListIter it = pst.current;
|
||||||
|
|
||||||
//The start time for the first entry is read.
|
//The start time for the first entry is read.
|
||||||
rtems_interval interval = RtemsBasic::convertMsToTicks(
|
rtems_interval interval = RtemsBasic::convertMsToTicks(it->pollingTimeMs);
|
||||||
(*it)->pollingTimeMs);
|
|
||||||
TaskBase::setAndStartPeriod(interval,&periodId);
|
TaskBase::setAndStartPeriod(interval,&periodId);
|
||||||
//The task's "infinite" inner loop is entered.
|
//The task's "infinite" inner loop is entered.
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -107,7 +108,7 @@ void PollingTask::taskFunctionality() {
|
|||||||
//If the deadline was missed, the deadlineMissedFunc is called.
|
//If the deadline was missed, the deadlineMissedFunc is called.
|
||||||
rtems_status_code status = TaskBase::restartPeriod(interval,periodId);
|
rtems_status_code status = TaskBase::restartPeriod(interval,periodId);
|
||||||
if (status == RTEMS_TIMEOUT) {
|
if (status == RTEMS_TIMEOUT) {
|
||||||
if (this->deadlineMissedFunc != NULL) {
|
if (this->deadlineMissedFunc != nullptr) {
|
||||||
this->deadlineMissedFunc();
|
this->deadlineMissedFunc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef POLLINGTASK_H_
|
#ifndef FSFW_OSAL_RTEMS_POLLINGTASK_H_
|
||||||
#define POLLINGTASK_H_
|
#define FSFW_OSAL_RTEMS_POLLINGTASK_H_
|
||||||
|
|
||||||
#include "../../devicehandlers/FixedSlotSequence.h"
|
#include "../../tasks/FixedSlotSequence.h"
|
||||||
#include "../../tasks/FixedTimeslotTaskIF.h"
|
#include "../../tasks/FixedTimeslotTaskIF.h"
|
||||||
#include "TaskBase.h"
|
#include "TaskBase.h"
|
||||||
|
|
||||||
@ -82,4 +82,4 @@ protected:
|
|||||||
void taskFunctionality( void );
|
void taskFunctionality( void );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* POLLINGTASK_H_ */
|
#endif /* FSFW_OSAL_RTEMS_POLLINGTASK_H_ */
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
#include "../../ipc/QueueFactory.h"
|
#include "../../ipc/QueueFactory.h"
|
||||||
|
#include "../../ipc/MessageQueueSenderIF.h"
|
||||||
#include "MessageQueue.h"
|
#include "MessageQueue.h"
|
||||||
#include "RtemsBasic.h"
|
#include "RtemsBasic.h"
|
||||||
|
|
||||||
QueueFactory* QueueFactory::factoryInstance = NULL;
|
QueueFactory* QueueFactory::factoryInstance = nullptr;
|
||||||
|
|
||||||
|
|
||||||
ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
|
ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
|
||||||
MessageQueueMessage* message, MessageQueueId_t sentFrom,bool ignoreFault) {
|
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,bool ignoreFault) {
|
||||||
//TODO add ignoreFault functionality
|
//TODO add ignoreFault functionality
|
||||||
message->setSender(sentFrom);
|
message->setSender(sentFrom);
|
||||||
rtems_status_code result = rtems_message_queue_send(sendTo, message->getBuffer(),
|
rtems_status_code result = rtems_message_queue_send(sendTo, message->getBuffer(),
|
||||||
message->messageSize);
|
message->getMessageSize());
|
||||||
switch(result){
|
switch(result){
|
||||||
case RTEMS_SUCCESSFUL:
|
case RTEMS_SUCCESSFUL:
|
||||||
//message sent successfully
|
//message sent successfully
|
||||||
@ -37,7 +38,7 @@ ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
QueueFactory* QueueFactory::instance() {
|
QueueFactory* QueueFactory::instance() {
|
||||||
if (factoryInstance == NULL) {
|
if (factoryInstance == nullptr) {
|
||||||
factoryInstance = new QueueFactory;
|
factoryInstance = new QueueFactory;
|
||||||
}
|
}
|
||||||
return factoryInstance;
|
return factoryInstance;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef OS_RTEMS_RTEMSBASIC_H_
|
#ifndef FSFW_OSAL_RTEMS_RTEMSBASIC_H_
|
||||||
#define OS_RTEMS_RTEMSBASIC_H_
|
#define FSFW_OSAL_RTEMS_RTEMSBASIC_H_
|
||||||
|
|
||||||
#include "../../returnvalues/HasReturnvaluesIF.h"
|
#include "../../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include <rtems.h>
|
#include <rtems.h>
|
||||||
@ -22,4 +22,4 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* OS_RTEMS_RTEMSBASIC_H_ */
|
#endif /* FSFW_OSAL_RTEMS_RTEMSBASIC_H_ */
|
||||||
|
@ -22,7 +22,7 @@ TaskBase::TaskBase(rtems_task_priority set_priority, size_t stack_size,
|
|||||||
}
|
}
|
||||||
ReturnValue_t result = convertReturnCode(status);
|
ReturnValue_t result = convertReturnCode(status);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
error << "TaskBase::TaskBase: createTask with name " << std::hex
|
sif::error << "TaskBase::TaskBase: createTask with name " << std::hex
|
||||||
<< osalName << std::dec << " failed with return code "
|
<< osalName << std::dec << " failed with return code "
|
||||||
<< (uint32_t) status << std::endl;
|
<< (uint32_t) status << std::endl;
|
||||||
this->id = 0;
|
this->id = 0;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef TASKBASE_H_
|
#ifndef FSFW_OSAL_RTEMS_TASKBASE_H_
|
||||||
#define TASKBASE_H_
|
#define FSFW_OSAL_RTEMS_TASKBASE_H_
|
||||||
|
|
||||||
#include "RtemsBasic.h"
|
#include "RtemsBasic.h"
|
||||||
#include "../../tasks/PeriodicTaskIF.h"
|
#include "../../tasks/PeriodicTaskIF.h"
|
||||||
@ -44,4 +44,4 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* TASKBASE_H_ */
|
#endif /* FSFW_OSAL_RTEMS_TASKBASE_H_ */
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define FRAMEWORK_TIMEMANAGER_CLOCK_H_
|
#define FRAMEWORK_TIMEMANAGER_CLOCK_H_
|
||||||
|
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "../ipc/MutexFactory.h"
|
#include "../ipc/MutexHelper.h"
|
||||||
#include "../globalfunctions/timevalOperations.h"
|
#include "../globalfunctions/timevalOperations.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
Loading…
Reference in New Issue
Block a user