Add DP Demo for testing DPs and fprime-dp-writer (#3951)

* Initial DpDemo component, added test for decoding DPs

* Updated Dp demo to include additional types, arrays, and struct records

* Added struct member array to DP demo

* Remove unused tlm

* Cleanup after merging devel

* Add deepdiff to requirements, fix formatting, update spelling

* fpp v3.0.0a16

* fprime-gds v4.0.0a10

* Add 3 array record cases to DP demo

* Remove comments

* Remove deepdiff

* Formatting, update spelling

* FPP v3.0.0a18

* Spelling

---------

Co-authored-by: Thomas Boyer-Chammard <49786685+thomas-bc@users.noreply.github.com>
This commit is contained in:
Justine West 2025-08-05 12:28:00 -07:00 committed by GitHub
parent d460468b1b
commit dfaf496263
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 942 additions and 7 deletions

View File

@ -337,6 +337,7 @@ itr
itrunc
itval
janamian
jawest
Jax
jdk
jdperez

View File

@ -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

View File

@ -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/")

23
Ref/DpDemo/CMakeLists.txt Normal file
View File

@ -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"
)

246
Ref/DpDemo/DpDemo.cpp Normal file
View File

@ -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<FwDpPriorityType>(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

212
Ref/DpDemo/DpDemo.fpp Normal file
View File

@ -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
}
}

77
Ref/DpDemo/DpDemo.hpp Normal file
View File

@ -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

View File

@ -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)

View File

@ -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"
]
]
}
]
}
]

View File

@ -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
# ----------------------------------------------------------------------

View File

@ -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 {
}
}
}

View File

@ -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