fprime
fprime copied to clipboard
toString doesn't display the last item in a struct
F` version v3.1.1 | |
**** |
Problem Description
Files generated by fpp tools doesn't produce the format string correctly and so the last member of a string doesn't show up as expected. For example
The take the following struct defined in fpp:
enum CMD_STATUS : U16 {
NA = 0,
ACK = 0x5,
NOT_ACK = 0x6,
BUSY = 0x7,
NCE = 0x8,
STACK_FULL = 0x9,
TEMP_NOT_ACC = 0x10
};
constant ESUP_HEADER_ID = 0x50555345
# NOTE that in byte form it will be represented with LE
struct EsupPacketHeader {
HeaderId: U32
ModuleId: U16
DataLength: U16
CmdStatus: CMD_STATUS
} default {HeaderId = ESUP_HEADER_ID, CmdStatus=CMD_STATUS.NA}
struct EsupStatusGet {
Header: EsupPacketHeader
CmdId: EsupCmdId
TypeId: U16
SystemState: U8 @< 1,2,3,4 (1 byte unsigned char value)
StatusFlags: U8 @< 1 byte unsigned char value
Reserved: U16 @< 2 byte unsigned short value
CpuTemperature: F32 @< -40 to 125 °C (4 byte float value)
FirmwareVersion: U32 @< firmware version (4 byte unsigned int value)
} default {CmdId = EsupCmdId.ConfGet, TypeId = EsupCmdType.StatusRep}
I then go to print out the contents like so:
static bool receiveEsupStatusResponse(int serialPort, EsupCmdId cmdId, boost::span<BYTE, GET_PADDED_SIZE(EsupStatusGet::SERIALIZED_SIZE)> txBuff) {
// Wait for a reply
EsupStatusGet cmdResult;
size_t bytesRead = read(serialPort, txBuff.data(), txBuff.size());
if (bytesRead > 0) {
FW_CHECK(bytesRead <= txBuff.size(), "Error deserializing response", return false; );
LE_ExternalDeSerializeBuffer responseBuff(txBuff.data(), bytesRead);
cmdResult.deserialize(responseBuff);
Fw::String ackString;
cmdResult.toString(ackString);
std::cout << std::string(ackString.toChar()) << std::endl;
} else {
std::cout << "No reply received." << std::endl;
}
return true;
}
I get the following:
(Header = (HeaderId = 1347769157, ModuleId = 8203, DataLength = 0, CmdStatus = ), CmdId = ConfGet, TypeId = 0, SystemState = 162, StatusFlags = 187, Reserved = 53517, CpuTemperature = 0, FirmwareVersion = )
Where I would normally expect to see something like this (the actual values don't matter for these purposes just that there is something to print):
(Header = (HeaderId = 1347769157, ModuleId = 8203, DataLength = 0, CmdStatus = ACK ), CmdId = ConfGet, TypeId = 0, SystemState = 162, StatusFlags = 187, Reserved = 53517, CpuTemperature = 0, FirmwareVersion = 102444)
I've found this is consistent across pretty much all the fpp serializable objects and it really comes down to the last member of the struct doesn't have a format string generated along with it
So for example we see with the header type the following gets generated:
void EsupPacketHeader::toString(Fw::StringBase& text) const {
static const char * formatString =
"("
"HeaderId = %u, "
"ModuleId = %u, "
"DataLength = %u, "
"CmdStatus = "
")";
// declare strings to hold any serializable toString() arguments
Fw::String CmdStatusStr;
this->m_CmdStatus.toString(CmdStatusStr);
char outputString[FW_SERIALIZABLE_TO_STRING_BUFFER_SIZE];
(void)snprintf(outputString,FW_SERIALIZABLE_TO_STRING_BUFFER_SIZE,formatString
,this->m_HeaderId
,this->m_ModuleId
,this->m_DataLength
,CmdStatusStr.toChar()
);
outputString[FW_SERIALIZABLE_TO_STRING_BUFFER_SIZE-1] = 0; // NULL terminate
text = outputString;
}
With the CmdStatus missing the "%s
".
I'm not really sure what the source of the error is since the xml seems to be fine:
<serializable namespace="FlightComputer" name="EsupPacketHeader">
<import_enum_type>FlightComputer/TransmitterInterface/CMD_STATUSEnumAi.xml</import_enum_type>
<members>
<member name="HeaderId" type="U32" format="%u">
<default>1347769157</default>
</member>
<member name="ModuleId" type="U16" format="%u">
<default>0</default>
</member>
<member name="DataLength" type="U16" format="%u">
<default>0</default>
</member>
<member name="CmdStatus" type="FlightComputer::CMD_STATUS" format="%s">
<default>FlightComputer::CMD_STATUS::NA</default>
</member>
</members>
</serializable>
I took a look in array_cpp.py and array_cpp.tmpl but couldn't make sense of the issue there.
If I can get some help on this that'd be much appreciated.