From e0afd3c3fb2880740a22b56761cbd33e665cd37a Mon Sep 17 00:00:00 2001 From: mshahabn Date: Tue, 2 Dec 2025 17:56:34 -0800 Subject: [PATCH] Add missing implementation of GenericHub (#4420) * Revise GenericHub model * Revise GenericHub model * Revise GenericHub model * Update spelling * Revise annotations * Revise annotations for GenericHub model * Revise annotations in GenericHub model * Revise GenericHub model * Revise GenericHub model * Revise GenericHub model * Revise GenericHub * Revise GenericHub * Revise GenericHub model * Revise GenericHub model * Revise GenericHub config * Revise GenericHub model * Revise GenericHub model * Clean up naming in GenericHub implementation * Revise GenericHub port names * Revise annotations in GenericHub model * Revise annotations in GenericHub model * Revise annotations in GenericHub model * Add ByteStreamDriverClient * Revise ByteStreamDriverClient * Revise ByteStreamDriverClient * Revise driver interfaces * Add PassiveByteStreamDriverClientSendAsync interface * Add PassiveAsyncByteStreamDriverClient interface * Add PassiveBufferDriver * Revise PassiveByteStreamDriverClient interfaces * Revise PassiveBufferDriver * Revise Drv interfaces * Revise PassiveBufferDriver * Add PassiveBufferDriverClient * Revise GenericHub model Use interfaces from Drv * Revise annotations in GenericHub model * Revise FPP models Point FPP to a non-released version with a bug fix * Add ByteStreamBufferAdapter * Revise ByteStreamBufferAdapter model * Revise ByteStreamBufferAdapter * Revise ByteStreamBufferAdapter * Add AsyncByteStreamBufferAdapter * Revise AsyncByteStreamBufferAdapter * Revsie AsyncByteStreamBufferAdapter * Revise AsyncByteStreamBufferAdapter * Revise annotations in FPP model * Revise ByteStreamBufferAdapter * Bump fpp version * Revise GenericHub model * Revise GenericHub interface * Revise GenericHub interface * Fix typo in FPP annotations * Revise Generic Hub model * Fix spelling and formatting * Review recommendations --------- Co-authored-by: Rob Bocchino Co-authored-by: thomas-bc --- .github/actions/spelling/expect.txt | 3 +- .../AsyncByteStreamBufferAdapter.cpp | 52 +++++ .../AsyncByteStreamBufferAdapter.fpp | 33 +++ .../AsyncByteStreamBufferAdapter.hpp | 80 ++++++++ .../CMakeLists.txt | 10 + .../ByteStreamBufferAdapter.cpp | 47 +++++ .../ByteStreamBufferAdapter.fpp | 33 +++ .../ByteStreamBufferAdapter.hpp | 72 +++++++ Drv/ByteStreamBufferAdapter/CMakeLists.txt | 10 + Drv/CMakeLists.txt | 6 +- Drv/Interfaces/CMakeLists.txt | 5 + .../PassiveAsyncByteStreamDriverClient.fpp | 25 +++ Drv/Interfaces/PassiveBufferDriver.fpp | 14 ++ Drv/Interfaces/PassiveBufferDriverClient.fpp | 40 ++++ .../PassiveByteStreamDriverClient.fpp | 22 ++ ...PassiveByteStreamDriverClientReadyRecv.fpp | 26 +++ Fw/Buffer/Buffer.fpp | 22 ++ Svc/GenericHub/CMakeLists.txt | 2 +- ...ricHubComponentImpl.cpp => GenericHub.cpp} | 69 ++++--- Svc/GenericHub/GenericHub.fpp | 191 +++++++++++++++--- Svc/GenericHub/GenericHub.hpp | 103 +++++++++- Svc/GenericHub/GenericHubComponentImpl.hpp | 97 --------- Svc/GenericHub/test/ut/GenericHubTester.cpp | 179 ++++++++-------- Svc/GenericHub/test/ut/GenericHubTester.hpp | 62 +++--- Svc/GenericHub/test/ut/README.md | 51 +++++ .../test/ut/img/buffer_data_transfer.svg | 1 + .../test/ut/img/event_data_transfer.svg | 1 + .../test/ut/img/generic_hub_testing_1.svg | 1 + .../test/ut/img/generic_hub_testing_2.svg | 1 + .../test/ut/img/serial_data_transfer.svg | 1 + .../test/ut/img/telem_data_transfer.svg | 1 + default/config/AcConstants.fpp | 9 - default/config/CMakeLists.txt | 3 +- default/config/GenericHubCfg.fpp | 16 ++ 34 files changed, 998 insertions(+), 290 deletions(-) create mode 100644 Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.cpp create mode 100644 Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.fpp create mode 100644 Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.hpp create mode 100644 Drv/AsyncByteStreamBufferAdapter/CMakeLists.txt create mode 100644 Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.cpp create mode 100644 Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.fpp create mode 100644 Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.hpp create mode 100644 Drv/ByteStreamBufferAdapter/CMakeLists.txt create mode 100644 Drv/Interfaces/PassiveAsyncByteStreamDriverClient.fpp create mode 100644 Drv/Interfaces/PassiveBufferDriver.fpp create mode 100644 Drv/Interfaces/PassiveBufferDriverClient.fpp create mode 100644 Drv/Interfaces/PassiveByteStreamDriverClient.fpp create mode 100644 Drv/Interfaces/PassiveByteStreamDriverClientReadyRecv.fpp rename Svc/GenericHub/{GenericHubComponentImpl.cpp => GenericHub.cpp} (75%) delete mode 100644 Svc/GenericHub/GenericHubComponentImpl.hpp create mode 100644 Svc/GenericHub/test/ut/README.md create mode 100644 Svc/GenericHub/test/ut/img/buffer_data_transfer.svg create mode 100644 Svc/GenericHub/test/ut/img/event_data_transfer.svg create mode 100644 Svc/GenericHub/test/ut/img/generic_hub_testing_1.svg create mode 100644 Svc/GenericHub/test/ut/img/generic_hub_testing_2.svg create mode 100644 Svc/GenericHub/test/ut/img/serial_data_transfer.svg create mode 100644 Svc/GenericHub/test/ut/img/telem_data_transfer.svg create mode 100644 default/config/GenericHubCfg.fpp diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 43d8c8c02f..62a5fc3769 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -18,7 +18,6 @@ arduino ARef argcomplete ARGN -binaryfile ARINC arpa ASize @@ -36,6 +35,7 @@ bfree BHn bibtex Bies +binaryfile BINDIR bitmaps bitshifts @@ -43,6 +43,7 @@ bitwidth bocchino boolt bsd +BSDI bst BUFFERALLOCATE BUFFERALLOCATIONFAILED diff --git a/Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.cpp b/Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.cpp new file mode 100644 index 0000000000..cd732406ea --- /dev/null +++ b/Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.cpp @@ -0,0 +1,52 @@ +// ====================================================================== +// \title AsyncByteStreamBufferAdapter.cpp +// \author bocchino +// \brief cpp file for AsyncByteStreamBufferAdapter component implementation class +// ====================================================================== + +#include "Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.hpp" + +namespace Drv { + +// ---------------------------------------------------------------------- +// Component construction and destruction +// ---------------------------------------------------------------------- + +AsyncByteStreamBufferAdapter::AsyncByteStreamBufferAdapter(const char* const compName) + : AsyncByteStreamBufferAdapterComponentBase(compName) {} + +AsyncByteStreamBufferAdapter::~AsyncByteStreamBufferAdapter() {} + +// ---------------------------------------------------------------------- +// Handler implementations for typed input ports +// ---------------------------------------------------------------------- + +void AsyncByteStreamBufferAdapter::bufferIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) { + // TODO: If m_driverIsReady then send fwBuffer on toByteStreamDriver_out + // TODO: Otherwise + // TODO: Log the error + // TODO: Send fwBuffer on bufferInReturn_out +} + +void AsyncByteStreamBufferAdapter::bufferOutReturn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) { + // TODO: Send fwBuffer on fromByteStreamDriverReturn_out +} + +void AsyncByteStreamBufferAdapter::byteStreamDriverReady_handler(FwIndexType portNum) { + this->m_driverIsReady = true; +} + +void AsyncByteStreamBufferAdapter::fromByteStreamDriver_handler(FwIndexType portNum, + Fw::Buffer& buffer, + const Drv::ByteStreamStatus& status) { + // TODO: If the status is OK, then send buffer on toByteStreamDriver_out + // TODO: Otherwise log the error and send buffer on fromByteStreamDriverReturn_out +} + +void AsyncByteStreamBufferAdapter::toByteStreamDriverReturn_handler(FwIndexType portNum, + Fw::Buffer& buffer, + const Drv::ByteStreamStatus& status) { + // TODO: Send fwBuffer on bufferInReturn_out +} + +} // namespace Drv diff --git a/Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.fpp b/Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.fpp new file mode 100644 index 0000000000..a80f1df47b --- /dev/null +++ b/Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.fpp @@ -0,0 +1,33 @@ +module Drv { + + @ A passive component for mediating between the AsyncByteStreamDriver + @ interface and the PassiveBufferDriver interface + @ + @ Sample topology: + @ + @ ----------------------------------------------------------- + @ | | + @ | AsyncByteStreamDriver <--> AsyncByteStreamBufferAdapter | <--> PassiveBufferDriverClient + @ | | + @ ----------------------------------------------------------- + @ + @ The two components in the box function together as a PassiveBufferDriver: + @ + @ ------------------------------------------------- + @ | | + @ | PassiveBufferDriver | <--> PassiveBufferDriverClient + @ | | + @ ------------------------------------------------- + @ + passive component AsyncByteStreamBufferAdapter { + + @ AsyncByteStreamBufferAdapter is a passive client of the + @ AsyncByteStreamDriver interface + import PassiveAsyncByteStreamDriverClient + + @ AsyncByteStreamBufferAdapter is a PassiveBufferDriver + import PassiveBufferDriver + + } + +} diff --git a/Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.hpp b/Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.hpp new file mode 100644 index 0000000000..6e86c598e2 --- /dev/null +++ b/Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapter.hpp @@ -0,0 +1,80 @@ +// ====================================================================== +// \title AsyncByteStreamBufferAdapter.hpp +// \author bocchino +// \brief hpp file for AsyncByteStreamBufferAdapter component implementation class +// ====================================================================== + +#ifndef Drv_AsyncByteStreamBufferAdapter_HPP +#define Drv_AsyncByteStreamBufferAdapter_HPP + +#include "Drv/AsyncByteStreamBufferAdapter/AsyncByteStreamBufferAdapterComponentAc.hpp" + +namespace Drv { + +class AsyncByteStreamBufferAdapter final : public AsyncByteStreamBufferAdapterComponentBase { + public: + // ---------------------------------------------------------------------- + // Component construction and destruction + // ---------------------------------------------------------------------- + + //! Construct AsyncByteStreamBufferAdapter object + AsyncByteStreamBufferAdapter(const char* const compName //!< The component name + ); + + //! Destroy AsyncByteStreamBufferAdapter object + ~AsyncByteStreamBufferAdapter(); + + private: + // ---------------------------------------------------------------------- + // Handler implementations for typed input ports + // ---------------------------------------------------------------------- + + //! Handler implementation for bufferIn + //! + //! Port for receiving buffers + void bufferIn_handler(FwIndexType portNum, //!< The port number + Fw::Buffer& fwBuffer //!< The buffer + ) override; + + //! Handler implementation for bufferOutReturn + //! + //! Port for receiving buffers sent on bufferOut and then returned + void bufferOutReturn_handler(FwIndexType portNum, //!< The port number + Fw::Buffer& fwBuffer //!< The buffer + ) override; + + //! Handler implementation for byteStreamDriver + //! + //! Port for receiving ready signals from the driver + //! Sample connection: byteStreamDriver.ready -> byteStreamDriverClient.byteStreamReady + void byteStreamDriverReady_handler(FwIndexType portNum //!< The port number + ) override; + + //! Handler implementation for fromByteStreamDriver + //! + //! Port for receiving data from the driver + //! Sample connection: byteStreamDriver.$recv -> byteStreamDriverClient.fromDriver + void fromByteStreamDriver_handler(FwIndexType portNum, //!< The port number + Fw::Buffer& buffer, + const Drv::ByteStreamStatus& status) override; + + //! Handler implementation for toByteStreamDriverReturn + //! + //! Port for receiving buffers sent on toByteStreamDriver and then returned + //! Sample connection: driver.sendReturnOut -> client.toByteStreamDriverReturn + void toByteStreamDriverReturn_handler(FwIndexType portNum, //!< The port number + Fw::Buffer& buffer, + const Drv::ByteStreamStatus& status) override; + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! Whether the driver is ready + bool m_driverIsReady = false; +}; + +} // namespace Drv + +#endif diff --git a/Drv/AsyncByteStreamBufferAdapter/CMakeLists.txt b/Drv/AsyncByteStreamBufferAdapter/CMakeLists.txt new file mode 100644 index 0000000000..6ca7a9ae1b --- /dev/null +++ b/Drv/AsyncByteStreamBufferAdapter/CMakeLists.txt @@ -0,0 +1,10 @@ +set(SOURCE_FILES + "${CMAKE_CURRENT_LIST_DIR}/AsyncByteStreamBufferAdapter.fpp" + "${CMAKE_CURRENT_LIST_DIR}/AsyncByteStreamBufferAdapter.cpp" +) + +set(MOD_DEPS + "Fw/Logger" +) + +register_fprime_module() diff --git a/Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.cpp b/Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.cpp new file mode 100644 index 0000000000..990a1aa86e --- /dev/null +++ b/Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.cpp @@ -0,0 +1,47 @@ +// ====================================================================== +// \title ByteStreamBufferAdapter.cpp +// \author bocchino +// \brief cpp file for ByteStreamBufferAdapter component implementation class +// ====================================================================== + +#include "Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.hpp" + +namespace Drv { + +// ---------------------------------------------------------------------- +// Component construction and destruction +// ---------------------------------------------------------------------- + +ByteStreamBufferAdapter::ByteStreamBufferAdapter(const char* const compName) + : ByteStreamBufferAdapterComponentBase(compName) {} + +ByteStreamBufferAdapter::~ByteStreamBufferAdapter() {} + +// ---------------------------------------------------------------------- +// Handler implementations for typed input ports +// ---------------------------------------------------------------------- + +void ByteStreamBufferAdapter::bufferIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) { + // TODO: If m_driverIsReady then + // TODO: Send fwBuffer on toByteStreamDriver_out + // TODO: Check the return status. If there is an error, then log it to the Logger. + // TODO: Otherwise log the error + // TODO: Send fwBuffer on bufferInReturn_out +} + +void ByteStreamBufferAdapter::bufferOutReturn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) { + // TODO: Send fwBuffer on fromByteStreamDriverReturn_out +} + +void ByteStreamBufferAdapter::fromByteStreamDriver_handler(FwIndexType portNum, + Fw::Buffer& buffer, + const Drv::ByteStreamStatus& status) { + // TODO: If the status is OK, then send buffer on toByteStreamDriver_out + // TODO: Otherwise log the error and send buffer on fromByteStreamDriverReturn_out +} + +void ByteStreamBufferAdapter::byteStreamDriverReady_handler(FwIndexType portNum) { + this->m_driverIsReady = true; +} + +} // namespace Drv diff --git a/Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.fpp b/Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.fpp new file mode 100644 index 0000000000..569342df3c --- /dev/null +++ b/Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.fpp @@ -0,0 +1,33 @@ +module Drv { + + @ A passive component for mediating between the ByteStreamDriver + @ interface and the PassiveBufferDriver interface + @ + @ Sample topology: + @ + @ ------------------------------------------------- + @ | | + @ | ByteStreamDriver <--> ByteStreamBufferAdapter | <--> PassiveBufferDriverClient + @ | | + @ ------------------------------------------------- + @ + @ The two components in the box function together as a PassiveBufferDriver: + @ + @ ------------------------------------------------- + @ | | + @ | PassiveBufferDriver | <--> PassiveBufferDriverClient + @ | | + @ ------------------------------------------------- + @ + passive component ByteStreamBufferAdapter { + + @ ByteStreamBufferAdapter is a passive client of the ByteStreamDriver + @ interface + import PassiveByteStreamDriverClient + + @ ByteStreamBufferAdapter is a PassiveBufferDriver + import PassiveBufferDriver + + } + +} diff --git a/Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.hpp b/Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.hpp new file mode 100644 index 0000000000..7248590cb9 --- /dev/null +++ b/Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapter.hpp @@ -0,0 +1,72 @@ +// ====================================================================== +// \title ByteStreamBufferAdapter.hpp +// \author bocchino +// \brief hpp file for ByteStreamBufferAdapter component implementation class +// ====================================================================== + +#ifndef Drv_ByteStreamBufferAdapter_HPP +#define Drv_ByteStreamBufferAdapter_HPP + +#include "Drv/ByteStreamBufferAdapter/ByteStreamBufferAdapterComponentAc.hpp" + +namespace Drv { + +class ByteStreamBufferAdapter final : public ByteStreamBufferAdapterComponentBase { + public: + // ---------------------------------------------------------------------- + // Component construction and destruction + // ---------------------------------------------------------------------- + + //! Construct ByteStreamBufferAdapter object + ByteStreamBufferAdapter(const char* const compName //!< The component name + ); + + //! Destroy ByteStreamBufferAdapter object + ~ByteStreamBufferAdapter(); + + private: + // ---------------------------------------------------------------------- + // Handler implementations for typed input ports + // ---------------------------------------------------------------------- + + //! Handler implementation for bufferIn + //! + //! Port for receiving buffers + void bufferIn_handler(FwIndexType portNum, //!< The port number + Fw::Buffer& fwBuffer //!< The buffer + ) override; + + //! Handler implementation for bufferOutReturn + //! + //! Port for receiving buffers sent on bufferOut and then returned + void bufferOutReturn_handler(FwIndexType portNum, //!< The port number + Fw::Buffer& fwBuffer //!< The buffer + ) override; + + //! Handler implementation for byteStreamIn + //! + //! Port for receiving data from the driver + //! Sample connection: byteStreamDriver.$recv -> byteStreamDriverClient.byteStreamIn + void fromByteStreamDriver_handler(FwIndexType portNum, //!< The port number + Fw::Buffer& buffer, + const Drv::ByteStreamStatus& status) override; + + //! Handler implementation for byteStreamReady + //! + //! Port for receiving ready signals from the driver + //! Sample connection: byteStreamDriver.ready -> byteStreamDriverClient.byteStreamDriverReady + void byteStreamDriverReady_handler(FwIndexType portNum //!< The port number + ) override; + + private: + // ---------------------------------------------------------------------- + // Private member variables + // ---------------------------------------------------------------------- + + //! Whether the driver is ready + bool m_driverIsReady = false; +}; + +} // namespace Drv + +#endif diff --git a/Drv/ByteStreamBufferAdapter/CMakeLists.txt b/Drv/ByteStreamBufferAdapter/CMakeLists.txt new file mode 100644 index 0000000000..e6da946149 --- /dev/null +++ b/Drv/ByteStreamBufferAdapter/CMakeLists.txt @@ -0,0 +1,10 @@ +set(SOURCE_FILES + "${CMAKE_CURRENT_LIST_DIR}/ByteStreamBufferAdapter.fpp" + "${CMAKE_CURRENT_LIST_DIR}/ByteStreamBufferAdapter.cpp" +) + +set(MOD_DEPS + "Fw/Logger" +) + +register_fprime_module() diff --git a/Drv/CMakeLists.txt b/Drv/CMakeLists.txt index 00b20eb848..d406490e16 100644 --- a/Drv/CMakeLists.txt +++ b/Drv/CMakeLists.txt @@ -5,11 +5,13 @@ add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Interfaces/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Ports/") # Components +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/AsyncByteStreamBufferAdapter/") +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/ByteStreamBufferAdapter/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/ByteStreamDriverModel/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/LinuxGpioDriver/") -add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/LinuxUartDriver/") -add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/LinuxSpiDriver/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/LinuxI2cDriver/") +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/LinuxSpiDriver/") +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/LinuxUartDriver/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Ip/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/TcpClient/") diff --git a/Drv/Interfaces/CMakeLists.txt b/Drv/Interfaces/CMakeLists.txt index 352ecb0136..e56dc6cba2 100644 --- a/Drv/Interfaces/CMakeLists.txt +++ b/Drv/Interfaces/CMakeLists.txt @@ -12,6 +12,11 @@ register_fprime_module( "${CMAKE_CURRENT_LIST_DIR}/ByteStreamDriver.fpp" "${CMAKE_CURRENT_LIST_DIR}/Gpio.fpp" "${CMAKE_CURRENT_LIST_DIR}/I2c.fpp" + "${CMAKE_CURRENT_LIST_DIR}/PassiveAsyncByteStreamDriverClient.fpp" + "${CMAKE_CURRENT_LIST_DIR}/PassiveBufferDriver.fpp" + "${CMAKE_CURRENT_LIST_DIR}/PassiveBufferDriverClient.fpp" + "${CMAKE_CURRENT_LIST_DIR}/PassiveByteStreamDriverClient.fpp" + "${CMAKE_CURRENT_LIST_DIR}/PassiveByteStreamDriverClientReadyRecv.fpp" "${CMAKE_CURRENT_LIST_DIR}/Spi.fpp" "${CMAKE_CURRENT_LIST_DIR}/Tick.fpp" INTERFACE diff --git a/Drv/Interfaces/PassiveAsyncByteStreamDriverClient.fpp b/Drv/Interfaces/PassiveAsyncByteStreamDriverClient.fpp new file mode 100644 index 0000000000..5847d33e7c --- /dev/null +++ b/Drv/Interfaces/PassiveAsyncByteStreamDriverClient.fpp @@ -0,0 +1,25 @@ +module Drv { + + @ The send interface of passive client of an asynchronous byte stream driver + interface PassiveByteStreamDriverClientSendAsync { + + @ Port for sending data to the driver + @ Sample connection: client.toByteStreamDriver -> driver.$send + output port toByteStreamDriver: Fw.BufferSend + + @ Port for receiving buffers sent on toByteStreamDriver and then returned + @ Sample connection: driver.sendReturnOut -> client.toByteStreamDriverReturn + sync input port toByteStreamDriverReturn: Drv.ByteStreamData + + } + + @ A passive client of an asynchronous byte stream driver + interface PassiveAsyncByteStreamDriverClient { + + import PassiveByteStreamDriverClientReadyRecv + + import PassiveByteStreamDriverClientSendAsync + + } + +} diff --git a/Drv/Interfaces/PassiveBufferDriver.fpp b/Drv/Interfaces/PassiveBufferDriver.fpp new file mode 100644 index 0000000000..ba47692c31 --- /dev/null +++ b/Drv/Interfaces/PassiveBufferDriver.fpp @@ -0,0 +1,14 @@ +module Drv { + + @ A passive buffer driver + interface PassiveBufferDriver { + + @ The interface for sending data to the driver + import Fw.PassiveBufferIn + + @ The interface for receiving data from the driver + import Fw.PassiveBufferOut + + } + +} diff --git a/Drv/Interfaces/PassiveBufferDriverClient.fpp b/Drv/Interfaces/PassiveBufferDriverClient.fpp new file mode 100644 index 0000000000..7a119117d0 --- /dev/null +++ b/Drv/Interfaces/PassiveBufferDriverClient.fpp @@ -0,0 +1,40 @@ +module Drv { + + @ The send interface of passive client of a buffer driver + interface PassiveBufferDriverClientSend { + + @ Port for sending data to the driver + @ Sample connection: client.toBufferDriver -> driver.bufferIn + output port toBufferDriver: Fw.BufferSend + + @ Port for receiving buffers sent on toBufferDriver and then returned + @ Sample connection: driver.bufferInReturn -> client.toBufferDriverReturn + sync input port toBufferDriverReturn: Fw.BufferSend + + } + + @ The receive interface of passive client of a buffer driver + interface PassiveBufferDriverClientRecv { + + @ Port for receiving data from the driver + @ Sample connection: driver.bufferOut -> client.fromBufferDriver + sync input port fromBufferDriver: Fw.BufferSend + + @ Port for returning buffers received on fromBufferDriver + @ Sample connection: client.fromBufferDriverReturn -> driver.bufferOutReturn + output port fromBufferDriverReturn: Fw.BufferSend + + } + + @ A passive client of a buffer driver + interface PassiveBufferDriverClient { + + @ The interface for sending data to the driver + import PassiveBufferDriverClientSend + + @ The interface for receiving data from the driver + import PassiveBufferDriverClientRecv + + } + +} diff --git a/Drv/Interfaces/PassiveByteStreamDriverClient.fpp b/Drv/Interfaces/PassiveByteStreamDriverClient.fpp new file mode 100644 index 0000000000..4ef31cfb3f --- /dev/null +++ b/Drv/Interfaces/PassiveByteStreamDriverClient.fpp @@ -0,0 +1,22 @@ +module Drv { + + @ The send interface of passive client of a synchronous byte stream driver + interface PassiveByteStreamDriverClientSendSync { + + @ Port for sending data to the driver + @ Sample connection: client.toByteStreamDriver -> driver.$send + output port toByteStreamDriver: Drv.ByteStreamSend + + } + + @ A passive client of a synchronous byte stream driver + interface PassiveByteStreamDriverClient { + + @ The ready and receive interfaces + import PassiveByteStreamDriverClientReadyRecv + + @ The send interface + import PassiveByteStreamDriverClientSendSync + + } +} diff --git a/Drv/Interfaces/PassiveByteStreamDriverClientReadyRecv.fpp b/Drv/Interfaces/PassiveByteStreamDriverClientReadyRecv.fpp new file mode 100644 index 0000000000..ff7595792f --- /dev/null +++ b/Drv/Interfaces/PassiveByteStreamDriverClientReadyRecv.fpp @@ -0,0 +1,26 @@ +module Drv { + + @ The ready and receive interfaces for a byte stream driver client + interface PassiveByteStreamDriverClientReadyRecv { + + # ---------------------------------------------------------------------- + # Ready interface + # ---------------------------------------------------------------------- + @ Port for receiving ready signals from the driver + @ Sample connection: byteStreamDriver.ready -> byteStreamDriverClient.byteStreamDriverReady + sync input port byteStreamDriverReady: Drv.ByteStreamReady + + # ---------------------------------------------------------------------- + # Receive interface + # ---------------------------------------------------------------------- + @ Port for receiving data from the driver + @ Sample connection: byteStreamDriver.$recv -> byteStreamDriverClient.fromDriver + sync input port fromByteStreamDriver: Drv.ByteStreamData + + @ Port for returning ownership of buffers received on fromDriver + @ Sample connection: byteStreamDriverClient.byteStreamReturn -> byteStreamDriver.recvReturnIn + output port fromByteStreamDriverReturn: Fw.BufferSend + + } + +} diff --git a/Fw/Buffer/Buffer.fpp b/Fw/Buffer/Buffer.fpp index 8315d0f15c..2e9e8e5e23 100644 --- a/Fw/Buffer/Buffer.fpp +++ b/Fw/Buffer/Buffer.fpp @@ -16,4 +16,26 @@ module Fw { $size: FwSizeType ) -> Fw.Buffer + @ The bufferIn interface for a passive component + interface PassiveBufferIn { + + @ Port for receiving buffers + sync input port bufferIn: BufferSend + + @ Port for returning buffers received on bufferIn + output port bufferInReturn: BufferSend + + } + + @ The bufferOut interface for a passive component + interface PassiveBufferOut { + + @ Port for sending buffers + output port bufferOut: BufferSend + + @ Port for receiving buffers sent on bufferOut and then returned + sync input port bufferOutReturn: BufferSend + + } + } diff --git a/Svc/GenericHub/CMakeLists.txt b/Svc/GenericHub/CMakeLists.txt index a542684619..4ca73e29c2 100644 --- a/Svc/GenericHub/CMakeLists.txt +++ b/Svc/GenericHub/CMakeLists.txt @@ -10,7 +10,7 @@ register_fprime_module( AUTOCODER_INPUTS "${CMAKE_CURRENT_LIST_DIR}/GenericHub.fpp" SOURCES - "${CMAKE_CURRENT_LIST_DIR}/GenericHubComponentImpl.cpp" + "${CMAKE_CURRENT_LIST_DIR}/GenericHub.cpp" EXCLUDE_FROM_ALL ) ### UTs ### diff --git a/Svc/GenericHub/GenericHubComponentImpl.cpp b/Svc/GenericHub/GenericHub.cpp similarity index 75% rename from Svc/GenericHub/GenericHubComponentImpl.cpp rename to Svc/GenericHub/GenericHub.cpp index af667a096e..416389aeed 100644 --- a/Svc/GenericHub/GenericHubComponentImpl.cpp +++ b/Svc/GenericHub/GenericHub.cpp @@ -1,5 +1,5 @@ // ====================================================================== -// \title GenericHubComponentImpl.cpp +// \title GenericHub.cpp // \author mstarch // \brief cpp file for GenericHub component implementation class // @@ -11,7 +11,7 @@ // ====================================================================== #include -#include +#include #include "Fw/Logger/Logger.hpp" #include "Fw/Types/Assert.hpp" @@ -24,19 +24,15 @@ namespace Svc { // Construction, initialization, and destruction // ---------------------------------------------------------------------- -GenericHubComponentImpl ::GenericHubComponentImpl(const char* const compName) : GenericHubComponentBase(compName) {} +GenericHub::GenericHub(const char* const compName) : GenericHubComponentBase(compName) {} -GenericHubComponentImpl ::~GenericHubComponentImpl() {} +GenericHub::~GenericHub() {} -void GenericHubComponentImpl ::send_data(const HubType type, - const FwIndexType port, - const U8* data, - const FwSizeType size) { +void GenericHub::send_data(const HubType type, const FwIndexType port, const U8* data, const FwSizeType size) { FW_ASSERT(data != nullptr); Fw::SerializeStatus status; // Buffer to send and a buffer used to write to it - Fw::Buffer outgoing = - dataOutAllocate_out(0, static_cast(size + sizeof(U32) + sizeof(U32) + sizeof(FwBuffSizeType))); + Fw::Buffer outgoing = allocate_out(0, static_cast(size + sizeof(U32) + sizeof(U32) + sizeof(FwBuffSizeType))); auto serialize = outgoing.getSerializer(); // Write data to our buffer status = serialize.serializeFrom(static_cast(type)); @@ -46,19 +42,24 @@ void GenericHubComponentImpl ::send_data(const HubType type, status = serialize.serializeFrom(data, size); FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast(status)); outgoing.setSize(static_cast(serialize.getSize())); - dataOut_out(0, outgoing); + toBufferDriver_out(0, outgoing); } // ---------------------------------------------------------------------- // Handler implementations for user-defined typed input ports // ---------------------------------------------------------------------- -void GenericHubComponentImpl ::buffersIn_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) { +void GenericHub::bufferIn_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) { send_data(HUB_TYPE_BUFFER, portNum, fwBuffer.getData(), fwBuffer.getSize()); - bufferDeallocate_out(0, fwBuffer); + bufferInReturn_out(portNum, fwBuffer); } -void GenericHubComponentImpl ::dataIn_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) { +void GenericHub::bufferOutReturn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) { + // Return the buffer + fromBufferDriverReturn_out(0, fwBuffer); +} + +void GenericHub::fromBufferDriver_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) { HubType type = HUB_TYPE_MAX; U32 type_in = 0; U32 port = 0; @@ -85,13 +86,13 @@ void GenericHubComponentImpl ::dataIn_handler(const FwIndexType portNum, Fw::Buf Fw::ExternalSerializeBuffer wrapper(rawData, rawSize); status = wrapper.setBuffLen(rawSize); FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast(status)); - portOut_out(static_cast(port), wrapper); + serialOut_out(static_cast(port), wrapper); // Deallocate the existing buffer - dataInDeallocate_out(0, fwBuffer); + fromBufferDriverReturn_out(0, fwBuffer); } else if (type == HUB_TYPE_BUFFER) { // Fw::Buffers can reuse the existing data buffer as the storage type! No deallocation done. fwBuffer.set(rawData, rawSize, fwBuffer.getContext()); - buffersOut_out(static_cast(port), fwBuffer); + bufferOut_out(static_cast(port), fwBuffer); } else if (type == HUB_TYPE_EVENT) { FwEventIdType id; Fw::Time timeTag; @@ -109,10 +110,10 @@ void GenericHubComponentImpl ::dataIn_handler(const FwIndexType portNum, Fw::Buf FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast(status)); // Send it! - this->LogSend_out(static_cast(port), id, timeTag, severity, args); + this->eventOut_out(static_cast(port), id, timeTag, severity, args); // Deallocate the existing buffer - dataInDeallocate_out(0, fwBuffer); + fromBufferDriverReturn_out(0, fwBuffer); } else if (type == HUB_TYPE_CHANNEL) { FwChanIdType id; Fw::Time timeTag; @@ -127,18 +128,23 @@ void GenericHubComponentImpl ::dataIn_handler(const FwIndexType portNum, Fw::Buf FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast(status)); // Send it! - this->TlmSend_out(static_cast(port), id, timeTag, val); + this->tlmOut_out(static_cast(port), id, timeTag, val); - // Deallocate the existing buffer - dataInDeallocate_out(0, fwBuffer); + // Return the received buffer + fromBufferDriverReturn_out(0, fwBuffer); } } -void GenericHubComponentImpl ::LogRecv_handler(const FwIndexType portNum, - FwEventIdType id, - Fw::Time& timeTag, - const Fw::LogSeverity& severity, - Fw::LogBuffer& args) { +void GenericHub::toBufferDriverReturn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) { + // Deallocate the existing buffer + deallocate_out(portNum, fwBuffer); +} + +void GenericHub::eventIn_handler(const FwIndexType portNum, + FwEventIdType id, + Fw::Time& timeTag, + const Fw::LogSeverity& severity, + Fw::LogBuffer& args) { Fw::SerializeStatus status = Fw::FW_SERIALIZE_OK; U8 buffer[sizeof(FwEventIdType) + Fw::Time::SERIALIZED_SIZE + Fw::LogSeverity::SERIALIZED_SIZE + FW_LOG_BUFFER_MAX_SIZE]; @@ -156,10 +162,7 @@ void GenericHubComponentImpl ::LogRecv_handler(const FwIndexType portNum, this->send_data(HubType::HUB_TYPE_EVENT, portNum, buffer, size); } -void GenericHubComponentImpl ::TlmRecv_handler(const FwIndexType portNum, - FwChanIdType id, - Fw::Time& timeTag, - Fw::TlmBuffer& val) { +void GenericHub::tlmIn_handler(const FwIndexType portNum, FwChanIdType id, Fw::Time& timeTag, Fw::TlmBuffer& val) { Fw::SerializeStatus status = Fw::FW_SERIALIZE_OK; U8 buffer[sizeof(FwChanIdType) + Fw::Time::SERIALIZED_SIZE + FW_TLM_BUFFER_MAX_SIZE]; Fw::ExternalSerializeBuffer serializer(buffer, sizeof(buffer)); @@ -178,8 +181,8 @@ void GenericHubComponentImpl ::TlmRecv_handler(const FwIndexType portNum, // Handler implementations for user-defined serial input ports // ---------------------------------------------------------------------- -void GenericHubComponentImpl ::portIn_handler(FwIndexType portNum, /*!< The port number*/ - Fw::SerializeBufferBase& Buffer /*!< The serialization buffer*/ +void GenericHub::serialIn_handler(FwIndexType portNum, /*!< The port number*/ + Fw::SerializeBufferBase& Buffer /*!< The serialization buffer*/ ) { send_data(HUB_TYPE_PORT, portNum, Buffer.getBuffAddr(), Buffer.getSize()); } diff --git a/Svc/GenericHub/GenericHub.fpp b/Svc/GenericHub/GenericHub.fpp index a495c4a729..2ab632fa44 100644 --- a/Svc/GenericHub/GenericHub.fpp +++ b/Svc/GenericHub/GenericHub.fpp @@ -1,54 +1,187 @@ module Svc { - @ A generic hub component + @| ---------------------------------------------------------------------- + @| A generic hub component + @| ---------------------------------------------------------------------- + @| In F Prime, a *hub* is a mechanism for implementing logical port connections + @| that physically span two F Prime deployments. The pattern is called a "hub" + @| because any number of logical connections may be multiplexed through a single + @| pair of hubs. For example, a pair of logical connections like this + @| + @| A1 --> B1 + @| A2 --> B2, + @| + @| where Ai and Bi are component instances in separate deployments A and B, + @| can be implemented using hubs HA and HB like this: + @| + @| A1 -->--+ +-->-- B1 + @| | | + @| HA ~~> HB + @| | | + @| A2 -->--+ +-->-- B2 + @| + @| The notation ~~> represents data transport between deployments, + @| e.g., via shared memory or across a network connection. + @| + @| The GenericHub component provides a generic capability for implementing a + @| hub. Typically there is a pair of instances of GenericHub, one in each + @| deployment, and each instance is paired with a driver for doing the + @| communication. Sending data between the deployments looks like this: + @| + @| FSW --> GenericHub --> Driver ~~> Driver --> GenericHub --> FSW + @| + @| The driver must be a *buffer driver*, i.e., any combination of component + @| instances that sends and receives Fw.Buffer objects across a network. + @| For example, the driver may be a pair consisting of (1) a ByteStreamDriver + @| component that implements ByteStreamDriverInterface and + @| (2) a ByteStreamBufferAdapter. + @| + @| The driver is specific to the transport mechanism. + @| The GenericHub may be paired with any driver that conforms to + @| its interface, and so can support any transport mechanism. + @| ---------------------------------------------------------------------- passive component GenericHub { # ---------------------------------------------------------------------- - # Mimic Ports + # Ports for sending data from FSW to the hub + # ---------------------------------------------------------------------- + # These ports establish the "send" interface from the rest of FSW to the hub. + # ---------------------------------------------------------------------- + # Each of these ports has the following behavior: + # 1. Invoke allocate to allocate a buffer B. + # 2. Serialize the hub message type (event, telemetry, serial, buffer), + # the port number, and the data into B. + # 3. Emit B on toBufferDriver. + # + # Sample connections: + # + # eventProducer.eventOut -> genericHub.eventIn + # telemetryProducer.tlmOut -> genericHub.tlmIn + # + # valueProducer0.valueOut[0] -> genericHub.serialIn[0] + # valueProducer1.valueOut[1] -> genericHub.serialIn[1] + # + # bufferProducer0.bufferOut -> genericHub.bufferIn[0] + # genericHub.bufferInReturn[0] -> bufferProducer0.bufferIn + # bufferProducer1.bufferOut -> genericHub.bufferIn[1] + # genericHub.bufferInReturn[1] -> bufferProducer1.bufferIn # ---------------------------------------------------------------------- - @ Telemetry input port for mimicking an event processor - sync input port TlmRecv: Fw.Tlm + @ Port for sending events to the hub + sync input port eventIn: Fw.Log - @ Event input port for mimicking an event processor - sync input port LogRecv: Fw.Log + @ Port for sending telemetry to the hub + sync input port tlmIn: Fw.Tlm - @ Cross-hub event output port - output port LogSend: Fw.Log + @ Ports for sending serial data to the hub + @ You can connect any typed output ports to these input ports, so + @ long as the data carried by the ports is serialized by value. + @ Do not connect ports that emit Fw.Buffer objects, because these objects + @ store pointers to data that is not serialized across the port + @ interface. To connect output ports that emit buffers, use + @ buffersIn below. + sync input port serialIn: [GenericHubCfg.NumSerialInputPorts] serial - @ Cross-hub telemetry output port - output port TlmSend: Fw.Tlm + @ Ports for sending buffer data to the hub + @ Output ports connected to these ports must emit Fw.Buffer objects. + @ On invocation, each of these ports allocates a new buffer B, copies the + @ data from the incoming buffer to B, and returns the incoming + @ buffer to the sender for deallocation. + @ + sync input port bufferIn: [GenericHubCfg.NumBufferInputPorts] Fw.BufferSend + + @ Ports for returning buffers arriving on buffersIn + output port bufferInReturn: [GenericHubCfg.NumBufferInputPorts] Fw.BufferSend + + @ bufferIn and bufferInReturn ports must match + match bufferIn with bufferInReturn # ---------------------------------------------------------------------- - # General Ports + # Ports for sending data from the hub to a buffer driver + # ---------------------------------------------------------------------- + # These ports establish the "send" interface from the hub to a buffer driver. + # + # Sample connections: + # + # genericHub.allocate -> bufferManager.bufferGetCallee + # genericHub.toBufferDriver -> bufferDriver.bufferIn + # bufferDriver.bufferInReturn -> genericHub.toBufferDriverReturn + # genericHub.deallocate -> bufferManager.bufferSendIn # ---------------------------------------------------------------------- - @ Input array of generic ports to shuttle to the other side of the hub connection - sync input port portIn: [GenericHubInputPorts] serial + @ This interface provides ports allocate and deallocate + import Svc.BufferAllocation - @ Output array of generic ports shuttled from the other side of the hub connection - output port portOut: [GenericHubOutputPorts] serial + @ This interface provides ports toBufferDriver and toBufferDriverReturn + import Drv.PassiveBufferDriverClientSend - @ Input array of generic ports shuttling in copy-free buffers form external sources - sync input port buffersIn: [GenericHubInputBuffers] Fw.BufferSend + # ---------------------------------------------------------------------- + # Ports for receiving data from a buffer driver to the hub + # ---------------------------------------------------------------------- + # These ports establish the "receive" interface from a driver to the hub. + # Each of these ports has the following behavior: + # 1. Unpack the incoming buffer into hub message type, port number, and data. + # 2. If the hub message type is event, telemetry, or serial, + # then pass the data by value to the receiver and invoke fromBufferDriverReturn + # to return the incoming buffer for deallocation. + # 3. Otherwise adjust the metadata of the incoming buffer to point + # to the data, and emit the same buffer on bufferOut. When the + # buffer is returned on bufferOutReturn, invoke fromBufferDriverReturn to return it. + # + # Sample connections: + # + # bufferDriver.bufferOut -> genericHub.fromBufferDriver + # genericHub.fromBufferDriverReturn -> bufferDriver.bufferOutReturn + # ---------------------------------------------------------------------- - @ Output array of generic ports shuttling in copy-free buffers form external sources - output port buffersOut: [GenericHubOutputBuffers] Fw.BufferSend + @ This interface provides ports fromBufferDriver and fromBufferDriverReturn + import Drv.PassiveBufferDriverClientRecv - @ Buffer return from incoming bufferIn calls - output port bufferDeallocate: Fw.BufferSend + # ---------------------------------------------------------------------- + # Ports for receiving data from the hub to FSW + # ---------------------------------------------------------------------- + # These ports establish the "receive" interface from the hub to FSW + # + # Sample connections: + # + # genericHub.eventOut -> eventManager.eventIn + # genericHub.tlmOut -> tlmDb.eventIn + # + # genericHub.serialOut[0] -> valueConsumer0.valueIn[0] + # genericHub.serialOut[1] -> valueConsumer1.valueIn[1] + # + # genericHub.bufferOut[0] -> bufferConsumer0.bufferIn + # bufferConsumer0.bufferInReturn -> genericHub.bufferOutReturn[0] + # genericHub.bufferOut[1] -> bufferConsumer1.bufferIn + # bufferConsumer1.bufferInReturn -> genericHub.bufferOutReturn[1] + # ---------------------------------------------------------------------- - @ Data output to remote hub - output port dataOut: Fw.BufferSend + @ Port for receiving events + @ Data emitted on this port is copied from a buffer received on fromBufferDriver, + @ and the buffer is returned. + output port eventOut: Fw.Log - @ Data input from remote hub - sync input port dataIn: Fw.BufferSend + @ Port for receiving telemetry channels + @ Data emitted on this port is copied from a buffer received on fromBufferDriver, + @ and the buffer is returned. + output port tlmOut: Fw.Tlm - @ Deallocation of buffer passed into data in - output port dataInDeallocate: Fw.BufferSend + @ Ports for receiving serial data + @ You can connect each of these output ports to any typed input port. + @ Data emitted on one of these ports is copied from a buffer received on fromBufferDriver, + @ and the buffer is returned. + output port serialOut: [GenericHubCfg.NumSerialOutputPorts] serial - @ Allocation of buffer passed to passed out dataOut - output port dataOutAllocate: Fw.BufferGet + @ Ports for receiving buffer data + @ A buffer emitted on one of these ports is a buffer received on fromBufferDriver, + @ With adjusted metadata to point to the data stored in the buffer. + output port bufferOut: [GenericHubCfg.NumBufferOutputPorts] Fw.BufferSend + + @ Ports for receiving buffers sent on bufferOut and then returned + sync input port bufferOutReturn: [GenericHubCfg.NumBufferOutputPorts] Fw.BufferSend + + @ bufferOut and bufferOutReturn ports must match + match bufferOut with bufferOutReturn } diff --git a/Svc/GenericHub/GenericHub.hpp b/Svc/GenericHub/GenericHub.hpp index 86ee628a53..dd88c99403 100644 --- a/Svc/GenericHub/GenericHub.hpp +++ b/Svc/GenericHub/GenericHub.hpp @@ -1,17 +1,110 @@ // ====================================================================== -// GenericHub.hpp -// Standardization header for GenericHub +// \title GenericHub.hpp +// \author mstarch +// \brief hpp file for GenericHub component implementation class +// +// \copyright +// Copyright 2009-2015, by the California Institute of Technology. +// ALL RIGHTS RESERVED. United States Government Sponsorship +// acknowledged. +// // ====================================================================== #ifndef Svc_GenericHub_HPP #define Svc_GenericHub_HPP -#include "Svc/GenericHub/GenericHubComponentImpl.hpp" +#include "Svc/GenericHub/GenericHubComponentAc.hpp" namespace Svc { -using GenericHub = GenericHubComponentImpl; +class GenericHub final : public GenericHubComponentBase { + public: + /** + * HubType: + * + * Type of serialized data on the wire. Allows for expanding them on the opposing end. + */ + enum HubType { + HUB_TYPE_PORT, //!< Port type transmission + HUB_TYPE_BUFFER, //!< Buffer type transmission + HUB_TYPE_EVENT, //!< Event transmission + HUB_TYPE_CHANNEL, //!< Telemetry channel type + HUB_TYPE_MAX + }; -} + // ---------------------------------------------------------------------- + // Construction, initialization, and destruction + // ---------------------------------------------------------------------- + + //! Construct object GenericHub + //! + GenericHub(const char* const compName /*!< The component name*/ + ); + + //! Destroy object GenericHub + //! + ~GenericHub(); + + private: + // ---------------------------------------------------------------------- + // Handler implementations for user-defined typed input ports + // ---------------------------------------------------------------------- + + //! Handler implementation for bufferIn + //! + void bufferIn_handler(const FwIndexType portNum, /*!< The port number*/ + Fw::Buffer& fwBuffer) override; + + //! Handler implementation for bufferOutReturn + //! + //! Ports for receiving buffers sent on bufferOut and then returned + void bufferOutReturn_handler(FwIndexType portNum, //!< The port number + Fw::Buffer& fwBuffer //!< The buffer + ) override; + + //! Handler implementation for fromBufferDriver + //! + void fromBufferDriver_handler(const FwIndexType portNum, /*!< The port number*/ + Fw::Buffer& fwBuffer) override; + + //! Handler implementation for toBufferDriverReturn + //! + //! Port for receiving buffers sent on toBufferDriver and then returned + void toBufferDriverReturn_handler(FwIndexType portNum, //!< The port number + Fw::Buffer& fwBuffer //!< The buffer + ) override; + + //! Handler implementation for eventIn + //! + void eventIn_handler(const FwIndexType portNum, /*!< The port number*/ + FwEventIdType id, /*!< Log ID */ + Fw::Time& timeTag, /*!< Time Tag */ + const Fw::LogSeverity& severity, /*!< The severity argument */ + Fw::LogBuffer& args /*!< Buffer containing serialized log entry */ + ) override; + + //! Handler implementation for tlmIn + //! + void tlmIn_handler(const FwIndexType portNum, /*!< The port number*/ + FwChanIdType id, /*!< Telemetry Channel ID */ + Fw::Time& timeTag, /*!< Time Tag */ + Fw::TlmBuffer& val /*!< Buffer containing serialized telemetry value */ + ) override; + + // ---------------------------------------------------------------------- + // Handler implementations for user-defined serial input ports + // ---------------------------------------------------------------------- + + //! Handler implementation for serialIn + //! + void serialIn_handler(FwIndexType portNum, /*!< The port number*/ + Fw::SerializeBufferBase& Buffer /*!< The serialization buffer*/ + ) override; + + // Helpers and members + void send_data(const HubType type, const FwIndexType port, const U8* data, const FwSizeType size); +}; + +} // end namespace Svc #endif diff --git a/Svc/GenericHub/GenericHubComponentImpl.hpp b/Svc/GenericHub/GenericHubComponentImpl.hpp deleted file mode 100644 index 3fb9be2e41..0000000000 --- a/Svc/GenericHub/GenericHubComponentImpl.hpp +++ /dev/null @@ -1,97 +0,0 @@ -// ====================================================================== -// \title GenericHubComponentImpl.hpp -// \author mstarch -// \brief hpp file for GenericHub component implementation class -// -// \copyright -// Copyright 2009-2015, by the California Institute of Technology. -// ALL RIGHTS RESERVED. United States Government Sponsorship -// acknowledged. -// -// ====================================================================== - -#ifndef GenericHub_HPP -#define GenericHub_HPP - -#include "Svc/GenericHub/GenericHubComponentAc.hpp" - -namespace Svc { - -class GenericHubComponentImpl final : public GenericHubComponentBase { - public: - /** - * HubType: - * - * Type of serialized data on the wire. Allows for expanding them on the opposing end. - */ - enum HubType { - HUB_TYPE_PORT, //!< Port type transmission - HUB_TYPE_BUFFER, //!< Buffer type transmission - HUB_TYPE_EVENT, //!< Event transmission - HUB_TYPE_CHANNEL, //!< Telemetry channel type - HUB_TYPE_MAX - }; - - constexpr static FwSizeType GENERIC_HUB_DATA_SIZE = 1024; - // ---------------------------------------------------------------------- - // Construction, initialization, and destruction - // ---------------------------------------------------------------------- - - //! Construct object GenericHub - //! - GenericHubComponentImpl(const char* const compName /*!< The component name*/ - ); - - //! Destroy object GenericHub - //! - ~GenericHubComponentImpl(); - - private: - // ---------------------------------------------------------------------- - // Handler implementations for user-defined typed input ports - // ---------------------------------------------------------------------- - - //! Handler implementation for buffersIn - //! - void buffersIn_handler(const FwIndexType portNum, /*!< The port number*/ - Fw::Buffer& fwBuffer); - - //! Handler implementation for dataIn - //! - void dataIn_handler(const FwIndexType portNum, /*!< The port number*/ - Fw::Buffer& fwBuffer); - - //! Handler implementation for LogRecv - //! - void LogRecv_handler(const FwIndexType portNum, /*!< The port number*/ - FwEventIdType id, /*!< Log ID */ - Fw::Time& timeTag, /*!< Time Tag */ - const Fw::LogSeverity& severity, /*!< The severity argument */ - Fw::LogBuffer& args /*!< Buffer containing serialized log entry */ - ); - - //! Handler implementation for TlmRecv - //! - void TlmRecv_handler(const FwIndexType portNum, /*!< The port number*/ - FwChanIdType id, /*!< Telemetry Channel ID */ - Fw::Time& timeTag, /*!< Time Tag */ - Fw::TlmBuffer& val /*!< Buffer containing serialized telemetry value */ - ); - - // ---------------------------------------------------------------------- - // Handler implementations for user-defined serial input ports - // ---------------------------------------------------------------------- - - //! Handler implementation for portIn - //! - void portIn_handler(FwIndexType portNum, /*!< The port number*/ - Fw::SerializeBufferBase& Buffer /*!< The serialization buffer*/ - ); - - // Helpers and members - void send_data(const HubType type, const FwIndexType port, const U8* data, const FwSizeType size); -}; - -} // end namespace Svc - -#endif diff --git a/Svc/GenericHub/test/ut/GenericHubTester.cpp b/Svc/GenericHub/test/ut/GenericHubTester.cpp index 363082178b..9fc5b938f4 100644 --- a/Svc/GenericHub/test/ut/GenericHubTester.cpp +++ b/Svc/GenericHub/test/ut/GenericHubTester.cpp @@ -43,21 +43,22 @@ GenericHubTester ::~GenericHubTester() {} // ---------------------------------------------------------------------- void GenericHubTester ::test_in_out() { - U32 max = std::min(this->componentIn.getNum_portIn_InputPorts(), this->componentOut.getNum_portOut_OutputPorts()); + U32 max = + std::min(this->componentIn.getNum_serialIn_InputPorts(), this->componentOut.getNum_serialOut_OutputPorts()); for (U32 i = 0; i < max; i++) { send_random_comm(i); - ASSERT_from_dataInDeallocate_SIZE(1); - fromPortHistory_dataInDeallocate->clear(); + ASSERT_from_fromBufferDriverReturn_SIZE(1); + fromPortHistory_fromBufferDriverReturn->clear(); } } void GenericHubTester ::test_buffer_io() { U32 max = - std::min(this->componentIn.getNum_buffersIn_InputPorts(), this->componentOut.getNum_buffersOut_OutputPorts()); + std::min(this->componentIn.getNum_bufferIn_InputPorts(), this->componentOut.getNum_bufferOut_OutputPorts()); for (U32 i = 0; i < max; i++) { send_random_buffer(i); - ASSERT_from_dataInDeallocate_SIZE(1); - fromPortHistory_dataInDeallocate->clear(); + ASSERT_from_fromBufferDriverReturn_SIZE(1); + fromPortHistory_fromBufferDriverReturn->clear(); } } @@ -65,18 +66,18 @@ void GenericHubTester ::test_random_io() { for (U32 i = 0; i < 10000; i++) { U32 choice = STest::Pick::lowerUpper(0, 1); if (choice) { - U32 port = STest::Pick::lowerUpper(0, std::min(this->componentIn.getNum_portIn_InputPorts(), - this->componentOut.getNum_portOut_OutputPorts()) - + U32 port = STest::Pick::lowerUpper(0, std::min(this->componentIn.getNum_serialIn_InputPorts(), + this->componentOut.getNum_serialOut_OutputPorts()) - 1); send_random_comm(port); } else { - U32 port = STest::Pick::lowerUpper(0, std::min(this->componentIn.getNum_buffersIn_InputPorts(), - this->componentOut.getNum_buffersOut_OutputPorts()) - + U32 port = STest::Pick::lowerUpper(0, std::min(this->componentIn.getNum_bufferIn_InputPorts(), + this->componentOut.getNum_bufferOut_OutputPorts()) - 1); send_random_buffer(port); } - ASSERT_from_dataInDeallocate_SIZE(1); - fromPortHistory_dataInDeallocate->clear(); + ASSERT_from_fromBufferDriverReturn_SIZE(1); + fromPortHistory_fromBufferDriverReturn->clear(); } } @@ -90,15 +91,16 @@ void GenericHubTester ::random_fill(Fw::SerializeBufferBase& buffer, U32 max_siz void GenericHubTester ::test_telemetry() { Fw::TlmBuffer buffer; + clearFromPortHistory(); random_fill(buffer, FW_TLM_BUFFER_MAX_SIZE); Fw::Time time(100, 200); - invoke_to_TlmRecv(0, 123, time, buffer); + invoke_to_tlmIn(0, 123, time, buffer); - // **must** deallocate buffer - ASSERT_from_dataInDeallocate_SIZE(1); - ASSERT_from_TlmSend_SIZE(1); - ASSERT_from_TlmSend(0, 123, time, buffer); + // **must** return buffer + ASSERT_from_fromBufferDriverReturn_SIZE(1); + ASSERT_from_tlmOut_SIZE(1); + ASSERT_from_tlmOut(0, 123, time, buffer); clearFromPortHistory(); } @@ -108,12 +110,12 @@ void GenericHubTester ::test_events() { random_fill(buffer, FW_LOG_BUFFER_MAX_SIZE); Fw::Time time(100, 200); - invoke_to_LogRecv(0, 123, time, severity, buffer); + invoke_to_eventIn(0, 123, time, severity, buffer); // **must** deallocate buffer - ASSERT_from_dataInDeallocate_SIZE(1); - ASSERT_from_LogSend_SIZE(1); - ASSERT_from_LogSend(0, 123, time, severity, buffer); + ASSERT_from_fromBufferDriverReturn_SIZE(1); + ASSERT_from_eventOut_SIZE(1); + ASSERT_from_eventOut(0, 123, time, severity, buffer); clearFromPortHistory(); } // Helpers @@ -121,9 +123,9 @@ void GenericHubTester ::test_events() { void GenericHubTester ::send_random_comm(U32 port) { random_fill(m_comm, FW_COM_BUFFER_MAX_SIZE); m_current_port = port; - invoke_to_portIn(m_current_port, m_comm); - // Ensure that the data out was called, and that the portOut unwrapped properly - ASSERT_from_dataOut_SIZE(m_comm_in + m_buffer_out + 1); + invoke_to_serialIn(m_current_port, m_comm); + // Ensure that the data out was called, and that the serialOut unwrapped properly + ASSERT_from_toBufferDriver_SIZE(m_comm_in + m_buffer_out + 1); ASSERT_EQ(m_comm_in + 1, m_comm_out); m_comm_in++; } @@ -136,12 +138,12 @@ void GenericHubTester ::send_random_buffer(U32 port) { random_fill(serializer, max_random_size); m_buffer.setSize(max_random_size); m_current_port = port; - invoke_to_buffersIn(m_current_port, m_buffer); - ASSERT_from_bufferDeallocate_SIZE(1); - ASSERT_from_bufferDeallocate(0, m_buffer); - fromPortHistory_bufferDeallocate->clear(); - // Ensure that the data out was called, and that the portOut unwrapped properly - ASSERT_from_dataOut_SIZE(m_buffer_in + m_comm_out + 1); + invoke_to_bufferIn(m_current_port, m_buffer); + ASSERT_from_bufferInReturn_SIZE(1); + ASSERT_from_bufferInReturn(0, m_buffer); + fromPortHistory_bufferInReturn->clear(); + // Ensure that the data out was called, and that the serialOut unwrapped properly + ASSERT_from_toBufferDriver_SIZE(m_buffer_in + m_comm_out + 1); ASSERT_EQ(m_buffer_in + 1, m_buffer_out); m_buffer_in++; } @@ -150,36 +152,36 @@ void GenericHubTester ::send_random_buffer(U32 port) { // Handlers for typed from ports // ---------------------------------------------------------------------- -void GenericHubTester ::from_LogSend_handler(const FwIndexType portNum, - FwEventIdType id, - Fw::Time& timeTag, - const Fw::LogSeverity& severity, - Fw::LogBuffer& args) { - this->pushFromPortEntry_LogSend(id, timeTag, severity, args); +void GenericHubTester ::from_eventOut_handler(const FwIndexType portNum, + FwEventIdType id, + Fw::Time& timeTag, + const Fw::LogSeverity& severity, + Fw::LogBuffer& args) { + this->pushFromPortEntry_eventOut(id, timeTag, severity, args); } -void GenericHubTester ::from_TlmSend_handler(const FwIndexType portNum, - FwChanIdType id, - Fw::Time& timeTag, - Fw::TlmBuffer& val) { - this->pushFromPortEntry_TlmSend(id, timeTag, val); +void GenericHubTester ::from_tlmOut_handler(const FwIndexType portNum, + FwChanIdType id, + Fw::Time& timeTag, + Fw::TlmBuffer& val) { + this->pushFromPortEntry_tlmOut(id, timeTag, val); } -void GenericHubTester ::from_dataOut_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) { +void GenericHubTester ::from_toBufferDriver_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) { ASSERT_NE(fwBuffer.getData(), nullptr) << "Empty buffer to deallocate"; ASSERT_GE(fwBuffer.getData(), m_data_for_allocation) << "Incorrect data pointer deallocated"; ASSERT_LT(fwBuffer.getData(), m_data_for_allocation + sizeof(m_data_for_allocation)) << "Incorrect data pointer deallocated"; // Reuse m_allocate to pass into the otherside of the hub - this->pushFromPortEntry_dataOut(fwBuffer); - invoke_to_dataIn(0, fwBuffer); + this->pushFromPortEntry_toBufferDriver(fwBuffer); + invoke_to_fromBufferDriver(0, fwBuffer); } // ---------------------------------------------------------------------- // Handlers for serial from ports // ---------------------------------------------------------------------- -void GenericHubTester ::from_buffersOut_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) { +void GenericHubTester ::from_bufferOut_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) { m_buffer_out++; // Assert the buffer came through exactly on the right port ASSERT_EQ(portNum, m_current_port); @@ -189,12 +191,13 @@ void GenericHubTester ::from_buffersOut_handler(const FwIndexType portNum, Fw::B U8 byte2 = reinterpret_cast(m_buffer.getData())[i]; ASSERT_EQ(byte1, byte2); } - // Pretend to deallocate like file uplink would - this->from_dataInDeallocate_handler(0, fwBuffer); + + this->invoke_to_bufferOutReturn(portNum, fwBuffer); + // this->from_fromBufferDriverReturn_handler(0, fwBuffer); } -void GenericHubTester ::from_portOut_handler(FwIndexType portNum, /*!< The port number*/ - Fw::SerializeBufferBase& Buffer /*!< The serialization buffer*/ +void GenericHubTester ::from_serialOut_handler(FwIndexType portNum, /*!< The port number*/ + Fw::SerializeBufferBase& Buffer /*!< The serialization buffer*/ ) { m_comm_out++; // Assert the buffer came through exactly on the right port @@ -203,31 +206,32 @@ void GenericHubTester ::from_portOut_handler(FwIndexType portNum, /*! for (U32 i = 0; i < Buffer.getSize(); i++) { ASSERT_EQ(Buffer.getBuffAddr()[i], m_comm.getBuffAddr()[i]); } - ASSERT_from_buffersOut_SIZE(0); + ASSERT_from_bufferOut_SIZE(0); } -Fw::Buffer GenericHubTester ::from_dataOutAllocate_handler(const FwIndexType portNum, const FwSizeType size) { +Fw::Buffer GenericHubTester ::from_allocate_handler(const FwIndexType portNum, const FwSizeType size) { EXPECT_EQ(m_allocate.getData(), nullptr) << "Allocation buffer is still in use"; - EXPECT_LE(size, sizeof(m_data_for_allocation)) << "Allocation buffer is still in use"; + EXPECT_LE(size, sizeof(m_data_for_allocation)) << "Allocation buffer size mismatch"; m_allocate.set(m_data_for_allocation, size); return m_allocate; } -void GenericHubTester ::from_bufferDeallocate_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) { +void GenericHubTester ::from_bufferInReturn_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) { // Check buffer deallocations here ASSERT_EQ(fwBuffer.getData(), m_buffer.getData()) << "Ensure that the buffer was deallocated"; ASSERT_EQ(fwBuffer.getSize(), m_buffer.getSize()) << "Ensure that the buffer was deallocated"; - this->pushFromPortEntry_bufferDeallocate(fwBuffer); + this->pushFromPortEntry_bufferInReturn(fwBuffer); } -void GenericHubTester ::from_dataInDeallocate_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) { +void GenericHubTester ::from_fromBufferDriverReturn_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) { ASSERT_NE(fwBuffer.getData(), nullptr) << "Empty buffer to deallocate"; ASSERT_GE(fwBuffer.getData(), m_data_for_allocation) << "Incorrect data pointer deallocated"; ASSERT_LT(fwBuffer.getData(), m_data_for_allocation + sizeof(m_data_for_allocation)) << "Incorrect data pointer deallocated"; + this->pushFromPortEntry_fromBufferDriverReturn(fwBuffer); + invoke_to_toBufferDriverReturn(portNum, fwBuffer); m_allocate.set(nullptr, 0); - this->pushFromPortEntry_dataInDeallocate(fwBuffer); } // ---------------------------------------------------------------------- @@ -235,59 +239,72 @@ void GenericHubTester ::from_dataInDeallocate_handler(const FwIndexType portNum, // ---------------------------------------------------------------------- void GenericHubTester ::connectPorts() { - // buffersIn + // bufferIn U32 max = - std::min(this->componentIn.getNum_buffersIn_InputPorts(), this->componentOut.getNum_buffersOut_OutputPorts()); + std::min(this->componentIn.getNum_bufferIn_InputPorts(), this->componentOut.getNum_bufferOut_OutputPorts()); for (U32 i = 0; i < max; ++i) { - this->connect_to_buffersIn(i, this->componentIn.get_buffersIn_InputPort(i)); + this->connect_to_bufferIn(i, this->componentIn.get_bufferIn_InputPort(i)); } - // LogRecv - this->connect_to_LogRecv(0, this->componentIn.get_LogRecv_InputPort(0)); + // eventIn + this->connect_to_eventIn(0, this->componentIn.get_eventIn_InputPort(0)); - // TlmRecv - this->connect_to_TlmRecv(0, this->componentIn.get_TlmRecv_InputPort(0)); + // tlmIn + this->connect_to_tlmIn(0, this->componentIn.get_tlmIn_InputPort(0)); - // dataIn - this->connect_to_dataIn(0, this->componentOut.get_dataIn_InputPort(0)); + // fromBufferDriver + this->connect_to_fromBufferDriver(0, this->componentOut.get_fromBufferDriver_InputPort(0)); - // buffersOut + // bufferOut for (U32 i = 0; i < max; ++i) { - this->componentOut.set_buffersOut_OutputPort(i, this->get_from_buffersOut(i)); + this->componentOut.set_bufferOut_OutputPort(i, this->get_from_bufferOut(i)); } - // LogSend - this->componentOut.set_LogSend_OutputPort(0, this->get_from_LogSend(0)); + // eventOut + this->componentOut.set_eventOut_OutputPort(0, this->get_from_eventOut(0)); - // TlmSend - this->componentOut.set_TlmSend_OutputPort(0, this->get_from_TlmSend(0)); + // tlmOut + this->componentOut.set_tlmOut_OutputPort(0, this->get_from_tlmOut(0)); - // dataOut - this->componentIn.set_dataOut_OutputPort(0, this->get_from_dataOut(0)); + // toBufferDriver + this->componentIn.set_toBufferDriver_OutputPort(0, this->get_from_toBufferDriver(0)); + + // toBufferDriverReturn + this->connect_to_toBufferDriverReturn(0, this->componentIn.get_toBufferDriverReturn_InputPort(0)); + + // bufferOutReturn + for (U32 i = 0; i < max; ++i) { + this->connect_to_bufferOutReturn(i, this->componentOut.get_bufferOutReturn_InputPort(i)); + } // bufferAllocate - this->componentIn.set_dataOutAllocate_OutputPort(0, this->get_from_dataOutAllocate(0)); + this->componentIn.set_allocate_OutputPort(0, this->get_from_allocate(0)); + + // buffer Return + this->componentOut.set_fromBufferDriverReturn_OutputPort(0, this->get_from_fromBufferDriverReturn(0)); // dataDeallocate - this->componentOut.set_dataInDeallocate_OutputPort(0, this->get_from_dataInDeallocate(0)); + this->componentIn.set_deallocate_OutputPort(0, this->get_from_deallocate(0)); - // bufferDeallocate - this->componentIn.set_bufferDeallocate_OutputPort(0, this->get_from_bufferDeallocate(0)); + // bufferInReturn + for (FwIndexType i = 0; i < GenericHubCfg::NumBufferInputPorts; i++) { + this->componentIn.set_bufferInReturn_OutputPort(i, this->get_from_bufferInReturn(i)); + } // ---------------------------------------------------------------------- // Connect serial output ports // ---------------------------------------------------------------------- - max = std::min(this->componentIn.getNum_portIn_InputPorts(), this->componentOut.getNum_portOut_OutputPorts()); + max = std::min(this->componentIn.getNum_serialIn_InputPorts(), this->componentOut.getNum_serialOut_OutputPorts()); for (U32 i = 0; i < max; ++i) { - this->componentOut.set_portOut_OutputPort(i, this->get_from_portOut(i)); + this->componentOut.set_serialOut_OutputPort(i, this->get_from_serialOut(i)); } // ---------------------------------------------------------------------- // Connect serial input ports // ---------------------------------------------------------------------- - // portIn + // serialIn for (U32 i = 0; i < max; ++i) { - this->connect_to_portIn(i, this->componentIn.get_portIn_InputPort(i)); + this->connect_to_serialIn(i, this->componentIn.get_serialIn_InputPort(i)); } } diff --git a/Svc/GenericHub/test/ut/GenericHubTester.hpp b/Svc/GenericHub/test/ut/GenericHubTester.hpp index 232b2d65bb..67068b430a 100644 --- a/Svc/GenericHub/test/ut/GenericHubTester.hpp +++ b/Svc/GenericHub/test/ut/GenericHubTester.hpp @@ -14,7 +14,7 @@ #define TESTER_HPP #include #include "GenericHubGTestBase.hpp" -#include "Svc/GenericHub/GenericHubComponentImpl.hpp" +#include "Svc/GenericHub/GenericHub.hpp" // Larger than com buffer size #define DATA_SIZE (FW_COM_BUFFER_MAX_SIZE * 10 + sizeof(U32) + sizeof(U32) + sizeof(FwBuffSizeType)) @@ -65,57 +65,57 @@ class GenericHubTester : public GenericHubGTestBase { // Handlers for typed from ports // ---------------------------------------------------------------------- - //! Handler for from_LogSend + //! Handler for from_eventOut //! - void from_LogSend_handler(const FwIndexType portNum, /*!< The port number*/ - FwEventIdType id, /*!< Log ID */ - Fw::Time& timeTag, /*!< Time Tag */ - const Fw::LogSeverity& severity, /*!< The severity argument */ - Fw::LogBuffer& args /*!< Buffer containing serialized log entry */ + void from_eventOut_handler(const FwIndexType portNum, /*!< The port number*/ + FwEventIdType id, /*!< Log ID */ + Fw::Time& timeTag, /*!< Time Tag */ + const Fw::LogSeverity& severity, /*!< The severity argument */ + Fw::LogBuffer& args /*!< Buffer containing serialized log entry */ ); - //! Handler for from_TlmSend + //! Handler for from_tlmOut //! - void from_TlmSend_handler(const FwIndexType portNum, /*!< The port number*/ - FwChanIdType id, /*!< Telemetry Channel ID */ - Fw::Time& timeTag, /*!< Time Tag */ - Fw::TlmBuffer& val /*!< Buffer containing serialized telemetry value */ + void from_tlmOut_handler(const FwIndexType portNum, /*!< The port number*/ + FwChanIdType id, /*!< Telemetry Channel ID */ + Fw::Time& timeTag, /*!< Time Tag */ + Fw::TlmBuffer& val /*!< Buffer containing serialized telemetry value */ ); - //! Handler for from_buffersOut + //! Handler for from_bufferOut //! - void from_buffersOut_handler(const FwIndexType portNum, /*!< The port number*/ - Fw::Buffer& fwBuffer); + void from_bufferOut_handler(const FwIndexType portNum, /*!< The port number*/ + Fw::Buffer& fwBuffer); - //! Handler for from_bufferDeallocate + //! Handler for from_bufferInReturn //! - void from_bufferDeallocate_handler(const FwIndexType portNum, /*!< The port number*/ - Fw::Buffer& fwBuffer); + void from_bufferInReturn_handler(const FwIndexType portNum, /*!< The port number*/ + Fw::Buffer& fwBuffer); - //! Handler for from_dataOutAllocate + //! Handler for from_allocate //! - Fw::Buffer from_dataOutAllocate_handler(const FwIndexType portNum, /*!< The port number*/ - FwSizeType size); + Fw::Buffer from_allocate_handler(const FwIndexType portNum, /*!< The port number*/ + FwSizeType size); - //! Handler for from_dataOut + //! Handler for from_toBufferDriver //! - void from_dataOut_handler(const FwIndexType portNum, /*!< The port number*/ - Fw::Buffer& fwBuffer); + void from_toBufferDriver_handler(const FwIndexType portNum, /*!< The port number*/ + Fw::Buffer& fwBuffer); //! Handler for from_dataDeallocate //! - void from_dataInDeallocate_handler(const FwIndexType portNum, /*!< The port number*/ - Fw::Buffer& fwBuffer); + void from_fromBufferDriverReturn_handler(const FwIndexType portNum, /*!< The port number*/ + Fw::Buffer& fwBuffer); private: // ---------------------------------------------------------------------- // Handlers for serial from ports // ---------------------------------------------------------------------- - //! Handler for from_portOut + //! Handler for from_serialOut //! - void from_portOut_handler(FwIndexType portNum, /*!< The port number*/ - Fw::SerializeBufferBase& Buffer /*!< The serialization buffer*/ + void from_serialOut_handler(FwIndexType portNum, /*!< The port number*/ + Fw::SerializeBufferBase& Buffer /*!< The serialization buffer*/ ); private: @@ -144,8 +144,8 @@ class GenericHubTester : public GenericHubGTestBase { //! The component under test //! - GenericHubComponentImpl componentIn; - GenericHubComponentImpl componentOut; + GenericHub componentIn; + GenericHub componentOut; Fw::ComBuffer m_comm; Fw::Buffer m_buffer; Fw::Buffer m_allocate; diff --git a/Svc/GenericHub/test/ut/README.md b/Svc/GenericHub/test/ut/README.md new file mode 100644 index 0000000000..dff1bab99b --- /dev/null +++ b/Svc/GenericHub/test/ut/README.md @@ -0,0 +1,51 @@ +# GenericHub Unit Testing + +Two Generic Hub component are instantiated in the unit test; one being the data transmitter and the other one being the receiver. In these unit tests, the two Generic Hubs are directly connected to each other. In real world Generic Hub will be connected to a buffer driver, that will interface with its counterpart on the other side. + +## Testing Configuration +### Configuration 1 + +In this test configuration data from the event-in, tlm-in or serial-in ports is processed by Generic Hub-In and sent to Generic Hub-Out via toBufferDriver port. Generic Hub-Out receives it on fromBufferDriver port, processes the incoming data and sends it to one of the corresponding output ports. Unit test verifies the data sent on input ports of Generic Hub-In matches to the data coming out of the output ports of Generic Hub-Out. + +In this test method a port connection is also established fromBufferDriverReturn port of Generic Hub out to toBufferDriverInReturn. This is done to test that original buffer allocation from Generic Hub In is deallocated after the test. + +**Note:** The two Generic Hubs are directly connected in this test, instead of being connected via Buffer Driver. The red lines show the interface between the two hubs + +The numbering (1,2,3..) in red shows the order in which the data will be processed by the two Generic Hub components + +![Top Level Generic Hub](./img/generic_hub_testing_1.svg) + +For more details see Events/Tlm/Serial data transfer sequence diagrams below + +### Test Method 2 + +In this test method data from the buffer-in port is processed by Generic Hub In and sent to Generic Hub Out via toBufferDriver port. Generic Hub Out receives it on fromBufferDriver port, processes the incoming data and sends it to one of the corresponding output ports. Unit test verifies the data sent on input ports of Generic Hub in to the data coming out of the output ports of Generic Hub Out. + +In this test method a port connection is also established fromBufferDriverReturn port of Generic Hub out to toBufferDriverInReturn. This is done to test that original buffer allocation from Generic Hub In is deallocated after the test. + +The numbering (1,2,3..) in red shows the order in which the data will be processed by the two Generic Hub components + +![Top Level Generic Hub](./img/generic_hub_testing_2.svg) + +For more details see buffer data transfer sequence diagram below + +## Sequence Diagram + + +### Scenario for Events-In/Events-Out Testing + +![Top Level Generic Hub](./img/event_data_transfer.svg) + +### Scenario for Telemetry-In/Telemetry-Out Testing + +![Top Level Generic Hub](./img/telem_data_transfer.svg) + +### Scenario for Serial-data-In/Serial-data-Out Testing + +![Top Level Generic Hub](./img/serial_data_transfer.svg) + +### Scenario for Buffer-data-In/Buffer-data-Out Testing + +![Top Level Generic Hub](./img/buffer_data_transfer.svg) + + diff --git a/Svc/GenericHub/test/ut/img/buffer_data_transfer.svg b/Svc/GenericHub/test/ut/img/buffer_data_transfer.svg new file mode 100644 index 0000000000..216bb1a1c4 --- /dev/null +++ b/Svc/GenericHub/test/ut/img/buffer_data_transfer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Svc/GenericHub/test/ut/img/event_data_transfer.svg b/Svc/GenericHub/test/ut/img/event_data_transfer.svg new file mode 100644 index 0000000000..808a212678 --- /dev/null +++ b/Svc/GenericHub/test/ut/img/event_data_transfer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Svc/GenericHub/test/ut/img/generic_hub_testing_1.svg b/Svc/GenericHub/test/ut/img/generic_hub_testing_1.svg new file mode 100644 index 0000000000..4eca9c2aac --- /dev/null +++ b/Svc/GenericHub/test/ut/img/generic_hub_testing_1.svg @@ -0,0 +1 @@ +611128345575Test PortsGH In Input PortsGH In Output PortsGH Out Input PortsGH Out Output PortsTest PortsTest Ports \ No newline at end of file diff --git a/Svc/GenericHub/test/ut/img/generic_hub_testing_2.svg b/Svc/GenericHub/test/ut/img/generic_hub_testing_2.svg new file mode 100644 index 0000000000..5279e3ea9a --- /dev/null +++ b/Svc/GenericHub/test/ut/img/generic_hub_testing_2.svg @@ -0,0 +1 @@ +12103596487Test PortsGH In Input PortsGH In Output PortsGH Out Input PortsGH Out Output PortsTest PortsTest Ports \ No newline at end of file diff --git a/Svc/GenericHub/test/ut/img/serial_data_transfer.svg b/Svc/GenericHub/test/ut/img/serial_data_transfer.svg new file mode 100644 index 0000000000..81bd8f9f59 --- /dev/null +++ b/Svc/GenericHub/test/ut/img/serial_data_transfer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Svc/GenericHub/test/ut/img/telem_data_transfer.svg b/Svc/GenericHub/test/ut/img/telem_data_transfer.svg new file mode 100644 index 0000000000..04c58b5c60 --- /dev/null +++ b/Svc/GenericHub/test/ut/img/telem_data_transfer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/default/config/AcConstants.fpp b/default/config/AcConstants.fpp index de3817573a..09e911ea83 100644 --- a/default/config/AcConstants.fpp +++ b/default/config/AcConstants.fpp @@ -59,12 +59,3 @@ constant FwAssertTextSize = 256 @ the constants FW_ASSERT_TEXT_SIZE and FW_LOG_STRING_MAX_SIZE, set @ in FpConfig.h. constant AssertFatalAdapterEventFileSize = FileNameStringSize - -# ---------------------------------------------------------------------- -# Hub connections. Connections on all deployments should mirror these settings. -# ---------------------------------------------------------------------- - -constant GenericHubInputPorts = 10 -constant GenericHubOutputPorts = 10 -constant GenericHubInputBuffers = 10 -constant GenericHubOutputBuffers = 10 diff --git a/default/config/CMakeLists.txt b/default/config/CMakeLists.txt index 6f72d87205..ebaf6d0991 100644 --- a/default/config/CMakeLists.txt +++ b/default/config/CMakeLists.txt @@ -6,11 +6,12 @@ register_fprime_config( AUTOCODER_INPUTS "${CMAKE_CURRENT_LIST_DIR}/AcConstants.fpp" - "${CMAKE_CURRENT_LIST_DIR}/DpCfg.fpp" "${CMAKE_CURRENT_LIST_DIR}/ComCfg.fpp" + "${CMAKE_CURRENT_LIST_DIR}/DpCfg.fpp" "${CMAKE_CURRENT_LIST_DIR}/FpConfig.fpp" "${CMAKE_CURRENT_LIST_DIR}/FpConstants.fpp" "${CMAKE_CURRENT_LIST_DIR}/FpySequencerCfg.fpp" + "${CMAKE_CURRENT_LIST_DIR}/GenericHubCfg.fpp" "${CMAKE_CURRENT_LIST_DIR}/MemoryAllocation.fpp" "${CMAKE_CURRENT_LIST_DIR}/MemoryAllocation.hpp" "${CMAKE_CURRENT_LIST_DIR}/PlatformCfg.fpp" diff --git a/default/config/GenericHubCfg.fpp b/default/config/GenericHubCfg.fpp new file mode 100644 index 0000000000..edad530340 --- /dev/null +++ b/default/config/GenericHubCfg.fpp @@ -0,0 +1,16 @@ +# ====================================================================== +# GenericHub configuration +# ====================================================================== + +module Svc { + + module GenericHubCfg { + + constant NumSerialInputPorts = 10 + constant NumBufferInputPorts = 10 + constant NumSerialOutputPorts = 10 + constant NumBufferOutputPorts = 10 + + } + +}