Compare commits

..

92 Commits

Author SHA1 Message Date
b00bfe4bda Merge pull request 'ASTP 1.1.0 Merge Development in Master' (#441) from development into master
Reviewed-on: fsfw/fsfw#441
2021-06-29 14:11:46 +02:00
2b2899e100 Merge pull request 'Missing function for TC Constructor' (#440) from KSat/fsfw:mueller/master into development
Reviewed-on: fsfw/fsfw#440
2021-06-22 14:36:05 +02:00
b52644dd2a tiny form fix 2021-06-21 14:50:19 +02:00
1015cdbe88 Merge remote-tracking branch 'upstream/development' into mueller/master 2021-06-20 17:16:35 +02:00
cae69d5400 Merge pull request 'added missing include' (#439) from mueller/missing-include into development
Reviewed-on: fsfw/fsfw#439
2021-06-17 12:35:20 +02:00
47af5260a2 added missing include 2021-06-17 12:04:39 +02:00
1e380fe562 Merge pull request 'NO_COMMANDER was not using NO_QUEUE in DHB' (#438) from gaisser/fsfw:gaisser_small_dhb_fix into development
Reviewed-on: fsfw/fsfw#438
2021-06-15 16:49:53 +02:00
bd7c13ff7e NO_COMMANDER was not using NO_QUEUE in DHB 2021-06-15 16:47:24 +02:00
2684e82c7f Merge pull request 'PUS C support for Telecommands and first FSFW.h file' (#432) from KSat/fsfw:mueller/update-package into development
Reviewed-on: fsfw/fsfw#432
2021-06-15 16:37:40 +02:00
66d1d14ae3 Merge branch 'development' into mueller/update-package 2021-06-15 16:33:26 +02:00
5f9a6bb155 Merge pull request 'Removed wrong static' (#437) from gaisser/fsfw:gaisser_clock_leap_seconds_move into development
Reviewed-on: fsfw/fsfw#437
2021-06-15 16:13:55 +02:00
8a5a3c0243 Merge branch 'development' into gaisser_clock_leap_seconds_move 2021-06-15 16:13:35 +02:00
2ccc0dbb00 Removed wrong static 2021-06-15 16:12:25 +02:00
cfbdb10a55 Merge pull request 'Moved leap second handling from OSALs to clock.h' (#436) from gaisser/fsfw:gaisser_clock_leap_seconds_move into development
Reviewed-on: fsfw/fsfw#436
2021-06-15 16:09:53 +02:00
ee89a2f00d Removed author tag 2021-06-15 16:05:12 +02:00
dbfcf8b271 Removed old check 2021-06-15 16:03:11 +02:00
717971f69c Fixed wrong namespace qualifier 2021-06-15 16:01:28 +02:00
b0a69d4c9d Merge remote-tracking branch 'my_fork/gaisser_clock_leap_seconds_move' into gaisser_clock_leap_seconds_move 2021-06-15 16:00:23 +02:00
ecb03b8a6d Moved Code to own cpp 2021-06-15 15:59:20 +02:00
b1f6252e30 Merge branch 'development' into gaisser_clock_leap_seconds_move 2021-06-15 15:53:16 +02:00
05edb7a00c Merge pull request 'Added some precautions in DHB::replyToReply' (#435) from gaisser/fsfw:gaisser_overflow_avoid_dhb into development
Reviewed-on: fsfw/fsfw#435
2021-06-15 15:53:05 +02:00
0cde65f5a1 Added some precautions in DHB::replyToReply 2021-06-15 15:33:52 +02:00
fbbc640f4d Merge pull request 'DHB tweak and class ID for GPIO HAL' (#434) from eive/fsfw:mueller/dhb-tweak into development
Reviewed-on: fsfw/fsfw#434
2021-06-15 15:23:23 +02:00
03e1a3e945 const correctness 2021-06-15 15:08:18 +02:00
cc5c8ca698 type 2021-06-15 15:04:40 +02:00
996fbf134e Merge branch 'mueller/dhb-tweak' of https://egit.irs.uni-stuttgart.de/eive/fsfw into mueller/dhb-tweak 2021-06-15 15:01:09 +02:00
1c7c532ef6 DHB update 2021-06-15 15:01:02 +02:00
41e3a6b54b Merge branch 'development' into mueller/dhb-tweak 2021-06-15 14:56:19 +02:00
aa1bfcbb96 DHB update 2021-06-15 14:52:56 +02:00
0f484abcaa Merge branch 'mueller/update-package' into mueller/master 2021-06-15 14:22:03 +02:00
c371cf4851 changelog update 2021-06-15 14:21:46 +02:00
ad191409f4 Merge remote-tracking branch 'upstream/development' into mueller/update-package 2021-06-15 14:20:03 +02:00
398250c959 Merge pull request 'added generic file system message' (#428) from KSat/fsfw:mueller/generic-filesyste-message into development
Reviewed-on: fsfw/fsfw#428
2021-06-15 14:08:24 +02:00
4b248740f3 added HAL gpio class ID 2021-06-15 13:32:11 +02:00
21d213f35f Merge branch 'development' into gaisser_clock_leap_seconds_move 2021-06-14 15:27:37 +02:00
105a498b93 added way to set source ID 2021-06-14 15:24:26 +02:00
0a0c5592f3 Merge branch 'mueller/update-package' into mueller/master 2021-06-14 15:15:23 +02:00
aa33ff2f48 max tm packet size now configurable 2021-06-14 15:14:57 +02:00
3076c423c0 Merge branch 'development' into mueller/generic-filesyste-message 2021-06-14 15:14:37 +02:00
5f27fe6392 indentation 2021-06-14 15:06:26 +02:00
af99303eac indentation 2021-06-14 15:05:40 +02:00
1d2dabb4b4 Merge remote-tracking branch 'upstream/development' into mueller/update-package 2021-06-14 14:52:52 +02:00
eead2a8a49 Moved leap second management 2021-06-14 14:40:40 +02:00
a7068acca7 updated generic file system message 2021-06-14 14:38:09 +02:00
99b007f37e added deletions 2021-06-14 14:37:38 +02:00
7cf4aa0d5a fixes for pus tc c 2021-06-14 11:44:39 +02:00
b1e3a1b2b5 const correctness 2021-06-14 11:16:56 +02:00
56d2af9d25 cleaned up a bit 2021-06-14 10:19:01 +02:00
dadba69272 Merge branch 'mueller/fsfw-pus-c-tc' into mueller/master 2021-06-13 18:00:13 +02:00
40a8c9a495 srv 20 fixes 2021-06-13 17:58:44 +02:00
8dc66784a8 tiny changes 2021-06-13 16:59:28 +02:00
d0f37b851b added pus c support for tc 2021-06-13 16:29:13 +02:00
1b6759020a added getter function 2021-06-13 12:38:24 +02:00
537a30a4de added pus a tc 2021-06-13 12:34:06 +02:00
a993872884 Merge pull request 'EIVE FSFW Update' (#430) from eive/fsfw:eive/develop into development
Reviewed-on: fsfw/fsfw#430
2021-06-12 15:44:31 +02:00
d700fb551c Merge remote-tracking branch 'upstream/development' into eive/develop 2021-06-12 15:24:08 +02:00
73bae057bd default color is magneta now for wanring 2021-06-12 15:03:18 +02:00
589e64fc46 void function now 2021-06-11 15:05:43 +02:00
1630682548 added function to set color 2021-06-11 14:52:09 +02:00
4b095eea89 Merge remote-tracking branch 'upstream/mueller/master' into mueller/master 2021-06-08 15:37:13 +02:00
fb7b059137 added clear message 2021-06-08 15:13:49 +02:00
bc151983b5 Merge branch 'development' into mueller/generic-filesyste-message 2021-06-08 15:05:41 +02:00
40b2979ce8 added generic file system message 2021-06-08 15:03:17 +02:00
7030d3e108 Merge pull request 'Make Object Manager a Singleton and Refactored Linux Error Printing' (#424) from KSat/fsfw:mueller/master into development
Reviewed-on: fsfw/fsfw#424
2021-06-08 15:01:00 +02:00
41cb8cb8ae Merge remote-tracking branch 'upstream/development' into mueller/master 2021-06-08 14:43:31 +02:00
75adf52d28 small update 2021-06-08 14:30:35 +02:00
0157681471 removed obsolete code 2021-06-08 14:27:21 +02:00
b6b144bcdb Merge pull request 'FreeRTOS Queue Map Manager' (#423) from KSat/fsfw:mueller/freertos-queue-map-manager into development
Reviewed-on: fsfw/fsfw#423
2021-06-08 14:03:45 +02:00
145dd33fb1 fixed merge conflict 2021-06-05 20:30:36 +02:00
50fac22f54 Merge remote-tracking branch 'ksat/mueller/master' into mueller/master 2021-06-05 20:10:17 +02:00
8b83541264 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/KSat/fsfw into mueller/master 2021-06-05 19:59:51 +02:00
57699cccb7 object manager is now a singleton 2021-06-05 19:52:38 +02:00
33e7c635c5 added hal class ids 2021-06-05 00:05:03 +02:00
070c3f3bbf added example usage 2021-06-04 14:39:21 +02:00
3891014340 linux error print handling improved 2021-06-03 12:29:06 +02:00
c3be4cdee6 Merge remote-tracking branch 'upstream/mueller/master' into mueller/master 2021-05-31 17:06:07 +02:00
6b9747ee0b Merge remote-tracking branch 'upstream/mueller/master' into mueller/master 2021-05-31 17:03:55 +02:00
ad820fbe99 important bugfix 2021-05-31 17:00:51 +02:00
722a7b3240 renamed variable 2021-05-31 16:46:32 +02:00
442b9370ae Merge remote-tracking branch 'upstream/mueller/master' into source/develop 2021-05-31 12:31:46 +02:00
54e60f4ddc cleaned up a bit 2021-05-31 12:30:54 +02:00
e961f3f038 better error handling for mq_receive() 2021-05-31 12:22:33 +02:00
c9836abf03 minor tweak 2021-05-31 11:36:32 +02:00
404c3821e6 corrected include 2021-05-31 11:12:52 +02:00
567699954c added missing event translation 2021-05-28 18:30:43 +02:00
f0a7b1cad2 indentation 2021-05-27 13:47:22 +02:00
e46615e830 Merge branch 'mueller/freertos-queue-map-manager' of https://egit.irs.uni-stuttgart.de/KSat/fsfw into mueller/freertos-queue-map-manager 2021-05-27 13:46:14 +02:00
e7ac2c7009 maybe this works 2021-05-27 13:46:04 +02:00
95c6a24437 Merge branch 'development' into mueller/freertos-queue-map-manager 2021-05-27 13:44:35 +02:00
237ba8112b more unrelated changes removed 2021-05-27 13:43:48 +02:00
aab3fd828b removed unrelated changes 2021-05-27 13:43:13 +02:00
2f511523cb Merge pull request 'Apollo Sojus Test Project Version 1.0.0' (#408) from development into master
Reviewed-on: fsfw/fsfw#408
2021-04-27 14:20:06 +02:00
158 changed files with 3350 additions and 3190 deletions

View File

@ -1,3 +1,16 @@
## Changes from ASTP 1.0.0 to 1.1.0
### PUS
- Added PUS C support
### Configuration
- Additional configuration option fsfwconfig::FSFW_MAX_TM_PACKET_SIZE which
need to be specified in FSFWConfig.h
## Changes from ASTP 0.0.1 to 1.0.0
### Host OSAL

View File

@ -138,9 +138,9 @@ else()
)
endif()
foreach(INCLUDE_PATH ${FSFW_ADDITIONAL_INC_PATH})
foreach(INCLUDE_PATH ${FSFW_ADDITIONAL_INC_PATHS})
if(IS_ABSOLUTE ${INCLUDE_PATH})
set(CURR_ABS_INC_PATH "${FREERTOS_PATH}")
set(CURR_ABS_INC_PATH "${INCLUDE_PATH}")
else()
get_filename_component(CURR_ABS_INC_PATH
${INCLUDE_PATH} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR})

7
FSFW.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef FSFW_FSFW_H_
#define FSFW_FSFW_H_
#include "FSFWConfig.h"
#endif /* FSFW_FSFW_H_ */

View File

@ -2,7 +2,7 @@
#include "HasActionsIF.h"
#include "../ipc/MessageQueueSenderIF.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
#include "../serviceinterface/ServiceInterface.h"
ActionHelper::ActionHelper(HasActionsIF* setOwner,
@ -25,7 +25,7 @@ ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) {
}
ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) {
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
if (ipcStore == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}

View File

@ -1,7 +1,7 @@
#include "ActionMessage.h"
#include "HasActionsIF.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
#include "../storagemanager/StorageManagerIF.h"
ActionMessage::ActionMessage() {
@ -69,7 +69,7 @@ void ActionMessage::clear(CommandMessage* message) {
switch(message->getCommand()) {
case EXECUTE_ACTION:
case DATA_REPLY: {
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
StorageManagerIF *ipcStore = ObjectManager::instance()->get<StorageManagerIF>(
objects::IPC_STORE);
if (ipcStore != NULL) {
ipcStore->deleteData(getStoreId(message));

View File

@ -2,7 +2,8 @@
#include "CommandActionHelper.h"
#include "CommandsActionsIF.h"
#include "HasActionsIF.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner) :
owner(setOwner), queueToUse(NULL), ipcStore(
@ -14,7 +15,7 @@ CommandActionHelper::~CommandActionHelper() {
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
ActionId_t actionId, SerializeIF *data) {
HasActionsIF *receiver = objectManager->get<HasActionsIF>(commandTo);
HasActionsIF *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
if (receiver == NULL) {
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
}
@ -40,7 +41,7 @@ ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
// if (commandCount != 0) {
// return CommandsFunctionsIF::ALREADY_COMMANDING;
// }
HasActionsIF *receiver = objectManager->get<HasActionsIF>(commandTo);
HasActionsIF *receiver = ObjectManager::instance()->get<HasActionsIF>(commandTo);
if (receiver == NULL) {
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
}
@ -66,7 +67,7 @@ ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId,
}
ReturnValue_t CommandActionHelper::initialize() {
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
if (ipcStore == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}

View File

@ -3,6 +3,7 @@
#include "../subsystem/SubsystemBase.h"
#include "../ipc/QueueFactory.h"
#include "../action/HasActionsIF.h"
#include "../objectmanager/ObjectManager.h"
ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
size_t commandQueueDepth) :
@ -25,7 +26,7 @@ ReturnValue_t ControllerBase::initialize() {
MessageQueueId_t parentQueue = 0;
if (parentId != objects::NO_OBJECT) {
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
SubsystemBase *parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
if (parent == nullptr) {
return RETURN_FAILED;
}

View File

@ -1,10 +1,13 @@
#include "MapPacketExtraction.h"
#include "../ipc/QueueFactory.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../storagemanager/StorageManagerIF.h"
#include "../tmtcpacket/SpacePacketBase.h"
#include "../tmtcservices/AcceptsTelecommandsIF.h"
#include "../tmtcservices/TmTcMessage.h"
#include "../objectmanager/ObjectManager.h"
#include <cstring>
MapPacketExtraction::MapPacketExtraction(uint8_t setMapId,
@ -131,9 +134,9 @@ void MapPacketExtraction::clearBuffers() {
}
ReturnValue_t MapPacketExtraction::initialize() {
packetStore = objectManager->get<StorageManagerIF>(objects::TC_STORE);
AcceptsTelecommandsIF* distributor = objectManager->get<
AcceptsTelecommandsIF>(packetDestination);
packetStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
AcceptsTelecommandsIF* distributor = ObjectManager::instance()->
get<AcceptsTelecommandsIF>(packetDestination);
if ((packetStore != NULL) && (distributor != NULL)) {
tcQueueId = distributor->getRequestQueue();
return RETURN_OK;

View File

@ -34,7 +34,8 @@ class LocalPoolObjectBase;
* can be retrieved using the object manager, provided the target object is a SystemObject.
* For example, the following line of code can be used to retrieve the interface
*
* HasLocalDataPoolIF* poolIF = objectManager->get<HasLocalDataPoolIF>(objects::SOME_OBJECT);
* HasLocalDataPoolIF* poolIF = ObjectManager::instance()->
* get<HasLocalDataPoolIF>(objects::SOME_OBJECT);
* if(poolIF != nullptr) {
* doSomething()
* }

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
#include "internal/HasLocalDpIFUserAttorney.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../objectmanager/ObjectManager.h"
#include "../globalfunctions/bitutility.h"
#include "../datapoollocal/LocalDataPoolManager.h"
#include "../housekeeping/PeriodicHousekeepingHelper.h"
@ -45,7 +46,7 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid, PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables):
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(
HasLocalDataPoolIF* hkOwner = ObjectManager::instance()->get<HasLocalDataPoolIF>(
sid.objectId);
if(hkOwner != nullptr) {
AccessPoolManagerIF* accessor = HasLocalDpIFUserAttorney::getAccessorHandle(hkOwner);

View File

@ -4,7 +4,7 @@
#include "HasLocalDataPoolIF.h"
#include "internal/HasLocalDpIFUserAttorney.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
LocalPoolObjectBase::LocalPoolObjectBase(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
@ -43,7 +43,7 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
"which is the NO_PARAMETER value!\n");
#endif
}
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(poolOwner);
HasLocalDataPoolIF* hkOwner = ObjectManager::instance()->get<HasLocalDataPoolIF>(poolOwner);
if(hkOwner == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "LocalPoolVariable: The supplied pool owner did not implement the correct "

View File

@ -7,29 +7,30 @@
//! Used to determine whether C++ ostreams are used which can increase
//! the binary size significantly. If this is disabled,
//! the C stdio functions can be used alternatively
#define FSFW_CPP_OSTREAM_ENABLED 1
#define FSFW_CPP_OSTREAM_ENABLED 1
//! More FSFW related printouts depending on level. Useful for development.
#define FSFW_VERBOSE_LEVEL 1
#define FSFW_VERBOSE_LEVEL 1
//! Can be used to completely disable printouts, even the C stdio ones.
#if FSFW_CPP_OSTREAM_ENABLED == 0 && FSFW_VERBOSE_LEVEL == 0
#define FSFW_DISABLE_PRINTOUT 0
#define FSFW_DISABLE_PRINTOUT 0
#endif
#define FSFW_USE_PUS_C_TELEMETRY 1
#define FSFW_USE_PUS_C_TELEMETRY 1
#define FSFW_USE_PUS_C_TELECOMMANDS 1
//! Can be used to disable the ANSI color sequences for C stdio.
#define FSFW_COLORED_OUTPUT 1
#define FSFW_COLORED_OUTPUT 1
//! If FSFW_OBJ_EVENT_TRANSLATION is set to one,
//! additional output which requires the translation files translateObjects
//! and translateEvents (and their compiled source files)
#define FSFW_OBJ_EVENT_TRANSLATION 0
#define FSFW_OBJ_EVENT_TRANSLATION 0
#if FSFW_OBJ_EVENT_TRANSLATION == 1
//! Specify whether info events are printed too.
#define FSFW_DEBUG_INFO 1
#define FSFW_DEBUG_INFO 1
#include "objects/translateObjects.h"
#include "events/translateEvents.h"
#else
@ -37,17 +38,17 @@
//! When using the newlib nano library, C99 support for stdio facilities
//! will not be provided. This define should be set to 1 if this is the case.
#define FSFW_NO_C99_IO 1
#define FSFW_NO_C99_IO 1
//! Specify whether a special mode store is used for Subsystem components.
#define FSFW_USE_MODESTORE 0
#define FSFW_USE_MODESTORE 0
//! Defines if the real time scheduler for linux should be used.
//! If set to 0, this will also disable priority settings for linux
//! as most systems will not allow to set nice values without privileges
//! For embedded linux system set this to 1.
//! If set to 1 the binary needs "cap_sys_nice=eip" privileges to run
#define FSFW_USE_REALTIME_FOR_LINUX 1
#define FSFW_USE_REALTIME_FOR_LINUX 1
namespace fsfwconfig {
@ -67,6 +68,8 @@ static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6;
static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124;
static constexpr size_t FSFW_MAX_TM_PACKET_SIZE = 2048;
}
#endif /* CONFIG_FSFWCONFIG_H_ */

View File

@ -1,6 +1,5 @@
#include "ChildHandlerBase.h"
#include "../subsystem/SubsystemBase.h"
#include "../subsystem/SubsystemBase.h"
ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId,
object_id_t deviceCommunication, CookieIF * cookie,
@ -30,7 +29,7 @@ ReturnValue_t ChildHandlerBase::initialize() {
MessageQueueId_t parentQueue = 0;
if (parentId != objects::NO_OBJECT) {
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
SubsystemBase *parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
if (parent == NULL) {
return RETURN_FAILED;
}

View File

@ -119,7 +119,7 @@ ReturnValue_t DeviceHandlerBase::initialize() {
return result;
}
communicationInterface = objectManager->get<DeviceCommunicationIF>(
communicationInterface = ObjectManager::instance()->get<DeviceCommunicationIF>(
deviceCommunicationId);
if (communicationInterface == nullptr) {
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize",
@ -136,7 +136,7 @@ ReturnValue_t DeviceHandlerBase::initialize() {
return result;
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
IPCStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == nullptr) {
printWarningOrError(sif::OutputTypes::OUT_ERROR, "initialize",
ObjectManagerIF::CHILD_INIT_FAILED, "IPC Store not set up");
@ -144,8 +144,8 @@ ReturnValue_t DeviceHandlerBase::initialize() {
}
if(rawDataReceiverId != objects::NO_OBJECT) {
AcceptsDeviceResponsesIF *rawReceiver = objectManager->get<
AcceptsDeviceResponsesIF>(rawDataReceiverId);
AcceptsDeviceResponsesIF *rawReceiver = ObjectManager::instance()->
get<AcceptsDeviceResponsesIF>(rawDataReceiverId);
if (rawReceiver == nullptr) {
printWarningOrError(sif::OutputTypes::OUT_ERROR,
@ -164,7 +164,7 @@ ReturnValue_t DeviceHandlerBase::initialize() {
}
if(powerSwitcherId != objects::NO_OBJECT) {
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
powerSwitcher = ObjectManager::instance()->get<PowerSwitchIF>(powerSwitcherId);
if (powerSwitcher == nullptr) {
printWarningOrError(sif::OutputTypes::OUT_ERROR,
"initialize", ObjectManagerIF::CHILD_INIT_FAILED,
@ -226,16 +226,15 @@ ReturnValue_t DeviceHandlerBase::initialize() {
}
void DeviceHandlerBase::decrementDeviceReplyMap() {
for (std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter =
deviceReplyMap.begin(); iter != deviceReplyMap.end(); iter++) {
if (iter->second.delayCycles != 0) {
iter->second.delayCycles--;
if (iter->second.delayCycles == 0) {
if (iter->second.periodic) {
iter->second.delayCycles = iter->second.maxDelayCycles;
for (std::pair<const DeviceCommandId_t, DeviceReplyInfo>& replyPair: deviceReplyMap) {
if (replyPair.second.delayCycles != 0) {
replyPair.second.delayCycles--;
if (replyPair.second.delayCycles == 0) {
if (replyPair.second.periodic) {
replyPair.second.delayCycles = replyPair.second.maxDelayCycles;
}
replyToReply(iter, TIMEOUT);
missedReply(iter->first);
replyToReply(replyPair.first, replyPair.second, TIMEOUT);
missedReply(replyPair.first);
}
}
}
@ -584,17 +583,28 @@ void DeviceHandlerBase::replyToCommand(ReturnValue_t status,
}
}
void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter,
void DeviceHandlerBase::replyToReply(const DeviceCommandId_t command, DeviceReplyInfo& replyInfo,
ReturnValue_t status) {
// No need to check if iter exists, as this is checked by callers.
// If someone else uses the method, add check.
if (iter->second.command == deviceCommandMap.end()) {
if (replyInfo.command == deviceCommandMap.end()) {
//Is most likely periodic reply. Silent return.
return;
}
DeviceCommandInfo* info = &replyInfo.command->second;
if (info == nullptr){
printWarningOrError(sif::OutputTypes::OUT_ERROR,
"replyToReply", HasReturnvaluesIF::RETURN_FAILED,
"Command pointer not found");
return;
}
if (info->expectedReplies > 0){
// Check before to avoid underflow
info->expectedReplies--;
}
// Check if more replies are expected. If so, do nothing.
DeviceCommandInfo* info = &(iter->second.command->second);
if (--info->expectedReplies == 0) {
if (info->expectedReplies == 0) {
// Check if it was transition or internal command.
// Don't send any replies in that case.
if (info->sendReplyTo != NO_COMMANDER) {
@ -602,7 +612,7 @@ void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter,
if(status == HasReturnvaluesIF::RETURN_OK) {
success = true;
}
actionHelper.finish(success, info->sendReplyTo, iter->first, status);
actionHelper.finish(success, info->sendReplyTo, command, status);
}
info->isExecuting = false;
}
@ -801,7 +811,7 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
replyRawReplyIfnotWiretapped(receivedData, foundLen);
triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, foundId);
}
replyToReply(iter, result);
replyToReply(iter->first, iter->second, result);
}
else {
/* Other completion failure messages are created by timeout.

View File

@ -667,7 +667,7 @@ protected:
static const ReturnValue_t CHILD_TIMEOUT = MAKE_RETURN_CODE(0xE0);
static const ReturnValue_t SWITCH_FAILED = MAKE_RETURN_CODE(0xE1);
static const MessageQueueId_t NO_COMMANDER = 0;
static const MessageQueueId_t NO_COMMANDER = MessageQueueIF::NO_QUEUE;
//! Pointer to the raw packet that will be sent.
uint8_t *rawPacket = nullptr;
@ -1195,7 +1195,8 @@ private:
* @foundLen the length of the packet
*/
void handleReply(const uint8_t *data, DeviceCommandId_t id, uint32_t foundLen);
void replyToReply(DeviceReplyMap::iterator iter, ReturnValue_t status);
void replyToReply(const DeviceCommandId_t command, DeviceReplyInfo& replyInfo,
ReturnValue_t status);
/**
* Build and send a command to the device.

View File

@ -1,6 +1,7 @@
#include "DeviceHandlerFailureIsolation.h"
#include "../devicehandlers/DeviceHandlerIF.h"
#include "../objectmanager/ObjectManager.h"
#include "../modes/HasModesIF.h"
#include "../health/HealthTableIF.h"
#include "../power/Fuse.h"
@ -175,7 +176,7 @@ ReturnValue_t DeviceHandlerFailureIsolation::initialize() {
#endif
return result;
}
ConfirmsFailuresIF* power = objectManager->get<ConfirmsFailuresIF>(
ConfirmsFailuresIF* power = ObjectManager::instance()->get<ConfirmsFailuresIF>(
powerConfirmationId);
if (power != nullptr) {
powerConfirmation = power->getEventReceptionQueue();

View File

@ -1,5 +1,5 @@
#include "DeviceHandlerMessage.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
store_address_t DeviceHandlerMessage::getStoreAddress(
const CommandMessage* message) {
@ -70,7 +70,7 @@ void DeviceHandlerMessage::clear(CommandMessage* message) {
case REPLY_RAW_COMMAND:
case REPLY_RAW_REPLY:
case REPLY_DIRECT_COMMAND_DATA: {
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
StorageManagerIF *ipcStore = ObjectManager::instance()->get<StorageManagerIF>(
objects::IPC_STORE);
if (ipcStore != nullptr) {
ipcStore->deleteData(getStoreAddress(message));

View File

@ -156,11 +156,11 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage *messag
sif::info << "0x" << std::hex << std::setw(8) << std::setfill('0') <<
message->getReporter() << std::setfill(' ') << std::dec;
}
sif::info << " report event with ID " << message->getEventId() << std::endl;
sif::info << std::hex << "P1 Hex: 0x" << message->getParameter1() <<
" | P1 Dec: " << std::dec << message->getParameter1() << std::hex <<
" | P2 Hex: 0x" << message->getParameter2() << " | P2 Dec: " << std::dec <<
message->getParameter2() << std::endl;
sif::info << " reported event with ID " << message->getEventId() << std::endl;
sif::debug << translateEvents(message->getEvent()) << " | " <<std::hex << "P1 Hex: 0x" <<
message->getParameter1() << " | P1 Dec: " << std::dec << message->getParameter1() <<
std::hex << " | P2 Hex: 0x" << message->getParameter2() << " | P2 Dec: " <<
std::dec << message->getParameter2() << std::endl;
#else
if (string != 0) {
sif::printInfo("Event Manager: %s reported event with ID %d\n", string,
@ -186,11 +186,11 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage *messag
sif::debug << "0x" << std::hex << std::setw(8) << std::setfill('0') <<
message->getReporter() << std::setfill(' ') << std::dec;
}
sif::debug << " report event with ID " << message->getEventId() << std::endl;
sif::debug << std::hex << "P1 Hex: 0x" << message->getParameter1() <<
" | P1 Dec: " << std::dec << message->getParameter1() << std::hex <<
" | P2 Hex: 0x" << message->getParameter2() << " | P2 Dec: " << std::dec <<
message->getParameter2() << std::endl;
sif::debug << " reported event with ID " << message->getEventId() << std::endl;
sif::debug << translateEvents(message->getEvent()) << " | " <<std::hex << "P1 Hex: 0x" <<
message->getParameter1() << " | P1 Dec: " << std::dec << message->getParameter1() <<
std::hex << " | P2 Hex: 0x" << message->getParameter2() << " | P2 Dec: " <<
std::dec << message->getParameter2() << std::endl;
#else
if (string != 0) {
sif::printDebug("Event Manager: %s reported event with ID %d\n", string,

View File

@ -3,8 +3,7 @@
#include "EventManagerIF.h"
#include "eventmatching/EventMatchTree.h"
#include <FSFWConfig.h>
#include "FSFWConfig.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../objectmanager/SystemObject.h"

View File

@ -3,7 +3,7 @@
#include "EventMessage.h"
#include "eventmatching/eventmatching.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
#include "../ipc/MessageQueueSenderIF.h"
#include "../ipc/MessageQueueIF.h"
#include "../serviceinterface/ServiceInterface.h"
@ -43,7 +43,7 @@ public:
static void triggerEvent(EventMessage* message,
MessageQueueId_t sentFrom = 0) {
if (eventmanagerQueue == MessageQueueIF::NO_QUEUE) {
EventManagerIF *eventmanager = objectManager->get<EventManagerIF>(
EventManagerIF *eventmanager = ObjectManager::instance()->get<EventManagerIF>(
objects::EVENT_MANAGER);
if (eventmanager == nullptr) {
#if FSFW_VERBOSE_LEVEL >= 1

View File

@ -3,7 +3,7 @@
#include "../health/HasHealthIF.h"
#include "../health/HealthMessage.h"
#include "../ipc/QueueFactory.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
FailureIsolationBase::FailureIsolationBase(object_id_t owner,
object_id_t parent, uint8_t messageDepth, uint8_t parameterDomainBase) :
@ -18,7 +18,7 @@ FailureIsolationBase::~FailureIsolationBase() {
}
ReturnValue_t FailureIsolationBase::initialize() {
EventManagerIF* manager = objectManager->get<EventManagerIF>(
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(
objects::EVENT_MANAGER);
if (manager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
@ -36,7 +36,7 @@ ReturnValue_t FailureIsolationBase::initialize() {
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
owner = objectManager->get<HasHealthIF>(ownerId);
owner = ObjectManager::instance()->get<HasHealthIF>(ownerId);
if (owner == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "FailureIsolationBase::intialize: Owner object "
@ -46,7 +46,7 @@ ReturnValue_t FailureIsolationBase::initialize() {
}
}
if (faultTreeParent != objects::NO_OBJECT) {
ConfirmsFailuresIF* parentIF = objectManager->get<ConfirmsFailuresIF>(
ConfirmsFailuresIF* parentIF = ObjectManager::instance()->get<ConfirmsFailuresIF>(
faultTreeParent);
if (parentIF == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1

View File

@ -1,5 +1,5 @@
#include "HealthHelper.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../serviceinterface/ServiceInterface.h"
HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId) :
objectId(objectId), owner(owner) {
@ -37,8 +37,8 @@ void HealthHelper::setParentQueue(MessageQueueId_t parentQueue) {
}
ReturnValue_t HealthHelper::initialize() {
healthTable = objectManager->get<HealthTableIF>(objects::HEALTH_TABLE);
eventSender = objectManager->get<EventReportingProxyIF>(objectId);
healthTable = ObjectManager::instance()->get<HealthTableIF>(objects::HEALTH_TABLE);
eventSender = ObjectManager::instance()->get<EventReportingProxyIF>(objectId);
if (healthTable == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1

View File

@ -1,6 +1,6 @@
#include "HousekeepingMessage.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
#include <cstring>
HousekeepingMessage::~HousekeepingMessage() {}
@ -161,7 +161,7 @@ void HousekeepingMessage::clear(CommandMessage* message) {
case(UPDATE_SNAPSHOT_VARIABLE): {
store_address_t storeId;
getHkDataReply(message, &storeId);
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
StorageManagerIF *ipcStore = ObjectManager::instance()->get<StorageManagerIF>(
objects::IPC_STORE);
if (ipcStore != nullptr) {
ipcStore->deleteData(storeId);

View File

@ -1,5 +1,6 @@
#include "CommandMessageCleaner.h"
#include "../memory/GenericFileSystemMessage.h"
#include "../devicehandlers/DeviceHandlerMessage.h"
#include "../health/HealthMessage.h"
#include "../memory/MemoryMessage.h"
@ -42,6 +43,9 @@ void CommandMessageCleaner::clearCommandMessage(CommandMessage* message) {
case messagetypes::HOUSEKEEPING:
HousekeepingMessage::clear(message);
break;
case messagetypes::FILE_SYSTEM_MESSAGE:
GenericFileSystemMessage::clear(message);
break;
default:
messagetypes::clearMissionMessage(message);
break;

View File

@ -1,5 +1,7 @@
#include "GenericFileSystemMessage.h"
#include "../objectmanager/ObjectManager.h"
#include "../storagemanager/StorageManagerIF.h"
void GenericFileSystemMessage::setCreateFileCommand(CommandMessage* message,
store_address_t storeId) {
@ -130,3 +132,30 @@ bool GenericFileSystemMessage::getReadReply(const CommandMessage *message,
}
return message->getParameter();
}
ReturnValue_t GenericFileSystemMessage::clear(CommandMessage* message) {
switch(message->getCommand()) {
case(CMD_CREATE_FILE):
case(CMD_DELETE_FILE):
case(CMD_CREATE_DIRECTORY):
case(CMD_REPORT_FILE_ATTRIBUTES):
case(REPLY_REPORT_FILE_ATTRIBUTES):
case(CMD_LOCK_FILE):
case(CMD_UNLOCK_FILE):
case(CMD_COPY_FILE):
case(REPLY_READ_FROM_FILE):
case(CMD_READ_FROM_FILE):
case(CMD_APPEND_TO_FILE):
case(CMD_FINISH_APPEND_TO_FILE):
case(REPLY_READ_FINISHED_STOP):
case(REPLY_FINISH_APPEND): {
store_address_t storeId = GenericFileSystemMessage::getStoreId(message);
auto ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
if(ipcStore == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
return ipcStore->deleteData(storeId);
}
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -108,6 +108,8 @@ public:
static ReturnValue_t getFailureReply(const CommandMessage* message,
uint32_t* errorParam = nullptr);
static ReturnValue_t clear(CommandMessage* message);
};
#endif /* MISSION_MEMORY_GENERICFILESYSTEMMESSAGE_H_ */

View File

@ -2,9 +2,9 @@
#include "MemoryMessage.h"
#include "../globalfunctions/CRC.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
#include "../serialize/EndianConverter.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../serviceinterface/ServiceInterface.h"
MemoryHelper::MemoryHelper(HasMemoryIF* workOnThis,
MessageQueueIF* useThisQueue):
@ -187,7 +187,7 @@ ReturnValue_t MemoryHelper::initialize(MessageQueueIF* queueToUse_) {
}
ReturnValue_t MemoryHelper::initialize() {
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
if (ipcStore != nullptr) {
return RETURN_OK;
} else {

View File

@ -1,6 +1,6 @@
#include "MemoryMessage.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
uint32_t MemoryMessage::getAddress(const CommandMessage* message) {
return message->getParameter();
@ -44,7 +44,7 @@ void MemoryMessage::clear(CommandMessage* message) {
switch (message->getCommand()) {
case CMD_MEMORY_LOAD:
case REPLY_MEMORY_DUMP: {
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
StorageManagerIF *ipcStore = ObjectManager::instance()->get<StorageManagerIF>(
objects::IPC_STORE);
if (ipcStore != NULL) {
ipcStore->deleteData(getStoreID(message));

View File

@ -1,13 +1,8 @@
/**
* @file LimitViolationReporter.cpp
* @brief This file defines the LimitViolationReporter class.
* @date 17.07.2014
* @author baetz
*/
#include "LimitViolationReporter.h"
#include "MonitoringIF.h"
#include "ReceivesMonitoringReportsIF.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
#include "../serialize/SerializeAdapter.h"
ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF* data) {
@ -16,7 +11,7 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF
return result;
}
store_address_t storeId;
uint8_t* dataTarget = NULL;
uint8_t* dataTarget = nullptr;
size_t maxSize = data->getSerializedSize();
if (maxSize > MonitoringIF::VIOLATION_REPORT_MAX_SIZE) {
return MonitoringIF::INVALID_SIZE;
@ -38,16 +33,16 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF
ReturnValue_t LimitViolationReporter::checkClassLoaded() {
if (reportQueue == 0) {
ReceivesMonitoringReportsIF* receiver = objectManager->get<
ReceivesMonitoringReportsIF* receiver = ObjectManager::instance()->get<
ReceivesMonitoringReportsIF>(reportingTarget);
if (receiver == NULL) {
if (receiver == nullptr) {
return ObjectManagerIF::NOT_FOUND;
}
reportQueue = receiver->getCommandQueue();
}
if (ipcStore == NULL) {
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (ipcStore == NULL) {
if (ipcStore == nullptr) {
ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
if (ipcStore == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
@ -56,5 +51,5 @@ ReturnValue_t LimitViolationReporter::checkClassLoaded() {
//Lazy initialization.
MessageQueueId_t LimitViolationReporter::reportQueue = 0;
StorageManagerIF* LimitViolationReporter::ipcStore = NULL;
StorageManagerIF* LimitViolationReporter::ipcStore = nullptr;
object_id_t LimitViolationReporter::reportingTarget = 0;

View File

@ -1,5 +1,5 @@
#include "MonitoringMessage.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
MonitoringMessage::~MonitoringMessage() {
}
@ -25,7 +25,7 @@ void MonitoringMessage::clear(CommandMessage* message) {
message->setCommand(CommandMessage::CMD_NONE);
switch (message->getCommand()) {
case MonitoringMessage::LIMIT_VIOLATION_REPORT: {
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
StorageManagerIF *ipcStore = ObjectManager::instance()->get<StorageManagerIF>(
objects::IPC_STORE);
if (ipcStore != NULL) {
ipcStore->deleteData(getStoreId(message));

View File

@ -5,7 +5,7 @@
#include "MonitoringIF.h"
#include "../datapoollocal/localPoolDefinitions.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
#include "../serialize/SerialBufferAdapter.h"
#include "../serialize/SerialFixedArrayListAdapter.h"
#include "../serialize/SerializeElement.h"
@ -71,7 +71,7 @@ private:
}
bool checkAndSetStamper() {
if (timeStamper == nullptr) {
timeStamper = objectManager->get<TimeStamperIF>( timeStamperId );
timeStamper = ObjectManager::instance()->get<TimeStamperIF>( timeStamperId );
if ( timeStamper == nullptr ) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MonitoringReportContent::checkAndSetStamper: "

View File

@ -5,7 +5,7 @@
#include "../datapool/PIDReaderList.h"
#include "../health/HealthTableIF.h"
#include "../parameters/HasParametersIF.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
//SHOULDDO: This is by far not perfect. Could be merged with new Monitor classes. But still, it's over-engineering.
@ -64,7 +64,7 @@ public:
return result;
}
ReturnValue_t initialize() {
healthTable = objectManager->get<HealthTableIF>(objects::HEALTH_TABLE);
healthTable = ObjectManager::instance()->get<HealthTableIF>(objects::HEALTH_TABLE);
if (healthTable == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}

View File

@ -6,11 +6,23 @@
#endif
#include <cstdlib>
ObjectManager::ObjectManager( void (*setProducer)() ):
produceObjects(setProducer) {
//There's nothing special to do in the constructor.
ObjectManager* ObjectManager::objManagerInstance = nullptr;
ObjectManager* ObjectManager::instance() {
if(objManagerInstance == nullptr) {
objManagerInstance = new ObjectManager();
}
return objManagerInstance;
}
void ObjectManager::setObjectFactoryFunction(produce_function_t objFactoryFunc, void *factoryArgs) {
this->objectFactoryFunction = objFactoryFunc;
this->factoryArgs = factoryArgs;
}
ObjectManager::ObjectManager() {}
ObjectManager::~ObjectManager() {
for (auto const& iter : objectList) {
@ -28,10 +40,13 @@ ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) {
return this->RETURN_OK;
} else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "ObjectManager::insert: Object id " << std::hex
<< static_cast<uint32_t>(id) << std::dec
<< " is already in use!" << std::endl;
sif::error << "Terminating program." << std::endl;
sif::error << "ObjectManager::insert: Object ID " << std::hex <<
static_cast<uint32_t>(id) << std::dec << " is already in use!" << std::endl;
sif::error << "Terminating program" << std::endl;
#else
sif::printError("ObjectManager::insert: Object ID 0x%08x is already in use!\n",
static_cast<unsigned int>(id));
sif::printError("Terminating program");
#endif
//This is very severe and difficult to handle in other places.
std::exit(INSERTION_FAILED);
@ -66,12 +81,8 @@ SystemObjectIF* ObjectManager::getSystemObject( object_id_t id ) {
}
}
ObjectManager::ObjectManager() : produceObjects(nullptr) {
}
void ObjectManager::initialize() {
if(produceObjects == nullptr) {
if(objectFactoryFunction == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "ObjectManager::initialize: Passed produceObjects "
"functions is nullptr!" << std::endl;
@ -80,7 +91,7 @@ void ObjectManager::initialize() {
#endif
return;
}
this->produceObjects();
objectFactoryFunction(factoryArgs);
ReturnValue_t result = RETURN_FAILED;
uint32_t errorCount = 0;
for (auto const& it : objectList) {

View File

@ -5,6 +5,7 @@
#include "SystemObjectIF.h"
#include <map>
/**
* @brief This class implements a global object manager.
* @details This manager handles a list of available objects with system-wide
@ -19,44 +20,59 @@
* @author Bastian Baetz
*/
class ObjectManager : public ObjectManagerIF {
private:
//comparison?
/**
* @brief This is the map of all initialized objects in the manager.
* @details Objects in the List must inherit the SystemObjectIF.
*/
std::map<object_id_t, SystemObjectIF*> objectList;
protected:
SystemObjectIF* getSystemObject( object_id_t id );
/**
* @brief This attribute is initialized with the factory function
* that creates new objects.
* @details The function is called if an object was requested with
* getSystemObject, but not found in objectList.
* @param The id of the object to be created.
* @return Returns a pointer to the newly created object or NULL.
*/
void (*produceObjects)();
public:
/**
* @brief Apart from setting the producer function, nothing special
* happens in the constructor.
* @param setProducer A pointer to a factory function.
*/
ObjectManager( void (*produce)() );
ObjectManager();
/**
* @brief In the class's destructor, all objects in the list are deleted.
*/
// SHOULDDO: If, for some reason, deleting an ObjectManager instance is
// required, check if this works.
virtual ~ObjectManager( void );
ReturnValue_t insert( object_id_t id, SystemObjectIF* object );
ReturnValue_t remove( object_id_t id );
void initialize();
void printList();
using produce_function_t = void (*) (void* args);
/**
* Returns the single instance of TaskFactory.
* The implementation of #instance is found in its subclasses.
* Thus, we choose link-time variability of the instance.
*/
static ObjectManager* instance();
void setObjectFactoryFunction(produce_function_t prodFunc, void* args);
template <typename T> T* get( object_id_t id );
/**
* @brief In the class's destructor, all objects in the list are deleted.
*/
virtual ~ObjectManager();
ReturnValue_t insert(object_id_t id, SystemObjectIF* object) override;
ReturnValue_t remove(object_id_t id) override;
void initialize() override;
void printList() override;
protected:
SystemObjectIF* getSystemObject(object_id_t id) override;
/**
* @brief This attribute is initialized with the factory function
* that creates new objects.
* @details The function is called if an object was requested with
* getSystemObject, but not found in objectList.
* @param The id of the object to be created.
* @return Returns a pointer to the newly created object or NULL.
*/
produce_function_t objectFactoryFunction = nullptr;
void* factoryArgs = nullptr;
private:
ObjectManager();
/**
* @brief This is the map of all initialized objects in the manager.
* @details Objects in the List must inherit the SystemObjectIF.
*/
std::map<object_id_t, SystemObjectIF*> objectList;
static ObjectManager* objManagerInstance;
};
// Documentation can be found in the class method declaration above
template <typename T>
T* ObjectManager::get( object_id_t id ) {
SystemObjectIF* temp = this->getSystemObject(id);
return dynamic_cast<T*>(temp);
}
#endif /* FSFW_OBJECTMANAGER_OBJECTMANAGER_H_ */

View File

@ -8,11 +8,11 @@
/**
* @brief This class provides an interface to the global object manager.
* @details This manager handles a list of available objects with system-wide
* relevance, such as device handlers, and TM/TC services. They can be
* inserted, removed and retrieved from the list. On getting the
* object, the call checks if the object implements the requested
* interface.
* @details
* This manager handles a list of available objects with system-wide relevance, such as device
* handlers, and TM/TC services. They can be inserted, removed and retrieved from the list.
* On getting the object, the call checks if the object implements the requested interface.
* This interface does not specify a getter function because templates can't be used in interfaces.
* @author Bastian Baetz
* @ingroup system_objects
*/
@ -21,7 +21,8 @@ public:
static constexpr uint8_t INTERFACE_ID = CLASS_ID::OBJECT_MANAGER_IF;
static constexpr ReturnValue_t INSERTION_FAILED = MAKE_RETURN_CODE( 1 );
static constexpr ReturnValue_t NOT_FOUND = MAKE_RETURN_CODE( 2 );
static constexpr ReturnValue_t CHILD_INIT_FAILED = MAKE_RETURN_CODE( 3 ); //!< Can be used if the initialization of a SystemObject failed.
//!< Can be used if the initialization of a SystemObject failed.
static constexpr ReturnValue_t CHILD_INIT_FAILED = MAKE_RETURN_CODE( 3 );
static constexpr ReturnValue_t INTERNAL_ERR_REPORTER_UNINIT = MAKE_RETURN_CODE( 4 );
protected:
@ -49,22 +50,11 @@ public:
* @li RETURN_OK in case the object was successfully inserted
*/
virtual ReturnValue_t insert( object_id_t id, SystemObjectIF* object ) = 0;
/**
* @brief With the get call, interfaces of an object can be retrieved in
* a type-safe manner.
* @details With the template-based call, the object list is searched with the
* getSystemObject method and afterwards it is checked, if the object
* implements the requested interface (with a dynamic_cast).
* @param id The object id of the requested object.
* @return The method returns a pointer to an object implementing the
* requested interface, or NULL.
*/
template <typename T> T* get( object_id_t id );
/**
* @brief With this call, an object is removed from the list.
* @param id The object id of the object to be removed.
* @return \li NOT_FOUND in case the object was not found
* \li RETURN_OK in case the object was successfully removed
* @return @li NOT_FOUND in case the object was not found
* @li RETURN_OK in case the object was successfully removed
*/
virtual ReturnValue_t remove( object_id_t id ) = 0;
virtual void initialize() = 0;
@ -75,24 +65,4 @@ public:
virtual void printList() = 0;
};
/**
* @brief This is the forward declaration of the global objectManager instance.
*/
// SHOULDDO: maybe put this in the glob namespace to explicitely mark it global?
extern ObjectManagerIF *objectManager;
/*Documentation can be found in the class method declaration above.*/
template <typename T>
T* ObjectManagerIF::get( object_id_t id ) {
if(objectManager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "ObjectManagerIF: Global object manager has not "
"been initialized yet!" << std::endl;
#endif
}
SystemObjectIF* temp = this->getSystemObject(id);
return dynamic_cast<T*>(temp);
}
#endif /* OBJECTMANAGERIF_H_ */

View File

@ -4,18 +4,14 @@
SystemObject::SystemObject(object_id_t setObjectId, bool doRegister) :
objectId(setObjectId), registered(doRegister) {
if (registered) {
if(objectManager != nullptr) {
objectManager->insert(objectId, this);
}
}
if (registered) {
ObjectManager::instance()->insert(objectId, this);
}
}
SystemObject::~SystemObject() {
if (registered) {
if(objectManager != nullptr) {
objectManager->remove(objectId);
}
ObjectManager::instance()->remove(objectId);
}
}

View File

@ -134,71 +134,3 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
/ 3600.;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
//SHOULDDO: works not for dates in the past (might have less leap seconds)
if (timeMutex == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
uint16_t leapSeconds;
ReturnValue_t result = getLeapSeconds(&leapSeconds);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
timeval leapSeconds_timeval = { 0, 0 };
leapSeconds_timeval.tv_sec = leapSeconds;
//initial offset between UTC and TAI
timeval UTCtoTAI1972 = { 10, 0 };
timeval TAItoTT = { 32, 184000 };
*tt = utc + leapSeconds_timeval + UTCtoTAI1972 + TAItoTT;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
if (checkOrCreateClockMutex() != HasReturnvaluesIF::RETURN_OK) {
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t result = timeMutex->lockMutex(MutexIF::TimeoutType::BLOCKING);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
leapSeconds = leapSeconds_;
result = timeMutex->unlockMutex();
return result;
}
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
if (timeMutex == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t result = timeMutex->lockMutex(MutexIF::TimeoutType::BLOCKING);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
*leapSeconds_ = leapSeconds;
result = timeMutex->unlockMutex();
return result;
}
ReturnValue_t Clock::checkOrCreateClockMutex() {
if (timeMutex == NULL) {
MutexFactory* mutexFactory = MutexFactory::instance();
if (mutexFactory == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
timeMutex = mutexFactory->createMutex();
if (timeMutex == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,6 +1,7 @@
#include "FixedTimeslotTask.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../objectmanager/ObjectManager.h"
#include "../../serviceinterface/ServiceInterface.h"
uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = configMINIMAL_STACK_SIZE;
@ -66,8 +67,7 @@ ReturnValue_t FixedTimeslotTask::startTask() {
ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId,
uint32_t slotTimeMs, int8_t executionStep) {
ExecutableObjectIF* handler =
objectManager->get<ExecutableObjectIF>(componentId);
ExecutableObjectIF* handler = ObjectManager::instance()->get<ExecutableObjectIF>(componentId);
if (handler != nullptr) {
pst.addSlot(componentId, slotTimeMs, executionStep, handler, this);
return HasReturnvaluesIF::RETURN_OK;

View File

@ -1,62 +1,62 @@
#include "MessageQueue.h"
#include "QueueMapManager.h"
#include "../../objectmanager/ObjectManagerIF.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../objectmanager/ObjectManager.h"
#include "../../serviceinterface/ServiceInterface.h"
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize):
maxMessageSize(maxMessageSize) {
handle = xQueueCreate(messageDepth, maxMessageSize);
if (handle == nullptr) {
maxMessageSize(maxMessageSize) {
handle = xQueueCreate(messageDepth, maxMessageSize);
if (handle == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::MessageQueue: Creation failed" << std::endl;
sif::error << "Specified Message Depth: " << messageDepth << std::endl;
sif::error << "Specified Maximum Message Size: " << maxMessageSize << std::endl;
sif::error << "MessageQueue::MessageQueue: Creation failed" << std::endl;
sif::error << "Specified Message Depth: " << messageDepth << std::endl;
sif::error << "Specified Maximum Message Size: " << maxMessageSize << std::endl;
#else
sif::printError("MessageQueue::MessageQueue: Creation failed\n");
sif::printError("Specified Message Depth: %d\n", messageDepth);
sif::printError("Specified MAximum Message Size: %d\n", maxMessageSize);
sif::printError("MessageQueue::MessageQueue: Creation failed\n");
sif::printError("Specified Message Depth: %d\n", messageDepth);
sif::printError("Specified MAximum Message Size: %d\n", maxMessageSize);
#endif
}
}
QueueMapManager::instance()->addMessageQueue(handle, &queueId);
}
MessageQueue::~MessageQueue() {
if (handle != nullptr) {
vQueueDelete(handle);
}
if (handle != nullptr) {
vQueueDelete(handle);
}
}
void MessageQueue::switchSystemContext(CallContext callContext) {
this->callContext = callContext;
this->callContext = callContext;
}
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, bool ignoreFault) {
return sendMessageFrom(sendTo, message, this->getId(), ignoreFault);
MessageQueueMessageIF* message, bool ignoreFault) {
return sendMessageFrom(sendTo, message, this->getId(), ignoreFault);
}
ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) {
return sendToDefaultFrom(message, this->getId());
return sendToDefaultFrom(message, this->getId());
}
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
MessageQueueId_t sentFrom, bool ignoreFault) {
return sendMessageFrom(defaultDestination,message,sentFrom,ignoreFault);
MessageQueueId_t sentFrom, bool ignoreFault) {
return sendMessageFrom(defaultDestination,message,sentFrom,ignoreFault);
}
ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
if (this->lastPartner != MessageQueueIF::NO_QUEUE) {
return sendMessageFrom(this->lastPartner, message, this->getId());
} else {
return NO_REPLY_PARTNER;
}
if (this->lastPartner != MessageQueueIF::NO_QUEUE) {
return sendMessageFrom(this->lastPartner, message, this->getId());
} else {
return NO_REPLY_PARTNER;
}
}
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault) {
return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault,
callContext);
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault) {
return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault,
callContext);
}
QueueHandle_t MessageQueue::getNativeQueueHandle() {
@ -66,7 +66,7 @@ QueueHandle_t MessageQueue::getNativeQueueHandle() {
ReturnValue_t MessageQueue::handleSendResult(BaseType_t result, bool ignoreFault) {
if (result != pdPASS) {
if (not ignoreFault) {
InternalErrorReporterIF* internalErrorReporter = objectManager->
InternalErrorReporterIF* internalErrorReporter = ObjectManager::instance()->
get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER);
if (internalErrorReporter != nullptr) {
internalErrorReporter->queueMessageNotSent();
@ -78,51 +78,51 @@ ReturnValue_t MessageQueue::handleSendResult(BaseType_t result, bool ignoreFault
}
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message,
MessageQueueId_t* receivedFrom) {
ReturnValue_t status = this->receiveMessage(message);
if(status == HasReturnvaluesIF::RETURN_OK) {
*receivedFrom = this->lastPartner;
}
return status;
MessageQueueId_t* receivedFrom) {
ReturnValue_t status = this->receiveMessage(message);
if(status == HasReturnvaluesIF::RETURN_OK) {
*receivedFrom = this->lastPartner;
}
return status;
}
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
BaseType_t result = xQueueReceive(handle,reinterpret_cast<void*>(
message->getBuffer()), 0);
if (result == pdPASS){
this->lastPartner = message->getSender();
return HasReturnvaluesIF::RETURN_OK;
} else {
return MessageQueueIF::EMPTY;
}
BaseType_t result = xQueueReceive(handle,reinterpret_cast<void*>(
message->getBuffer()), 0);
if (result == pdPASS){
this->lastPartner = message->getSender();
return HasReturnvaluesIF::RETURN_OK;
} else {
return MessageQueueIF::EMPTY;
}
}
MessageQueueId_t MessageQueue::getLastPartner() const {
return lastPartner;
return lastPartner;
}
ReturnValue_t MessageQueue::flush(uint32_t* count) {
//TODO FreeRTOS does not support flushing partially
//Is always successful
xQueueReset(handle);
return HasReturnvaluesIF::RETURN_OK;
//TODO FreeRTOS does not support flushing partially
//Is always successful
xQueueReset(handle);
return HasReturnvaluesIF::RETURN_OK;
}
MessageQueueId_t MessageQueue::getId() const {
return queueId;
return queueId;
}
void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
defaultDestinationSet = true;
this->defaultDestination = defaultDestination;
defaultDestinationSet = true;
this->defaultDestination = defaultDestination;
}
MessageQueueId_t MessageQueue::getDefaultDestination() const {
return defaultDestination;
return defaultDestination;
}
bool MessageQueue::isDefaultDestinationSet() const {
return defaultDestinationSet;
return defaultDestinationSet;
}
@ -130,15 +130,15 @@ bool MessageQueue::isDefaultDestinationSet() const {
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault, CallContext callContext) {
BaseType_t result = pdFALSE;
if(sendTo == MessageQueueIF::NO_QUEUE) {
BaseType_t result = pdFALSE;
if(sendTo == MessageQueueIF::NO_QUEUE) {
return MessageQueueIF::DESTINATION_INVALID;
}
}
QueueHandle_t destination = QueueMapManager::instance()->getMessageQueue(sendTo);
if(destination == nullptr) {
QueueHandle_t destination = QueueMapManager::instance()->getMessageQueue(sendTo);
if(destination == nullptr) {
return MessageQueueIF::DESTINATION_INVALID;
}
}
message->setSender(sentFrom);
if(callContext == CallContext::TASK) {

View File

@ -35,116 +35,116 @@
* @ingroup message_queue
*/
class MessageQueue : public MessageQueueIF {
friend class MessageQueueSenderIF;
friend class MessageQueueSenderIF;
public:
/**
* @brief The constructor initializes and configures the message queue.
* @details
* By making use of the according operating system call, a message queue
* is created and initialized. The message depth - the maximum number of
* messages to be buffered - may be set with the help of a parameter,
* whereas the message size is automatically set to the maximum message
* queue message size. The operating system sets the message queue id, or
* in case of failure, it is set to zero.
* @param message_depth
* The number of messages to be buffered before passing an error to the
* sender. Default is three.
* @param max_message_size
* With this parameter, the maximum message size can be adjusted.
* This should be left default.
*/
MessageQueue( size_t messageDepth = 3,
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE );
/**
* @brief The constructor initializes and configures the message queue.
* @details
* By making use of the according operating system call, a message queue
* is created and initialized. The message depth - the maximum number of
* messages to be buffered - may be set with the help of a parameter,
* whereas the message size is automatically set to the maximum message
* queue message size. The operating system sets the message queue id, or
* in case of failure, it is set to zero.
* @param message_depth
* The number of messages to be buffered before passing an error to the
* sender. Default is three.
* @param max_message_size
* With this parameter, the maximum message size can be adjusted.
* This should be left default.
*/
MessageQueue( size_t messageDepth = 3,
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE );
/** Copying message queues forbidden */
MessageQueue(const MessageQueue&) = delete;
MessageQueue& operator=(const MessageQueue&) = delete;
/** Copying message queues forbidden */
MessageQueue(const MessageQueue&) = delete;
MessageQueue& operator=(const MessageQueue&) = delete;
/**
* @brief The destructor deletes the formerly created message queue.
* @details This is accomplished by using the delete call provided
* by the operating system.
*/
virtual ~MessageQueue();
/**
* @brief The destructor deletes the formerly created message queue.
* @details This is accomplished by using the delete call provided
* by the operating system.
*/
virtual ~MessageQueue();
/**
* This function is used to switch the call context. This has to be called
* if a message is sent or received from an ISR!
* @param callContext
*/
void switchSystemContext(CallContext callContext);
/**
* This function is used to switch the call context. This has to be called
* if a message is sent or received from an ISR!
* @param callContext
*/
void switchSystemContext(CallContext callContext);
/** MessageQueueIF implementation */
ReturnValue_t sendMessage(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, bool ignoreFault = false) override;
/** MessageQueueIF implementation */
ReturnValue_t sendMessage(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, bool ignoreFault = false) override;
ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override;
ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override;
ReturnValue_t reply(MessageQueueMessageIF* message) override;
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo,
MessageQueueMessageIF* message,
MessageQueueId_t sentFrom = NO_QUEUE,
bool ignoreFault = false) override;
ReturnValue_t reply(MessageQueueMessageIF* message) override;
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo,
MessageQueueMessageIF* message,
MessageQueueId_t sentFrom = NO_QUEUE,
bool ignoreFault = false) override;
virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message,
MessageQueueId_t sentFrom = NO_QUEUE,
bool ignoreFault = false) override;
virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message,
MessageQueueId_t sentFrom = NO_QUEUE,
bool ignoreFault = false) override;
ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
MessageQueueId_t *receivedFrom) override;
ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
MessageQueueId_t *receivedFrom) override;
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override;
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override;
ReturnValue_t flush(uint32_t* count) override;
ReturnValue_t flush(uint32_t* count) override;
MessageQueueId_t getLastPartner() const override;
MessageQueueId_t getLastPartner() const override;
MessageQueueId_t getId() const override;
MessageQueueId_t getId() const override;
void setDefaultDestination(MessageQueueId_t defaultDestination) override;
void setDefaultDestination(MessageQueueId_t defaultDestination) override;
MessageQueueId_t getDefaultDestination() const override;
MessageQueueId_t getDefaultDestination() const override;
bool isDefaultDestinationSet() const override;
bool isDefaultDestinationSet() const override;
QueueHandle_t getNativeQueueHandle();
QueueHandle_t getNativeQueueHandle();
protected:
/**
* @brief Implementation to be called from any send Call within
* MessageQueue and MessageQueueSenderIF.
* @details
* This method takes the message provided, adds the sentFrom information and
* passes it on to the destination provided with an operating system call.
* The OS's return value is returned.
* @param sendTo
* This parameter specifies the message queue id to send the message to.
* @param message
* This is a pointer to a previously created message, which is sent.
* @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.
* @param ignoreFault
* If set to true, the internal software fault counter is not incremented
* if queue is full.
* @param context Specify whether call is made from task or from an ISR.
*/
static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE,
bool ignoreFault=false, CallContext callContext = CallContext::TASK);
/**
* @brief Implementation to be called from any send Call within
* MessageQueue and MessageQueueSenderIF.
* @details
* This method takes the message provided, adds the sentFrom information and
* passes it on to the destination provided with an operating system call.
* The OS's return value is returned.
* @param sendTo
* This parameter specifies the message queue id to send the message to.
* @param message
* This is a pointer to a previously created message, which is sent.
* @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.
* @param ignoreFault
* If set to true, the internal software fault counter is not incremented
* if queue is full.
* @param context Specify whether call is made from task or from an ISR.
*/
static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE,
bool ignoreFault=false, CallContext callContext = CallContext::TASK);
static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault);
static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault);
private:
bool defaultDestinationSet = false;
QueueHandle_t handle;
MessageQueueId_t queueId = MessageQueueIF::NO_QUEUE;
bool defaultDestinationSet = false;
QueueHandle_t handle;
MessageQueueId_t queueId = MessageQueueIF::NO_QUEUE;
MessageQueueId_t defaultDestination = MessageQueueIF::NO_QUEUE;
MessageQueueId_t lastPartner = MessageQueueIF::NO_QUEUE;
const size_t maxMessageSize;
//! Stores the current system context
CallContext callContext = CallContext::TASK;
MessageQueueId_t defaultDestination = MessageQueueIF::NO_QUEUE;
MessageQueueId_t lastPartner = MessageQueueIF::NO_QUEUE;
const size_t maxMessageSize;
//! Stores the current system context
CallContext callContext = CallContext::TASK;
};
#endif /* FSFW_OSAL_FREERTOS_MESSAGEQUEUE_H_ */

View File

@ -1,6 +1,7 @@
#include "PeriodicTask.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../objectmanager/ObjectManager.h"
#include "../../serviceinterface/ServiceInterface.h"
#include "../../tasks/ExecutableObjectIF.h"
PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority,
@ -100,7 +101,7 @@ void PeriodicTask::taskFunctionality() {
}
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(
object);
if (newObject == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1

View File

@ -6,7 +6,7 @@
#include "../../container/SharedRingBuffer.h"
#include "../../ipc/MessageQueueSenderIF.h"
#include "../../ipc/MutexGuard.h"
#include "../../objectmanager/ObjectManagerIF.h"
#include "../../objectmanager/ObjectManager.h"
#include "../../serviceinterface/ServiceInterface.h"
#include "../../tmtcservices/TmTcMessage.h"
@ -41,7 +41,7 @@ ReturnValue_t TcpTmTcServer::initialize() {
return result;
}
tcStore = objectManager->get<StorageManagerIF>(objects::TC_STORE);
tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
if (tcStore == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TcpTmTcServer::initialize: TC store uninitialized!" << std::endl;
@ -51,7 +51,7 @@ ReturnValue_t TcpTmTcServer::initialize() {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
tmtcBridge = objectManager->get<TcpTmTcBridge>(tmtcBridgeId);
tmtcBridge = ObjectManager::instance()->get<TcpTmTcBridge>(tmtcBridgeId);
int retval = 0;
struct addrinfo *addrResult = nullptr;

View File

@ -2,7 +2,8 @@
#include "tcpipHelpers.h"
#include "../../platform.h"
#include "../../globalfunctions/arrayprinter.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../serviceinterface/ServiceInterface.h"
#include "../../objectmanager/ObjectManager.h"
#ifdef PLATFORM_WIN
#include <winsock2.h>
@ -116,7 +117,7 @@ ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
}
ReturnValue_t UdpTcPollingTask::initialize() {
tcStore = objectManager->get<StorageManagerIF>(objects::TC_STORE);
tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
if (tcStore == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "UdpTcPollingTask::initialize: TC store uninitialized!" << std::endl;
@ -124,7 +125,7 @@ ReturnValue_t UdpTcPollingTask::initialize() {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
tmtcBridge = objectManager->get<UdpTmTcBridge>(tmtcBridgeId);
tmtcBridge = ObjectManager::instance()->get<UdpTmTcBridge>(tmtcBridgeId);
if(tmtcBridge == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "UdpTcPollingTask::initialize: Invalid TMTC bridge object!" <<

View File

@ -171,71 +171,3 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
/ 3600.;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
//SHOULDDO: works not for dates in the past (might have less leap seconds)
if (timeMutex == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
uint16_t leapSeconds;
ReturnValue_t result = getLeapSeconds(&leapSeconds);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
timeval leapSeconds_timeval = { 0, 0 };
leapSeconds_timeval.tv_sec = leapSeconds;
//initial offset between UTC and TAI
timeval UTCtoTAI1972 = { 10, 0 };
timeval TAItoTT = { 32, 184000 };
*tt = utc + leapSeconds_timeval + UTCtoTAI1972 + TAItoTT;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t result = timeMutex->lockMutex();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
leapSeconds = leapSeconds_;
result = timeMutex->unlockMutex();
return result;
}
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
if(timeMutex == nullptr){
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t result = timeMutex->lockMutex();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
*leapSeconds_ = leapSeconds;
result = timeMutex->unlockMutex();
return result;
}
ReturnValue_t Clock::checkOrCreateClockMutex(){
if(timeMutex == nullptr){
MutexFactory* mutexFactory = MutexFactory::instance();
if (mutexFactory == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
timeMutex = mutexFactory->createMutex();
if (timeMutex == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,9 +1,11 @@
#include "taskHelpers.h"
#include "../../platform.h"
#include "../../osal/host/FixedTimeslotTask.h"
#include "../../ipc/MutexFactory.h"
#include "../../osal/host/Mutex.h"
#include "../../osal/host/FixedTimeslotTask.h"
#include "../../objectmanager/ObjectManager.h"
#include "../../serviceinterface/ServiceInterface.h"
#include "../../tasks/ExecutableObjectIF.h"
@ -110,7 +112,7 @@ void FixedTimeslotTask::taskFunctionality() {
ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId,
uint32_t slotTimeMs, int8_t executionStep) {
ExecutableObjectIF* executableObject = objectManager->
ExecutableObjectIF* executableObject = ObjectManager::instance()->
get<ExecutableObjectIF>(componentId);
if (executableObject != nullptr) {
pollingSeqTable.addSlot(componentId, slotTimeMs, executionStep,

View File

@ -1,7 +1,8 @@
#include "MessageQueue.h"
#include "QueueMapManager.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../serviceinterface/ServiceInterface.h"
#include "../../objectmanager/ObjectManager.h"
#include "../../ipc/MutexFactory.h"
#include "../../ipc/MutexGuard.h"
@ -13,8 +14,9 @@ MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize):
auto result = QueueMapManager::instance()->addMessageQueue(this, &mqId);
if(result != HasReturnvaluesIF::RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::MessageQueue:"
<< " Could not be created" << std::endl;
sif::error << "MessageQueue::MessageQueue: Could not be created" << std::endl;
#else
sif::printError("MessageQueue::MessageQueue: Could not be created\n");
#endif
}
}
@ -121,9 +123,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
QueueMapManager::instance()->getMessageQueue(sendTo));
if(targetQueue == nullptr) {
if(not ignoreFault) {
InternalErrorReporterIF* internalErrorReporter =
objectManager->get<InternalErrorReporterIF>(
objects::INTERNAL_ERROR_REPORTER);
InternalErrorReporterIF* internalErrorReporter = ObjectManager::instance()->
get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER);
if (internalErrorReporter != nullptr) {
internalErrorReporter->queueMessageNotSent();
}

View File

@ -4,7 +4,8 @@
#include "../../platform.h"
#include "../../ipc/MutexFactory.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../objectmanager/ObjectManager.h"
#include "../../serviceinterface/ServiceInterface.h"
#include "../../tasks/ExecutableObjectIF.h"
#include <thread>
@ -103,7 +104,7 @@ void PeriodicTask::taskFunctionality() {
}
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(
object);
if (newObject == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;

View File

@ -1,4 +1,5 @@
#include "BinarySemaphore.h"
#include "unixUtility.h"
#include "../../serviceinterface/ServiceInterfacePrinter.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
@ -8,154 +9,154 @@
BinarySemaphore::BinarySemaphore() {
// Using unnamed semaphores for now
initSemaphore();
// Using unnamed semaphores for now
initSemaphore();
}
BinarySemaphore::~BinarySemaphore() {
sem_destroy(&handle);
sem_destroy(&handle);
}
BinarySemaphore::BinarySemaphore(BinarySemaphore&& s) {
initSemaphore();
initSemaphore();
}
BinarySemaphore& BinarySemaphore::operator =(
BinarySemaphore&& s) {
initSemaphore();
return * this;
initSemaphore();
return * this;
}
ReturnValue_t BinarySemaphore::acquire(TimeoutType timeoutType,
uint32_t timeoutMs) {
int result = 0;
if(timeoutType == TimeoutType::POLLING) {
result = sem_trywait(&handle);
}
else if(timeoutType == TimeoutType::BLOCKING) {
result = sem_wait(&handle);
}
else if(timeoutType == TimeoutType::WAITING){
timespec timeOut;
clock_gettime(CLOCK_REALTIME, &timeOut);
uint64_t nseconds = timeOut.tv_sec * 1000000000 + timeOut.tv_nsec;
nseconds += timeoutMs * 1000000;
timeOut.tv_sec = nseconds / 1000000000;
timeOut.tv_nsec = nseconds - timeOut.tv_sec * 1000000000;
result = sem_timedwait(&handle, &timeOut);
if(result != 0 and errno == EINVAL) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "BinarySemaphore::acquire: Invalid time value possible"
<< std::endl;
#endif
}
}
if(result == 0) {
return HasReturnvaluesIF::RETURN_OK;
}
uint32_t timeoutMs) {
int result = 0;
if(timeoutType == TimeoutType::POLLING) {
result = sem_trywait(&handle);
}
else if(timeoutType == TimeoutType::BLOCKING) {
result = sem_wait(&handle);
}
else if(timeoutType == TimeoutType::WAITING){
timespec timeOut;
clock_gettime(CLOCK_REALTIME, &timeOut);
uint64_t nseconds = timeOut.tv_sec * 1000000000 + timeOut.tv_nsec;
nseconds += timeoutMs * 1000000;
timeOut.tv_sec = nseconds / 1000000000;
timeOut.tv_nsec = nseconds - timeOut.tv_sec * 1000000000;
result = sem_timedwait(&handle, &timeOut);
if(result != 0 and errno == EINVAL) {
utility::printUnixErrorGeneric(CLASS_NAME, "acquire", "sem_timedwait");
}
}
if(result == 0) {
return HasReturnvaluesIF::RETURN_OK;
}
switch(errno) {
case(EAGAIN):
// Operation could not be performed without blocking (for sem_trywait)
case(ETIMEDOUT):
// Semaphore is 0
return SemaphoreIF::SEMAPHORE_TIMEOUT;
case(EINVAL):
// Semaphore invalid
return SemaphoreIF::SEMAPHORE_INVALID;
case(EINTR):
// Call was interrupted by signal handler
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "BinarySemaphore::acquire: Signal handler interrupted."
"Code " << strerror(errno) << std::endl;
#endif
/* No break */
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
switch(errno) {
case(EAGAIN):
// Operation could not be performed without blocking (for sem_trywait)
case(ETIMEDOUT): {
// Semaphore is 0
utility::printUnixErrorGeneric(CLASS_NAME, "acquire", "ETIMEDOUT");
return SemaphoreIF::SEMAPHORE_TIMEOUT;
}
case(EINVAL): {
// Semaphore invalid
utility::printUnixErrorGeneric(CLASS_NAME, "acquire", "EINVAL");
return SemaphoreIF::SEMAPHORE_INVALID;
}
case(EINTR): {
// Call was interrupted by signal handler
utility::printUnixErrorGeneric(CLASS_NAME, "acquire", "EINTR");
return HasReturnvaluesIF::RETURN_FAILED;
}
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t BinarySemaphore::release() {
return BinarySemaphore::release(&this->handle);
return BinarySemaphore::release(&this->handle);
}
ReturnValue_t BinarySemaphore::release(sem_t *handle) {
ReturnValue_t countResult = checkCount(handle, 1);
if(countResult != HasReturnvaluesIF::RETURN_OK) {
return countResult;
}
ReturnValue_t countResult = checkCount(handle, 1);
if(countResult != HasReturnvaluesIF::RETURN_OK) {
return countResult;
}
int result = sem_post(handle);
if(result == 0) {
return HasReturnvaluesIF::RETURN_OK;
}
int result = sem_post(handle);
if(result == 0) {
return HasReturnvaluesIF::RETURN_OK;
}
switch(errno) {
case(EINVAL):
// Semaphore invalid
return SemaphoreIF::SEMAPHORE_INVALID;
case(EOVERFLOW):
// SEM_MAX_VALUE overflow. This should never happen
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
switch(errno) {
case(EINVAL): {
// Semaphore invalid
utility::printUnixErrorGeneric(CLASS_NAME, "release", "EINVAL");
return SemaphoreIF::SEMAPHORE_INVALID;
}
case(EOVERFLOW): {
// SEM_MAX_VALUE overflow. This should never happen
utility::printUnixErrorGeneric(CLASS_NAME, "release", "EOVERFLOW");
return HasReturnvaluesIF::RETURN_FAILED;
}
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
}
uint8_t BinarySemaphore::getSemaphoreCounter() const {
// And another ugly cast :-D
return getSemaphoreCounter(const_cast<sem_t*>(&this->handle));
// And another ugly cast :-D
return getSemaphoreCounter(const_cast<sem_t*>(&this->handle));
}
uint8_t BinarySemaphore::getSemaphoreCounter(sem_t *handle) {
int value = 0;
int result = sem_getvalue(handle, &value);
if (result == 0) {
return value;
}
else if(result != 0 and errno == EINVAL) {
// Could be called from interrupt, use lightweight printf
sif::printError("BinarySemaphore::getSemaphoreCounter: "
"Invalid semaphore\n");
return 0;
}
else {
// This should never happen.
return 0;
}
int value = 0;
int result = sem_getvalue(handle, &value);
if (result == 0) {
return value;
}
else if(result != 0 and errno == EINVAL) {
// Could be called from interrupt, use lightweight printf
sif::printError("BinarySemaphore::getSemaphoreCounter: "
"Invalid semaphore\n");
return 0;
}
else {
// This should never happen.
return 0;
}
}
void BinarySemaphore::initSemaphore(uint8_t initCount) {
auto result = sem_init(&handle, true, initCount);
if(result == -1) {
switch(errno) {
case(EINVAL):
// Value exceeds SEM_VALUE_MAX
case(ENOSYS): {
// System does not support process-shared semaphores
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "BinarySemaphore: Init failed with "
<< strerror(errno) << std::endl;
#else
sif::printError("BinarySemaphore: Init failed with %s\n",
strerror(errno));
#endif
}
}
}
auto result = sem_init(&handle, true, initCount);
if(result == -1) {
switch(errno) {
case(EINVAL): {
utility::printUnixErrorGeneric(CLASS_NAME, "initSemaphore", "EINVAL");
break;
}
case(ENOSYS): {
// System does not support process-shared semaphores
utility::printUnixErrorGeneric(CLASS_NAME, "initSemaphore", "ENOSYS");
break;
}
}
}
}
ReturnValue_t BinarySemaphore::checkCount(sem_t* handle, uint8_t maxCount) {
int value = getSemaphoreCounter(handle);
if(value >= maxCount) {
if(maxCount == 1 and value > 1) {
// Binary Semaphore special case.
// This is a config error use lightweight printf is this is called
// from an interrupt
printf("BinarySemaphore::release: Value of binary semaphore greater"
" than 1!\n");
return HasReturnvaluesIF::RETURN_FAILED;
}
return SemaphoreIF::SEMAPHORE_NOT_OWNED;
}
return HasReturnvaluesIF::RETURN_OK;
int value = getSemaphoreCounter(handle);
if(value >= maxCount) {
if(maxCount == 1 and value > 1) {
// Binary Semaphore special case.
// This is a config error use lightweight printf is this is called
// from an interrupt
printf("BinarySemaphore::release: Value of binary semaphore greater than 1!\n");
return HasReturnvaluesIF::RETURN_FAILED;
}
return SemaphoreIF::SEMAPHORE_NOT_OWNED;
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -76,6 +76,7 @@ public:
static ReturnValue_t checkCount(sem_t* handle, uint8_t maxCount);
protected:
sem_t handle;
static constexpr const char* CLASS_NAME = "BinarySemaphore";
};
#endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */

View File

@ -15,6 +15,7 @@ target_sources(${LIB_FSFW_NAME}
TaskFactory.cpp
Timer.cpp
tcpipHelpers.cpp
unixUtility.cpp
)
find_package(Threads REQUIRED)

View File

@ -153,71 +153,3 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
/ 3600.;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
//SHOULDDO: works not for dates in the past (might have less leap seconds)
if (timeMutex == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
uint16_t leapSeconds;
ReturnValue_t result = getLeapSeconds(&leapSeconds);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
timeval leapSeconds_timeval = { 0, 0 };
leapSeconds_timeval.tv_sec = leapSeconds;
//initial offset between UTC and TAI
timeval UTCtoTAI1972 = { 10, 0 };
timeval TAItoTT = { 32, 184000 };
*tt = utc + leapSeconds_timeval + UTCtoTAI1972 + TAItoTT;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t result = timeMutex->lockMutex(MutexIF::TimeoutType::BLOCKING);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
leapSeconds = leapSeconds_;
result = timeMutex->unlockMutex();
return result;
}
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
if(timeMutex==NULL){
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t result = timeMutex->lockMutex(MutexIF::TimeoutType::BLOCKING);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
*leapSeconds_ = leapSeconds;
result = timeMutex->unlockMutex();
return result;
}
ReturnValue_t Clock::checkOrCreateClockMutex(){
if(timeMutex == nullptr){
MutexFactory* mutexFactory = MutexFactory::instance();
if (mutexFactory == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
timeMutex = mutexFactory->createMutex();
if (timeMutex == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,58 +1,70 @@
#include "../../osal/linux/CountingSemaphore.h"
#include "CountingSemaphore.h"
#include "unixUtility.h"
#include "../../serviceinterface/ServiceInterface.h"
#include <errno.h>
CountingSemaphore::CountingSemaphore(const uint8_t maxCount, uint8_t initCount):
maxCount(maxCount), initCount(initCount) {
if(initCount > maxCount) {
maxCount(maxCount), initCount(initCount) {
if(initCount > maxCount) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "CountingSemaphoreUsingTask: Max count bigger than "
"intial cout. Setting initial count to max count." << std::endl;
sif::warning << "CountingSemaphoreUsingTask: Max count bigger than "
"intial cout. Setting initial count to max count" << std::endl;
#else
sif::printWarning("CountingSemaphoreUsingTask: Max count bigger than "
"intial cout. Setting initial count to max count\n");
#endif
initCount = maxCount;
}
initCount = maxCount;
}
initSemaphore(initCount);
initSemaphore(initCount);
}
CountingSemaphore::CountingSemaphore(CountingSemaphore&& other):
maxCount(other.maxCount), initCount(other.initCount) {
initSemaphore(initCount);
maxCount(other.maxCount), initCount(other.initCount) {
initSemaphore(initCount);
}
CountingSemaphore& CountingSemaphore::operator =(
CountingSemaphore&& other) {
initSemaphore(other.initCount);
return * this;
CountingSemaphore&& other) {
initSemaphore(other.initCount);
return * this;
}
ReturnValue_t CountingSemaphore::release() {
ReturnValue_t result = checkCount(&handle, maxCount);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return CountingSemaphore::release(&this->handle);
ReturnValue_t result = checkCount(&handle, maxCount);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return CountingSemaphore::release(&this->handle);
}
ReturnValue_t CountingSemaphore::release(sem_t* handle) {
int result = sem_post(handle);
if(result == 0) {
return HasReturnvaluesIF::RETURN_OK;
}
int result = sem_post(handle);
if(result == 0) {
return HasReturnvaluesIF::RETURN_OK;
}
switch(errno) {
case(EINVAL):
// Semaphore invalid
return SemaphoreIF::SEMAPHORE_INVALID;
case(EOVERFLOW):
// SEM_MAX_VALUE overflow. This should never happen
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
switch(errno) {
case(EINVAL): {
// Semaphore invalid
utility::printUnixErrorGeneric("CountingSemaphore", "release", "EINVAL");
return SemaphoreIF::SEMAPHORE_INVALID;
}
case(EOVERFLOW): {
// SEM_MAX_VALUE overflow. This should never happen
utility::printUnixErrorGeneric("CountingSemaphore", "release", "EOVERFLOW");
return SemaphoreIF::SEMAPHORE_INVALID;
}
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
}
uint8_t CountingSemaphore::getMaxCount() const {
return maxCount;
return maxCount;
}

View File

@ -1,5 +1,7 @@
#include "FixedTimeslotTask.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../objectmanager/ObjectManager.h"
#include "../../serviceinterface/ServiceInterface.h"
#include <limits.h>
@ -40,7 +42,7 @@ uint32_t FixedTimeslotTask::getPeriodMs() const {
ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId,
uint32_t slotTimeMs, int8_t executionStep) {
ExecutableObjectIF* executableObject =
objectManager->get<ExecutableObjectIF>(componentId);
ObjectManager::instance()->get<ExecutableObjectIF>(componentId);
if (executableObject != nullptr) {
pst.addSlot(componentId, slotTimeMs, executionStep,
executableObject,this);

View File

@ -1,6 +1,8 @@
#include "MessageQueue.h"
#include "unixUtility.h"
#include "../../serviceinterface/ServiceInterface.h"
#include "../../objectmanager/ObjectManagerIF.h"
#include "../../objectmanager/ObjectManager.h"
#include <fstream>
@ -11,398 +13,380 @@
MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize):
id(MessageQueueIF::NO_QUEUE),lastPartner(MessageQueueIF::NO_QUEUE),
defaultDestination(MessageQueueIF::NO_QUEUE),
maxMessageSize(maxMessageSize) {
//debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl;
mq_attr attributes;
this->id = 0;
//Set attributes
attributes.mq_curmsgs = 0;
attributes.mq_maxmsg = messageDepth;
attributes.mq_msgsize = maxMessageSize;
attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open
//Set the name of the queue. The slash is mandatory!
sprintf(name, "/FSFW_MQ%u\n", queueCounter++);
id(MessageQueueIF::NO_QUEUE),lastPartner(MessageQueueIF::NO_QUEUE),
defaultDestination(MessageQueueIF::NO_QUEUE), maxMessageSize(maxMessageSize) {
mq_attr attributes;
this->id = 0;
//Set attributes
attributes.mq_curmsgs = 0;
attributes.mq_maxmsg = messageDepth;
attributes.mq_msgsize = maxMessageSize;
attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open
//Set the name of the queue. The slash is mandatory!
sprintf(name, "/FSFW_MQ%u\n", queueCounter++);
// Create a nonblocking queue if the name is available (the queue is read
// and writable for the owner as well as the group)
int oflag = O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL;
mode_t mode = S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH;
mqd_t tempId = mq_open(name, oflag, mode, &attributes);
if (tempId == -1) {
handleError(&attributes, messageDepth);
}
else {
//Successful mq_open call
this->id = tempId;
}
// Create a nonblocking queue if the name is available (the queue is read
// and writable for the owner as well as the group)
int oflag = O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL;
mode_t mode = S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH;
mqd_t tempId = mq_open(name, oflag, mode, &attributes);
if (tempId == -1) {
handleOpenError(&attributes, messageDepth);
}
else {
//Successful mq_open call
this->id = tempId;
}
}
MessageQueue::~MessageQueue() {
int status = mq_close(this->id);
if(status != 0){
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::Destructor: mq_close Failed with status: "
<< strerror(errno) <<std::endl;
#endif
}
status = mq_unlink(name);
if(status != 0){
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::Destructor: mq_unlink Failed with status: "
<< strerror(errno) << std::endl;
#endif
}
}
ReturnValue_t MessageQueue::handleError(mq_attr* attributes,
uint32_t messageDepth) {
switch(errno) {
case(EINVAL): {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::MessageQueue: Invalid name or attributes"
" for message size" << std::endl;
#endif
size_t defaultMqMaxMsg = 0;
// Not POSIX conformant, but should work for all UNIX systems.
// Just an additional helpful printout :-)
if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >>
defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) {
/*
See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html
This happens if the msg_max value is not large enough
It is ignored if the executable is run in privileged mode.
Run the unlockRealtime script or grant the mode manually by using:
sudo setcap 'CAP_SYS_RESOURCE=+ep' <pathToBinary>
Persistent solution for session:
echo <newMsgMax> | sudo tee /proc/sys/fs/mqueue/msg_max
Permanent solution:
sudo nano /etc/sysctl.conf
Append at end: fs/mqueue/msg_max = <newMsgMaxLen>
Apply changes with: sudo sysctl -p
*/
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::MessageQueue: Default MQ size "
<< defaultMqMaxMsg << " is too small for requested size "
<< messageDepth << std::endl;
sif::error << "This error can be fixed by setting the maximum "
"allowed message size higher!" << std::endl;
#endif
}
break;
}
case(EEXIST): {
// An error occured during open
// We need to distinguish if it is caused by an already created queue
//There's another queue with the same name
//We unlink the other queue
int status = mq_unlink(name);
if (status != 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "mq_unlink Failed with status: " << strerror(errno)
<< std::endl;
#endif
}
else {
// Successful unlinking, try to open again
mqd_t tempId = mq_open(name,
O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL,
S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes);
if (tempId != -1) {
//Successful mq_open
this->id = tempId;
return HasReturnvaluesIF::RETURN_OK;
}
}
break;
}
default: {
// Failed either the first time or the second time
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::MessageQueue: Creating Queue " << name
<< " failed with status: " << strerror(errno) << std::endl;
#else
sif::printError("MessageQueue::MessageQueue: Creating Queue %s"
" failed with status: %s\n", name, strerror(errno));
#endif
}
}
return HasReturnvaluesIF::RETURN_FAILED;
int status = mq_close(this->id);
if(status != 0){
utility::printUnixErrorGeneric(CLASS_NAME, "~MessageQueue", "close");
}
status = mq_unlink(name);
if(status != 0){
utility::printUnixErrorGeneric(CLASS_NAME, "~MessageQueue", "unlink");
}
}
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, bool ignoreFault) {
return sendMessageFrom(sendTo, message, this->getId(), false);
MessageQueueMessageIF* message, bool ignoreFault) {
return sendMessageFrom(sendTo, message, this->getId(), false);
}
ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) {
return sendToDefaultFrom(message, this->getId());
return sendToDefaultFrom(message, this->getId());
}
ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
if (this->lastPartner != 0) {
return sendMessageFrom(this->lastPartner, message, this->getId());
} else {
return NO_REPLY_PARTNER;
}
if (this->lastPartner != 0) {
return sendMessageFrom(this->lastPartner, message, this->getId());
} else {
return NO_REPLY_PARTNER;
}
}
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message,
MessageQueueId_t* receivedFrom) {
ReturnValue_t status = this->receiveMessage(message);
*receivedFrom = this->lastPartner;
return status;
MessageQueueId_t* receivedFrom) {
ReturnValue_t status = this->receiveMessage(message);
*receivedFrom = this->lastPartner;
return status;
}
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
if(message == nullptr) {
if(message == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::receiveMessage: Message is "
"nullptr!" << std::endl;
sif::error << "MessageQueue::receiveMessage: Message is "
"nullptr!" << std::endl;
#endif
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
if(message->getMaximumMessageSize() < maxMessageSize) {
if(message->getMaximumMessageSize() < maxMessageSize) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::receiveMessage: Message size "
<< message->getMaximumMessageSize()
<< " too small to receive data!" << std::endl;
sif::error << "MessageQueue::receiveMessage: Message size "
<< message->getMaximumMessageSize()
<< " too small to receive data!" << std::endl;
#endif
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
unsigned int messagePriority = 0;
int status = mq_receive(id,reinterpret_cast<char*>(message->getBuffer()),
message->getMaximumMessageSize(),&messagePriority);
if (status > 0) {
this->lastPartner = message->getSender();
//Check size of incoming message.
if (message->getMessageSize() < message->getMinimumMessageSize()) {
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
else if (status==0) {
//Success but no message received
return MessageQueueIF::EMPTY;
}
else {
//No message was received. Keep lastPartner anyway, I might send
//something later. But still, delete packet content.
memset(message->getData(), 0, message->getMaximumDataSize());
switch(errno){
case EAGAIN:
//O_NONBLOCK or MQ_NONBLOCK was set and there are no messages
//currently on the specified queue.
return MessageQueueIF::EMPTY;
case EBADF:
//mqdes doesn't represent a valid queue open for reading.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::receive: configuration error "
<< strerror(errno) << std::endl;
#endif
/*NO BREAK*/
case EINVAL:
/*
* This value indicates one of the following:
* - The pointer to the buffer for storing the received message,
* msg_ptr, is NULL.
* - The number of bytes requested, msg_len is less than zero.
* - msg_len is anything other than the mq_msgsize of the specified
* queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't
* been set in the queue's mq_flags.
*/
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::receive: configuration error "
<< strerror(errno) << std::endl;
#endif
/*NO BREAK*/
case EMSGSIZE:
/*
* This value indicates one of the following:
* - the QNX extended option MQ_READBUF_DYNAMIC hasn't been set,
* and the given msg_len is shorter than the mq_msgsize for
* the given queue.
* - the extended option MQ_READBUF_DYNAMIC has been set, but the
* given msg_len is too short for the message that would have
* been received.
*/
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::receive: configuration error "
<< strerror(errno) << std::endl;
#endif
/*NO BREAK*/
case EINTR:
//The operation was interrupted by a signal.
default:
unsigned int messagePriority = 0;
int status = mq_receive(id,reinterpret_cast<char*>(message->getBuffer()),
message->getMaximumMessageSize(),&messagePriority);
if (status > 0) {
this->lastPartner = message->getSender();
//Check size of incoming message.
if (message->getMessageSize() < message->getMinimumMessageSize()) {
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
else if (status==0) {
//Success but no message received
return MessageQueueIF::EMPTY;
}
else {
//No message was received. Keep lastPartner anyway, I might send
//something later. But still, delete packet content.
memset(message->getData(), 0, message->getMaximumDataSize());
switch(errno){
case EAGAIN:
//O_NONBLOCK or MQ_NONBLOCK was set and there are no messages
//currently on the specified queue.
return MessageQueueIF::EMPTY;
case EBADF: {
//mqdes doesn't represent a valid queue open for reading.
utility::printUnixErrorGeneric(CLASS_NAME, "receiveMessage", "EBADF");
break;
}
case EINVAL: {
/*
* This value indicates one of the following:
* - The pointer to the buffer for storing the received message,
* msg_ptr, is NULL.
* - The number of bytes requested, msg_len is less than zero.
* - msg_len is anything other than the mq_msgsize of the specified
* queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't
* been set in the queue's mq_flags.
*/
utility::printUnixErrorGeneric(CLASS_NAME, "receiveMessage", "EINVAL");
break;
}
case EMSGSIZE: {
/*
* This value indicates one of the following:
* - the QNX extended option MQ_READBUF_DYNAMIC hasn't been set,
* and the given msg_len is shorter than the mq_msgsize for
* the given queue.
* - the extended option MQ_READBUF_DYNAMIC has been set, but the
* given msg_len is too short for the message that would have
* been received.
*/
utility::printUnixErrorGeneric(CLASS_NAME, "receiveMessage", "EMSGSIZE");
break;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
case EINTR: {
//The operation was interrupted by a signal.
utility::printUnixErrorGeneric(CLASS_NAME, "receiveMessage", "EINTR");
break;
}
case ETIMEDOUT: {
//The operation was interrupted by a signal.
utility::printUnixErrorGeneric(CLASS_NAME, "receiveMessage", "ETIMEDOUT");
break;
}
}
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
}
MessageQueueId_t MessageQueue::getLastPartner() const {
return this->lastPartner;
return this->lastPartner;
}
ReturnValue_t MessageQueue::flush(uint32_t* count) {
mq_attr attrib;
int status = mq_getattr(id,&attrib);
if(status != 0){
switch(errno){
case EBADF:
//mqdes doesn't represent a valid message queue.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::flush configuration error, "
"called flush with an invalid queue ID" << std::endl;
#endif
/*NO BREAK*/
case EINVAL:
//mq_attr is NULL
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
}
*count = attrib.mq_curmsgs;
attrib.mq_curmsgs = 0;
status = mq_setattr(id,&attrib,NULL);
if(status != 0){
switch(errno){
case EBADF:
//mqdes doesn't represent a valid message queue.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::flush configuration error, "
"called flush with an invalid queue ID" << std::endl;
#endif
/*NO BREAK*/
case EINVAL:
/*
* This value indicates one of the following:
* - mq_attr is NULL.
* - MQ_MULT_NOTIFY had been set for this queue, and the given
* mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once
* MQ_MULT_NOTIFY has been turned on, it may never be turned off.
*/
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
}
return HasReturnvaluesIF::RETURN_OK;
mq_attr attrib;
int status = mq_getattr(id,&attrib);
if(status != 0){
switch(errno){
case EBADF:
//mqdes doesn't represent a valid message queue.
utility::printUnixErrorGeneric(CLASS_NAME, "flush", "EBADF");
break;
/*NO BREAK*/
case EINVAL:
//mq_attr is NULL
utility::printUnixErrorGeneric(CLASS_NAME, "flush", "EINVAL");
break;
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
*count = attrib.mq_curmsgs;
attrib.mq_curmsgs = 0;
status = mq_setattr(id,&attrib,NULL);
if(status != 0){
switch(errno) {
case EBADF:
//mqdes doesn't represent a valid message queue.
utility::printUnixErrorGeneric(CLASS_NAME, "flush", "EBADF");
break;
case EINVAL:
/*
* This value indicates one of the following:
* - mq_attr is NULL.
* - MQ_MULT_NOTIFY had been set for this queue, and the given
* mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once
* MQ_MULT_NOTIFY has been turned on, it may never be turned off.
*/
utility::printUnixErrorGeneric(CLASS_NAME, "flush", "EINVAL");
break;
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
MessageQueueId_t MessageQueue::getId() const {
return this->id;
return this->id;
}
void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
this->defaultDestination = defaultDestination;
this->defaultDestination = defaultDestination;
}
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
MessageQueueId_t sentFrom, bool ignoreFault) {
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
MessageQueueId_t sentFrom, bool ignoreFault) {
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
}
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault) {
return sendMessageFromMessageQueue(sendTo,message, sentFrom,ignoreFault);
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault) {
return sendMessageFromMessageQueue(sendTo,message, sentFrom,ignoreFault);
}
MessageQueueId_t MessageQueue::getDefaultDestination() const {
return this->defaultDestination;
return this->defaultDestination;
}
bool MessageQueue::isDefaultDestinationSet() const {
return (defaultDestination != NO_QUEUE);
return (defaultDestination != NO_QUEUE);
}
uint16_t MessageQueue::queueCounter = 0;
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
MessageQueueMessageIF *message, MessageQueueId_t sentFrom,
bool ignoreFault) {
if(message == nullptr) {
MessageQueueMessageIF *message, MessageQueueId_t sentFrom,
bool ignoreFault) {
if(message == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::sendMessageFromMessageQueue: Message is "
"nullptr!" << std::endl;
sif::error << "MessageQueue::sendMessageFromMessageQueue: Message is nullptr!" << std::endl;
#else
sif::printError("MessageQueue::sendMessageFromMessageQueue: Message is nullptr!\n");
#endif
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
message->setSender(sentFrom);
int result = mq_send(sendTo,
reinterpret_cast<const char*>(message->getBuffer()),
message->getMessageSize(),0);
message->setSender(sentFrom);
int result = mq_send(sendTo,
reinterpret_cast<const char*>(message->getBuffer()),
message->getMessageSize(),0);
//TODO: Check if we're in ISR.
if (result != 0) {
if(!ignoreFault){
InternalErrorReporterIF* internalErrorReporter =
objectManager->get<InternalErrorReporterIF>(
objects::INTERNAL_ERROR_REPORTER);
if (internalErrorReporter != NULL) {
internalErrorReporter->queueMessageNotSent();
}
}
switch(errno){
case EAGAIN:
//The O_NONBLOCK flag was set when opening the queue, or the
//MQ_NONBLOCK flag was set in its attributes, and the
//specified queue is full.
return MessageQueueIF::FULL;
case EBADF: {
//mq_des doesn't represent a valid message queue descriptor,
//or mq_des wasn't opened for writing.
//TODO: Check if we're in ISR.
if (result != 0) {
if(!ignoreFault){
InternalErrorReporterIF* internalErrorReporter = ObjectManager::instance()->
get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER);
if (internalErrorReporter != NULL) {
internalErrorReporter->queueMessageNotSent();
}
}
switch(errno){
case EAGAIN:
//The O_NONBLOCK flag was set when opening the queue, or the
//MQ_NONBLOCK flag was set in its attributes, and the
//specified queue is full.
return MessageQueueIF::FULL;
case EBADF: {
//mq_des doesn't represent a valid message queue descriptor,
//or mq_des wasn't opened for writing.
utility::printUnixErrorGeneric(CLASS_NAME, "sendMessageFromMessageQueue", "EBADF");
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::sendMessage: Configuration error, MQ"
<< " destination invalid." << std::endl;
sif::error << strerror(errno) << " in "
<<"mq_send to: " << sendTo << " sent from "
<< sentFrom << std::endl;
sif::warning << "mq_send to: " << sendTo << " sent from "
<< sentFrom << "failed" << std::endl;
#else
sif::printWarning("mq_send to: %d sent from %d failed\n", sendTo, sentFrom);
#endif
return DESTINATION_INVALID;
}
case EINTR:
//The call was interrupted by a signal.
case EINVAL:
/*
* This value indicates one of the following:
* - msg_ptr is NULL.
* - msg_len is negative.
* - msg_prio is greater than MQ_PRIO_MAX.
* - msg_prio is less than 0.
* - MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, and
* msg_prio is greater than the priority of the calling process.
*/
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::sendMessage: Configuration error "
<< strerror(errno) << " in mq_send" << std::endl;
#endif
/*NO BREAK*/
case EMSGSIZE:
// The msg_len is greater than the msgsize associated with
//the specified queue.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::sendMessage: Size error [" <<
strerror(errno) << "] in mq_send" << std::endl;
#endif
/*NO BREAK*/
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
}
return HasReturnvaluesIF::RETURN_OK;
return DESTINATION_INVALID;
}
case EINTR:
//The call was interrupted by a signal.
utility::printUnixErrorGeneric(CLASS_NAME, "sendMessageFromMessageQueue", "EINTR");
break;
case EINVAL:
/*
* This value indicates one of the following:
* - msg_ptr is NULL.
* - msg_len is negative.
* - msg_prio is greater than MQ_PRIO_MAX.
* - msg_prio is less than 0.
* - MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, and
* msg_prio is greater than the priority of the calling process.
*/
utility::printUnixErrorGeneric(CLASS_NAME, "sendMessageFromMessageQueue", "EINVAL");
break;
case EMSGSIZE:
// The msg_len is greater than the msgsize associated with
//the specified queue.
utility::printUnixErrorGeneric(CLASS_NAME, "sendMessageFromMessageQueue", "EMSGSIZE");
break;
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t MessageQueue::handleOpenError(mq_attr* attributes,
uint32_t messageDepth) {
switch(errno) {
case(EINVAL): {
utility::printUnixErrorGeneric(CLASS_NAME, "MessageQueue", "EINVAL");
size_t defaultMqMaxMsg = 0;
// Not POSIX conformant, but should work for all UNIX systems.
// Just an additional helpful printout :-)
if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >>
defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) {
/*
See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html
This happens if the msg_max value is not large enough
It is ignored if the executable is run in privileged mode.
Run the unlockRealtime script or grant the mode manually by using:
sudo setcap 'CAP_SYS_RESOURCE=+ep' <pathToBinary>
Persistent solution for session:
echo <newMsgMax> | sudo tee /proc/sys/fs/mqueue/msg_max
Permanent solution:
sudo nano /etc/sysctl.conf
Append at end: fs/mqueue/msg_max = <newMsgMaxLen>
Apply changes with: sudo sysctl -p
*/
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "MessageQueue::MessageQueue: Default MQ size " << defaultMqMaxMsg <<
" is too small for requested size " << messageDepth << std::endl;
sif::error << "This error can be fixed by setting the maximum "
"allowed message size higher!" << std::endl;
#else
sif::printError("MessageQueue::MessageQueue: Default MQ size %d is too small for"
"requested size %d\n");
sif::printError("This error can be fixes by setting the maximum allowed"
"message size higher!\n");
#endif
}
break;
}
case(EEXIST): {
// An error occured during open.
// We need to distinguish if it is caused by an already created queue
// There's another queue with the same name
// We unlink the other queue
int status = mq_unlink(name);
if (status != 0) {
utility::printUnixErrorGeneric(CLASS_NAME, "MessageQueue", "EEXIST");
}
else {
// Successful unlinking, try to open again
mqd_t tempId = mq_open(name,
O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL,
S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes);
if (tempId != -1) {
//Successful mq_open
this->id = tempId;
return HasReturnvaluesIF::RETURN_OK;
}
}
break;
}
default: {
// Failed either the first time or the second time
utility::printUnixErrorGeneric(CLASS_NAME, "MessageQueue", "Unknown");
}
}
return HasReturnvaluesIF::RETURN_FAILED;
}

View File

@ -181,7 +181,8 @@ private:
static uint16_t queueCounter;
const size_t maxMessageSize;
ReturnValue_t handleError(mq_attr* attributes, uint32_t messageDepth);
static constexpr const char* CLASS_NAME = "MessageQueue";
ReturnValue_t handleOpenError(mq_attr* attributes, uint32_t messageDepth);
};
#endif /* FSFW_OSAL_LINUX_MESSAGEQUEUE_H_ */

View File

@ -1,43 +1,34 @@
#include "Mutex.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "unixUtility.h"
#include "../../serviceinterface/ServiceInterface.h"
#include "../../timemanager/Clock.h"
uint8_t Mutex::count = 0;
#include <cstring>
#include <errno.h>
uint8_t Mutex::count = 0;
Mutex::Mutex() {
pthread_mutexattr_t mutexAttr;
int status = pthread_mutexattr_init(&mutexAttr);
if (status != 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Mutex: Attribute init failed with: " << strerror(status) << std::endl;
#endif
utility::printUnixErrorGeneric("Mutex", "Mutex", "pthread_mutexattr_init");
}
status = pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_INHERIT);
if (status != 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Mutex: Attribute set PRIO_INHERIT failed with: " << strerror(status)
<< std::endl;
#endif
utility::printUnixErrorGeneric("Mutex", "Mutex", "pthread_mutexattr_setprotocol");
}
status = pthread_mutex_init(&mutex, &mutexAttr);
if (status != 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Mutex: creation with name, id " << mutex.__data.__count
<< ", " << " failed with " << strerror(status) << std::endl;
#endif
utility::printUnixErrorGeneric("Mutex", "Mutex", "pthread_mutex_init");
}
// After a mutex attributes object has been used to initialize one or more
// mutexes, any function affecting the attributes object
// (including destruction) shall not affect any previously initialized mutexes.
status = pthread_mutexattr_destroy(&mutexAttr);
if (status != 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Mutex: Attribute destroy failed with " << strerror(status) << std::endl;
#endif
utility::printUnixErrorGeneric("Mutex", "Mutex", "pthread_mutexattr_destroy");
}
}

View File

@ -1,8 +1,11 @@
#include "../../tasks/ExecutableObjectIF.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include <errno.h>
#include "PeriodicPosixTask.h"
#include "../../objectmanager/ObjectManager.h"
#include "../../tasks/ExecutableObjectIF.h"
#include "../../serviceinterface/ServiceInterface.h"
#include <errno.h>
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_,
size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()):
PosixThread(name_, priority_, stackSize_), objectList(), started(false),
@ -22,12 +25,15 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) {
}
ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(
object);
if (newObject == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
<< " it implements ExecutableObjectIF!" << std::endl;
#else
sif::printError("PeriodicTask::addComponent: Invalid object. Make sure it "
"implements ExecutableObjectIF!\n");
#endif
return HasReturnvaluesIF::RETURN_FAILED;
}
@ -44,9 +50,6 @@ ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) {
ReturnValue_t PeriodicPosixTask::startTask(void) {
started = true;
#if FSFW_CPP_OSTREAM_ENABLED == 1
//sif::info << stackSize << std::endl;
#endif
PosixThread::createTask(&taskEntryPoint,this);
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,4 +1,5 @@
#include "PosixThread.h"
#include "unixUtility.h"
#include "../../serviceinterface/ServiceInterface.h"
@ -6,263 +7,240 @@
#include <errno.h>
PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_):
thread(0), priority(priority_), stackSize(stackSize_) {
thread(0), priority(priority_), stackSize(stackSize_) {
name[0] = '\0';
std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1);
}
PosixThread::~PosixThread() {
//No deletion and no free of Stack Pointer
//No deletion and no free of Stack Pointer
}
ReturnValue_t PosixThread::sleep(uint64_t ns) {
//TODO sleep might be better with timer instead of sleep()
timespec time;
time.tv_sec = ns/1000000000;
time.tv_nsec = ns - time.tv_sec*1e9;
//TODO sleep might be better with timer instead of sleep()
timespec time;
time.tv_sec = ns/1000000000;
time.tv_nsec = ns - time.tv_sec*1e9;
//Remaining Time is not set here
int status = nanosleep(&time,NULL);
if(status != 0){
switch(errno){
case EINTR:
//The nanosleep() function was interrupted by a signal.
return HasReturnvaluesIF::RETURN_FAILED;
case EINVAL:
//The rqtp argument specified a nanosecond value less than zero or
// greater than or equal to 1000 million.
return HasReturnvaluesIF::RETURN_FAILED;
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
//Remaining Time is not set here
int status = nanosleep(&time,NULL);
if(status != 0){
switch(errno){
case EINTR:
//The nanosleep() function was interrupted by a signal.
return HasReturnvaluesIF::RETURN_FAILED;
case EINVAL:
//The rqtp argument specified a nanosecond value less than zero or
// greater than or equal to 1000 million.
return HasReturnvaluesIF::RETURN_FAILED;
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
}
return HasReturnvaluesIF::RETURN_OK;
}
return HasReturnvaluesIF::RETURN_OK;
}
void PosixThread::suspend() {
//Wait for SIGUSR1
int caughtSig = 0;
sigset_t waitSignal;
sigemptyset(&waitSignal);
sigaddset(&waitSignal, SIGUSR1);
sigwait(&waitSignal, &caughtSig);
if (caughtSig != SIGUSR1) {
//Wait for SIGUSR1
int caughtSig = 0;
sigset_t waitSignal;
sigemptyset(&waitSignal);
sigaddset(&waitSignal, SIGUSR1);
sigwait(&waitSignal, &caughtSig);
if (caughtSig != SIGUSR1) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "FixedTimeslotTask: Unknown Signal received: " <<
caughtSig << std::endl;
sif::error << "FixedTimeslotTask::suspend: Unknown Signal received: " << caughtSig <<
std::endl;
#else
sif::printError("FixedTimeslotTask::suspend: Unknown Signal received: %d\n", caughtSig);
#endif
}
}
}
void PosixThread::resume(){
/* Signal the thread to start. Makes sense to call kill to start or? ;)
*
* According to Posix raise(signal) will call pthread_kill(pthread_self(), sig),
* but as the call must be done from the thread itsself this is not possible here
*/
pthread_kill(thread,SIGUSR1);
/* Signal the thread to start. Makes sense to call kill to start or? ;)
*
* According to Posix raise(signal) will call pthread_kill(pthread_self(), sig),
* but as the call must be done from the thread itsself this is not possible here
*/
pthread_kill(thread,SIGUSR1);
}
bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms,
const uint64_t delayTime_ms) {
uint64_t nextTimeToWake_ms;
bool shouldDelay = false;
//Get current Time
const uint64_t currentTime_ms = getCurrentMonotonicTimeMs();
/* Generate the tick time at which the task wants to wake. */
nextTimeToWake_ms = (*prevoiusWakeTime_ms) + delayTime_ms;
const uint64_t delayTime_ms) {
uint64_t nextTimeToWake_ms;
bool shouldDelay = false;
//Get current Time
const uint64_t currentTime_ms = getCurrentMonotonicTimeMs();
/* Generate the tick time at which the task wants to wake. */
nextTimeToWake_ms = (*prevoiusWakeTime_ms) + delayTime_ms;
if (currentTime_ms < *prevoiusWakeTime_ms) {
/* The tick count has overflowed since this function was
if (currentTime_ms < *prevoiusWakeTime_ms) {
/* The tick count has overflowed since this function was
lasted called. In this case the only time we should ever
actually delay is if the wake time has also overflowed,
and the wake time is greater than the tick time. When this
is the case it is as if neither time had overflowed. */
if ((nextTimeToWake_ms < *prevoiusWakeTime_ms)
&& (nextTimeToWake_ms > currentTime_ms)) {
shouldDelay = true;
}
} else {
/* The tick time has not overflowed. In this case we will
if ((nextTimeToWake_ms < *prevoiusWakeTime_ms)
&& (nextTimeToWake_ms > currentTime_ms)) {
shouldDelay = true;
}
} else {
/* The tick time has not overflowed. In this case we will
delay if either the wake time has overflowed, and/or the
tick time is less than the wake time. */
if ((nextTimeToWake_ms < *prevoiusWakeTime_ms)
|| (nextTimeToWake_ms > currentTime_ms)) {
shouldDelay = true;
}
}
if ((nextTimeToWake_ms < *prevoiusWakeTime_ms)
|| (nextTimeToWake_ms > currentTime_ms)) {
shouldDelay = true;
}
}
/* Update the wake time ready for the next call. */
/* Update the wake time ready for the next call. */
(*prevoiusWakeTime_ms) = nextTimeToWake_ms;
(*prevoiusWakeTime_ms) = nextTimeToWake_ms;
if (shouldDelay) {
uint64_t sleepTime = nextTimeToWake_ms - currentTime_ms;
PosixThread::sleep(sleepTime * 1000000ull);
return true;
}
//We are shifting the time in case the deadline was missed like rtems
(*prevoiusWakeTime_ms) = currentTime_ms;
return false;
if (shouldDelay) {
uint64_t sleepTime = nextTimeToWake_ms - currentTime_ms;
PosixThread::sleep(sleepTime * 1000000ull);
return true;
}
//We are shifting the time in case the deadline was missed like rtems
(*prevoiusWakeTime_ms) = currentTime_ms;
return false;
}
uint64_t PosixThread::getCurrentMonotonicTimeMs(){
timespec timeNow;
clock_gettime(CLOCK_MONOTONIC_RAW, &timeNow);
uint64_t currentTime_ms = (uint64_t) timeNow.tv_sec * 1000
+ timeNow.tv_nsec / 1000000;
timespec timeNow;
clock_gettime(CLOCK_MONOTONIC_RAW, &timeNow);
uint64_t currentTime_ms = (uint64_t) timeNow.tv_sec * 1000
+ timeNow.tv_nsec / 1000000;
return currentTime_ms;
return currentTime_ms;
}
void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
//sif::debug << "PosixThread::createTask" << std::endl;
//sif::debug << "PosixThread::createTask" << std::endl;
#endif
/*
* The attr argument points to a pthread_attr_t structure whose contents
/*
* The attr argument points to a pthread_attr_t structure whose contents
are used at thread creation time to determine attributes for the new
thread; this structure is initialized using pthread_attr_init(3) and
related functions. If attr is NULL, then the thread is created with
default attributes.
*/
pthread_attr_t attributes;
int status = pthread_attr_init(&attributes);
if(status != 0){
*/
pthread_attr_t attributes;
int status = pthread_attr_init(&attributes);
if(status != 0){
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_init");
}
void* stackPointer;
status = posix_memalign(&stackPointer, sysconf(_SC_PAGESIZE), stackSize);
if(status != 0) {
if(errno == ENOMEM) {
size_t stackMb = stackSize/10e6;
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Posix Thread attribute init failed with: " <<
strerror(status) << std::endl;
#endif
}
void* stackPointer;
status = posix_memalign(&stackPointer, sysconf(_SC_PAGESIZE), stackSize);
if(status != 0){
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PosixThread::createTask: Stack init failed with: " <<
strerror(status) << std::endl;
#endif
if(errno == ENOMEM) {
size_t stackMb = stackSize/10e6;
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PosixThread::createTask: Insufficient memory for"
" the requested " << stackMb << " MB" << std::endl;
sif::error << "PosixThread::createTask: Insufficient memory for"
" the requested " << stackMb << " MB" << std::endl;
#else
sif::printError("PosixThread::createTask: Insufficient memory for "
"the requested %lu MB\n", static_cast<unsigned long>(stackMb));
sif::printError("PosixThread::createTask: Insufficient memory for "
"the requested %lu MB\n", static_cast<unsigned long>(stackMb));
#endif
}
else if(errno == EINVAL) {
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "ENOMEM");
}
else if(errno == EINVAL) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PosixThread::createTask: Wrong alignment argument!"
<< std::endl;
sif::error << "PosixThread::createTask: Wrong alignment argument!"
<< std::endl;
#else
sif::printError("PosixThread::createTask: "
"Wrong alignment argument!\n");
sif::printError("PosixThread::createTask: Wrong alignment argument!\n");
#endif
}
return;
}
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "EINVAL");
}
return;
}
status = pthread_attr_setstack(&attributes, stackPointer, stackSize);
if(status != 0){
status = pthread_attr_setstack(&attributes, stackPointer, stackSize);
if(status != 0) {
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setstack");
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PosixThread::createTask: pthread_attr_setstack "
" failed with: " << strerror(status) << std::endl;
sif::error << "Make sure the specified stack size is valid and is "
"larger than the minimum allowed stack size." << std::endl;
sif::warning << "Make sure the specified stack size is valid and is "
"larger than the minimum allowed stack size." << std::endl;
#else
sif::printWarning("Make sure the specified stack size is valid and is "
"larger than the minimum allowed stack size.\n");
#endif
}
}
status = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED);
if(status != 0){
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Posix Thread attribute setinheritsched failed with: " <<
strerror(status) << std::endl;
#endif
}
status = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED);
if(status != 0){
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setinheritsched");
}
#ifndef FSFW_USE_REALTIME_FOR_LINUX
#error "Please define FSFW_USE_REALTIME_FOR_LINUX with either 0 or 1"
#endif
#if FSFW_USE_REALTIME_FOR_LINUX == 1
// FIFO -> This needs root privileges for the process
status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO);
if(status != 0){
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Posix Thread attribute schedule policy failed with: " <<
strerror(status) << std::endl;
#endif
}
// FIFO -> This needs root privileges for the process
status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO);
if(status != 0){
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedpolicy");
}
sched_param scheduleParams;
scheduleParams.__sched_priority = priority;
status = pthread_attr_setschedparam(&attributes, &scheduleParams);
if(status != 0){
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Posix Thread attribute schedule params failed with: " <<
strerror(status) << std::endl;
sched_param scheduleParams;
scheduleParams.__sched_priority = priority;
status = pthread_attr_setschedparam(&attributes, &scheduleParams);
if(status != 0){
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedparam");
}
#endif
}
#endif
//Set Signal Mask for suspend until startTask is called
sigset_t waitSignal;
sigemptyset(&waitSignal);
sigaddset(&waitSignal, SIGUSR1);
status = pthread_sigmask(SIG_BLOCK, &waitSignal, NULL);
if(status != 0){
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Posix Thread sigmask failed failed with: " <<
strerror(status) << " errno: " << strerror(errno) << std::endl;
#endif
}
//Set Signal Mask for suspend until startTask is called
sigset_t waitSignal;
sigemptyset(&waitSignal);
sigaddset(&waitSignal, SIGUSR1);
status = pthread_sigmask(SIG_BLOCK, &waitSignal, NULL);
if(status != 0){
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_sigmask");
}
status = pthread_create(&thread,&attributes,fnc_,arg_);
if(status != 0){
status = pthread_create(&thread,&attributes,fnc_,arg_);
if(status != 0){
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_create");
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PosixThread::createTask: Failed with: " <<
strerror(status) << std::endl;
sif::error << "For FSFW_USE_REALTIME_FOR_LINUX == 1 make sure to call " <<
"\"all sudo setcap 'cap_sys_nice=eip'\" on the application or set "
"/etc/security/limit.conf" << std::endl;
sif::error << "For FSFW_USE_REALTIME_FOR_LINUX == 1 make sure to call " <<
"\"all sudo setcap 'cap_sys_nice=eip'\" on the application or set "
"/etc/security/limit.conf" << std::endl;
#else
sif::printError("PosixThread::createTask: Create failed with: %s\n", strerror(status));
sif::printError("For FSFW_USE_REALTIME_FOR_LINUX == 1 make sure to call "
"\"all sudo setcap 'cap_sys_nice=eip'\" on the application or set "
sif::printError("For FSFW_USE_REALTIME_FOR_LINUX == 1 make sure to call "
"\"all sudo setcap 'cap_sys_nice=eip'\" on the application or set "
"/etc/security/limit.conf\n");
#endif
}
}
status = pthread_setname_np(thread,name);
if(status != 0){
status = pthread_setname_np(thread,name);
if(status != 0){
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_setname_np");
if(status == ERANGE) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PosixThread::createTask: setname failed with: " <<
strerror(status) << std::endl;
sif::warning << "PosixThread::createTask: Task name length longer"
" than 16 chars. Truncating.." << std::endl;
#else
sif::printWarning("PosixThread::createTask: Task name length longer"
" than 16 chars. Truncating..\n");
#endif
if(status == ERANGE) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PosixThread::createTask: Task name length longer"
" than 16 chars. Truncating.." << std::endl;
#endif
name[15] = '\0';
status = pthread_setname_np(thread,name);
if(status != 0){
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PosixThread::createTask: Setting name"
" did not work.." << std::endl;
#endif
}
}
}
name[15] = '\0';
status = pthread_setname_np(thread,name);
if(status != 0){
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_setname_np");
}
}
}
status = pthread_attr_destroy(&attributes);
if(status!=0){
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Posix Thread attribute destroy failed with: " <<
strerror(status) << std::endl;
#endif
}
status = pthread_attr_destroy(&attributes);
if (status != 0) {
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_destroy");
}
}

View File

@ -9,69 +9,71 @@
class PosixThread {
public:
static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16;
PosixThread(const char* name_, int priority_, size_t stackSize_);
virtual ~PosixThread();
/**
* Set the Thread to sleep state
* @param ns Nanosecond sleep time
* @return Returns Failed if sleep fails
*/
static ReturnValue_t sleep(uint64_t ns);
/**
* @brief Function to suspend the task until SIGUSR1 was received
*
* @details Will be called in the beginning to suspend execution until startTask() is called explicitly.
*/
void suspend();
static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16;
PosixThread(const char* name_, int priority_, size_t stackSize_);
virtual ~PosixThread();
/**
* Set the Thread to sleep state
* @param ns Nanosecond sleep time
* @return Returns Failed if sleep fails
*/
static ReturnValue_t sleep(uint64_t ns);
/**
* @brief Function to suspend the task until SIGUSR1 was received
*
* @details Will be called in the beginning to suspend execution until startTask() is called explicitly.
*/
void suspend();
/**
* @brief Function to allow a other thread to start the thread again from suspend state
*
* @details Restarts the Thread after suspend call
*/
void resume();
/**
* @brief Function to allow a other thread to start the thread again from suspend state
*
* @details Restarts the Thread after suspend call
*/
void resume();
/**
* Delay function similar to FreeRtos delayUntil function
*
* @param prevoiusWakeTime_ms Needs the previous wake time and returns the next wakeup time
* @param delayTime_ms Time period to delay
*
* @return False If deadline was missed; True if task was delayed
*/
static bool delayUntil(uint64_t* const prevoiusWakeTime_ms, const uint64_t delayTime_ms);
/**
* Delay function similar to FreeRtos delayUntil function
*
* @param prevoiusWakeTime_ms Needs the previous wake time and returns the next wakeup time
* @param delayTime_ms Time period to delay
*
* @return False If deadline was missed; True if task was delayed
*/
static bool delayUntil(uint64_t* const prevoiusWakeTime_ms, const uint64_t delayTime_ms);
/**
* Returns the current time in milliseconds from CLOCK_MONOTONIC
*
* @return current time in milliseconds from CLOCK_MONOTONIC
*/
static uint64_t getCurrentMonotonicTimeMs();
/**
* Returns the current time in milliseconds from CLOCK_MONOTONIC
*
* @return current time in milliseconds from CLOCK_MONOTONIC
*/
static uint64_t getCurrentMonotonicTimeMs();
protected:
pthread_t thread;
pthread_t thread;
/**
* @brief Function that has to be called by derived class because the
* derived class pointer has to be valid as argument.
* @details
* This function creates a pthread with the given parameters. As the
* function requires a pointer to the derived object it has to be called
* after the this pointer of the derived object is valid.
* Sets the taskEntryPoint as function to be called by new a thread.
* @param fnc_ Function which will be executed by the thread.
* @param arg_
* argument of the taskEntryPoint function, needs to be this pointer
* of derived class
*/
void createTask(void* (*fnc_)(void*),void* arg_);
/**
* @brief Function that has to be called by derived class because the
* derived class pointer has to be valid as argument.
* @details
* This function creates a pthread with the given parameters. As the
* function requires a pointer to the derived object it has to be called
* after the this pointer of the derived object is valid.
* Sets the taskEntryPoint as function to be called by new a thread.
* @param fnc_ Function which will be executed by the thread.
* @param arg_
* argument of the taskEntryPoint function, needs to be this pointer
* of derived class
*/
void createTask(void* (*fnc_)(void*),void* arg_);
private:
char name[PTHREAD_MAX_NAMELEN];
int priority;
size_t stackSize = 0;
char name[PTHREAD_MAX_NAMELEN];
int priority;
size_t stackSize = 0;
static constexpr const char* CLASS_NAME = "PosixThread";
};
#endif /* FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ */

View File

@ -0,0 +1,32 @@
#include "FSFWConfig.h"
#include "unixUtility.h"
#include "../../serviceinterface/ServiceInterface.h"
#include <cstring>
#include <errno.h>
void utility::printUnixErrorGeneric(const char* const className,
const char* const function, const char* const failString,
sif::OutputTypes outputType) {
if(className == nullptr or failString == nullptr or function == nullptr) {
return;
}
#if FSFW_VERBOSE_LEVEL >= 1
if(outputType == sif::OutputTypes::OUT_ERROR) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << className << "::" << function << ":" << failString << " error: "
<< strerror(errno) << std::endl;
#else
sif::printError("%s::%s: %s error: %s\n", className, function, failString, strerror(errno));
#endif
}
else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << className << "::" << function << ":" << failString << " error: "
<< strerror(errno) << std::endl;
#else
sif::printWarning("%s::%s: %s error: %s\n", className, function, failString, strerror(errno));
#endif
}
#endif
}

13
osal/linux/unixUtility.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef FSFW_OSAL_LINUX_UNIXUTILITY_H_
#define FSFW_OSAL_LINUX_UNIXUTILITY_H_
#include "../../serviceinterface/serviceInterfaceDefintions.h"
namespace utility {
void printUnixErrorGeneric(const char* const className, const char* const function,
const char* const failString, sif::OutputTypes outputType = sif::OutputTypes::OUT_ERROR);
}
#endif /* FSFW_OSAL_LINUX_UNIXUTILITY_H_ */

View File

@ -154,65 +154,3 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
/ 3600.;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
//SHOULDDO: works not for dates in the past (might have less leap seconds)
if (timeMutex == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
uint16_t leapSeconds;
ReturnValue_t result = getLeapSeconds(&leapSeconds);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
timeval leapSeconds_timeval = { 0, 0 };
leapSeconds_timeval.tv_sec = leapSeconds;
//initial offset between UTC and TAI
timeval UTCtoTAI1972 = { 10, 0 };
timeval TAItoTT = { 32, 184000 };
*tt = utc + leapSeconds_timeval + UTCtoTAI1972 + TAItoTT;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){
return HasReturnvaluesIF::RETURN_FAILED;
}
MutexGuard helper(timeMutex);
leapSeconds = leapSeconds_;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
if(timeMutex==nullptr){
return HasReturnvaluesIF::RETURN_FAILED;
}
MutexGuard helper(timeMutex);
*leapSeconds_ = leapSeconds;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Clock::checkOrCreateClockMutex(){
if(timeMutex==nullptr){
MutexFactory* mutexFactory = MutexFactory::instance();
if (mutexFactory == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
timeMutex = mutexFactory->createMutex();
if (timeMutex == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -3,7 +3,7 @@
#include "../../tasks/FixedSequenceSlot.h"
#include "../../objectmanager/SystemObjectIF.h"
#include "../../objectmanager/ObjectManagerIF.h"
#include "../../objectmanager/ObjectManager.h"
#include "../../returnvalues/HasReturnvaluesIF.h"
#include "../../serviceinterface/ServiceInterface.h"
@ -81,7 +81,7 @@ ReturnValue_t FixedTimeslotTask::startTask() {
ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId,
uint32_t slotTimeMs, int8_t executionStep) {
ExecutableObjectIF* object = objectManager->get<ExecutableObjectIF>(componentId);
ExecutableObjectIF* object = ObjectManager::instance()->get<ExecutableObjectIF>(componentId);
if (object != nullptr) {
pst.addSlot(componentId, slotTimeMs, executionStep, object, this);
return HasReturnvaluesIF::RETURN_OK;

View File

@ -1,8 +1,11 @@
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../objectmanager/ObjectManagerIF.h"
#include "MessageQueue.h"
#include "RtemsBasic.h"
#include "../../serviceinterface/ServiceInterface.h"
#include "../../objectmanager/ObjectManager.h"
#include <cstring>
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) :
id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(nullptr) {
rtems_name name = ('Q' << 24) + (queueCounter++ << 8);
@ -94,7 +97,7 @@ ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
//TODO: Check if we're in ISR.
if (result != RTEMS_SUCCESSFUL && !ignoreFault) {
if (internalErrorReporter == nullptr) {
internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
internalErrorReporter = ObjectManager::instance()->get<InternalErrorReporterIF>(
objects::INTERNAL_ERROR_REPORTER);
}
if (internalErrorReporter != nullptr) {

View File

@ -1,6 +1,7 @@
#include "PeriodicTask.h"
#include "../../serviceinterface/ServiceInterface.h"
#include "../../objectmanager/ObjectManager.h"
#include "../../tasks/ExecutableObjectIF.h"
PeriodicTask::PeriodicTask(const char *name, rtems_task_priority setPriority,
@ -68,7 +69,7 @@ void PeriodicTask::taskFunctionality() {
}
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(object);
ExecutableObjectIF* newObject = ObjectManager::instance()->get<ExecutableObjectIF>(object);
if (newObject == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}

View File

@ -1,6 +1,7 @@
#include "ParameterHelper.h"
#include "ParameterMessage.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
ParameterHelper::ParameterHelper(ReceivesParameterMessagesIF* owner):
owner(owner) {}
@ -124,7 +125,7 @@ ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id,
ReturnValue_t ParameterHelper::initialize() {
ownerQueueId = owner->getCommandQueue();
storage = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
storage = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
if (storage == nullptr) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}

View File

@ -1,5 +1,6 @@
#include "../parameters/ParameterMessage.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "ParameterMessage.h"
#include "../objectmanager/ObjectManager.h"
ParameterId_t ParameterMessage::getParameterId(const CommandMessage* message) {
return message->getParameter();
@ -51,7 +52,7 @@ void ParameterMessage::clear(CommandMessage* message) {
switch (message->getCommand()) {
case CMD_PARAMETER_LOAD:
case REPLY_PARAMETER_DUMP: {
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
StorageManagerIF *ipcStore = ObjectManager::instance()->get<StorageManagerIF>(
objects::IPC_STORE);
if (ipcStore != NULL) {
ipcStore->deleteData(getStoreId(message));

View File

@ -2,7 +2,7 @@
#include "../monitoring/LimitViolationReporter.h"
#include "../monitoring/MonitoringMessageContent.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
#include "../serialize/SerialFixedArrayListAdapter.h"
#include "../ipc/QueueFactory.h"
@ -44,7 +44,7 @@ ReturnValue_t Fuse::initialize() {
if (result != RETURN_OK) {
return result;
}
powerIF = objectManager->get<PowerSwitchIF>(powerSwitchId);
powerIF = ObjectManager::instance()->get<PowerSwitchIF>(powerSwitchId);
if (powerIF == NULL) {
return RETURN_FAILED;
}

View File

@ -1,7 +1,7 @@
#include "PowerSwitcher.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../objectmanager/ObjectManager.h"
#include "../serviceinterface/ServiceInterface.h"
PowerSwitcher::PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2,
PowerSwitcher::State_t setStartState):
@ -10,7 +10,7 @@ PowerSwitcher::PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2,
}
ReturnValue_t PowerSwitcher::initialize(object_id_t powerSwitchId) {
power = objectManager->get<PowerSwitchIF>(powerSwitchId);
power = ObjectManager::instance()->get<PowerSwitchIF>(powerSwitchId);
if (power == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}

View File

@ -2,7 +2,8 @@
#include "servicepackets/Service200Packets.h"
#include "../modes/HasModesIF.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../objectmanager/ObjectManager.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../serialize/SerialLinkedListAdapter.h"
#include "../modes/ModeMessage.h"
@ -40,7 +41,7 @@ ReturnValue_t CService200ModeCommanding::getMessageQueueAndObject(
ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t* messageQueueToSet, object_id_t* objectId) {
HasModesIF * destination = objectManager->get<HasModesIF>(*objectId);
HasModesIF * destination = ObjectManager::instance()->get<HasModesIF>(*objectId);
if(destination == nullptr) {
return CommandingServiceBase::INVALID_OBJECT;

View File

@ -1,9 +1,11 @@
#include "CService201HealthCommanding.h"
#include "servicepackets/Service201Packets.h"
#include "../health/HasHealthIF.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../objectmanager/ObjectManager.h"
#include "../health/HealthMessage.h"
#include "servicepackets/Service201Packets.h"
CService201HealthCommanding::CService201HealthCommanding(object_id_t objectId,
uint16_t apid, uint8_t serviceId, uint8_t numParallelCommands,
@ -43,7 +45,7 @@ ReturnValue_t CService201HealthCommanding::getMessageQueueAndObject(
ReturnValue_t CService201HealthCommanding::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t* messageQueueToSet, object_id_t* objectId) {
HasHealthIF * destination = objectManager->get<HasHealthIF>(*objectId);
HasHealthIF * destination = ObjectManager::instance()->get<HasHealthIF>(*objectId);
if(destination == nullptr) {
return CommandingServiceBase::INVALID_OBJECT;
}

View File

@ -3,7 +3,7 @@
#include "../serviceinterface/ServiceInterface.h"
#include "../objectmanager/SystemObject.h"
#include "../tmtcpacket/pus/TmPacketStored.h"
#include "../tmtcpacket/pus/tm/TmPacketStored.h"
Service17Test::Service17Test(object_id_t objectId,

View File

@ -2,8 +2,9 @@
#include "servicepackets/Service1Packets.h"
#include "../ipc/QueueFactory.h"
#include "../objectmanager/ObjectManager.h"
#include "../tmtcservices/PusVerificationReport.h"
#include "../tmtcpacket/pus/TmPacketStored.h"
#include "../tmtcpacket/pus/tm/TmPacketStored.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../tmtcservices/AcceptsTelemetryIF.h"
@ -99,7 +100,7 @@ ReturnValue_t Service1TelecommandVerification::generateSuccessReport(
ReturnValue_t Service1TelecommandVerification::initialize() {
// Get target object for TC verification messages
AcceptsTelemetryIF* funnel = objectManager->
AcceptsTelemetryIF* funnel = ObjectManager::instance()->
get<AcceptsTelemetryIF>(targetDestination);
if(funnel == nullptr){
#if FSFW_CPP_OSTREAM_ENABLED == 1

View File

@ -1,11 +1,11 @@
#include "Service20ParameterManagement.h"
#include "servicepackets/Service20Packets.h"
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/parameters/HasParametersIF.h>
#include <fsfw/parameters/ParameterMessage.h>
#include <fsfw/parameters/ReceivesParameterMessagesIF.h>
#include <tmtc/pusIds.h>
#include "../serviceinterface/ServiceInterface.h"
#include "../parameters/HasParametersIF.h"
#include "../parameters/ParameterMessage.h"
#include "../objectmanager/ObjectManager.h"
#include "../parameters/ReceivesParameterMessagesIF.h"
Service20ParameterManagement::Service20ParameterManagement(object_id_t objectId, uint16_t apid,
@ -65,7 +65,7 @@ ReturnValue_t Service20ParameterManagement::checkInterfaceAndAcquireMessageQueue
MessageQueueId_t* messageQueueToSet, object_id_t* objectId) {
// check ReceivesParameterMessagesIF property of target
ReceivesParameterMessagesIF* possibleTarget =
objectManager->get<ReceivesParameterMessagesIF>(*objectId);
ObjectManager::instance()->get<ReceivesParameterMessagesIF>(*objectId);
if(possibleTarget == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Service20ParameterManagement::checkInterfaceAndAcquire"
@ -133,6 +133,9 @@ ReturnValue_t Service20ParameterManagement::prepareLoadCommand(
store_address_t storeAddress;
size_t parameterDataLen = tcDataLen - sizeof(object_id_t) - sizeof(ParameterId_t) -
sizeof(uint32_t);
if(parameterDataLen == 0) {
return CommandingServiceBase::INVALID_TC;
}
ReturnValue_t result = IPCStore->getFreeElement(&storeAddress,
parameterDataLen, &storePointer);
if(result != HasReturnvaluesIF::RETURN_OK) {

View File

@ -1,7 +1,7 @@
#ifndef FSFW_PUS_SERVICE20PARAMETERMANAGEMENT_H_
#define FSFW_PUS_SERVICE20PARAMETERMANAGEMENT_H_
#include <fsfw/tmtcservices/CommandingServiceBase.h>
#include "../tmtcservices/CommandingServiceBase.h"
/**
* @brief PUS Service 20 Parameter Service implementation

View File

@ -1,6 +1,7 @@
#include "Service2DeviceAccess.h"
#include "servicepackets/Service2Packets.h"
#include "../objectmanager/ObjectManager.h"
#include "../devicehandlers/DeviceHandlerIF.h"
#include "../storagemanager/StorageManagerIF.h"
#include "../devicehandlers/DeviceHandlerMessage.h"
@ -47,7 +48,7 @@ ReturnValue_t Service2DeviceAccess::getMessageQueueAndObject(
ReturnValue_t Service2DeviceAccess::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t * messageQueueToSet, object_id_t *objectId) {
DeviceHandlerIF* possibleTarget =
objectManager->get<DeviceHandlerIF>(*objectId);
ObjectManager::instance()->get<DeviceHandlerIF>(*objectId);
if(possibleTarget == nullptr) {
return CommandingServiceBase::INVALID_OBJECT;
}

View File

@ -1,7 +1,8 @@
#include "Service3Housekeeping.h"
#include "servicepackets/Service3Packets.h"
#include "../datapoollocal/HasLocalDataPoolIF.h"
#include "../objectmanager/ObjectManager.h"
#include "../datapoollocal/HasLocalDataPoolIF.h"
Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid,
uint8_t serviceId):
@ -56,7 +57,7 @@ ReturnValue_t Service3Housekeeping::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t* messageQueueToSet, object_id_t* objectId) {
// check HasLocalDataPoolIF property of target
HasLocalDataPoolIF* possibleTarget =
objectManager->get<HasLocalDataPoolIF>(*objectId);
ObjectManager::instance()->get<HasLocalDataPoolIF>(*objectId);
if(possibleTarget == nullptr){
return CommandingServiceBase::INVALID_OBJECT;
}

View File

@ -1,10 +1,11 @@
#include "Service5EventReporting.h"
#include "servicepackets/Service5Packets.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../objectmanager/ObjectManager.h"
#include "../events/EventManagerIF.h"
#include "../ipc/QueueFactory.h"
#include "../tmtcpacket/pus/TmPacketStored.h"
#include "../tmtcpacket/pus/tm/TmPacketStored.h"
Service5EventReporting::Service5EventReporting(object_id_t objectId,
@ -89,7 +90,7 @@ ReturnValue_t Service5EventReporting::handleRequest(uint8_t subservice) {
// In addition to the default PUSServiceBase initialization, this service needs
// to be registered to the event manager to listen for events.
ReturnValue_t Service5EventReporting::initialize() {
EventManagerIF* manager = objectManager->get<EventManagerIF>(
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(
objects::EVENT_MANAGER);
if (manager == NULL) {
return RETURN_FAILED;

View File

@ -1,11 +1,12 @@
#include "Service8FunctionManagement.h"
#include "servicepackets/Service8Packets.h"
#include "../objectmanager/ObjectManager.h"
#include "../objectmanager/SystemObjectIF.h"
#include "../action/HasActionsIF.h"
#include "../devicehandlers/DeviceHandlerIF.h"
#include "../serialize/SerializeAdapter.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../serviceinterface/ServiceInterface.h"
Service8FunctionManagement::Service8FunctionManagement(object_id_t objectId,
uint16_t apid, uint8_t serviceId, uint8_t numParallelCommands,
@ -41,7 +42,7 @@ ReturnValue_t Service8FunctionManagement::getMessageQueueAndObject(
ReturnValue_t Service8FunctionManagement::checkInterfaceAndAcquireMessageQueue(
MessageQueueId_t* messageQueueToSet, object_id_t* objectId) {
// check HasActionIF property of target
HasActionsIF* possibleTarget = objectManager->get<HasActionsIF>(*objectId);
HasActionsIF* possibleTarget = ObjectManager::instance()->get<HasActionsIF>(*objectId);
if(possibleTarget == nullptr){
return CommandingServiceBase::INVALID_OBJECT;
}

View File

@ -27,12 +27,11 @@ public:
ParameterCommand(uint8_t* storePointer, size_t parameterDataLen):
parameterBuffer(storePointer, parameterDataLen) {
#if FSFW_VERBOSE_LEVEL >= 1
if(parameterDataLen < sizeof(object_id_t) + sizeof(ParameterId_t) + 4) {
if(parameterDataLen == 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "ParameterCommand: Parameter data length is less than 12!"
<< std::endl;
sif::warning << "ParameterCommand: Parameter data length is 0" << std::endl;
#else
sif::printWarning("ParameterCommand: Parameter data length is less than 12!\n");
sif::printWarning("ParameterCommand: Parameter data length is 0!\n");
#endif
}
#endif /* FSFW_VERBOSE_LEVEL >= 1 */

View File

@ -72,6 +72,10 @@ enum: uint8_t {
PUS_SERVICE_3, //PUS3
PUS_SERVICE_9, //PUS9
FILE_SYSTEM, //FILS
HAL_SPI, //HSPI
HAL_UART, //HURT
HAL_I2C, //HI2C
HAL_GPIO, //HGIO
FW_CLASS_ID_COUNT // [EXPORT] : [END]
};

View File

@ -35,7 +35,7 @@ ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string setMessage,
colorPrefix = sif::ANSI_COLOR_GREEN;
}
else if(setMessage.find("WARNING") != std::string::npos) {
colorPrefix = sif::ANSI_COLOR_YELLOW;
colorPrefix = sif::ANSI_COLOR_MAGENTA;
}
else if(setMessage.find("ERROR") != std::string::npos) {
colorPrefix = sif::ANSI_COLOR_RED;
@ -171,6 +171,10 @@ bool ServiceInterfaceBuffer::crAdditionEnabled() const {
return addCrToPreamble;
}
void ServiceInterfaceBuffer::setAsciiColorPrefix(std::string colorPrefix) {
this->colorPrefix = colorPrefix;
}
#ifdef UT699
#include "../osal/rtems/Interrupt.h"

View File

@ -48,6 +48,7 @@ private:
#if FSFW_COLORED_OUTPUT == 1
std::string colorPrefix;
void setAsciiColorPrefix(std::string colorPrefix);
#endif
// For EOF detection

View File

@ -7,6 +7,8 @@
//! https://stackoverflow.com/questions/111928/is-there-a-printf-converter-to-print-in-binary-format
//! Can be used to print out binary numbers in human-readable format.
//! Example usage:
//! sif::printInfo("Status register: " BYTE_TO_BINARY_PATTERN "\n",BYTE_TO_BINARY(0x1f));
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
#define BYTE_TO_BINARY(byte) \
(byte & 0x80 ? '1' : '0'), \

View File

@ -19,5 +19,9 @@ bool ServiceInterfaceStream::crAdditionEnabled() const {
return streambuf.crAdditionEnabled();
}
void ServiceInterfaceStream::setAsciiColorPrefix(std::string asciiColorCode) {
streambuf.setAsciiColorPrefix(asciiColorCode);
}
#endif

View File

@ -46,6 +46,8 @@ public:
*/
bool crAdditionEnabled() const;
void setAsciiColorPrefix(std::string asciiColorCode);
protected:
ServiceInterfaceBuffer streambuf;
};

View File

@ -1,5 +1,8 @@
#include "LocalPool.h"
#include <FSFWConfig.h>
#include "FSFWConfig.h"
#include "../objectmanager/ObjectManager.h"
#include <cstring>
LocalPool::LocalPool(object_id_t setObjectId, const LocalPoolConfig& poolConfig,
@ -185,7 +188,7 @@ ReturnValue_t LocalPool::initialize() {
if (result != RETURN_OK) {
return result;
}
internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
internalErrorReporter = ObjectManager::instance()->get<InternalErrorReporterIF>(
objects::INTERNAL_ERROR_REPORTER);
if (internalErrorReporter == nullptr){
return ObjectManagerIF::INTERNAL_ERR_REPORTER_UNINIT;

View File

@ -1,6 +1,7 @@
#include "Subsystem.h"
#include "../health/HealthMessage.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../objectmanager/ObjectManager.h"
#include "../serialize/SerialArrayListAdapter.h"
#include "../serialize/SerialFixedArrayListAdapter.h"
#include "../serialize/SerializeElement.h"
@ -477,13 +478,13 @@ ReturnValue_t Subsystem::initialize() {
return result;
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
IPCStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == NULL) {
return RETURN_FAILED;
}
#if FSFW_USE_MODESTORE == 1
modeStore = objectManager->get<ModeStoreIF>(objects::MODE_STORE);
modeStore = ObjectManager::instance()->get<ModeStoreIF>(objects::MODE_STORE);
if (modeStore == nullptr) {
return RETURN_FAILED;

View File

@ -1,6 +1,7 @@
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../subsystem/SubsystemBase.h"
#include "SubsystemBase.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../objectmanager/ObjectManager.h"
#include "../ipc/QueueFactory.h"
SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent,
@ -19,10 +20,10 @@ SubsystemBase::~SubsystemBase() {
ReturnValue_t SubsystemBase::registerChild(object_id_t objectId) {
ChildInfo info;
HasModesIF *child = objectManager->get<HasModesIF>(objectId);
HasModesIF *child = ObjectManager::instance()->get<HasModesIF>(objectId);
// This is a rather ugly hack to have the changedHealth info for all
// children available.
HasHealthIF* healthChild = objectManager->get<HasHealthIF>(objectId);
HasHealthIF* healthChild = ObjectManager::instance()->get<HasHealthIF>(objectId);
if (child == nullptr) {
if (healthChild == nullptr) {
return CHILD_DOESNT_HAVE_MODES;
@ -174,7 +175,7 @@ ReturnValue_t SubsystemBase::initialize() {
}
if (parentId != objects::NO_OBJECT) {
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
SubsystemBase *parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
if (parent == nullptr) {
return RETURN_FAILED;
}

View File

@ -1,6 +1,6 @@
#include "ModeSequenceMessage.h"
#include "../../objectmanager/ObjectManagerIF.h"
#include "../../objectmanager/ObjectManager.h"
#include "../../storagemanager/StorageManagerIF.h"
void ModeSequenceMessage::setModeSequenceMessage(CommandMessage* message,
@ -50,7 +50,7 @@ void ModeSequenceMessage::clear(CommandMessage *message) {
case TABLE_LIST:
case TABLE:
case SEQUENCE: {
StorageManagerIF *ipcStore = objectManager->get<StorageManagerIF>(
StorageManagerIF *ipcStore = ObjectManager::instance()->get<StorageManagerIF>(
objects::IPC_STORE);
if (ipcStore != nullptr){
ipcStore->deleteData(ModeSequenceMessage::getStoreAddress(message));

View File

@ -1,5 +1,6 @@
#include "CCSDSDistributor.h"
#include "../objectmanager/ObjectManager.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../tmtcpacket/SpacePacketBase.h"
@ -86,7 +87,7 @@ uint16_t CCSDSDistributor::getIdentifier() {
ReturnValue_t CCSDSDistributor::initialize() {
ReturnValue_t status = this->TcDistributor::initialize();
this->tcStore = objectManager->get<StorageManagerIF>( objects::TC_STORE );
this->tcStore = ObjectManager::instance()->get<StorageManagerIF>( objects::TC_STORE );
if (this->tcStore == nullptr) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1

View File

@ -1,7 +1,6 @@
target_sources(${LIB_FSFW_NAME}
PRIVATE
CCSDSDistributor.cpp
PUSDistributor.cpp
TcDistributor.cpp
TcPacketCheck.cpp
target_sources(${LIB_FSFW_NAME} PRIVATE
CCSDSDistributor.cpp
PUSDistributor.cpp
TcDistributor.cpp
TcPacketCheck.cpp
)

View File

@ -1,8 +1,8 @@
#include "CCSDSDistributorIF.h"
#include "PUSDistributor.h"
#include "../objectmanager/ObjectManager.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../tmtcpacket/pus/TcPacketStored.h"
#include "../tmtcservices/PusVerificationReport.h"
#define PUS_DISTRIBUTOR_DEBUGGING 0
@ -118,14 +118,14 @@ uint16_t PUSDistributor::getIdentifier() {
}
ReturnValue_t PUSDistributor::initialize() {
currentPacket = new TcPacketStored();
currentPacket = new TcPacketStoredPus();
if(currentPacket == nullptr) {
// Should not happen, memory allocation failed!
return ObjectManagerIF::CHILD_INIT_FAILED;
}
CCSDSDistributorIF* ccsdsDistributor =
objectManager->get<CCSDSDistributorIF>(packetSource);
ObjectManager::instance()->get<CCSDSDistributorIF>(packetSource);
if (ccsdsDistributor == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "PUSDistributor::initialize: Packet source invalid" << std::endl;

View File

@ -5,6 +5,7 @@
#include "TcDistributor.h"
#include "TcPacketCheck.h"
#include "../tmtcpacket/pus/tc.h"
#include "../returnvalues/HasReturnvaluesIF.h"
#include "../tmtcservices/AcceptsTelecommandsIF.h"
#include "../tmtcservices/VerificationReporter.h"
@ -51,7 +52,8 @@ protected:
/**
* The currently handled packet is stored here.
*/
TcPacketStored* currentPacket = nullptr;
TcPacketStoredPus* currentPacket = nullptr;
/**
* With this variable, the current check status is stored to generate
* acceptance messages later.

View File

@ -1,39 +1,46 @@
#include "TcPacketCheck.h"
#include "../globalfunctions/CRC.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
#include "../tmtcpacket/pus/tc/TcPacketBase.h"
#include "../tmtcpacket/pus/tc/TcPacketStoredBase.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../storagemanager/StorageManagerIF.h"
#include "../tmtcservices/VerificationCodes.h"
TcPacketCheck::TcPacketCheck( uint16_t setApid ) : apid(setApid) {
TcPacketCheck::TcPacketCheck(uint16_t setApid): apid(setApid) {
}
ReturnValue_t TcPacketCheck::checkPacket( TcPacketStored* currentPacket ) {
uint16_t calculated_crc = CRC::crc16ccitt( currentPacket->getWholeData(),
currentPacket->getFullSize() );
if ( calculated_crc != 0 ) {
return INCORRECT_CHECKSUM;
}
bool condition = (not currentPacket->hasSecondaryHeader()) or
(currentPacket->getPacketVersionNumber() != CCSDS_VERSION_NUMBER) or
(not currentPacket->isTelecommand());
if ( condition ) {
return INCORRECT_PRIMARY_HEADER;
}
if ( currentPacket->getAPID() != this->apid )
return ILLEGAL_APID;
ReturnValue_t TcPacketCheck::checkPacket(TcPacketStoredBase* currentPacket) {
TcPacketBase* tcPacketBase = currentPacket->getPacketBase();
if(tcPacketBase == nullptr) {
return RETURN_FAILED;
}
uint16_t calculated_crc = CRC::crc16ccitt(tcPacketBase->getWholeData(),
tcPacketBase->getFullSize());
if (calculated_crc != 0) {
return INCORRECT_CHECKSUM;
}
bool condition = (not tcPacketBase->hasSecondaryHeader()) or
(tcPacketBase->getPacketVersionNumber() != CCSDS_VERSION_NUMBER) or
(not tcPacketBase->isTelecommand());
if (condition) {
return INCORRECT_PRIMARY_HEADER;
}
if (tcPacketBase->getAPID() != this->apid)
return ILLEGAL_APID;
if ( not currentPacket->isSizeCorrect() ) {
return INCOMPLETE_PACKET;
}
condition = (currentPacket->getSecondaryHeaderFlag() != CCSDS_SECONDARY_HEADER_FLAG) ||
(currentPacket->getPusVersionNumber() != PUS_VERSION_NUMBER);
if ( condition ) {
return INCORRECT_SECONDARY_HEADER;
}
return RETURN_OK;
if (not currentPacket->isSizeCorrect()) {
return INCOMPLETE_PACKET;
}
condition = (tcPacketBase->getSecondaryHeaderFlag() != CCSDS_SECONDARY_HEADER_FLAG) ||
(tcPacketBase->getPusVersionNumber() != PUS_VERSION_NUMBER);
if (condition) {
return INCORRECT_SECONDARY_HEADER;
}
return RETURN_OK;
}
uint16_t TcPacketCheck::getApid() const {
return apid;
return apid;
}

View File

@ -1,10 +1,12 @@
#ifndef FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_
#define FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_
#include "../FSFW.h"
#include "../returnvalues/HasReturnvaluesIF.h"
#include "../tmtcpacket/pus/TcPacketStored.h"
#include "../tmtcservices/PusVerificationReport.h"
class TcPacketStoredBase;
/**
* This class performs a formal packet check for incoming PUS Telecommand Packets.
* Currently, it only checks if the APID and CRC are correct.
@ -12,49 +14,53 @@
*/
class TcPacketCheck : public HasReturnvaluesIF {
protected:
/**
* Describes the version number a packet must have to pass.
*/
static constexpr uint8_t CCSDS_VERSION_NUMBER = 0;
/**
* Describes the secondary header a packet must have to pass.
*/
static constexpr uint8_t CCSDS_SECONDARY_HEADER_FLAG = 0;
/**
* Describes the TC Packet PUS Version Number a packet must have to pass.
*/
static constexpr uint8_t PUS_VERSION_NUMBER = 1;
/**
* The packet id each correct packet should have.
* It is composed of the APID and some static fields.
*/
uint16_t apid;
public:
static const uint8_t INTERFACE_ID = CLASS_ID::TC_PACKET_CHECK;
static const ReturnValue_t ILLEGAL_APID = MAKE_RETURN_CODE( 0 );
static const ReturnValue_t INCOMPLETE_PACKET = MAKE_RETURN_CODE( 1 );
static const ReturnValue_t INCORRECT_CHECKSUM = MAKE_RETURN_CODE( 2 );
static const ReturnValue_t ILLEGAL_PACKET_TYPE = MAKE_RETURN_CODE( 3 );
static const ReturnValue_t ILLEGAL_PACKET_SUBTYPE = MAKE_RETURN_CODE( 4 );
static const ReturnValue_t INCORRECT_PRIMARY_HEADER = MAKE_RETURN_CODE( 5 );
static const ReturnValue_t INCORRECT_SECONDARY_HEADER = MAKE_RETURN_CODE( 6 );
/**
* The constructor only sets the APID attribute.
* @param set_apid The APID to set.
*/
TcPacketCheck( uint16_t setApid );
/**
* This is the actual method to formally check a certain Telecommand Packet.
* The packet's Application Data can not be checked here.
* @param current_packet The packt to check
* @return - @c RETURN_OK on success.
* - @c INCORRECT_CHECKSUM if checksum is invalid.
* - @c ILLEGAL_APID if APID does not match.
*/
ReturnValue_t checkPacket( TcPacketStored* currentPacket );
/**
* Describes the version number a packet must have to pass.
*/
static constexpr uint8_t CCSDS_VERSION_NUMBER = 0;
/**
* Describes the secondary header a packet must have to pass.
*/
static constexpr uint8_t CCSDS_SECONDARY_HEADER_FLAG = 0;
/**
* Describes the TC Packet PUS Version Number a packet must have to pass.
*/
#if FSFW_USE_PUS_C_TELECOMMANDS == 1
static constexpr uint8_t PUS_VERSION_NUMBER = 2;
#else
static constexpr uint8_t PUS_VERSION_NUMBER = 1;
#endif
uint16_t getApid() const;
/**
* The packet id each correct packet should have.
* It is composed of the APID and some static fields.
*/
uint16_t apid;
public:
static const uint8_t INTERFACE_ID = CLASS_ID::TC_PACKET_CHECK;
static const ReturnValue_t ILLEGAL_APID = MAKE_RETURN_CODE( 0 );
static const ReturnValue_t INCOMPLETE_PACKET = MAKE_RETURN_CODE( 1 );
static const ReturnValue_t INCORRECT_CHECKSUM = MAKE_RETURN_CODE( 2 );
static const ReturnValue_t ILLEGAL_PACKET_TYPE = MAKE_RETURN_CODE( 3 );
static const ReturnValue_t ILLEGAL_PACKET_SUBTYPE = MAKE_RETURN_CODE( 4 );
static const ReturnValue_t INCORRECT_PRIMARY_HEADER = MAKE_RETURN_CODE( 5 );
static const ReturnValue_t INCORRECT_SECONDARY_HEADER = MAKE_RETURN_CODE( 6 );
/**
* The constructor only sets the APID attribute.
* @param set_apid The APID to set.
*/
TcPacketCheck(uint16_t setApid);
/**
* This is the actual method to formally check a certain Telecommand Packet.
* The packet's Application Data can not be checked here.
* @param current_packet The packt to check
* @return - @c RETURN_OK on success.
* - @c INCORRECT_CHECKSUM if checksum is invalid.
* - @c ILLEGAL_APID if APID does not match.
*/
ReturnValue_t checkPacket(TcPacketStoredBase* currentPacket);
uint16_t getApid() const;
};
#endif /* FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_ */

View File

@ -1,5 +1,6 @@
#include "Heater.h"
#include "../objectmanager/ObjectManager.h"
#include "../devicehandlers/DeviceHandlerFailureIsolation.h"
#include "../power/Fuse.h"
#include "../ipc/QueueFactory.h"
@ -239,7 +240,7 @@ ReturnValue_t Heater::initialize() {
return result;
}
EventManagerIF* manager = objectManager->get<EventManagerIF>(
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(
objects::EVENT_MANAGER);
if (manager == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
@ -249,7 +250,7 @@ ReturnValue_t Heater::initialize() {
return result;
}
ConfirmsFailuresIF* pcdu = objectManager->get<ConfirmsFailuresIF>(
ConfirmsFailuresIF* pcdu = ObjectManager::instance()->get<ConfirmsFailuresIF>(
DeviceHandlerFailureIsolation::powerConfirmationId);
if (pcdu == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;

View File

@ -5,4 +5,5 @@ target_sources(${LIB_FSFW_NAME}
Stopwatch.cpp
TimeMessage.cpp
TimeStamper.cpp
ClockCommon.cpp
)

View File

@ -41,14 +41,14 @@ public:
* @return -@c RETURN_OK on success. Otherwise, the OS failure code
* is returned.
*/
static ReturnValue_t setClock(const TimeOfDay_t* time);
static ReturnValue_t setClock(const TimeOfDay_t *time);
/**
* This system call sets the system time.
* To set the time, it uses a timeval struct.
* @param time The struct with the time settings to set.
* @return -@c RETURN_OK on success. Otherwise, the OS failure code is returned.
*/
static ReturnValue_t setClock(const timeval* time);
static ReturnValue_t setClock(const timeval *time);
/**
* This system call returns the current system clock in timeval format.
* The timval format has the fields @c tv_sec with seconds and @c tv_usec with
@ -56,7 +56,7 @@ public:
* @param time A pointer to a timeval struct where the current time is stored.
* @return @c RETURN_OK on success. Otherwise, the OS failure code is returned.
*/
static ReturnValue_t getClock_timeval(timeval* time);
static ReturnValue_t getClock_timeval(timeval *time);
/**
* Get the time since boot in a timeval struct
@ -66,7 +66,7 @@ public:
*
* @deprecated, I do not think this should be able to fail, use timeval getUptime()
*/
static ReturnValue_t getUptime(timeval* uptime);
static ReturnValue_t getUptime(timeval *uptime);
static timeval getUptime();
@ -79,7 +79,7 @@ public:
* @param ms uptime in ms
* @return RETURN_OK on success. Otherwise, the OS failure code is returned.
*/
static ReturnValue_t getUptime(uint32_t* uptimeMs);
static ReturnValue_t getUptime(uint32_t *uptimeMs);
/**
* Returns the time in microseconds since an OS-defined epoch.
@ -89,7 +89,7 @@ public:
* - @c RETURN_OK on success.
* - Otherwise, the OS failure code is returned.
*/
static ReturnValue_t getClock_usecs(uint64_t* time);
static ReturnValue_t getClock_usecs(uint64_t *time);
/**
* Returns the time in a TimeOfDay_t struct.
* @param time A pointer to a TimeOfDay_t struct.
@ -97,7 +97,7 @@ public:
* - @c RETURN_OK on success.
* - Otherwise, the OS failure code is returned.
*/
static ReturnValue_t getDateAndTime(TimeOfDay_t* time);
static ReturnValue_t getDateAndTime(TimeOfDay_t *time);
/**
* Converts a time of day struct to POSIX seconds.
@ -107,8 +107,8 @@ public:
* - @c RETURN_OK on success.
* - Otherwise, the OS failure code is returned.
*/
static ReturnValue_t convertTimeOfDayToTimeval(const TimeOfDay_t* from,
timeval* to);
static ReturnValue_t convertTimeOfDayToTimeval(const TimeOfDay_t *from,
timeval *to);
/**
* Converts a time represented as seconds and subseconds since unix
@ -118,12 +118,14 @@ public:
* @param[out] JD2000 days since J2000
* @return @c RETURN_OK
*/
static ReturnValue_t convertTimevalToJD2000(timeval time, double* JD2000);
static ReturnValue_t convertTimevalToJD2000(timeval time, double *JD2000);
/**
* Calculates and adds the offset between UTC and TT
*
* Depends on the leap seconds to be set correctly.
* Therefore, it does not work for historic
* dates as only the current leap seconds are known.
*
* @param utc timeval, corresponding to UTC time
* @param[out] tt timeval, corresponding to Terrestial Time
@ -131,7 +133,7 @@ public:
* - @c RETURN_OK on success
* - @c RETURN_FAILED if leapSeconds are not set
*/
static ReturnValue_t convertUTCToTT(timeval utc, timeval* tt);
static ReturnValue_t convertUTCToTT(timeval utc, timeval *tt);
/**
* Set the Leap Seconds since 1972
@ -139,22 +141,22 @@ public:
* @param leapSeconds_
* @return
* - @c RETURN_OK on success.
* - Otherwise, the OS failure code is returned.
*/
static ReturnValue_t setLeapSeconds(const uint16_t leapSeconds_);
/**
* Get the Leap Seconds since 1972
*
* Must be set before!
* Setter must be called before
*
* @param[out] leapSeconds_
* @return
* - @c RETURN_OK on success.
* - Otherwise, the OS failure code is returned.
* - @c RETURN_FAILED on error
*/
static ReturnValue_t getLeapSeconds(uint16_t *leapSeconds_);
private:
/**
* Function to check and create the Mutex for the clock
* @return
@ -163,10 +165,8 @@ public:
*/
static ReturnValue_t checkOrCreateClockMutex();
private:
static MutexIF* timeMutex;
static MutexIF *timeMutex;
static uint16_t leapSeconds;
};
#endif /* FSFW_TIMEMANAGER_CLOCK_H_ */

Some files were not shown because too many files have changed in this diff Show More