diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index df45d9e2628..f2c7ffe1341 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -337,6 +337,7 @@ itr itrunc itval janamian +jawest Jax jdk jdperez diff --git a/Fw/Dp/docs/sdd.md b/Fw/Dp/docs/sdd.md index 0d53a8ae75e..70dad586ee5 100644 --- a/Fw/Dp/docs/sdd.md +++ b/Fw/Dp/docs/sdd.md @@ -98,7 +98,7 @@ Single-value records with _type = T_ have the following format: |Field Name|Data Type|Serialized Size|Description| |----------|---------|---------------|-----------| |`Id`|`FwDpIdType`|`sizeof(FwDpIdType)`|The record ID| -|`Data`|_T_|`sizeof(`_T_`)` if _T_ is a primitive type; otherwise _T_`::SERIALIZED_SIZE`|The serialized data| +|`Data`|_T_|Size of the serialized data|The serialized data| **Array records:** An array record is specified in FPP in the form `product record` _name_ `:` _type_ `array`. @@ -110,7 +110,7 @@ Array records with _type = T_ have the following format: |----------|---------|---------------|-----------| |`Id`|`FwDpIdType`|`sizeof(FwDpIdType)`|The record ID| |`Size`|`FwSizeType`|`sizeof(FwSizeStoreType)`|The number _n_ of elements in the record| -|`Data`|Array of _n_ _T_|_n_ * [`sizeof(`_T_`)` if _T_ is a primitive type; otherwise _T_`::SERIALIZED_SIZE`]|_n_ elements, each of type _T_| +|`Data`|Array of _n_ _T_|Sum of the serialized sizes of the elements in the array|_n_ elements, each of type _T_| #### 5.1.4. Data Hash diff --git a/Ref/CMakeLists.txt b/Ref/CMakeLists.txt index 91f73d265ec..4d078810075 100644 --- a/Ref/CMakeLists.txt +++ b/Ref/CMakeLists.txt @@ -35,6 +35,7 @@ add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/RecvBuffApp/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/SendBuffApp/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/SignalGen/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/TypeDemo/") +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/DpDemo/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/BlockDriver/") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Top/") diff --git a/Ref/DpDemo/CMakeLists.txt b/Ref/DpDemo/CMakeLists.txt new file mode 100644 index 00000000000..18562c66fac --- /dev/null +++ b/Ref/DpDemo/CMakeLists.txt @@ -0,0 +1,23 @@ +#### +# F Prime CMakeLists.txt: +# +# SOURCES: list of source files (to be compiled) +# AUTOCODER_INPUTS: list of files to be passed to the autocoders +# DEPENDS: list of libraries that this module depends on +# +# More information in the F´ CMake API documentation: +# https://fprime.jpl.nasa.gov/latest/docs/reference/api/cmake/API/ +# +#### + +register_fprime_library( + AUTOCODER_INPUTS + "${CMAKE_CURRENT_LIST_DIR}/DpDemo.fpp" + SOURCES + "${CMAKE_CURRENT_LIST_DIR}/DpDemo.cpp" +) + +set(SOURCE_FILES + "${CMAKE_CURRENT_LIST_DIR}/DpDemo.fpp" + "${CMAKE_CURRENT_LIST_DIR}/DpDemo.cpp" +) diff --git a/Ref/DpDemo/DpDemo.cpp b/Ref/DpDemo/DpDemo.cpp new file mode 100644 index 00000000000..75ea1492fae --- /dev/null +++ b/Ref/DpDemo/DpDemo.cpp @@ -0,0 +1,246 @@ +// ====================================================================== +// \title DpDemo.cpp +// \author jawest +// \brief cpp file for DpDemo component implementation class +// ====================================================================== + +#include "Ref/DpDemo/DpDemo.hpp" + +namespace Ref { + + // ---------------------------------------------------------------------- + // Component construction and destruction + // ---------------------------------------------------------------------- + + DpDemo ::DpDemo(const char* const compName) : DpDemoComponentBase(compName) { + this->selectedColor = DpDemo_ColorEnum::RED; + this->numRecords = 0; + this->dpPriority = 0; + } + + DpDemo ::~DpDemo() {} + + // ---------------------------------------------------------------------- + // Handler implementations for typed input ports + // ---------------------------------------------------------------------- + + void DpDemo ::run_handler(FwIndexType portNum, U32 context) { + // If a Data product is being generated, store records + if (this->dpInProgress) { + this->dpContainer.serializeRecord_StringRecord(Fw::String("Test string")); + this->dpContainer.serializeRecord_BooleanRecord(true); + this->dpContainer.serializeRecord_I32Record(-100); + this->dpContainer.serializeRecord_F64Record(1.25); + this->dpContainer.serializeRecord_U32ArrayRecord(DpDemo_U32Array(1, 2, 3, 4, 5)); + this->dpContainer.serializeRecord_F32ArrayRecord(DpDemo_F32Array(1.1f, 2.2f, 3.3f)); + this->dpContainer.serializeRecord_BooleanArrayRecord(DpDemo_BooleanArray(true, false)); + // Array Records + // Array record of strings + Fw::String str0("String array element 0"); + Fw::String str1("String array element 1"); + Fw::String str2("String array element 2"); + const Fw::StringBase* strings[3] = { &str0, &str1, &str2 }; + this->dpContainer.serializeRecord_StringArrayRecord(strings, 3); + // Array record of arrays + const DpDemo_StringArray arrayArray[1] = { + DpDemo_StringArray( + Fw::String("0 - String array record element 0"), + Fw::String("0 - String array record element 1") + ) + }; + this->dpContainer.serializeRecord_ArrayArrayRecord(arrayArray, 1); + // Array record of structs + const DpDemo_StructWithStringMembers structArray[2] = { + DpDemo_StructWithStringMembers( + Fw::String("0 - String member"), + DpDemo_StringArray( + Fw::String("0 - String array element 0"), + Fw::String("0 - String array element 1") + ) + ), + DpDemo_StructWithStringMembers( + Fw::String("1 - String member"), + DpDemo_StringArray( + Fw::String("1 - String array element 0"), + Fw::String("1 - String array element 1") + ) + ) + }; + this->dpContainer.serializeRecord_StructArrayRecord(structArray, 2); + this->dpContainer.serializeRecord_ArrayOfStringArrayRecord( + DpDemo_ArrayOfStringArray( + DpDemo_StringArray( + Fw::String("0 - String array element 0"), + Fw::String("0 - String array element 1") + ), + DpDemo_StringArray( + Fw::String("1 - String array element 0"), + Fw::String("1 - String array element 1") + ), + DpDemo_StringArray( + Fw::String("2 - String array element 0"), + Fw::String("2 - String array element 1") + ) + ) + ); + this->dpContainer.serializeRecord_ArrayOfStructsRecord( + DpDemo_ArrayOfStructs( + DpDemo_StructWithStringMembers( + Fw::String("0 - String member"), + DpDemo_StringArray( + Fw::String("0 - String array element 0"), + Fw::String("0 - String array element 1") + ) + ), + DpDemo_StructWithStringMembers( + Fw::String("1 - String member"), + DpDemo_StringArray( + Fw::String("1 - String array element 0"), + Fw::String("1 - String array element 1") + ) + ), + DpDemo_StructWithStringMembers( + Fw::String("2 - String member"), + DpDemo_StringArray( + Fw::String("2 - String array element 0"), + Fw::String("2 - String array element 1") + ) + ) + ) + ); + this->dpContainer.serializeRecord_EnumArrayRecord(DpDemo_EnumArray(DpDemo_ColorEnum::RED, DpDemo_ColorEnum::GREEN, DpDemo_ColorEnum::BLUE)); + this->dpContainer.serializeRecord_StructWithEverythingRecord(DpDemo_StructWithEverything( + -1, + 2.5, + Fw::String("String Member"), + false, + this->selectedColor, + { + DpDemo_U32Array(1, 2, 3, 4, 5), + DpDemo_U32Array(6, 7, 8, 9, 10) + }, + DpDemo_F32Array(4.4f, 5.5f, 6.6f), + DpDemo_U32Array(6, 7, 8, 9, 10), + DpDemo_EnumArray(DpDemo_ColorEnum::RED, DpDemo_ColorEnum::GREEN, DpDemo_ColorEnum::BLUE), + DpDemo_StringArray( + Fw::String("String array element 0"), + Fw::String("String array element 1") + ), + DpDemo_BooleanArray(true, false), + DpDemo_StructWithStringMembers( + Fw::String("String member"), + DpDemo_StringArray( + Fw::String("String array element 0"), + Fw::String("String array element 1") + ) + ), + DpDemo_ArrayOfStringArray( + DpDemo_StringArray( + Fw::String("0 - String array element 0"), + Fw::String("0 - String array element 1") + ), + DpDemo_StringArray( + Fw::String("1 - String array element 0"), + Fw::String("1 - String array element 1") + ), + DpDemo_StringArray( + Fw::String("2 - String array element 0"), + Fw::String("2 - String array element 1") + ) + ) + )); + this->log_ACTIVITY_LO_DpComplete(this->numRecords); + this->cleanupAndSendDp(); + } + } + + // ---------------------------------------------------------------------- + // Handler implementations for commands + // ---------------------------------------------------------------------- + + void DpDemo ::SelectColor_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Ref::DpDemo_ColorEnum color) { + this->selectedColor = color; + log_ACTIVITY_HI_ColorSelected(color); + this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); + } + + void DpDemo ::Dp_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, DpDemo_DpReqType reqType, U32 priority) { + + // make sure DPs are available + if (!this->isConnected_productGetOut_OutputPort(0) || !this->isConnected_productRequestOut_OutputPort(0)) { + this->log_WARNING_HI_DpsNotConnected(); + this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); + return; + } + + this->numRecords = 15; // 15 records in current demo + FwSizeType dpSize = DpDemo_StringAlias::SERIALIZED_SIZE + + sizeof(DpDemo_BoolAlias) + + sizeof(DpDemo_I32Alias) + + sizeof(DpDemo_F64Alias) + + DpDemo_U32Array::SERIALIZED_SIZE + + DpDemo_F32Array::SERIALIZED_SIZE + + DpDemo_BooleanArray::SERIALIZED_SIZE + + DpDemo_EnumArray::SERIALIZED_SIZE + + DpDemo_StringArray::SERIALIZED_SIZE + + DpDemo_StructWithEverything::SERIALIZED_SIZE + + DpDemo_StructWithStringMembers::SERIALIZED_SIZE + + (DpDemo_StringArray::SERIALIZED_SIZE * 3) + + (DpDemo_StringArray::SERIALIZED_SIZE * 1) + + (DpDemo_StructWithStringMembers::SERIALIZED_SIZE * 2) + + DpDemo_ArrayOfStringArray::SERIALIZED_SIZE + + (numRecords * sizeof(FwDpIdType)); + + this->dpPriority = static_cast(priority); + this->log_ACTIVITY_LO_DpMemRequested(dpSize); + if(reqType == DpDemo_DpReqType::IMMEDIATE) { + Fw::Success stat = this->dpGet_DpDemoContainer(dpSize, this->dpContainer); + // make sure we got the memory we wanted + if (Fw::Success::FAILURE == stat) { + this->log_WARNING_HI_DpMemoryFail(); + this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); + } else { + this->dpInProgress = true; + this->log_ACTIVITY_LO_DpStarted(numRecords); + this->log_ACTIVITY_LO_DpMemReceived(this->dpContainer.getBuffer().getSize()); + // override priority with requested priority + this->dpContainer.setPriority(priority); + this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); + } + } + else if (reqType == DpDemo_DpReqType::ASYNC) { + this->dpRequest_DpDemoContainer(dpSize); + } + else { + // should never get here + FW_ASSERT(0, reqType.e); + } + } + + // ---------------------------------------------------------------------- + // Handler implementations for data products + // ---------------------------------------------------------------------- + + void DpDemo ::dpRecv_DpDemoContainer_handler(DpContainer& container, Fw::Success::T status) { + // Make sure we got the buffer we wanted or quit + if (Fw::Success::SUCCESS == status) { + this->dpContainer = container; + this->dpInProgress = true; + // set previously requested priority + this->dpContainer.setPriority(this->dpPriority); + this->log_ACTIVITY_LO_DpStarted(this->numRecords); + } else { + this->log_WARNING_HI_DpMemoryFail(); + // cleanup + this->dpInProgress = false; + this->numRecords = 0; + } + } + + void DpDemo ::cleanupAndSendDp() { + this->dpSend(this->dpContainer); + this->dpInProgress = false; + this->numRecords = 0; + } + +} // namespace Ref diff --git a/Ref/DpDemo/DpDemo.fpp b/Ref/DpDemo/DpDemo.fpp new file mode 100644 index 00000000000..15a80e3d6e3 --- /dev/null +++ b/Ref/DpDemo/DpDemo.fpp @@ -0,0 +1,212 @@ +module Ref { + @ DP Demo + active component DpDemo { + + enum ColorEnum { + RED + GREEN + BLUE + } + + enum DpReqType { + IMMEDIATE + ASYNC + } + + type StringAlias = string + type BoolAlias = bool + type I32Alias = I32 + type F64Alias = F64 + + @ Array of floats + array F32Array = [3] F32 + + @ Array of integers + array U32Array = [5] U32 + + @ Array of strings + array StringArray = [2] string + + @ Array of array of strings + array ArrayOfStringArray = [3] StringArray + + @ Array of booleans + array BooleanArray = [2] bool + + @ Array of enumerations + array EnumArray = [3] ColorEnum + + array ArrayOfStructs = [3] StructWithStringMembers + + struct ColorInfoStruct { + Color: ColorEnum + } + + struct StructWithStringMembers { + stringMember: string, + stringArrayMember: StringArray + } + + struct StructWithEverything { + integerMember: I32Alias, + floatMember: F32, + stringMember: string, + booleanMember: bool, + enumMember: ColorEnum, + arrayMemberU32: [2] U32Array, + F32Array: F32Array, + U32Array: U32Array, + enumArray: EnumArray + stringArray: StringArray, + booleanArray: BooleanArray, + structWithStrings: StructWithStringMembers + nestedArrays: ArrayOfStringArray + } + + @ Select color + async command SelectColor(color: ColorEnum) opcode 0 + + @ Command for generating a DP + sync command Dp(reqType: DpReqType, $priority: U32) + + @ Color selected event + event ColorSelected(color: ColorEnum) severity activity high id 0 format "Color selected {}" + + @ DP started event + event DpStarted(records: U32) \ + severity activity low \ + id 1 \ + format "Writing {} DP records" + + @ DP complete event + event DpComplete(records: U32) \ + severity activity low \ + id 2 \ + format "Finished writing {} DP records" + + event DpRecordFull(records: U32, bytes: U32) \ + severity warning low \ + id 3 \ + format "DP container full with {} records and {} bytes. Closing DP." + + event DpMemRequested($size: FwSizeType) \ + severity activity low \ + id 4 \ + format "Requesting {} bytes for DP" + + event DpMemReceived($size: FwSizeType) \ + severity activity low \ + id 5 \ + format "Received {} bytes for DP" + + event DpMemoryFail \ + severity warning high \ + id 6 \ + format "Failed to acquire a DP buffer" + + event DpsNotConnected \ + severity warning high \ + id 7 \ + format "DP Ports not connected!" + + @ Example port: receiving calls from the rate group + sync input port run: Svc.Sched + + # @ Example parameter + # param PARAMETER_NAME: U32 + + ############################################################################### + # Standard AC Ports: Required for Channels, Events, Commands, and Parameters # + ############################################################################### + @ Port for requesting the current time + time get port timeCaller + + @ Port for sending command registrations + command reg port cmdRegOut + + @ Port for receiving commands + command recv port cmdIn + + @ Port for sending command responses + command resp port cmdResponseOut + + @ Port for sending textual representation of events + text event port logTextOut + + @ Port for sending events to downlink + event port logOut + + @ Port for sending telemetry channels to downlink + telemetry port tlmOut + + @ Port to return the value of a parameter + param get port prmGetOut + + @ Port to set the value of a parameter + param set port prmSetOut + + @ Data product get port + product get port productGetOut + + @ Data product request port + product request port productRequestOut + + @ Data product receive port + async product recv port productRecvIn + + @ Data product send port + product send port productSendOut + + @ Data product record - struct record + product record ColorInfoStructRecord: ColorInfoStruct id 0 + + @ Data product record - enum + product record ColorEnumRecord: ColorEnum id 1 + + @ Data product record - string + product record StringRecord: StringAlias id 2 + + @ Data product record - boolean + product record BooleanRecord: BoolAlias id 3 + + @ Data product record - I32 + product record I32Record: I32Alias id 4 + + @ Data product record - F64 + product record F64Record: F64Alias id 5 + + @ Data product record - U32 array record + product record U32ArrayRecord: U32Array id 6 + + @ Data product record - F32 array record + product record F32ArrayRecord: F32Array id 7 + + @ Data product record - boolean array record + product record BooleanArrayRecord: BooleanArray id 8 + + @ Data product record - enum array record + product record EnumArrayRecord: EnumArray id 9 + + @ Data product record - string array record + product record StringArrayRecord: string array id 10 + + @ Data product record - array record (structs) + product record StructArrayRecord: StructWithStringMembers array id 11 + + @ Data product record - array record (arrays) + product record ArrayArrayRecord: StringArray array id 12 + + @ Data product record - array record (string arrays) + product record ArrayOfStringArrayRecord: ArrayOfStringArray id 13 + + @ Data product record - struct record + product record StructWithEverythingRecord: StructWithEverything id 14 + + @ Data product record - array of structs + product record ArrayOfStructsRecord: ArrayOfStructs id 15 + + @ Data product container + product container DpDemoContainer id 0 default priority 10 + + } +} diff --git a/Ref/DpDemo/DpDemo.hpp b/Ref/DpDemo/DpDemo.hpp new file mode 100644 index 00000000000..7094fd9f315 --- /dev/null +++ b/Ref/DpDemo/DpDemo.hpp @@ -0,0 +1,77 @@ +// ====================================================================== +// \title DpDemo.hpp +// \author jawest +// \brief hpp file for DpDemo component implementation class +// ====================================================================== + +#ifndef Ref_DpDemo_HPP +#define Ref_DpDemo_HPP + +#include "Ref/DpDemo/DpDemoComponentAc.hpp" + +namespace Ref { + +class DpDemo final : public DpDemoComponentBase { + public: + // ---------------------------------------------------------------------- + // Component construction and destruction + // ---------------------------------------------------------------------- + + //! Construct DpDemo object + DpDemo(const char* const compName //!< The component name + ); + + //! Destroy DpDemo object + ~DpDemo(); + + private: + // ---------------------------------------------------------------------- + // Handler implementations for commands + // ---------------------------------------------------------------------- + + //! Handler implementation for run + //! + //! Example port: receiving calls from the rate group + void run_handler(FwIndexType portNum, //!< The port number + U32 context //!< The call order + ) override; + + //! Handler implementation for command SelectColor + //! + //! Select color + void SelectColor_cmdHandler(FwOpcodeType opCode, //!< The opcode + U32 cmdSeq, //!< The command sequence number + Ref::DpDemo_ColorEnum color) override; + + //! Handler implementation for command Dp + //! + //! Command for generating a DP + void Dp_cmdHandler(FwOpcodeType opCode, //!< The opcode + U32 cmdSeq, //!< The command sequence number + DpDemo_DpReqType reqType, + U32 priority) override; + + private: + // ---------------------------------------------------------------------- + // Handler implementations for data products + // ---------------------------------------------------------------------- + + //! Receive a container of type DpDemoContainer + void dpRecv_DpDemoContainer_handler(DpContainer& container, //!< The container + Fw::Success::T status //!< The container status + ) override; + + // DP cleanup helper + void cleanupAndSendDp(); + + // Member variables + DpDemo_ColorEnum selectedColor; + U32 numRecords; + U32 dpPriority; + DpContainer dpContainer; + bool dpInProgress; +}; + +} // namespace Ref + +#endif diff --git a/Ref/DpDemo/test/int/dp_demo_integration_test.py b/Ref/DpDemo/test/int/dp_demo_integration_test.py new file mode 100644 index 00000000000..edb8354b15e --- /dev/null +++ b/Ref/DpDemo/test/int/dp_demo_integration_test.py @@ -0,0 +1,59 @@ +import os +import json +from fprime_gds.executables.data_product_writer import DataProductWriter + + +def test_dp_send(fprime_test_api): + """Test that DPs are generated and received on the ground""" + + # Run Dp command to send a data product + fprime_test_api.send_and_assert_command("Ref.dpDemo.Dp", ["IMMEDIATE", 1]) + # Wait for DpStarted event + result = fprime_test_api.await_event("Ref.dpDemo.DpStarted", start=0, timeout=5) + assert result + # Wait for DpComplete event + result = fprime_test_api.await_event("Ref.dpDemo.DpComplete", start=0, timeout=10) + assert result + # Check for FileWritten event and capture the name of the file that was created + file_result = fprime_test_api.await_event( + "DataProducts.dpWriter.FileWritten", start=0, timeout=10 + ) + dp_file_path = file_result.get_display_text().split().pop() + # Verify that the file exists + # Assumes that we are running the test from the Ref directory + assert os.path.isfile(dp_file_path) + + +def test_dp_decode(fprime_test_api): + """Test that we can decode DPs on the ground via fprime_dp_writer""" + + # Run Dp command to send a data product + fprime_test_api.send_and_assert_command("Ref.dpDemo.Dp", ["IMMEDIATE", 1]) + # Check for FileWritten event and capture the name of the file that was created + file_result = fprime_test_api.await_event( + "DataProducts.dpWriter.FileWritten", start=0, timeout=10 + ) + dp_file_path = file_result.get_display_text().split().pop() + # Verify that the file exists + # Assumes that we are running the test from the Ref directory + assert os.path.isfile(dp_file_path) + # Decode DP with fprime-dp-writer tool + json_dict = fprime_test_api.pipeline.dictionary_path + decoded_file_name = os.path.basename(dp_file_path).replace(".fdp", ".json") + DataProductWriter(json_dict, dp_file_path).process() + assert os.path.isfile(decoded_file_name) + with open("./DpDemo/test/int/dp_ref_output.json", "r") as ref_file, open( + decoded_file_name, "r" + ) as output_file: + ref_json = json.load(ref_file) + output_json = json.load(output_file) + # Remove fields that we expect to be different + exclude = ["Seconds", "USeconds", "TimeBase", "Context", "headerHash"] + assert len(ref_json) > 0 and len(output_json) > 0 + for f in exclude: + assert isinstance(ref_json[0], dict) and isinstance(output_json[0], dict) + assert f in ref_json[0] and f in output_json[0] + ref_json[0].pop(f) + output_json[0].pop(f) + # Check that the JSON strings are the same + assert json.dumps(ref_json) == json.dumps(output_json) diff --git a/Ref/DpDemo/test/int/dp_ref_output.json b/Ref/DpDemo/test/int/dp_ref_output.json new file mode 100644 index 00000000000..0eed1795f04 --- /dev/null +++ b/Ref/DpDemo/test/int/dp_ref_output.json @@ -0,0 +1,303 @@ +[ + { + "PacketDescriptor": 5, + "Id": 2576, + "Priority": 1, + "Seconds": 131176, + "USeconds": 2435760640, + "TimeBase": 2418, + "Context": 210, + "ProcTypes": 0, + "UserData": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "DpState": 0, + "DataSize": 1212, + "headerHash": 2646027546, + "dataHash": 4072048964 + }, + { + "dataId": 2578, + "data": "Test string" + }, + { + "dataId": 2579, + "data": true + }, + { + "dataId": 2580, + "data": -100 + }, + { + "dataId": 2581, + "data": 1.25 + }, + { + "dataId": 2582, + "data": [ + 1, + 2, + 3, + 4, + 5 + ] + }, + { + "dataId": 2583, + "data": [ + 1.100000023841858, + 2.200000047683716, + 3.299999952316284 + ] + }, + { + "dataId": 2584, + "data": [ + true, + false + ] + }, + { + "dataId": 2586, + "size": 3, + "data": [ + "String array element 0", + "String array element 1", + "String array element 2" + ] + }, + { + "dataId": 2588, + "size": 1, + "data": [ + [ + "0 - String array record element 0", + "0 - String array record element 1" + ] + ] + }, + { + "dataId": 2587, + "size": 2, + "data": [ + [ + { + "stringMember": "0 - String member" + }, + { + "stringArrayMember": [ + "0 - String array element 0", + "0 - String array element 1" + ] + } + ], + [ + { + "stringMember": "1 - String member" + }, + { + "stringArrayMember": [ + "1 - String array element 0", + "1 - String array element 1" + ] + } + ] + ] + }, + { + "dataId": 2589, + "data": [ + [ + "0 - String array element 0", + "0 - String array element 1" + ], + [ + "1 - String array element 0", + "1 - String array element 1" + ], + [ + "2 - String array element 0", + "2 - String array element 1" + ] + ] + }, + { + "dataId": 2591, + "data": [ + [ + { + "stringMember": "0 - String member" + }, + { + "stringArrayMember": [ + "0 - String array element 0", + "0 - String array element 1" + ] + } + ], + [ + { + "stringMember": "1 - String member" + }, + { + "stringArrayMember": [ + "1 - String array element 0", + "1 - String array element 1" + ] + } + ], + [ + { + "stringMember": "2 - String member" + }, + { + "stringArrayMember": [ + "2 - String array element 0", + "2 - String array element 1" + ] + } + ] + ] + }, + { + "dataId": 2585, + "data": [ + "RED", + "GREEN", + "BLUE" + ] + }, + { + "dataId": 2590, + "data": [ + { + "integerMember": -1 + }, + { + "floatMember": 2.5 + }, + { + "stringMember": "String Member" + }, + { + "booleanMember": false + }, + { + "enumMember": "RED" + }, + { + "arrayMemberU32": [ + 1, + 2, + 3, + 4, + 5 + ] + }, + { + "arrayMemberU32": [ + 6, + 7, + 8, + 9, + 10 + ] + }, + { + "F32Array": [ + 4.400000095367432, + 5.5, + 6.599999904632568 + ] + }, + { + "U32Array": [ + 6, + 7, + 8, + 9, + 10 + ] + }, + { + "enumArray": [ + "RED", + "GREEN", + "BLUE" + ] + }, + { + "stringArray": [ + "String array element 0", + "String array element 1" + ] + }, + { + "booleanArray": [ + true, + false + ] + }, + { + "structWithStrings": [ + { + "stringMember": "String member" + }, + { + "stringArrayMember": [ + "String array element 0", + "String array element 1" + ] + } + ] + }, + { + "nestedArrays": [ + [ + "0 - String array element 0", + "0 - String array element 1" + ], + [ + "1 - String array element 0", + "1 - String array element 1" + ], + [ + "2 - String array element 0", + "2 - String array element 1" + ] + ] + } + ] + } +] diff --git a/Ref/Top/instances.fpp b/Ref/Top/instances.fpp index 075dedbee8b..22632f54695 100644 --- a/Ref/Top/instances.fpp +++ b/Ref/Top/instances.fpp @@ -58,6 +58,11 @@ module Ref { stack size Default.STACK_SIZE \ priority 97 + instance dpDemo: Ref.DpDemo base id 0x0A10 \ + queue size Default.QUEUE_SIZE \ + stack size Default.STACK_SIZE \ + priority 96 + # ---------------------------------------------------------------------- # Queued component instances # ---------------------------------------------------------------------- diff --git a/Ref/Top/topology.fpp b/Ref/Top/topology.fpp index 2e9692b6738..c414359ca01 100644 --- a/Ref/Top/topology.fpp +++ b/Ref/Top/topology.fpp @@ -41,6 +41,7 @@ module Ref { instance sendBuffComp instance typeDemo instance systemResources + instance dpDemo instance linuxTimer instance comDriver instance cmdSeq @@ -93,6 +94,7 @@ module Ref { rateGroup2Comp.RateGroupMemberOut[1] -> sendBuffComp.SchedIn rateGroup2Comp.RateGroupMemberOut[2] -> SG3.schedIn rateGroup2Comp.RateGroupMemberOut[3] -> SG4.schedIn + rateGroup2Comp.RateGroupMemberOut[4] -> dpDemo.run # Rate group 3 rateGroupDriverComp.CycleOut[Ports_RateGroups.rateGroup3] -> rateGroup3Comp.CycleIn @@ -132,7 +134,13 @@ module Ref { DataProducts.dpMgr.productResponseOut -> SG1.productRecvIn # Send filled DP SG1.productSendOut -> DataProducts.dpMgr.productSendIn - + # Synchronous request + dpDemo.productGetOut -> DataProducts.dpMgr.productGetIn + # Send filled DP + dpDemo.productSendOut -> DataProducts.dpMgr.productSendIn + # Asynchronous request + dpDemo.productRequestOut -> DataProducts.dpMgr.productRequestIn + DataProducts.dpMgr.productResponseOut -> dpDemo.productRecvIn } connections ComCcsds_CdhCore{ @@ -151,7 +159,7 @@ module Ref { # File Downlink <-> ComQueue FileHandling.fileDownlink.bufferSendOut -> ComCcsds.comQueue.bufferQueueIn[ComCcsds.Ports_ComBufferQueue.FILE] ComCcsds.comQueue.bufferReturnOut[ComCcsds.Ports_ComBufferQueue.FILE] -> FileHandling.fileDownlink.bufferReturn - + # Router <-> FileUplink ComCcsds.fprimeRouter.fileOut -> FileHandling.fileUplink.bufferSendIn FileHandling.fileUplink.bufferSendOut -> ComCcsds.fprimeRouter.fileBufferReturnIn @@ -165,4 +173,4 @@ module Ref { } -} \ No newline at end of file +} diff --git a/requirements.txt b/requirements.txt index 8dcd2c0a1d9..653eb9414b8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,8 +20,8 @@ Flask-Compress==1.15 Flask-RESTful==0.3.10 fprime-fpl-layout==1.0.3 fprime-fpl-write-pic==1.0.3 -fprime-fpp==3.0.0a16 -fprime-gds==4.0.0a9 +fprime-fpp==3.0.0a18 +fprime-gds==4.0.0a10 fprime-tools==4.0.0a9 fprime-visual==1.0.2 gcovr==8.2