30 Commits

Author SHA1 Message Date
54160e540c fix 2022-06-21 11:15:21 +02:00
b8e06cba99 Merge remote-tracking branch 'origin/master' into mueller/fmt-log 2022-06-21 11:01:00 +02:00
c564fa37fd common cmake files moved to example_common 2022-05-29 18:41:33 +02:00
ff569dd02c bugfixes & use new lwip mempool for FreeRTOS lwip 2022-05-29 17:34:43 +02:00
d34effb278 run auto-formatter 2022-05-22 15:30:08 +02:00
b53aed9cf9 made script more generic 2022-05-22 15:27:54 +02:00
be6e94bf87 added afmt script 2022-05-22 15:25:13 +02:00
8203995deb renamed objects header 2022-05-20 09:16:59 +02:00
4896003e3f afmt 2022-05-20 08:58:42 +02:00
4bb9e9c996 max num scheduled TCS in cmake config now 2022-05-20 08:58:23 +02:00
f17612bd0e auto-fmt 2022-05-20 08:43:12 +02:00
6b81955c85 new definitions file 2022-05-20 08:42:41 +02:00
21e9987636 afmt cmakelists.txt 2022-05-20 08:38:57 +02:00
6814d0cf2b apply auto-formatter 2022-05-20 08:36:12 +02:00
503c6301c6 renamed cmake variable / config define 2022-05-09 02:02:57 +02:00
bdc27d72f4 format fixes 2022-05-09 01:28:41 +02:00
b7fda13b4b complete iostream log replacements 2022-05-09 01:14:53 +02:00
0e619e3327 printout fixes 2022-05-09 00:12:25 +02:00
6f2e03f003 replaced loggers 2022-05-09 00:09:39 +02:00
e1aa39f5e4 i guess no way around exceptions.. 2022-05-08 17:11:43 +02:00
ca501272d8 some refactoring 2022-05-08 02:11:57 +02:00
6984404979 add fmt tests 2022-05-08 02:06:29 +02:00
9d70db97f8 bump subversion 2022-05-05 20:57:30 +02:00
c88a534e1c apply auto-formatter 2022-05-05 20:55:28 +02:00
c2a9db8ac8 clang/clang-tidy improvements 2022-05-02 11:04:43 +02:00
a9fe6f92be bugfix 2022-05-01 17:45:53 +02:00
4b66682c5e mac os change 2022-04-30 19:03:22 +02:00
797801ffde update ctor call 2022-04-11 14:18:20 +02:00
0720dc5121 add FSFW example specific controller 2021-12-14 17:49:19 +01:00
f193608c38 added FSFW test task 2021-11-19 14:12:12 +01:00
59 changed files with 2098 additions and 1793 deletions

View File

@ -1,9 +1,7 @@
add_subdirectory(config)
add_subdirectory(example)
target_include_directories(${TARGET_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
if(TGT_BSP MATCHES "arm/stm32h743zi-nucleo")
add_subdirectory(stm32h7)

45
cmake/BuildType.cmake Normal file
View File

@ -0,0 +1,45 @@
function(set_build_type)
message(STATUS "Used build generator: ${CMAKE_GENERATOR}")
# Set a default build type if none was specified
set(DEFAULT_BUILD_TYPE "RelWithDebInfo")
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
set(DEFAULT_BUILD_TYPE "Debug")
endif()
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS
"Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified."
)
set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE
STRING "Choose the type of build." FORCE
)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo"
)
endif()
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
message(STATUS
"Building Debug application with flags: ${CMAKE_C_FLAGS_DEBUG}"
)
elseif(${CMAKE_BUILD_TYPE} MATCHES "RelWithDebInfo")
message(STATUS
"Building Release (Debug) application with "
"flags: ${CMAKE_C_FLAGS_RELWITHDEBINFO}"
)
elseif(${CMAKE_BUILD_TYPE} MATCHES "MinSizeRel")
message(STATUS
"Building Release (Size) application with "
"flags: ${CMAKE_C_FLAGS_MINSIZEREL}"
)
else()
message(STATUS
"Building Release (Speed) application with "
"flags: ${CMAKE_C_FLAGS_RELEASE}"
)
endif()
endfunction()

42
cmake/common.cmake Normal file
View File

@ -0,0 +1,42 @@
function(get_common_build_flags TGT_NAME)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(COMMON_COMPILE_OPTS
-ffunction-sections
-fdata-sections
PARENT_SCOPE)
set(COMMON_LINK_OPTS
-Wl,--gc-sections
-Wl,-Map=${TARGET_NAME}.map
PARENT_SCOPE)
set(COMMON_WARNING_FLAGS
-Wall
-Wextra
-Wimplicit-fallthrough=1
-Wno-unused-parameter
-Wno-psabi
-Wduplicated-cond # check for duplicate conditions
-Wduplicated-branches # check for duplicate branches
-Wlogical-op # Search for bitwise operations instead of logical
-Wnull-dereference # Search for NULL dereference
-Wundef # Warn if undefind marcos are used
-Wformat=2 # Format string problem detection
-Wformat-overflow=2 # Formatting issues in printf
-Wformat-truncation=2 # Formatting issues in printf
-Wformat-security # Search for dangerous printf operations
-Wstrict-overflow=3 # Warn if integer overflows might happen
-Warray-bounds=2 # Some array bounds violations will be found
-Wshift-overflow=2 # Search for bit left shift overflows (<c++14)
-Wcast-qual # Warn if the constness is cast away
-Wstringop-overflow=4
# -Wstack-protector # Emits a few false positives for low level access
# -Wconversion # Creates many false positives -Warith-conversion # Use
# with Wconversion to find more implicit conversions -fanalyzer # Should
# be used to look through problems
PARENT_SCOPE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
add_compile_options(/permissive- /d2SSAOptimizer-)
# To avoid nameclashes with min and max macro
add_compile_definitions(NOMINMAX)
endif()
endfunction()

View File

@ -1,7 +1,3 @@
target_sources(${TARGET_NAME} PRIVATE
commonPollingSequenceFactory.cpp
)
target_sources(${TARGET_NAME} PRIVATE commonPollingSequenceFactory.cpp)
target_include_directories(${TARGET_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

View File

@ -2,7 +2,7 @@
#define COMMON_OBSWVERSION_H_
#define FSFW_EXAMPLE_VERSION 1
#define FSFW_EXAMPLE_SUBVERSION 4
#define FSFW_EXAMPLE_SUBVERSION 5
#define FSFW_EXAMPLE_REVISION 0
#endif /* COMMON_OBSWVERSION_H_ */

View File

@ -0,0 +1,21 @@
#pragma once
#include <cstdint>
/**
* Enumerations for used PUS service IDs.
*/
namespace pus {
enum ServiceIds : uint8_t {
PUS_SERVICE_1 = 1,
PUS_SERVICE_2 = 2,
PUS_SERVICE_3 = 3,
PUS_SERVICE_5 = 5,
PUS_SERVICE_8 = 8,
PUS_SERVICE_9 = 9,
PUS_SERVICE_11 = 11,
PUS_SERVICE_17 = 17,
PUS_SERVICE_20 = 20,
PUS_SERVICE_200 = 200
};
}

View File

@ -4,9 +4,9 @@
#include "fsfw/returnvalues/FwClassIds.h"
namespace CLASS_ID {
enum commonClassIds: uint8_t {
enum commonClassIds : uint8_t {
COMMON_CLASS_ID_START = FW_CLASS_ID_COUNT,
DUMMY_HANDLER, //DDH
DUMMY_HANDLER, // DDH
COMMON_CLASS_ID_END // [EXPORT] : [END]
};
}

View File

@ -4,11 +4,13 @@
#ifndef COMMON_COMMONCONFIG_H_
#define COMMON_COMMONCONFIG_H_
#include <stdint.h>
#include <cstdint>
#cmakedefine01 OBSW_ADD_FMT_TESTS
//! Specify the debug output verbose level
#define OBSW_VERBOSE_LEVEL 1
#define OBSW_TCPIP_UDP_WIRETAPPING 0
#define OBSW_PRINT_MISSED_DEADLINES 0
//! Perform internal unit testd at application startup
@ -42,24 +44,10 @@ static const uint16_t COMMON_APID = 0xEF;
#ifdef __cplusplus
#include <fsfw/events/fwSubsystemIdRanges.h>
#include <fsfw/returnvalues/FwClassIds.h>
namespace cfg {
static constexpr uint32_t OBSW_MAX_SCHEDULED_TCS = @OBSW_MAX_SCHEDULED_TCS@;
/**
* Enumerations for used PUS service IDs.
*/
namespace pus {
enum ServiceIds: uint8_t {
PUS_SERVICE_1 = 1,
PUS_SERVICE_2 = 2,
PUS_SERVICE_3 = 3,
PUS_SERVICE_5 = 5,
PUS_SERVICE_8 = 8,
PUS_SERVICE_9 = 9,
PUS_SERVICE_17 = 17,
PUS_SERVICE_20 = 20,
PUS_SERVICE_200 = 200
};
}
#endif /* __cplusplus */

39
config/commonObjects.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef COMMON_COMMONSYSTEMOBJECTS_H_
#define COMMON_COMMONSYSTEMOBJECTS_H_
#include <fsfw/objectmanager/frameworkObjects.h>
#include <cstdint>
namespace objects {
enum commonObjects : object_id_t {
/* 0x41 ('A') for Assemblies */
TEST_ASSEMBLY = 0x4100CAFE,
/* 0x43 ('C') for Controllers */
TEST_CONTROLLER = 0x4301CAFE,
/* 0x44 ('D') for Device Handlers */
TEST_DEVICE_HANDLER_0 = 0x4401AFFE,
TEST_DEVICE_HANDLER_1 = 0x4402AFFE,
/* 0x49 ('I') for Communication Interfaces */
TEST_ECHO_COM_IF = 0x4900AFFE,
/* 0x63 ('C') for core objects */
CCSDS_DISTRIBUTOR = 0x63000000,
PUS_DISTRIBUTOR = 0x63000001,
TM_FUNNEL = 0x63000002,
/* 0x74 ('t') for test and example objects */
TEST_TASK = 0x7400CAFE,
TEST_DUMMY_1 = 0x74000001,
TEST_DUMMY_2 = 0x74000002,
TEST_DUMMY_3 = 0x74000003,
TEST_DUMMY_4 = 0x74000004,
TEST_DUMMY_5 = 0x74000005,
};
}
#endif /* COMMON_COMMONSYSTEMOBJECTS_H_ */

View File

@ -1,14 +1,12 @@
#include "pollingsequence/pollingSequenceFactory.h"
#include "objects/systemObjectList.h"
#include "example/test/FsfwExampleTask.h"
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
#include "example/test/FsfwExampleTask.h"
#include "objects/systemObjectList.h"
#include "pollingsequence/pollingSequenceFactory.h"
ReturnValue_t pst::pollingSequenceExamples(FixedTimeslotTaskIF* thisSequence) {
ReturnValue_t pst::pollingSequenceExamples(FixedTimeslotTaskIF *thisSequence) {
uint32_t length = thisSequence->getPeriodMs();
thisSequence->addSlot(objects::TEST_DUMMY_1, length * 0,
@ -34,13 +32,8 @@ ReturnValue_t pst::pollingSequenceExamples(FixedTimeslotTaskIF* thisSequence) {
if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) {
return HasReturnvaluesIF::RETURN_OK;
}
else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "pst::pollingSequenceInitFunction: Initialization errors!" << std::endl;
#else
sif::printError("pst::pollingSequenceInitFunction: Initialization errors!\n");
#endif
} else {
FSFW_LOGE("pst::pollingSequenceInitFunction: Initialization errors\n");
return HasReturnvaluesIF::RETURN_FAILED;
}
}
@ -48,36 +41,35 @@ ReturnValue_t pst::pollingSequenceExamples(FixedTimeslotTaskIF* thisSequence) {
ReturnValue_t pst::pollingSequenceDevices(FixedTimeslotTaskIF *thisSequence) {
uint32_t length = thisSequence->getPeriodMs();
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.3, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.3, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.3 * length,
DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.3 * length,
DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.45 * length,
DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.45 * length,
DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.6 * length, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.6 * length, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.6 * length,
DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.6 * length,
DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.8 * length, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.8 * length, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_0, 0.8 * length,
DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::TEST_DEVICE_HANDLER_1, 0.8 * length,
DeviceHandlerIF::GET_READ);
if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) {
return HasReturnvaluesIF::RETURN_OK;
}
else {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "pst::pollingSequenceTestFunction: Initialization errors!" << std::endl;
#else
sif::printError("pst::pollingSequenceTestFunction: Initialization errors!\n");
#endif
} else {
FSFW_LOGE("pst::pollingSequenceTestFunction: Initialization errors\n");
return HasReturnvaluesIF::RETURN_FAILED;
}
}

View File

@ -7,12 +7,11 @@
* The subsystem IDs will be part of the event IDs used throughout the FSFW.
*/
namespace SUBSYSTEM_ID {
enum commonSubsystemId: uint8_t {
enum commonSubsystemId : uint8_t {
COMMON_SUBSYSTEM_ID_START = FW_SUBSYSTEM_ID_RANGE,
TEST_TASK_ID = 105,
COMMON_SUBSYSTEM_ID_END
};
}
#endif /* COMMON_CONFIG_COMMONSUBSYSTEMIDS_H_ */

View File

@ -1,40 +0,0 @@
#ifndef COMMON_COMMONSYSTEMOBJECTS_H_
#define COMMON_COMMONSYSTEMOBJECTS_H_
#include <cstdint>
#include <fsfw/objectmanager/frameworkObjects.h>
namespace objects {
enum commonObjects: object_id_t {
/* 0x41 ('A') for Assemblies */
TEST_ASSEMBLY = 0x4100CAFE,
/* 0x43 ('C') for Controllers */
TEST_CONTROLLER = 0x4301CAFE,
/* 0x44 ('D') for Device Handlers */
TEST_DEVICE_HANDLER_0 = 0x4401AFFE,
TEST_DEVICE_HANDLER_1 = 0x4402AFFE,
/* 0x49 ('I') for Communication Interfaces */
TEST_ECHO_COM_IF = 0x4900AFFE,
/* 0x63 ('C') for core objects */
CCSDS_DISTRIBUTOR = 0x63000000,
PUS_DISTRIBUTOR = 0x63000001,
TM_FUNNEL = 0x63000002,
/* 0x74 ('t') for test and example objects */
TEST_TASK = 0x7400CAFE,
TEST_DUMMY_1 = 0x74000001,
TEST_DUMMY_2 = 0x74000002,
TEST_DUMMY_3= 0x74000003,
TEST_DUMMY_4 = 0x74000004,
TEST_DUMMY_5 = 0x74000005,
};
}
#endif /* COMMON_COMMONSYSTEMOBJECTS_H_ */

View File

@ -0,0 +1 @@
target_sources(${TARGET_NAME} PRIVATE FsfwTestController.cpp)

View File

@ -0,0 +1,172 @@
#include "FsfwTestController.h"
#include <fsfw/datapool/PoolReadGuard.h>
FsfwTestController::FsfwTestController(object_id_t objectId,
object_id_t device0, object_id_t device1,
uint8_t verboseLevel)
: TestController(objectId, objects::NO_OBJECT, 5), device0Id(device0),
device1Id(device1), deviceDataset0(device0), deviceDataset1(device1) {}
FsfwTestController::~FsfwTestController() {}
ReturnValue_t
FsfwTestController::handleCommandMessage(CommandMessage *message) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t FsfwTestController::initializeLocalDataPool(
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
return HasReturnvaluesIF::RETURN_OK;
}
void FsfwTestController::performControlOperation() {
// We will trace variables if we received an update notification or snapshots
if (verboseLevel >= 1) {
if (not traceVariable) {
return;
}
switch (currentTraceType) {
case (NONE): {
break;
}
case (TRACE_DEV_0_UINT8): {
if (traceCounter == 0) {
FSFW_LOGI("Tracing finished\n");
traceVariable = false;
traceCounter = traceCycles;
currentTraceType = TraceTypes::NONE;
break;
}
PoolReadGuard readHelper(&deviceDataset0.testUint8Var);
FSFW_LOGI("Tracing device 0 variable 0 (UINT8), current value: {}",
static_cast<int>(deviceDataset0.testUint8Var.value));
traceCounter--;
break;
}
case (TRACE_DEV_0_VECTOR): {
break;
}
}
}
}
ReturnValue_t FsfwTestController::initializeAfterTaskCreation() {
namespace td = testdevice;
ReturnValue_t result = TestController::initializeAfterTaskCreation();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
auto* device0 =
ObjectManager::instance()->get<HasLocalDataPoolIF>(deviceDataset0.getCreatorObjectId());
if (device0 == nullptr) {
FSFW_LOGW("initializeAfterTaskCreation: Test device handler 0 handle invalid\n");
return ObjectManagerIF::CHILD_INIT_FAILED;
}
ProvidesDataPoolSubscriptionIF *subscriptionIF =
device0->getSubscriptionInterface();
if (subscriptionIF != nullptr) {
/* For DEVICE_0, we only subscribe for notifications */
subscriptionIF->subscribeForSetUpdateMessage(td::TEST_SET_ID, getObjectId(),
getCommandQueue(), false);
subscriptionIF->subscribeForVariableUpdateMessage(
td::PoolIds::TEST_UINT8_ID, getObjectId(), getCommandQueue(), false);
}
auto* device1 =
ObjectManager::instance()->get<HasLocalDataPoolIF>(deviceDataset0.getCreatorObjectId());
if (device1 == nullptr) {
FSFW_LOGW("initializeAfterTaskCreation: Test device handler 1 handle invalid\n");
}
subscriptionIF = device1->getSubscriptionInterface();
if (subscriptionIF != nullptr) {
/* For DEVICE_1, we will subscribe for snapshots */
subscriptionIF->subscribeForSetUpdateMessage(td::TEST_SET_ID, getObjectId(),
getCommandQueue(), true);
subscriptionIF->subscribeForVariableUpdateMessage(
td::PoolIds::TEST_UINT8_ID, getObjectId(), getCommandQueue(), true);
}
return result;
}
LocalPoolDataSetBase *FsfwTestController::getDataSetHandle(sid_t sid) {
return nullptr;
}
ReturnValue_t FsfwTestController::checkModeCommand(Mode_t mode,
Submode_t submode,
uint32_t *msToReachTheMode) {
return HasReturnvaluesIF::RETURN_OK;
}
void FsfwTestController::handleChangedDataset(sid_t sid,
store_address_t storeId,
bool *clearMessage) {
using namespace std;
if (verboseLevel >= 1) {
char const *printout = nullptr;
if (storeId == storeId::INVALID_STORE_ADDRESS) {
printout = "Notification";
} else {
printout = "Snapshot";
}
FSFW_LOGI("handleChangedDataset: {} update from object ID {:#010x} and set ID {}\n", printout,
sid.objectId, sid.ownerSetId);
if (storeId == storeId::INVALID_STORE_ADDRESS) {
if (sid.objectId == device0Id) {
PoolReadGuard readHelper(&deviceDataset0.testFloat3Vec);
float floatVec[3];
floatVec[0] = deviceDataset0.testFloat3Vec.value[0];
floatVec[1] = deviceDataset0.testFloat3Vec.value[1];
floatVec[2] = deviceDataset0.testFloat3Vec.value[2];
FSFW_LOGI("Current float vector (3) values: [{},{},{}]\n", floatVec[0], floatVec[1],
floatVec[2]);
}
}
}
/* We will trace the variables for snapshots and update notifications */
if (not traceVariable) {
traceVariable = true;
traceCounter = traceCycles;
currentTraceType = TraceTypes::TRACE_DEV_0_VECTOR;
}
}
void FsfwTestController::handleChangedPoolVariable(gp_id_t globPoolId,
store_address_t storeId,
bool *clearMessage) {
using namespace std;
if (verboseLevel >= 1) {
char const *printout = nullptr;
if (storeId == storeId::INVALID_STORE_ADDRESS) {
printout = "Notification";
} else {
printout = "Snapshot";
}
FSFW_LOGI(
"TestController::handleChangedPoolVariable: {} update from object "
"ID {:#010x} and LPID {}\n",
printout, globPoolId.objectId, globPoolId.localPoolId);
if (storeId == storeId::INVALID_STORE_ADDRESS) {
if (globPoolId.objectId == device0Id) {
PoolReadGuard readHelper(&deviceDataset0.testUint8Var);
FSFW_LOGI("Current test variable 0 (UINT8) value: {}",
static_cast<int>(deviceDataset0.testUint8Var.value));
}
}
}
/* We will trace the variables for snapshots and update notifications */
if (not traceVariable) {
traceVariable = true;
traceCounter = traceCycles;
currentTraceType = TraceTypes::TRACE_DEV_0_UINT8;
}
}

View File

@ -0,0 +1,46 @@
#ifndef EXAMPLE_COMMON_EXAMPLE_CONTROLLER_FSFWTESTCONTROLLER_H_
#define EXAMPLE_COMMON_EXAMPLE_CONTROLLER_FSFWTESTCONTROLLER_H_
#include "fsfw/controller/ExtendedControllerBase.h"
#include "fsfw_tests/integration/controller/TestController.h"
class FsfwTestController : public TestController {
public:
FsfwTestController(object_id_t objectId, object_id_t device0,
object_id_t device1, uint8_t verboseLevel = 0);
virtual ~FsfwTestController();
ReturnValue_t handleCommandMessage(CommandMessage *message) override;
/**
* Periodic helper from ControllerBase, implemented by child class.
*/
void performControlOperation() override;
private:
object_id_t device0Id;
object_id_t device1Id;
testdevice::TestDataSet deviceDataset0;
testdevice::TestDataSet deviceDataset1;
uint8_t verboseLevel = 0;
bool traceVariable = false;
uint8_t traceCycles = 5;
uint8_t traceCounter = traceCycles;
enum TraceTypes { NONE, TRACE_DEV_0_UINT8, TRACE_DEV_0_VECTOR };
TraceTypes currentTraceType = TraceTypes::NONE;
ReturnValue_t initializeAfterTaskCreation() override;
void handleChangedDataset(sid_t sid, store_address_t storeId,
bool *clearMessage) override;
void handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId,
bool *clearMessage) override;
ReturnValue_t
initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) override;
};
#endif /* EXAMPLE_COMMON_EXAMPLE_CONTROLLER_FSFWTESTCONTROLLER_H_ */

View File

@ -1,4 +1 @@
target_sources(${TARGET_NAME}
PRIVATE
GenericFactory.cpp
)
target_sources(${TARGET_NAME} PRIVATE GenericFactory.cpp)

View File

@ -1,27 +1,17 @@
#include "GenericFactory.h"
#include "OBSWConfig.h"
#include "fsfw/FSFW.h"
#include "tmtc/apid.h"
#include "tmtc/pusIds.h"
#include "objects/systemObjectList.h"
#include "example/utility/TmFunnel.h"
#include "common/definitions.h"
#include "example/test/FsfwExampleTask.h"
#include "example/test/FsfwReaderTask.h"
#include "fsfw_tests/internal/InternalUnitTester.h"
#include "fsfw_tests/integration/assemblies/TestAssembly.h"
#include "fsfw_tests/integration/devices/TestCookie.h"
#include "fsfw_tests/integration/devices/TestDeviceHandler.h"
#include "fsfw_tests/integration/devices/TestEchoComIF.h"
#include "fsfw_tests/integration/controller/TestController.h"
#include "example/utility/TmFunnel.h"
#include "fsfw/FSFW.h"
#include "fsfw/devicehandlers/CookieIF.h"
#include "fsfw/events/EventManager.h"
#include "fsfw/health/HealthTable.h"
#include "fsfw/internalerror/InternalErrorReporter.h"
#include "fsfw/pus/CService200ModeCommanding.h"
#include "fsfw/pus/Service11TelecommandScheduling.h"
#include "fsfw/pus/Service17Test.h"
#include "fsfw/pus/Service1TelecommandVerification.h"
#include "fsfw/pus/Service20ParameterManagement.h"
@ -34,8 +24,14 @@
#include "fsfw/tcdistribution/PUSDistributor.h"
#include "fsfw/timemanager/TimeStamper.h"
#include "fsfw/tmtcpacket/pus/tm.h"
#include "fsfw_tests/integration/assemblies/TestAssembly.h"
#include "fsfw_tests/integration/controller/TestController.h"
#include "fsfw_tests/integration/devices/TestCookie.h"
#include "fsfw_tests/integration/devices/TestDeviceHandler.h"
#include "fsfw_tests/integration/devices/TestEchoComIF.h"
#include "fsfw_tests/internal/InternalUnitTester.h"
#include "objects/systemObjectList.h"
#include "tmtc/apid.h"
void ObjectFactory::produceGenericObjects() {
#if OBSW_ADD_CORE_COMPONENTS == 1
@ -44,6 +40,7 @@ void ObjectFactory::produceGenericObjects() {
new HealthTable(objects::HEALTH_TABLE);
new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER);
new TimeStamper(objects::TIME_STAMPER);
auto *ccsdsDistrib =
new CCSDSDistributor(apid::APID, objects::CCSDS_DISTRIBUTOR);
new PUSDistributor(apid::APID, objects::PUS_DISTRIBUTOR,
objects::CCSDS_DISTRIBUTOR);
@ -53,22 +50,29 @@ void ObjectFactory::produceGenericObjects() {
/* PUS stack */
#if OBSW_ADD_PUS_STACK == 1
new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION,
apid::APID, pus::PUS_SERVICE_1, objects::TM_FUNNEL, 5);
new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS,
apid::APID, pus::PUS_SERVICE_2, 3, 10);
new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, apid::APID, pus::PUS_SERVICE_3);
new Service5EventReporting(objects::PUS_SERVICE_5_EVENT_REPORTING,
apid::APID, pus::PUS_SERVICE_5, 50);
apid::APID, pus::PUS_SERVICE_1,
objects::TM_FUNNEL, 5);
new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, apid::APID,
pus::PUS_SERVICE_2, 3, 10);
new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, apid::APID,
pus::PUS_SERVICE_3);
new Service5EventReporting(objects::PUS_SERVICE_5_EVENT_REPORTING, apid::APID,
pus::PUS_SERVICE_5, 50);
new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT,
apid::APID, pus::PUS_SERVICE_8, 3, 10);
new Service9TimeManagement(objects::PUS_SERVICE_9_TIME_MGMT, apid::APID,
pus::PUS_SERVICE_9);
new Service17Test(objects::PUS_SERVICE_17_TEST, apid::APID,
pus::PUS_SERVICE_17);
new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS, apid::APID,
pus::PUS_SERVICE_20);
new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT,
apid::APID, pus::PUS_SERVICE_200);
new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS,
apid::APID, pus::PUS_SERVICE_20);
#if OBSW_ADD_CORE_COMPONENTS == 1
new Service11TelecommandScheduling<cfg::OBSW_MAX_SCHEDULED_TCS>(
objects::PUS_SERVICE_11_TC_SCHEDULER, apid::APID, pus::PUS_SERVICE_11,
ccsdsDistrib);
#endif
new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, apid::APID,
pus::PUS_SERVICE_200);
#endif /* OBSW_ADD_PUS_STACK == 1 */
#if OBSW_ADD_TASK_EXAMPLE == 1
@ -77,7 +81,6 @@ void ObjectFactory::produceGenericObjects() {
new FsfwExampleTask(objects::TEST_DUMMY_2);
new FsfwExampleTask(objects::TEST_DUMMY_3);
bool enablePrintout = false;
#if OBSW_TASK_EXAMPLE_PRINTOUT == 1
enablePrintout = true;
@ -95,29 +98,32 @@ void ObjectFactory::produceGenericObjects() {
/* Demo device handler object */
size_t expectedMaxReplyLen = 64;
CookieIF* testCookie = new TestCookie(
static_cast<address_t>(testdevice::DeviceIndex::DEVICE_0), expectedMaxReplyLen);
new TestEchoComIF(objects::TEST_ECHO_COM_IF);
new TestDevice(objects::TEST_DEVICE_HANDLER_0, objects::TEST_ECHO_COM_IF, testCookie,
testdevice::DeviceIndex::DEVICE_0, enableInfoPrintout);
testCookie = new TestCookie(static_cast<address_t>(testdevice::DeviceIndex::DEVICE_1),
CookieIF *testCookie =
new TestCookie(static_cast<address_t>(testdevice::DeviceIndex::DEVICE_0),
expectedMaxReplyLen);
new TestDevice(objects::TEST_DEVICE_HANDLER_1, objects::TEST_ECHO_COM_IF, testCookie,
testdevice::DeviceIndex::DEVICE_1, enableInfoPrintout);
new TestEchoComIF(objects::TEST_ECHO_COM_IF);
new TestDevice(objects::TEST_DEVICE_HANDLER_0, objects::TEST_ECHO_COM_IF,
testCookie, testdevice::DeviceIndex::DEVICE_0,
enableInfoPrintout);
testCookie =
new TestCookie(static_cast<address_t>(testdevice::DeviceIndex::DEVICE_1),
expectedMaxReplyLen);
new TestDevice(objects::TEST_DEVICE_HANDLER_1, objects::TEST_ECHO_COM_IF,
testCookie, testdevice::DeviceIndex::DEVICE_1,
enableInfoPrintout);
new TestAssembly(objects::TEST_ASSEMBLY, objects::NO_OBJECT, objects::TEST_DEVICE_HANDLER_0,
new TestAssembly(objects::TEST_ASSEMBLY, objects::NO_OBJECT,
objects::TEST_DEVICE_HANDLER_0,
objects::TEST_DEVICE_HANDLER_1);
#endif /* OBSW_ADD_DEVICE_HANDLER_DEMO == 1 */
/* Demo controller object */
#if OBSW_ADD_CONTROLLER_DEMO == 1
#if OBSW_CONTROLLER_PRINTOUT == 1
#endif
new TestController(objects::TEST_CONTROLLER, objects::TEST_DEVICE_HANDLER_0,
objects::TEST_DEVICE_HANDLER_1);
new TestController(objects::TEST_CONTROLLER, objects::NO_OBJECT);
#endif /* OBSW_ADD_CONTROLLER_DEMO == 1 */
@ -154,7 +160,4 @@ void Factory::setStaticFrameworkObjectIds() {
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
TmPacketBase::timeStamperId = objects::TIME_STAMPER;
}

View File

@ -11,7 +11,6 @@ namespace ObjectFactory {
*/
void produceGenericObjects();
}
} // namespace ObjectFactory
#endif /* MISSION_CORE_GENERICFACTORY_H_ */

View File

@ -0,0 +1 @@

View File

@ -3,10 +3,8 @@
//#include "fsfw_tests/integration/TestDeviceHandler.h"
//
//class FsfwTestDeviceHandler: public TestDeviceHandler {
// class FsfwTestDeviceHandler: public TestDeviceHandler {
//
//};
#endif /* EXAMPLE_COMMON_DEVICES_TESTDEVICEHANDLER_H_ */

View File

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

View File

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

View File

@ -1,18 +1,17 @@
#ifndef MISSION_DEMO_FSFWDEMOTASK_H_
#define MISSION_DEMO_FSFWDEMOTASK_H_
#include "testdefinitions/demoDefinitions.h"
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include <fsfw/datapoollocal/LocalPoolVariable.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include <fsfw/ipc/MessageQueueIF.h>
#include <fsfw/monitoring/AbsLimitMonitor.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include "testdefinitions/demoDefinitions.h"
class PeriodicTaskIF;
/**
* @brief This demo set shows the local data pool functionality and fixed
* timeslot capabilities of the FSFW.
@ -25,16 +24,11 @@ class PeriodicTaskIF;
* value directly from the sender via the local data pool interface.
* If the timing is set up correctly, the values will always be the same.
*/
class FsfwExampleTask:
public ExecutableObjectIF,
class FsfwExampleTask : public ExecutableObjectIF,
public SystemObject,
public HasLocalDataPoolIF {
public:
enum OpCodes {
SEND_RAND_NUM,
RECEIVE_RAND_NUM,
DELAY_SHORT
};
enum OpCodes { SEND_RAND_NUM, RECEIVE_RAND_NUM, DELAY_SHORT };
static constexpr uint8_t MONITOR_ID = 2;
@ -52,7 +46,7 @@ public:
* other member of the class can be used.
* @return Currently, the return value is ignored.
*/
virtual ReturnValue_t performOperation(uint8_t operationCode = 0);
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
/**
* @brief This function will be called by the global object manager
@ -80,29 +74,28 @@ public:
* task interface handle can be cached to access task specific properties.
* @param task
*/
void setTaskIF(PeriodicTaskIF* task) override;
void setTaskIF(PeriodicTaskIF *task) override;
object_id_t getObjectId() const override;
MessageQueueId_t getMessageQueueId();
private:
LocalDataPoolManager poolManager;
FsfwDemoSet* senderSet = nullptr;
FsfwDemoSet *senderSet = nullptr;
FsfwDemoSet demoSet;
AbsLimitMonitor<int32_t> monitor;
PeriodicTaskIF* task = nullptr;
MessageQueueIF* commandQueue = nullptr;
PeriodicTaskIF *task = nullptr;
MessageQueueIF *commandQueue = nullptr;
/* HasLocalDatapoolIF overrides */
MessageQueueId_t getCommandQueue() const override;
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override;
uint32_t getPeriodicOperationFrequency() const override;
virtual ReturnValue_t initializeLocalDataPool(
localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
virtual LocalDataPoolManager* getHkManagerHandle() override;
ReturnValue_t
initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
LocalDataPoolManager *getHkManagerHandle() override;
object_id_t getNextRecipient();
object_id_t getSender();
@ -110,7 +103,6 @@ private:
ReturnValue_t performMonitoringDemo();
ReturnValue_t performSendOperation();
ReturnValue_t performReceiveOperation();
uint8_t execCounter = 0;
};
#endif /* MISSION_DEMO_FSFWDEMOTASK_H_ */

View File

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

View File

@ -1,19 +1,19 @@
#ifndef MISSION_DEMO_FSFWPERIODICTASK_H_
#define MISSION_DEMO_FSFWPERIODICTASK_H_
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include "testdefinitions/demoDefinitions.h"
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/objectmanager/SystemObject.h>
class FsfwReaderTask: public ExecutableObjectIF, public SystemObject {
class FsfwReaderTask : public ExecutableObjectIF, public SystemObject {
public:
FsfwReaderTask(object_id_t objectId, bool enablePrintout);
virtual ~FsfwReaderTask();
~FsfwReaderTask() override;
ReturnValue_t initializeAfterTaskCreation() override;
virtual ReturnValue_t performOperation(uint8_t operationCode = 0);
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
private:
bool printoutEnabled = false;

View File

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

View File

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

View File

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

View File

@ -1,8 +1,8 @@
#ifndef MISSION_DEMO_MUTEXEXAMPLE_H_
#define MISSION_DEMO_MUTEXEXAMPLE_H_
#ifndef EXAMPLE_COMMON_MUTEXEXAMPLE_H_
#define EXAMPLE_COMMON_MUTEXEXAMPLE_H_
namespace MutexExample {
void example();
void example();
};
#endif /* MISSION_DEMO_MUTEXEXAMPLE_H_ */
#endif /* EXAMPLE_COMMON_MUTEXEXAMPLE_H_ */

20
example/test/testFmt.cpp Normal file
View File

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

3
example/test/testFmt.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void fmtTests();

View File

@ -1,8 +1,8 @@
#ifndef MISSION_DEMO_DEMODEFINITIONS_H_
#define MISSION_DEMO_DEMODEFINITIONS_H_
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include <fsfw/datapoollocal/LocalPoolVariable.h>
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
/**
* @brief This demo set showcases the local data pool functionality of the
@ -11,27 +11,23 @@
* Each demo object will have an own instance of this set class, which contains
* pool variables (for read and write access respectively).
*/
class FsfwDemoSet: public StaticLocalDataSet<3> {
class FsfwDemoSet : public StaticLocalDataSet<3> {
public:
static constexpr uint32_t DEMO_SET_ID = 0;
enum PoolIds {
VARIABLE,
VARIABLE_LIMIT
};
enum PoolIds { VARIABLE, VARIABLE_LIMIT };
FsfwDemoSet(HasLocalDataPoolIF* hkOwner):
StaticLocalDataSet(hkOwner, DEMO_SET_ID) {}
FsfwDemoSet(HasLocalDataPoolIF *hkOwner)
: StaticLocalDataSet(hkOwner, DEMO_SET_ID) {}
lp_var_t<uint32_t> variableRead = lp_var_t<uint32_t>(
sid.objectId, PoolIds::VARIABLE, this, pool_rwm_t::VAR_READ);
lp_var_t<uint32_t> variableWrite = lp_var_t<uint32_t>(
sid.objectId, PoolIds::VARIABLE, this, pool_rwm_t::VAR_WRITE);
lp_var_t<uint16_t> variableLimit =
lp_var_t<uint16_t>(sid.objectId, PoolIds::VARIABLE_LIMIT, this);
lp_var_t<uint32_t> variableRead = lp_var_t<uint32_t>(sid.objectId,
PoolIds::VARIABLE, this, pool_rwm_t::VAR_READ);
lp_var_t<uint32_t> variableWrite = lp_var_t<uint32_t>(sid.objectId,
PoolIds::VARIABLE, this, pool_rwm_t::VAR_WRITE);
lp_var_t<uint16_t> variableLimit = lp_var_t<uint16_t>(sid.objectId,
PoolIds::VARIABLE_LIMIT, this);
private:
};
/**
@ -39,25 +35,22 @@ private:
* above. An example application would be a consumer object like a controller
* which reads multiple sensor values at once.
*/
class CompleteDemoReadSet: public StaticLocalDataSet<3> {
class CompleteDemoReadSet : public StaticLocalDataSet<3> {
public:
static constexpr uint32_t DEMO_SET_ID = 0;
CompleteDemoReadSet(object_id_t owner, gp_id_t variable1,
gp_id_t variable2, gp_id_t variable3):
StaticLocalDataSet(sid_t(owner, DEMO_SET_ID)),
CompleteDemoReadSet(object_id_t owner, gp_id_t variable1, gp_id_t variable2,
gp_id_t variable3)
: StaticLocalDataSet(sid_t(owner, DEMO_SET_ID)),
variable1(variable1, this, pool_rwm_t::VAR_READ),
variable2(variable2, this, pool_rwm_t::VAR_READ),
variable3(variable3, this, pool_rwm_t::VAR_READ) {}
lp_var_t<uint32_t> variable1;
lp_var_t<uint32_t> variable2;
lp_var_t<uint32_t> variable3;
private:
};
#endif /* MISSION_DEMO_DEMODEFINITIONS_H_ */

View File

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

View File

@ -1,10 +1,9 @@
#include <fsfw/tmtcpacket/pus/tc.h>
#include <fsfw/tmtcpacket/pus/tm.h>
#include <fsfw/globalfunctions/arrayprinter.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/tmtcpacket/pus/tc.h>
#include <fsfw/tmtcpacket/pus/tm.h>
#include <mission/utility/PusPacketCreator.h>
void PusPacketCreator::createPusPacketAndPrint() {
// TODO: use TC packet stored here instead..
}

View File

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

View File

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

View File

@ -1,13 +1,13 @@
#ifndef MISSION_UTILITY_TMFUNNEL_H_
#define MISSION_UTILITY_TMFUNNEL_H_
#include <fsfw/ipc/MessageQueueIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
#include <fsfw/ipc/MessageQueueIF.h>
#include <fsfw/tmtcservices/TmTcMessage.h>
namespace Factory{
namespace Factory {
void setStaticFrameworkObjectIds();
}
@ -19,17 +19,17 @@ void setStaticFrameworkObjectIds();
* @ingroup utility
* @author J. Meier
*/
class TmFunnel:
public AcceptsTelemetryIF,
class TmFunnel : public AcceptsTelemetryIF,
public ExecutableObjectIF,
public SystemObject {
friend void (Factory::setStaticFrameworkObjectIds)();
friend void(Factory::setStaticFrameworkObjectIds)();
public:
TmFunnel(object_id_t objectId, uint32_t messageDepth = 20);
virtual ~TmFunnel();
virtual MessageQueueId_t getReportReceptionQueue(
uint8_t virtualChannel = 0) override;
virtual MessageQueueId_t
getReportReceptionQueue(uint8_t virtualChannel = 0) override;
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
virtual ReturnValue_t initialize() override;
@ -39,13 +39,13 @@ protected:
private:
uint16_t sourceSequenceCount = 0;
MessageQueueIF* tmQueue = nullptr;
MessageQueueIF* storageQueue = nullptr;
MessageQueueIF *tmQueue = nullptr;
MessageQueueIF *storageQueue = nullptr;
StorageManagerIF* tmPool = nullptr;
StorageManagerIF *tmPool = nullptr;
uint32_t messageDepth = 0;
ReturnValue_t handlePacket(TmTcMessage* message);
ReturnValue_t handlePacket(TmTcMessage *message);
};
#endif /* MISSION_UTILITY_TMFUNNEL_H_ */

View File

@ -5,16 +5,21 @@
* Authors:
*
* Assembled from the code released on Stackoverflow by:
* Dennis (instructable.com/member/nqtronix) | https://stackoverflow.com/questions/23032002/c-c-how-to-get-integer-unix-timestamp-of-build-time-not-string
* Dennis (instructable.com/member/nqtronix) |
* https://stackoverflow.com/questions/23032002/c-c-how-to-get-integer-unix-timestamp-of-build-time-not-string
* and
* Alexis Wilke | https://stackoverflow.com/questions/10538444/do-you-know-of-a-c-macro-to-compute-unix-time-and-date
* Alexis Wilke |
* https://stackoverflow.com/questions/10538444/do-you-know-of-a-c-macro-to-compute-unix-time-and-date
*
* Assembled by Jean Rabault
*
* UNIX_TIMESTAMP gives the UNIX timestamp (unsigned long integer of seconds since 1st Jan 1970) of compilation from macros using the compiler defined __TIME__ macro.
* This should include Gregorian calendar leap days, in particular the 29ths of February, 100 and 400 years modulo leaps.
* UNIX_TIMESTAMP gives the UNIX timestamp (unsigned long integer of seconds
* since 1st Jan 1970) of compilation from macros using the compiler defined
* __TIME__ macro. This should include Gregorian calendar leap days, in
* particular the 29ths of February, 100 and 400 years modulo leaps.
*
* Careful: __TIME__ is the local time of the computer, NOT the UTC time in general!
* Careful: __TIME__ is the local time of the computer, NOT the UTC time in
* general!
*
*/
@ -25,27 +30,29 @@
#define SEC_PER_MIN 60UL
#define SEC_PER_HOUR 3600UL
#define SEC_PER_DAY 86400UL
#define SEC_PER_YEAR (SEC_PER_DAY*365)
#define SEC_PER_YEAR (SEC_PER_DAY * 365)
// extracts 1..4 characters from a string and interprets it as a decimal value
#define CONV_STR2DEC_1(str, i) (str[i]>'0'?str[i]-'0':0)
#define CONV_STR2DEC_2(str, i) (CONV_STR2DEC_1(str, i)*10 + str[i+1]-'0')
#define CONV_STR2DEC_3(str, i) (CONV_STR2DEC_2(str, i)*10 + str[i+2]-'0')
#define CONV_STR2DEC_4(str, i) (CONV_STR2DEC_3(str, i)*10 + str[i+3]-'0')
#define CONV_STR2DEC_1(str, i) (str[i] > '0' ? str[i] - '0' : 0)
#define CONV_STR2DEC_2(str, i) (CONV_STR2DEC_1(str, i) * 10 + str[i + 1] - '0')
#define CONV_STR2DEC_3(str, i) (CONV_STR2DEC_2(str, i) * 10 + str[i + 2] - '0')
#define CONV_STR2DEC_4(str, i) (CONV_STR2DEC_3(str, i) * 10 + str[i + 3] - '0')
// Custom "glue logic" to convert the month name to a usable number
#define GET_MONTH(str, i) (str[i]=='J' && str[i+1]=='a' && str[i+2]=='n' ? 1 : \
str[i]=='F' && str[i+1]=='e' && str[i+2]=='b' ? 2 : \
str[i]=='M' && str[i+1]=='a' && str[i+2]=='r' ? 3 : \
str[i]=='A' && str[i+1]=='p' && str[i+2]=='r' ? 4 : \
str[i]=='M' && str[i+1]=='a' && str[i+2]=='y' ? 5 : \
str[i]=='J' && str[i+1]=='u' && str[i+2]=='n' ? 6 : \
str[i]=='J' && str[i+1]=='u' && str[i+2]=='l' ? 7 : \
str[i]=='A' && str[i+1]=='u' && str[i+2]=='g' ? 8 : \
str[i]=='S' && str[i+1]=='e' && str[i+2]=='p' ? 9 : \
str[i]=='O' && str[i+1]=='c' && str[i+2]=='t' ? 10 : \
str[i]=='N' && str[i+1]=='o' && str[i+2]=='v' ? 11 : \
str[i]=='D' && str[i+1]=='e' && str[i+2]=='c' ? 12 : 0)
#define GET_MONTH(str, i) \
(str[i] == 'J' && str[i + 1] == 'a' && str[i + 2] == 'n' ? 1 \
: str[i] == 'F' && str[i + 1] == 'e' && str[i + 2] == 'b' ? 2 \
: str[i] == 'M' && str[i + 1] == 'a' && str[i + 2] == 'r' ? 3 \
: str[i] == 'A' && str[i + 1] == 'p' && str[i + 2] == 'r' ? 4 \
: str[i] == 'M' && str[i + 1] == 'a' && str[i + 2] == 'y' ? 5 \
: str[i] == 'J' && str[i + 1] == 'u' && str[i + 2] == 'n' ? 6 \
: str[i] == 'J' && str[i + 1] == 'u' && str[i + 2] == 'l' ? 7 \
: str[i] == 'A' && str[i + 1] == 'u' && str[i + 2] == 'g' ? 8 \
: str[i] == 'S' && str[i + 1] == 'e' && str[i + 2] == 'p' ? 9 \
: str[i] == 'O' && str[i + 1] == 'c' && str[i + 2] == 't' ? 10 \
: str[i] == 'N' && str[i + 1] == 'o' && str[i + 2] == 'v' ? 11 \
: str[i] == 'D' && str[i + 1] == 'e' && str[i + 2] == 'c' ? 12 \
: 0)
// extract the information from the time string given by __TIME__ and __DATE__
#define __TIME_SECONDS__ CONV_STR2DEC_2(__TIME__, 6)
@ -57,41 +64,36 @@
// Days in February
#define _UNIX_TIMESTAMP_FDAY(year) \
(((year) % 400) == 0UL ? 29UL : \
(((year) % 100) == 0UL ? 28UL : \
(((year) % 4) == 0UL ? 29UL : \
28UL)))
(((year) % 400) == 0UL \
? 29UL \
: (((year) % 100) == 0UL ? 28UL : (((year) % 4) == 0UL ? 29UL : 28UL)))
// Days in the year
#define _UNIX_TIMESTAMP_YDAY(year, month, day) \
( \
/* January */ day \
/* February */ + (month >= 2 ? 31UL : 0UL) \
/* March */ + (month >= 3 ? _UNIX_TIMESTAMP_FDAY(year) : 0UL) \
/* April */ + (month >= 4 ? 31UL : 0UL) \
/* May */ + (month >= 5 ? 30UL : 0UL) \
/* June */ + (month >= 6 ? 31UL : 0UL) \
/* July */ + (month >= 7 ? 30UL : 0UL) \
/* August */ + (month >= 8 ? 31UL : 0UL) \
/* September */+ (month >= 9 ? 31UL : 0UL) \
/* October */ + (month >= 10 ? 30UL : 0UL) \
/* November */ + (month >= 11 ? 31UL : 0UL) \
/* December */ + (month >= 12 ? 30UL : 0UL) \
)
(/* January */ day /* February */ + (month >= 2 ? 31UL : 0UL) /* March */ + \
(month >= 3 ? _UNIX_TIMESTAMP_FDAY(year) : 0UL) /* April */ + \
(month >= 4 ? 31UL : 0UL) /* May */ + \
(month >= 5 ? 30UL : 0UL) /* June */ + \
(month >= 6 ? 31UL : 0UL) /* July */ + \
(month >= 7 ? 30UL : 0UL) /* August */ + \
(month >= 8 ? 31UL : 0UL) /* September */ + \
(month >= 9 ? 31UL : 0UL) /* October */ + \
(month >= 10 ? 30UL : 0UL) /* November */ + \
(month >= 11 ? 31UL : 0UL) /* December */ + (month >= 12 ? 30UL : 0UL))
// get the UNIX timestamp from a digits representation
#define _UNIX_TIMESTAMP(year, month, day, hour, minute, second) \
( /* time */ second \
+ minute * SEC_PER_MIN \
+ hour * SEC_PER_HOUR \
+ /* year day (month + day) */ (_UNIX_TIMESTAMP_YDAY(year, month, day) - 1) * SEC_PER_DAY \
+ /* year */ (year - 1970UL) * SEC_PER_YEAR \
+ ((year - 1969UL) / 4UL) * SEC_PER_DAY \
- ((year - 1901UL) / 100UL) * SEC_PER_DAY \
+ ((year - 1601UL) / 400UL) * SEC_PER_DAY \
)
(/* time */ second + minute * SEC_PER_MIN + hour * SEC_PER_HOUR + \
/* year day (month + day) */ (_UNIX_TIMESTAMP_YDAY(year, month, day) - 1) * \
SEC_PER_DAY + \
/* year */ (year - 1970UL) * SEC_PER_YEAR + \
((year - 1969UL) / 4UL) * SEC_PER_DAY - \
((year - 1901UL) / 100UL) * SEC_PER_DAY + \
((year - 1601UL) / 400UL) * SEC_PER_DAY)
// the UNIX timestamp
#define UNIX_TIMESTAMP (_UNIX_TIMESTAMP(__TIME_YEARS__, __TIME_MONTH__, __TIME_DAYS__, __TIME_HOURS__, __TIME_MINUTES__, __TIME_SECONDS__))
#define UNIX_TIMESTAMP \
(_UNIX_TIMESTAMP(__TIME_YEARS__, __TIME_MONTH__, __TIME_DAYS__, \
__TIME_HOURS__, __TIME_MINUTES__, __TIME_SECONDS__))
#endif

View File

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

View File

@ -3,9 +3,8 @@
namespace utility {
void commonInitPrint(const char *const os, const char* const board);
void commonInitPrint(const char *const os, const char *const board);
}
#endif /* COMMON_UTILITY_UTILITY_H_ */

44
scripts/auto-formatter.sh Executable file
View File

@ -0,0 +1,44 @@
#!/bin/bash
counter=0
common_example_dir="example_common"
while [ ${counter} -lt 5 ]
do
if [ ! -d ${common_example_dir} ];then
break
fi
counter=$((counter=counter + 1))
cd ..
done
if [ "${counter}" -ge 5 ];then
echo "${common_example_dir} not found in upper directories!"
exit 1
fi
folder_list=(
"./bsp_hosted"
"./example_common"
)
cmake_fmt="cmake-format"
file_selectors="-iname CMakeLists.txt"
if command -v ${cmake_fmt} &> /dev/null; then
echo "Auto-formatting all CMakeLists.txt files"
${cmake_fmt} -i CMakeLists.txt
for dir in ${folder_list[@]}; do
find ${dir} ${file_selectors} | xargs ${cmake_fmt} -i
done
else
echo "No ${cmake_fmt} tool found, not formatting CMake files"
fi
cpp_format="clang-format"
file_selectors="-iname *.h -o -iname *.cpp -o -iname *.c -o -iname *.tpp"
if command -v ${cpp_format} &> /dev/null; then
for dir in ${folder_list[@]}; do
echo "Auto-formatting C/C++ files in ${dir} recursively"
find ${dir} ${file_selectors} | xargs ${cpp_format} --style=file -i
done
else
echo "No ${cpp_format} tool found, not formatting C++/C files"
fi

View File

@ -1,6 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
STM32TestTask.cpp
)
target_sources(${TARGET_NAME} PRIVATE STM32TestTask.cpp)
option(STM32_ADD_NETWORKING_CODE "Add networking code requiring lwIP" ON)

View File

@ -1,33 +1,34 @@
#include "STM32TestTask.h"
#include "stm32h7xx_nucleo.h"
#include "OBSWConfig.h"
#include "stm32h7xx_nucleo.h"
STM32TestTask::STM32TestTask(object_id_t objectId, bool enablePrintout,
bool blinkyLed): TestTask(objectId), blinkyLed(blinkyLed) {
bool blinkyLed)
: TestTask(objectId), blinkyLed(blinkyLed) {
BSP_LED_Init(LED1);
BSP_LED_Init(LED2);
BSP_LED_Init(LED3);
}
ReturnValue_t STM32TestTask::initialize() {
if (testSpi) {
spiComIF = new SpiComIF(objects::SPI_COM_IF);
spiTest = new SpiTest(*spiComIF);
}
return TestTask::initialize();
}
ReturnValue_t STM32TestTask::performPeriodicAction() {
if(blinkyLed) {
#if OBSW_ETHERNET_USE_LEDS == 0
if (blinkyLed) {
#if OBSW_ETHERNET_USE_LED1_LED2 == 0
BSP_LED_Toggle(LED1);
BSP_LED_Toggle(LED2);
#endif
BSP_LED_Toggle(LED3);
}
if(testSpi) {
if (testSpi) {
spiTest->performOperation();
}
return TestTask::performPeriodicAction();
}
ReturnValue_t STM32TestTask::initialize() {
if(testSpi) {
spiComIF = new SpiComIF(objects::SPI_COM_IF);
spiTest = new SpiTest(*spiComIF);
}
return TestTask::initialize();
}

View File

@ -4,22 +4,20 @@
#include "bsp_stm32h7_freertos/boardtest/SpiTest.h"
#include "fsfw_tests/integration/task/TestTask.h"
class STM32TestTask: public TestTask {
class STM32TestTask : public TestTask {
public:
STM32TestTask(object_id_t objectId, bool enablePrintout, bool blinkyLed = true);
STM32TestTask(object_id_t objectId, bool enablePrintout,
bool blinkyLed = true);
ReturnValue_t initialize() override;
ReturnValue_t performPeriodicAction() override;
private:
SpiComIF* spiComIF = nullptr;
SpiTest* spiTest = nullptr;
private:
SpiComIF *spiComIF = nullptr;
SpiTest *spiTest = nullptr;
bool blinkyLed = false;
bool testSpi = true;
bool testSpi = false;
};
#endif /* BSP_STM32_BOARDTEST_STM32TESTTASK_H_ */

View File

@ -1,14 +1,8 @@
# These are part of the RTEMS BSP for RTEMS
if(FSFW_OSAL MATCHES freertos)
target_sources(${TARGET_NAME} PRIVATE
ethernetif.c
)
target_sources(${TARGET_NAME} PRIVATE ethernetif.c)
endif()
target_sources(${TARGET_NAME} PRIVATE
UdpTcLwIpPollingTask.cpp
TmTcLwIpUdpBridge.cpp
networking.cpp
app_dhcp.cpp
app_ethernet.cpp
)
target_sources(
${TARGET_NAME} PRIVATE UdpTcLwIpPollingTask.cpp TmTcLwIpUdpBridge.cpp
networking.cpp app_dhcp.cpp app_ethernet.cpp)

View File

@ -1,52 +1,49 @@
#include "TmTcLwIpUdpBridge.h"
#include "udp_config.h"
#include "app_ethernet.h"
#include "ethernetif.h"
#include <OBSWConfig.h>
#include <fsfw/ipc/MutexGuard.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/serialize/EndianConverter.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include "app_ethernet.h"
#include "udp_config.h"
TmTcLwIpUdpBridge::TmTcLwIpUdpBridge(object_id_t objectId,
object_id_t ccsdsPacketDistributor, object_id_t tmStoreId,
object_id_t tcStoreId):
TmTcBridge(objectId, ccsdsPacketDistributor, tmStoreId, tcStoreId) {
object_id_t ccsdsPacketDistributor,
object_id_t tmStoreId,
object_id_t tcStoreId)
: TmTcBridge(objectId, ccsdsPacketDistributor, tmStoreId, tcStoreId) {
TmTcLwIpUdpBridge::lastAdd.addr = IPADDR_TYPE_ANY;
}
TmTcLwIpUdpBridge::~TmTcLwIpUdpBridge() {}
TmTcLwIpUdpBridge::~TmTcLwIpUdpBridge() = default;
ReturnValue_t TmTcLwIpUdpBridge::initialize() {
TmTcBridge::initialize();
bridgeLock = MutexFactory::instance()->createMutex();
if(bridgeLock == nullptr) {
if (bridgeLock == nullptr) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
ReturnValue_t result = udp_server_init();
return result;
}
ReturnValue_t TmTcLwIpUdpBridge::udp_server_init(void) {
ReturnValue_t TmTcLwIpUdpBridge::udp_server_init() {
err_t err;
/* Create a new UDP control block */
TmTcLwIpUdpBridge::upcb = udp_new();
if (TmTcLwIpUdpBridge::upcb)
{
if (TmTcLwIpUdpBridge::upcb) {
sif::printInfo("Opening UDP server on port %d\n", UDP_SERVER_PORT);
/* Bind the upcb to the UDP_PORT port */
/* Using IP_ADDR_ANY allow the upcb to be used by any local interface */
err = udp_bind(TmTcLwIpUdpBridge::upcb, IP_ADDR_ANY, UDP_SERVER_PORT);
if(err == ERR_OK)
{
if (err == ERR_OK) {
/* Set a receive callback for the upcb */
udp_recv(TmTcLwIpUdpBridge::upcb, &udp_server_receive_callback,
(void*) this);
(void *)this);
return RETURN_OK;
}
else
{
} else {
udp_remove(TmTcLwIpUdpBridge::upcb);
return RETURN_FAILED;
}
@ -58,9 +55,9 @@ ReturnValue_t TmTcLwIpUdpBridge::udp_server_init(void) {
ReturnValue_t TmTcLwIpUdpBridge::performOperation(uint8_t operationCode) {
TmTcBridge::performOperation();
#if TCPIP_RECV_WIRETAPPING == 1
if(connectFlag) {
uint32_t ipAddress = ((ip4_addr*) &lastAdd)->addr;
#if OBSW_TCPIP_UDP_WIRETAPPING == 1
if (connectFlag) {
uint32_t ipAddress = ((ip4_addr *)&lastAdd)->addr;
int ipAddress1 = (ipAddress & 0xFF000000) >> 24;
int ipAddress2 = (ipAddress & 0xFF0000) >> 16;
int ipAddress3 = (ipAddress & 0xFF00) >> 8;
@ -71,8 +68,8 @@ ReturnValue_t TmTcLwIpUdpBridge::performOperation(uint8_t operationCode) {
<< ipAddress4 << "." << ipAddress3 << "." << ipAddress2 << "."
<< ipAddress1 << std::endl;
uint16_t portSwapped = EndianConverter::convertBigEndian(lastPort);
sif::info << "TmTcLwIpUdpBridge: Client IP Port "
<< (int)portSwapped << std::endl;
sif::info << "TmTcLwIpUdpBridge: Client IP Port " << (int)portSwapped
<< std::endl;
#else
sif::printInfo("TmTcLwIpUdpBridge: Client IP Address %d.%d.%d.%d\n",
ipAddress4, ipAddress3, ipAddress2, ipAddress1);
@ -87,82 +84,83 @@ ReturnValue_t TmTcLwIpUdpBridge::performOperation(uint8_t operationCode) {
return RETURN_OK;
}
ReturnValue_t TmTcLwIpUdpBridge::sendTm(const uint8_t * data, size_t dataLen) {
ReturnValue_t TmTcLwIpUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
struct pbuf *p_tx = pbuf_alloc(PBUF_TRANSPORT, dataLen, PBUF_RAM);
if ((p_tx != nullptr) && (lastAdd.addr != IPADDR_TYPE_ANY) && (upcb != nullptr)) {
if ((p_tx != nullptr) && (lastAdd.addr != IPADDR_TYPE_ANY) &&
(upcb != nullptr)) {
/* copy data to pbuf */
err_t err = pbuf_take(p_tx, (char*) data, dataLen);
if(err!=ERR_OK){
err_t err = pbuf_take(p_tx, (const char *)data, dataLen);
if (err != ERR_OK) {
pbuf_free(p_tx);
return err;
}
/* Connect to the remote client */
err = udp_connect(TmTcLwIpUdpBridge::upcb, &lastAdd , lastPort);
if(err != ERR_OK){
err = udp_connect(TmTcLwIpUdpBridge::upcb, &lastAdd, lastPort);
if (err != ERR_OK) {
pbuf_free(p_tx);
return err;
}
/* Tell the client that we have accepted it */
err = udp_send(TmTcLwIpUdpBridge::upcb, p_tx);
pbuf_free(p_tx);
if(err!=ERR_OK){
if (err != ERR_OK) {
return err;
}
/* free the UDP connection, so we can accept new clients */
udp_disconnect (TmTcLwIpUdpBridge::upcb);
}
else{
udp_disconnect(TmTcLwIpUdpBridge::upcb);
} else {
return RETURN_FAILED;
}
return RETURN_OK;
}
void TmTcLwIpUdpBridge::udp_server_receive_callback(void* arg,
struct udp_pcb* upcb_, struct pbuf* p, const ip_addr_t* addr,
void TmTcLwIpUdpBridge::udp_server_receive_callback(void *arg,
struct udp_pcb *upcb_,
struct pbuf *p,
const ip_addr_t *addr,
u16_t port) {
struct pbuf *p_tx = nullptr;
auto udpBridge = reinterpret_cast<TmTcLwIpUdpBridge*>(arg);
if(udpBridge == nullptr) {
auto udpBridge = reinterpret_cast<TmTcLwIpUdpBridge *>(arg);
if (udpBridge == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TmTcLwIpUdpBridge::udp_server_receive_callback: Invalid UDP bridge!" <<
std::endl;
sif::warning
<< "TmTcLwIpUdpBridge::udp_server_receive_callback: Invalid UDP bridge!"
<< std::endl;
#else
sif::printWarning("TmTcLwIpUdpBridge::udp_server_receive_callback: Invalid UDP bridge!\n");
sif::printWarning("TmTcLwIpUdpBridge::udp_server_receive_callback: Invalid "
"UDP bridge!\n");
#endif
}
/* allocate pbuf from RAM*/
p_tx = pbuf_alloc(PBUF_TRANSPORT,p->len, PBUF_RAM);
struct pbuf *p_tx = pbuf_alloc(PBUF_TRANSPORT, p->len, PBUF_RAM);
if(p_tx != NULL)
{
if(udpBridge != nullptr) {
if (p_tx != nullptr) {
if (udpBridge != nullptr) {
MutexGuard lg(udpBridge->bridgeLock);
udpBridge->upcb = upcb_;
udpBridge->lastAdd = *addr;
udpBridge->lastPort = port;
if(not udpBridge->comLinkUp()) {
if (not udpBridge->comLinkUp()) {
udpBridge->registerCommConnect();
#if TCPIP_RECV_WIRETAPPING == 1
#if OBSW_TCPIP_UDP_WIRETAPPING == 1
udpBridge->connectFlag = true;
#endif
/* This should have already been done, but we will still do it */
udpBridge->physicalConnectStatusChange(true);
}
}
pbuf_take(p_tx, (char*)p->payload, p->len);
pbuf_take(p_tx, (char *)p->payload, p->len);
/* send the received data to the uart port */
char* data = reinterpret_cast<char*>(p_tx->payload);
*(data+p_tx->len) = '\0';
char *data = reinterpret_cast<char *>(p_tx->payload);
*(data + p_tx->len) = '\0';
#if TCPIP_RECV_WIRETAPPING == 1
udpBridge->printData(p,data);
#if OBSW_TCPIP_UDP_WIRETAPPING == 1
udpBridge->printData(reinterpret_cast<uint8_t *>(p->payload), p->len);
#endif
store_address_t storeId;
ReturnValue_t returnValue = udpBridge->tcStore->addData(&storeId,
reinterpret_cast<uint8_t*>(p->payload), p->len);
ReturnValue_t returnValue = udpBridge->tcStore->addData(
&storeId, reinterpret_cast<uint8_t *>(p->payload), p->len);
if (returnValue != RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UDP Server: Data storage failed" << std::endl;
@ -171,8 +169,7 @@ void TmTcLwIpUdpBridge::udp_server_receive_callback(void* arg,
return;
}
TmTcMessage message(storeId);
if (udpBridge->tmTcReceptionQueue->sendToDefault(&message)
!= RETURN_OK) {
if (udpBridge->tmTcReceptionQueue->sendToDefault(&message) != RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TmTcLwIpUdpBridgw::udp_server_receive_callback:"
<< " Sending message to queue failed" << std::endl;
@ -185,18 +182,15 @@ void TmTcLwIpUdpBridge::udp_server_receive_callback(void* arg,
}
/* Caller must ensure thread-safety */
bool TmTcLwIpUdpBridge::comLinkUp() const {
return communicationLinkUp;
}
bool TmTcLwIpUdpBridge::comLinkUp() const { return communicationLinkUp; }
/* Caller must ensure thread-safety */
void TmTcLwIpUdpBridge::physicalConnectStatusChange(bool connect) {
if(connect) {
/* Physical connection does not mean there is a recipient to send packets too.
This will be done by the receive callback! */
if (connect) {
/* Physical connection does not mean there is a recipient to send packets
too. This will be done by the receive callback! */
physicalConnection = true;
}
else {
} else {
physicalConnection = false;
/* If there is no physical connection, we can't send anything back */
registerCommDisconnect();

View File

@ -1,25 +1,25 @@
#ifndef BSP_STM32_RTEMS_NETWORKING_TMTCUDPBRIDGE_H_
#define BSP_STM32_RTEMS_NETWORKING_TMTCUDPBRIDGE_H_
#include <fsfw/tmtcservices/TmTcBridge.h>
#include "fsfw/tmtcservices/TmTcBridge.h"
#include "commonConfig.h"
#include <lwip/udp.h>
#include <lwip/ip_addr.h>
#define TCPIP_RECV_WIRETAPPING 0
#include <lwip/udp.h>
/**
* This bridge is used to forward TMTC packets received via LwIP UDP to the internal software bus.
* This bridge is used to forward TMTC packets received via LwIP UDP to the
* internal software bus.
*/
class TmTcLwIpUdpBridge : public TmTcBridge {
friend class UdpTcLwIpPollingTask;
public:
TmTcLwIpUdpBridge(object_id_t objectId,
object_id_t ccsdsPacketDistributor, object_id_t tmStoreId,
object_id_t tcStoreId);
virtual ~TmTcLwIpUdpBridge();
virtual ReturnValue_t initialize() override;
public:
TmTcLwIpUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor,
object_id_t tmStoreId, object_id_t tcStoreId);
~TmTcLwIpUdpBridge() override;
ReturnValue_t initialize() override;
ReturnValue_t udp_server_init();
/**
@ -27,14 +27,14 @@ public:
* @param operationCode
* @return
*/
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
ReturnValue_t performOperation(uint8_t operationCode) override;
/** TM Send implementation uses udp_send function from lwIP stack
* @param data
* @param dataLen
* @return
*/
virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override;
ReturnValue_t sendTm(const uint8_t *data, size_t dataLen) override;
/**
* @brief This function is called when an UDP datagram has been
@ -45,8 +45,8 @@ public:
* @param addr Source address which will be bound to TmTcUdpBridge::lastAdd
* @param port
*/
static void udp_server_receive_callback(void *arg,
struct udp_pcb *upcb_, struct pbuf *p, const ip_addr_t *addr,
static void udp_server_receive_callback(void *arg, struct udp_pcb *upcb_,
struct pbuf *p, const ip_addr_t *addr,
u16_t port);
/**
@ -54,24 +54,24 @@ public:
* Caller must ensure thread-safety by using the bridge lock.
* @return
*/
bool comLinkUp() const;
[[nodiscard]] bool comLinkUp() const;
private:
struct udp_pcb *upcb = nullptr;
ip_addr_t lastAdd;
ip_addr_t lastAdd{};
u16_t lastPort = 0;
bool physicalConnection = false;
MutexIF* bridgeLock = nullptr;
MutexIF *bridgeLock = nullptr;
#if TCPIP_RECV_WIRETAPPING == 1
#if OBSW_TCPIP_UDP_WIRETAPPING == 1
bool connectFlag = false;
#endif
/**
* Used to notify bridge about change in the physical ethernet connection.
* Connection does not mean that replies are possible (recipient not set yet), but
* disconnect means that we can't send anything. Caller must ensure thread-safety
* by using the bridge lock.
* Connection does not mean that replies are possible (recipient not set yet),
* but disconnect means that we can't send anything. Caller must ensure
* thread-safety by using the bridge lock.
*/
void physicalConnectStatusChange(bool connect);
};

View File

@ -1,30 +1,26 @@
#include "UdpTcLwIpPollingTask.h"
#include "TmTcLwIpUdpBridge.h"
#include "app_dhcp.h"
#include "app_ethernet.h"
#include "ethernetif.h"
#include "app_dhcp.h"
#include "networking.h"
#include <hardware_init.h>
#include "fsfw/ipc/MutexGuard.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "lwip/timeouts.h"
#include "networking.h"
UdpTcLwIpPollingTask::UdpTcLwIpPollingTask(object_id_t objectId, object_id_t bridgeId,
struct netif* gnetif):
SystemObject(objectId), periodicHandleCounter(0), bridgeId(bridgeId), gnetif(gnetif) {
}
UdpTcLwIpPollingTask::UdpTcLwIpPollingTask(object_id_t objectId,
object_id_t bridgeId,
struct netif *gnetif)
: SystemObject(objectId), periodicHandleCounter(0), bridgeId(bridgeId),
gnetif(gnetif) {}
UdpTcLwIpPollingTask::~UdpTcLwIpPollingTask() {
}
UdpTcLwIpPollingTask::~UdpTcLwIpPollingTask() = default;
ReturnValue_t UdpTcLwIpPollingTask::initialize() {
udpBridge = ObjectManager::instance()->get<TmTcLwIpUdpBridge>(bridgeId);
if(udpBridge == nullptr) {
if (udpBridge == nullptr) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
if (netif_is_link_up(gnetif)) {
@ -33,7 +29,6 @@ ReturnValue_t UdpTcLwIpPollingTask::initialize() {
return RETURN_OK;
}
/* Poll the EMAC Interface and pass content to the network interface (lwIP) */
ReturnValue_t UdpTcLwIpPollingTask::performOperation(uint8_t operationCode) {
/* Read a received packet from the Ethernet buffers and send it
@ -47,13 +42,13 @@ ReturnValue_t UdpTcLwIpPollingTask::performOperation(uint8_t operationCode) {
networking::ethernetLinkPeriodicHandle(gnetif);
#endif
if(udpBridge != nullptr) {
if (udpBridge != nullptr) {
MutexGuard lg(udpBridge->bridgeLock);
/* In case ethernet cable is disconnected */
if(not networking::getEthCableConnected() and udpBridge->comLinkUp()) {
if (not networking::getEthCableConnected() and udpBridge->comLinkUp()) {
udpBridge->physicalConnectStatusChange(false);
}
else if(networking::getEthCableConnected() and not udpBridge->comLinkUp()) {
} else if (networking::getEthCableConnected() and
not udpBridge->comLinkUp()) {
udpBridge->physicalConnectStatusChange(true);
}
}

View File

@ -1,10 +1,8 @@
#ifndef BSP_STM32_RTEMS_EMACPOLLINGTASK_H_
#define BSP_STM32_RTEMS_EMACPOLLINGTASK_H_
#pragma once
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <lwip/netif.h>
class TmTcLwIpUdpBridge;
@ -13,29 +11,27 @@ class TmTcLwIpUdpBridge;
* @brief Separate task to poll EMAC interface.
* Polled data is passed to the netif (lwIP)
*/
class UdpTcLwIpPollingTask:
public SystemObject,
class UdpTcLwIpPollingTask : public SystemObject,
public ExecutableObjectIF,
public HasReturnvaluesIF {
public:
UdpTcLwIpPollingTask(object_id_t objectId, object_id_t bridgeId, struct netif* gnetif);
virtual ~UdpTcLwIpPollingTask();
UdpTcLwIpPollingTask(object_id_t objectId, object_id_t bridgeId,
struct netif *gnetif);
~UdpTcLwIpPollingTask() override;
virtual ReturnValue_t initialize() override;
ReturnValue_t initialize() override;
/**
* Executed periodically.
* @param operationCode
* @return
*/
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
ReturnValue_t performOperation(uint8_t operationCode) override;
private:
static const uint8_t PERIODIC_HANDLE_TRIGGER = 5;
uint8_t periodicHandleCounter;
object_id_t bridgeId = 0;
TmTcLwIpUdpBridge* udpBridge = nullptr;
struct netif* gnetif = nullptr;
TmTcLwIpUdpBridge *udpBridge = nullptr;
struct netif *gnetif = nullptr;
};
#endif /* BSP_STM32_RTEMS_EMACPOLLINGTASK_H_ */

View File

@ -1,32 +1,28 @@
#include "OBSWConfig.h"
#include "app_dhcp.h"
#include "app_ethernet.h"
#include "networking.h"
#include "udp_config.h"
#include "ethernetif.h"
#include "OBSWConfig.h"
#include "lwip/dhcp.h"
#include "networking.h"
#include "stm32h7xx_nucleo.h"
#include "udp_config.h"
#if LWIP_DHCP == 1
uint8_t DHCP_state = DHCP_OFF;
uint32_t DHCPfineTimer = 0;
void handle_dhcp_timeout(struct netif* netif);
void handle_dhcp_start(struct netif* netif);
void handle_dhcp_wait(struct netif* netif, struct dhcp** dhcp);
void handle_dhcp_down(struct netif* netif);
void handle_dhcp_timeout(struct netif *netif);
void handle_dhcp_start(struct netif *netif);
void handle_dhcp_wait(struct netif *netif, struct dhcp **dhcp);
void handle_dhcp_down(struct netif *netif);
/**
* @brief DHCP_Process_Handle
* @param None
* @retval None
*/
void DHCP_Process(struct netif *netif)
{
struct dhcp* dhcp = NULL;
void DHCP_Process(struct netif *netif) {
struct dhcp *dhcp = nullptr;
switch (DHCP_state) {
case DHCP_START: {
handle_dhcp_start(netif);
@ -47,7 +43,7 @@ void DHCP_Process(struct netif *netif)
}
}
void handle_dhcp_timeout(struct netif* netif) {
void handle_dhcp_timeout(struct netif *netif) {
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gw;
@ -67,7 +63,7 @@ void handle_dhcp_timeout(struct netif* netif) {
printf("Assigning static IP address: %s\n", iptxt);
#if defined FSFW_OSAL_FREERTOS
ETH_HandleTypeDef* handle = getEthernetHandle();
ETH_HandleTypeDef *handle = getEthernetHandle();
handle->gState = HAL_ETH_STATE_READY;
#endif
@ -84,8 +80,7 @@ void handle_dhcp_timeout(struct netif* netif) {
* @param netif
* @retval None
*/
void DHCP_Periodic_Handle(struct netif *netif)
{
void DHCP_Periodic_Handle(struct netif *netif) {
/* Fine DHCP periodic process every 500ms */
if (HAL_GetTick() - DHCPfineTimer >= DHCP_FINE_TIMER_MSECS) {
DHCPfineTimer = HAL_GetTick();
@ -94,7 +89,7 @@ void DHCP_Periodic_Handle(struct netif *netif)
}
}
void handle_dhcp_start(struct netif* netif) {
void handle_dhcp_start(struct netif *netif) {
printf("handle_dhcp_start: Looking for DHCP server ...\n\r");
#if OBSW_ETHERNET_TMTC_COMMANDING == 1
#if OBSW_ETHERNET_USE_LED1_LED2 == 1
@ -109,10 +104,11 @@ void handle_dhcp_start(struct netif* netif) {
DHCP_state = DHCP_WAIT_ADDRESS;
}
void handle_dhcp_wait(struct netif* netif, struct dhcp** dhcp) {
void handle_dhcp_wait(struct netif *netif, struct dhcp **dhcp) {
if (dhcp_supplied_address(netif)) {
DHCP_state = DHCP_ADDRESS_ASSIGNED;
printf("IP address assigned by a DHCP server: %s\n\r", ip4addr_ntoa(netif_ip4_addr(netif)));
printf("IP address assigned by a DHCP server: %s\n\r",
ip4addr_ntoa(netif_ip4_addr(netif)));
printf("Listener port: %d\n\r", UDP_SERVER_PORT);
#if OBSW_ETHERNET_TMTC_COMMANDING == 1
#if OBSW_ETHERNET_USE_LED1_LED2 == 1
@ -120,19 +116,19 @@ void handle_dhcp_wait(struct netif* netif, struct dhcp** dhcp) {
BSP_LED_Off(LED2);
#endif
#endif
}
else {
*dhcp = (struct dhcp*) netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP);
} else {
*dhcp = static_cast<struct dhcp *>(netif_get_client_data(
netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP));
/* DHCP timeout */
if ((*dhcp)->tries > MAX_DHCP_TRIES)
{
if ((*dhcp)->tries > MAX_DHCP_TRIES) {
handle_dhcp_timeout(netif);
}
}
}
void handle_dhcp_down(struct netif* netif) {
void handle_dhcp_down(struct netif *netif) {
static_cast<void>(netif);
DHCP_state = DHCP_OFF;
#if OBSW_ETHERNET_TMTC_COMMANDING == 1
printf("DHCP_Process: The network cable is not connected.\n\r");
@ -146,12 +142,8 @@ void handle_dhcp_down(struct netif* netif) {
networking::setEthCableConnected(false);
}
uint8_t get_dhcp_state() {
return DHCP_state;
}
uint8_t get_dhcp_state() { return DHCP_state; }
void set_dhcp_state(uint8_t new_state) {
DHCP_state = new_state;
}
void set_dhcp_state(uint8_t new_state) { DHCP_state = new_state; }
#endif /* LWIP_DHCP == 1 */

View File

@ -12,12 +12,12 @@ extern "C" {
#include "lwip/netif.h"
/* DHCP process states */
#define DHCP_OFF (uint8_t) 0
#define DHCP_START (uint8_t) 1
#define DHCP_WAIT_ADDRESS (uint8_t) 2
#define DHCP_ADDRESS_ASSIGNED (uint8_t) 3
#define DHCP_TIMEOUT (uint8_t) 4
#define DHCP_LINK_DOWN (uint8_t) 5
#define DHCP_OFF (uint8_t)0
#define DHCP_START (uint8_t)1
#define DHCP_WAIT_ADDRESS (uint8_t)2
#define DHCP_ADDRESS_ASSIGNED (uint8_t)3
#define DHCP_TIMEOUT (uint8_t)4
#define DHCP_LINK_DOWN (uint8_t)5
uint8_t get_dhcp_state();
void set_dhcp_state(uint8_t new_state);

View File

@ -1,17 +1,18 @@
/* Includes ------------------------------------------------------------------*/
#include "app_ethernet.h"
#include "ethernetif.h"
#include "udp_config.h"
#include "networking.h"
#include "udp_config.h"
#if LWIP_DHCP
#include "app_dhcp.h"
#endif
#include <lwipopts.h>
#include <lwip/netif.h>
#include <stm32h7xx_nucleo.h>
#include <OBSWConfig.h>
#include <lwip/netif.h>
#include <lwipopts.h>
#include <stm32h7xx_nucleo.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
@ -20,8 +21,7 @@
uint32_t ethernetLinkTimer = 0;
/* Private function prototypes -----------------------------------------------*/
void handle_status_change(struct netif* netif, bool link_up);
void handle_status_change(struct netif *netif, bool link_up);
/* Private functions ---------------------------------------------------------*/
/**
@ -29,37 +29,32 @@ void handle_status_change(struct netif* netif, bool link_up);
* @param netif: the network interface
* @retval None
*/
void networking::ethernetLinkStatusUpdated(struct netif *netif)
{
if (netif_is_link_up(netif))
{
void networking::ethernetLinkStatusUpdated(struct netif *netif) {
if (netif_is_link_up(netif)) {
networking::setEthCableConnected(true);
handle_status_change(netif, true);
}
else
{
} else {
networking::setEthCableConnected(false);
handle_status_change(netif, false);
}
}
void handle_status_change(struct netif* netif, bool link_up) {
if(link_up) {
void handle_status_change(struct netif *netif, bool link_up) {
if (link_up) {
#if LWIP_DHCP
/* Update DHCP state machine */
set_dhcp_state(DHCP_START);
#else
uint8_t iptxt[20];
sprintf((char *)iptxt, "%s", ip4addr_ntoa(netif_ip4_addr(netif)));
printf("\rNetwork cable connected. Static IP address: %s | Port: %d\n\r", iptxt,
UDP_SERVER_PORT);
printf("\rNetwork cable connected. Static IP address: %s | Port: %d\n\r",
iptxt, UDP_SERVER_PORT);
#if OBSW_ETHERNET_USE_LED1_LED2 == 1
BSP_LED_On(LED1);
BSP_LED_Off(LED2);
#endif
#endif /* LWIP_DHCP */
}
else {
} else {
printf("Network cable disconnected\n\r");
#if LWIP_DHCP
/* Update DHCP state machine */
@ -80,11 +75,9 @@ void handle_status_change(struct netif* netif, bool link_up) {
* @param netif
* @retval None
*/
void networking::ethernetLinkPeriodicHandle(struct netif *netif)
{
void networking::ethernetLinkPeriodicHandle(struct netif *netif) {
/* Ethernet Link every 100ms */
if (HAL_GetTick() - ethernetLinkTimer >= 100)
{
if (HAL_GetTick() - ethernetLinkTimer >= 100) {
ethernetLinkTimer = HAL_GetTick();
ethernet_link_check_state(netif);
}

View File

@ -48,7 +48,7 @@
#define EXAMPLE_COMMON_APP_ETHERNET_H
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
@ -65,7 +65,7 @@ namespace networking {
void ethernetLinkStatusUpdated(struct netif *netif);
void ethernetLinkPeriodicHandle(struct netif *netif);
}
} // namespace networking
#ifdef __cplusplus
}
@ -73,6 +73,4 @@ void ethernetLinkPeriodicHandle(struct netif *netif);
#endif /* EXAMPLE_COMMON_APP_ETHERNET_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -44,16 +44,17 @@
*/
/* Includes ------------------------------------------------------------------*/
#include "fsfw/FSFW.h"
#include "stm32h7xx_hal.h"
#include "lwip/opt.h"
#include "lwip/timeouts.h"
#include "lwip/netif.h"
#include "netif/etharp.h"
#include "ethernetif.h"
#include "lan8742.h"
#include <string.h>
#include <lan8742.h>
#include <stm32h7xx_hal.h>
#include <lwip/netif.h>
#include <lwip/opt.h>
#include <lwip/timeouts.h>
#include <netif/etharp.h>
#include <stdbool.h>
#include "fsfw/FSFW.h"
#ifdef FSFW_OSAL_RTEMS
#include <rtems.h>
@ -65,14 +66,20 @@
#define IFNAME0 's'
#define IFNAME1 't'
#define ETH_DMA_TRANSMIT_TIMEOUT (20U)
#define ETH_RX_BUFFER_SIZE 1536U
#define ETH_RX_BUFFER_CNT 12U
#define ETH_TX_BUFFER_MAX ((ETH_TX_DESC_CNT) * 2U)
#define DMA_DESCRIPTOR_ALIGNMENT 0x20
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/*
@Note: This interface is implemented to operate in zero-copy mode only:
- Rx buffers are allocated statically and passed directly to the LwIP stack
they will return back to DMA after been processed by the stack.
- Rx buffers are allocated statically and passed directly to the LwIP
stack they will return back to DMA after been processed by the stack.
- Tx Buffers will be allocated from LwIP stack memory heap,
then passed to ETH HAL driver.
@ -86,68 +93,97 @@
2.b. Rx Buffers must have the same size: ETH_RX_BUFFER_SIZE, this value must
passed to ETH DMA in the init field (EthHandle.Init.RxBuffLen)
*/
typedef enum
{
RX_ALLOC_OK = 0x00,
RX_ALLOC_ERROR = 0x01
} RxAllocStatusTypeDef;
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
typedef struct
{
struct pbuf_custom pbuf_custom;
uint8_t buff[(ETH_RX_BUFFER_SIZE + 31) & ~31] __ALIGNED(32);
} RxBuff_t;
#pragma location=0x30040000
#if defined(__ICCARM__) /*!< IAR Compiler */
#pragma location=0x30000000
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
#pragma location=0x30040060
#pragma location=0x30000200
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
#pragma location=0x30040200
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
#elif defined(__CC_ARM) /* MDK ARM Compiler */
__attribute__((section(".RxDecripSection"))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
__attribute__((section(".TxDecripSection"))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
__attribute__((section(".RxArraySection"))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */
#elif defined ( __GNUC__ ) /* GNU Compiler */
#elif defined(__GNUC__) /* GNU Compiler */
#ifdef FSFW_OSAL_RTEMS
/* Put into special RTEMS section and align correctly */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".bsp_nocache"), __aligned__(DMA_DESCRIPTOR_ALIGNMENT))); /* Ethernet Rx DMA Descriptors */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((
section(".bsp_nocache"),
__aligned__(DMA_DESCRIPTOR_ALIGNMENT))); /* Ethernet Rx DMA Descriptors */
/* Put into special RTEMS section and align correctly */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".bsp_nocache"), __aligned__(DMA_DESCRIPTOR_ALIGNMENT))); /* Ethernet Tx DMA Descriptors */
/* Ethernet Receive Buffers. Just place somewhere is BSS instead of explicitely placing it */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((
section(".bsp_nocache"),
__aligned__(DMA_DESCRIPTOR_ALIGNMENT))); /* Ethernet Tx DMA Descriptors */
/* Ethernet Receive Buffers. Just place somewhere is BSS instead of explicitely
* placing it */
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE];
#elif defined FSFW_OSAL_FREERTOS
/* Placement and alignment specified in linker script here */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffers */
#endif /* FSFW_FREERTOS */
#endif /* FSFW_OSAL_RTEMS */
#endif /* defined ( __GNUC__ ) */
/* Memory Pool Declaration */
LWIP_MEMPOOL_DECLARE(RX_POOL, ETH_RX_BUFFER_CNT, sizeof(RxBuff_t), "Zero-copy RX PBUF pool");
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma location = 0x30000400
extern u8_t memp_memory_RX_POOL_base[];
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
#elif defined ( __GNUC__ ) /* GNU Compiler */
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
#endif
/* Global boolean to track ethernet connection */
bool ethernet_cable_connected;
struct pbuf_custom rx_pbuf[ETH_RX_DESC_CNT];
uint32_t current_pbuf_idx =0;
/* Variable Definitions */
static uint8_t RxAllocStatus;
/* Global Ethernet handle*/
ETH_HandleTypeDef EthHandle;
ETH_TxPacketConfig TxConfig;
lan8742_Object_t LAN8742;
/* Private function prototypes -----------------------------------------------*/
u32_t sys_now(void);
void pbuf_free_custom(struct pbuf *p);
extern void Error_Handler(void);
int32_t ETH_PHY_IO_Init(void);
int32_t ETH_PHY_IO_DeInit (void);
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal);
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal);
int32_t ETH_PHY_IO_GetTick(void);
lan8742_Object_t LAN8742;
lan8742_IOCtx_t LAN8742_IOCtx = {ETH_PHY_IO_Init,
ETH_PHY_IO_DeInit,
ETH_PHY_IO_WriteReg,
ETH_PHY_IO_ReadReg,
ETH_PHY_IO_GetTick};
/* Private functions ---------------------------------------------------------*/
void pbuf_free_custom(struct pbuf *p);
/*******************************************************************************
LL Driver Interface ( LwIP stack --> ETH)
*******************************************************************************/
@ -158,9 +194,7 @@ lan8742_IOCtx_t LAN8742_IOCtx = {ETH_PHY_IO_Init,
* @param netif the already initialized lwip network interface structure
* for this ethernetif
*/
static void low_level_init(struct netif *netif)
{
uint32_t idx = 0;
static void low_level_init(struct netif *netif) {
uint8_t macaddress[6]= {ETH_MAC_ADDR0, ETH_MAC_ADDR1, ETH_MAC_ADDR2, ETH_MAC_ADDR3, ETH_MAC_ADDR4, ETH_MAC_ADDR5};
EthHandle.Instance = ETH;
@ -174,15 +208,15 @@ static void low_level_init(struct netif *netif)
HAL_ETH_Init(&EthHandle);
/* set MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
netif->hwaddr_len = ETH_HWADDR_LEN;
/* set MAC hardware address */
netif->hwaddr[0] = 0x02;
netif->hwaddr[1] = 0x00;
netif->hwaddr[2] = 0x00;
netif->hwaddr[3] = 0x00;
netif->hwaddr[4] = 0x00;
netif->hwaddr[5] = 0x00;
netif->hwaddr[0] = ETH_MAC_ADDR0;
netif->hwaddr[1] = ETH_MAC_ADDR1;
netif->hwaddr[2] = ETH_MAC_ADDR2;
netif->hwaddr[3] = ETH_MAC_ADDR3;
netif->hwaddr[4] = ETH_MAC_ADDR4;
netif->hwaddr[5] = ETH_MAC_ADDR5;
/* maximum transfer unit */
netif->mtu = ETH_MAX_PAYLOAD;
@ -191,13 +225,8 @@ static void low_level_init(struct netif *netif)
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
for(idx = 0; idx < ETH_RX_DESC_CNT; idx ++)
{
HAL_ETH_DescAssignMemory(&EthHandle, idx, Rx_Buff[idx], NULL);
/* Set Custom pbuf free function */
rx_pbuf[idx].custom_free_function = pbuf_free_custom;
}
/* Initialize the RX POOL */
LWIP_MEMPOOL_INIT(RX_POOL);
/* Set Tx packet config common parameters */
memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig));
@ -212,16 +241,16 @@ static void low_level_init(struct netif *netif)
LAN8742_Init(&LAN8742);
ethernet_link_check_state(netif);
}
/**
* @brief This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* @brief This function should do the actual transmission of the packet. The
* packet is contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this ethernetif
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and
* type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
@ -230,12 +259,13 @@ static void low_level_init(struct netif *netif)
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
uint32_t i=0, framelen = 0;
struct pbuf *q;
static err_t low_level_output(struct netif *netif, struct pbuf *p) {
uint32_t i = 0U;
struct pbuf *q = NULL;
err_t errval = ERR_OK;
ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT];
ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT] = {0};
memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef));
for(q = p; q != NULL; q = q->next)
{
@ -244,7 +274,6 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p)
Txbuffer[i].buffer = q->payload;
Txbuffer[i].len = q->len;
framelen += q->len;
if(i>0)
{
@ -259,15 +288,15 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p)
i++;
}
TxConfig.Length = framelen;
TxConfig.Length = p->tot_len;
TxConfig.TxBuffer = Txbuffer;
TxConfig.pData = p;
HAL_StatusTypeDef ret = HAL_ETH_Transmit(&EthHandle, &TxConfig, 20);
if(ret != HAL_OK) {
printf("low_level_output: Could not transmit ethernet packet, code %d!\n\r", ret);
HAL_StatusTypeDef ret = HAL_ETH_Transmit(&EthHandle, &TxConfig, ETH_DMA_TRANSMIT_TIMEOUT);
if (ret != HAL_OK) {
printf("low_level_output: Could not transmit ethernet packet, code %d!\n\r",
ret);
}
return errval;
}
@ -279,69 +308,42 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p)
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
static struct pbuf * low_level_input(struct netif *netif)
{
static struct pbuf *low_level_input(struct netif *netif) {
struct pbuf *p = NULL;
ETH_BufferTypeDef RxBuff;
uint32_t framelength = 0;
if (HAL_ETH_IsRxDataAvailable(&EthHandle))
if(RxAllocStatus == RX_ALLOC_OK)
{
HAL_ETH_GetRxDataBuffer(&EthHandle, &RxBuff);
HAL_ETH_GetRxDataLength(&EthHandle, &framelength);
/* Invalidate data cache for ETH Rx Buffers */
SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff, (ETH_RX_DESC_CNT*ETH_RX_BUFFER_SIZE));
p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_POOL, &rx_pbuf[current_pbuf_idx], RxBuff.buffer, ETH_RX_BUFFER_SIZE);
if(current_pbuf_idx < (ETH_RX_DESC_CNT -1))
{
current_pbuf_idx++;
}
else
{
current_pbuf_idx = 0;
HAL_ETH_ReadData(&EthHandle, (void **)&p);
}
return p;
}
else
{
return NULL;
}
}
/**
* @brief This function is the ethernetif_input task, it is processed when a packet
* is ready to be read from the interface. It uses the function low_level_input()
* that should handle the actual reception of bytes from the network
* interface. Then the type of the received packet is determined and
* the appropriate input function is called.
* @brief This function is the ethernetif_input task, it is processed when a
* packet is ready to be read from the interface. It uses the function
* low_level_input() that should handle the actual reception of bytes from the
* network interface. Then the type of the received packet is determined and the
* appropriate input function is called.
*
* @param netif the lwip network interface structure for this ethernetif
*/
void ethernetif_input(struct netif *netif)
{
err_t err;
struct pbuf *p;
void ethernetif_input(struct netif *netif) {
struct pbuf *p = NULL;
/* move received packet into a new pbuf */
p = low_level_input(netif);
/* no packet could be read, silently ignore this */
if (p == NULL) return;
/* entry point to the LwIP stack */
err = netif->input(p, netif);
if (err != ERR_OK)
do
{
p = low_level_input( netif );
if (p != NULL)
{
if (netif->input( p, netif) != ERR_OK )
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
p = NULL;
}
}
HAL_ETH_BuildRxDescriptors(&EthHandle);
} while(p!=NULL);
}
/**
@ -356,8 +358,7 @@ void ethernetif_input(struct netif *netif)
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t ethernetif_init(struct netif *netif)
{
err_t ethernetif_init(struct netif *netif) {
LWIP_ASSERT("netif != NULL", (netif != NULL));
#if LWIP_NETIF_HOSTNAME
@ -367,6 +368,7 @@ err_t ethernetif_init(struct netif *netif)
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
@ -385,15 +387,14 @@ err_t ethernetif_init(struct netif *netif)
* @param pbuf: pbuf to be freed
* @retval None
*/
void pbuf_free_custom(struct pbuf *p)
{
if(p != NULL)
void pbuf_free_custom(struct pbuf *p) {
struct pbuf_custom* custom_pbuf = (struct pbuf_custom*)p;
LWIP_MEMPOOL_FREE(RX_POOL, custom_pbuf);
/* If the Rx Buffer Pool was exhausted, signal the ethernetif_input task to
* call HAL_ETH_GetRxDataBuffer to rebuild the Rx descriptors. */
if (RxAllocStatus == RX_ALLOC_ERROR)
{
p->flags = 0;
p->next = NULL;
p->len = p->tot_len = 0;
p->ref = 0;
p->payload = NULL;
RxAllocStatus = RX_ALLOC_OK;
}
}
@ -403,10 +404,7 @@ void pbuf_free_custom(struct pbuf *p)
* @param None
* @retval Current Time value
*/
u32_t sys_now(void)
{
return HAL_GetTick();
}
u32_t sys_now(void) { return HAL_GetTick(); }
/*******************************************************************************
Ethernet MSP Routines
@ -415,9 +413,8 @@ u32_t sys_now(void)
* @brief Initializes the ETH MSP.
* @param heth: ETH handle
* @retval None
*/
void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
{
*/
void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) {
GPIO_InitTypeDef GPIO_InitStructure;
/* Ethernett MSP init: RMII Mode */
@ -428,7 +425,8 @@ void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/* Ethernet pins configuration ************************************************/
/* Ethernet pins configuration
* ************************************************/
/*
RMII_REF_CLK ----------------------> PA1
RMII_MDIO -------------------------> PA2
@ -482,8 +480,7 @@ void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
* @param None
* @retval 0 if OK, -1 if ERROR
*/
int32_t ETH_PHY_IO_Init(void)
{
int32_t ETH_PHY_IO_Init(void) {
/* We assume that MDIO GPIO configuration is already done
in the ETH_MspInit() else it should be done here
*/
@ -499,10 +496,7 @@ int32_t ETH_PHY_IO_Init(void)
* @param None
* @retval 0 if OK, -1 if ERROR
*/
int32_t ETH_PHY_IO_DeInit (void)
{
return 0;
}
int32_t ETH_PHY_IO_DeInit(void) { return 0; }
/**
* @brief Read a PHY register through the MDIO interface.
@ -511,10 +505,10 @@ int32_t ETH_PHY_IO_DeInit (void)
* @param pRegVal: pointer to hold the register value
* @retval 0 if OK -1 if Error
*/
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal)
{
if(HAL_ETH_ReadPHYRegister(&EthHandle, DevAddr, RegAddr, pRegVal) != HAL_OK)
{
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr,
uint32_t *pRegVal) {
if (HAL_ETH_ReadPHYRegister(&EthHandle, DevAddr, RegAddr, pRegVal) !=
HAL_OK) {
return -1;
}
@ -528,10 +522,10 @@ int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal
* @param RegVal: Value to be written
* @retval 0 if OK -1 if Error
*/
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal)
{
if(HAL_ETH_WritePHYRegister(&EthHandle, DevAddr, RegAddr, RegVal) != HAL_OK)
{
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr,
uint32_t RegVal) {
if (HAL_ETH_WritePHYRegister(&EthHandle, DevAddr, RegAddr, RegVal) !=
HAL_OK) {
return -1;
}
@ -542,26 +536,22 @@ int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal)
* @brief Get the time in millisecons used for internal PHY driver process.
* @retval Time value
*/
int32_t ETH_PHY_IO_GetTick(void)
{
return HAL_GetTick();
}
int32_t ETH_PHY_IO_GetTick(void) { return HAL_GetTick(); }
/**
* @brief
* @retval None
*/
void ethernet_link_check_state(struct netif *netif)
{
ETH_MACConfigTypeDef MACConf;
uint32_t PHYLinkState;
uint32_t linkchanged = 0, speed = 0, duplex =0;
void ethernet_link_check_state(struct netif *netif) {
ETH_MACConfigTypeDef MACConf = {0};
int32_t PHYLinkState = 0U;
uint32_t linkchanged = 0U, speed = 0U, duplex = 0U;
PHYLinkState = LAN8742_GetLinkState(&LAN8742);
if(netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN))
{
HAL_ETH_Stop(&EthHandle);
HAL_ETH_Stop_IT(&EthHandle);
netif_set_down(netif);
netif_set_link_down(netif);
}
@ -600,15 +590,74 @@ void ethernet_link_check_state(struct netif *netif)
MACConf.DuplexMode = duplex;
MACConf.Speed = speed;
HAL_ETH_SetMACConfig(&EthHandle, &MACConf);
HAL_ETH_Start(&EthHandle);
HAL_ETH_Start_IT(&EthHandle);
netif_set_up(netif);
netif_set_link_up(netif);
}
}
}
ETH_HandleTypeDef* getEthernetHandle() {
return &EthHandle;
void HAL_ETH_RxAllocateCallback(uint8_t **buff)
{
struct pbuf_custom *p = LWIP_MEMPOOL_ALLOC(RX_POOL);
if (p)
{
/* Get the buff from the struct pbuf address. */
*buff = (uint8_t *)p + offsetof(RxBuff_t, buff);
p->custom_free_function = pbuf_free_custom;
/* Initialize the struct pbuf.
* This must be performed whenever a buffer's allocated because it may be
* changed by lwIP or the app, e.g., pbuf_free decrements ref. */
pbuf_alloced_custom(PBUF_RAW, 0, PBUF_REF, p, *buff, ETH_RX_BUFFER_SIZE);
}
else
{
RxAllocStatus = RX_ALLOC_ERROR;
*buff = NULL;
}
}
void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length)
{
struct pbuf **ppStart = (struct pbuf **)pStart;
struct pbuf **ppEnd = (struct pbuf **)pEnd;
struct pbuf *p = NULL;
/* Get the struct pbuf from the buff address. */
p = (struct pbuf *)(buff - offsetof(RxBuff_t, buff));
p->next = NULL;
p->tot_len = 0;
p->len = Length;
/* Chain the buffer. */
if (!*ppStart)
{
/* The first buffer of the packet. */
*ppStart = p;
}
else
{
/* Chain the buffer to the end of the packet. */
(*ppEnd)->next = p;
}
*ppEnd = p;
/* Update the total length of all the buffers of the chain. Each pbuf in the chain should have its tot_len
* set to its own length, plus the length of all the following pbufs in the chain. */
for (p = *ppStart; p != NULL; p = p->next)
{
p->tot_len += Length;
}
/* Invalidate data cache because Rx DMA's writing to physical memory makes it stale. */
SCB_InvalidateDCache_by_Addr((uint32_t *)buff, Length);
}
void HAL_ETH_TxFreeCallback(uint32_t * buff)
{
pbuf_free((struct pbuf *)buff);
}
ETH_HandleTypeDef *getEthernetHandle() { return &EthHandle; }
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -46,27 +46,24 @@
#ifndef __ETHERNETIF_H__
#define __ETHERNETIF_H__
#include <stm32h7xx_hal.h>
#include "lwip/err.h"
#include "lwip/netif.h"
#include <stm32h7xx_hal.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#define ETH_RX_BUFFER_SIZE (1536UL)
/* Exported types ------------------------------------------------------------*/
ETH_HandleTypeDef* getEthernetHandle();
ETH_HandleTypeDef *getEthernetHandle();
err_t ethernetif_init(struct netif *netif);
void ethernetif_input(struct netif *netif);
void ethernet_link_check_state(struct netif *netif);
extern ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT];
extern ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT];
extern uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE];
#ifdef __cplusplus
}

View File

@ -1,19 +1,18 @@
#include "udp_config.h"
#include "networking.h"
#include "udp_config.h"
bool ethernetCableConnected = false;
void networking::setEthCableConnected(bool status) {
ethernetCableConnected = status;
}
bool networking::getEthCableConnected() {
return ethernetCableConnected;
}
bool networking::getEthCableConnected() { return ethernetCableConnected; }
void networking::setLwipAddresses(ip_addr_t* ipaddr, ip_addr_t* netmask, ip_addr_t* gw) {
void networking::setLwipAddresses(ip_addr_t *ipaddr, ip_addr_t *netmask,
ip_addr_t *gw) {
IP4_ADDR(ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
IP4_ADDR(netmask, NETMASK_ADDR0, NETMASK_ADDR1 ,
NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
}

View File

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

View File

@ -8,7 +8,8 @@ extern "C" {
/* UDP local connection port. Client needs to bind to this port */
#define UDP_SERVER_PORT 7
/*Static DEST IP ADDRESS: DEST_IP_ADDR0.DEST_IP_ADDR1.DEST_IP_ADDR2.DEST_IP_ADDR3 */
/*Static DEST IP ADDRESS:
* DEST_IP_ADDR0.DEST_IP_ADDR1.DEST_IP_ADDR2.DEST_IP_ADDR3 */
#define DEST_IP_ADDR0 ((uint8_t)169U)
#define DEST_IP_ADDR1 ((uint8_t)254U)
#define DEST_IP_ADDR2 ((uint8_t)39U)