18 const TlmPacketizer_TelemetrySendPortMap TlmPacketizer::TELEMETRY_SEND_PORT_MAP = {};
30 this->m_tlmEntries.slots[entry] =
nullptr;
34 this->m_tlmEntries.buckets[entry].used =
false;
35 this->m_tlmEntries.buckets[entry].bucketNo = entry;
36 this->m_tlmEntries.buckets[entry].next =
nullptr;
37 this->m_tlmEntries.buckets[entry].id = 0;
40 this->m_tlmEntries.free = 0;
43 this->m_missTlmCheck[entry].checked =
false;
44 this->m_missTlmCheck[entry].id = 0;
49 this->m_fillBuffers[buffer].updated =
false;
50 this->m_sendBuffers[buffer].updated =
false;
59 "NUM_CONFIGURABLE_TLMPACKETIZER_GROUPS MUST BE MAX_CONFIGURABLE_TLMPACKETIZER_GROUP + 1");
78 FW_ASSERT(packetList.
list[pktEntry]->
list, static_cast<FwAssertArgType>(pktEntry));
83 TlmEntry* entryToUse = this->findBucket(
id);
86 entryToUse->used =
true;
88 entryToUse->ignored =
false;
90 entryToUse->hasValue =
false;
91 entryToUse->channelSize = packetList.
list[pktEntry]->
list[tlmEntry].
size;
94 FW_ASSERT(packetLen <= static_cast<FwSizeType>(std::numeric_limits<FwSignedSizeType>::max()),
95 static_cast<FwAssertArgType>(packetLen));
96 entryToUse->packetOffset[pktEntry] =
static_cast<FwSignedSizeType>(packetLen);
98 packetLen += entryToUse->channelSize;
102 static_cast<FwAssertArgType>(pktEntry));
104 memset(this->m_fillBuffers[pktEntry].buffer.getBuffAddr(), 0,
static_cast<size_t>(packetLen));
107 static_cast<FwPacketDescriptorType>(Fw::ComPacketType::FW_PACKET_PACKETIZED_TLM));
109 stat = this->m_fillBuffers[pktEntry].buffer.serializeFrom(packetList.
list[pktEntry]->
id);
112 stat = this->m_fillBuffers[pktEntry].buffer.setBuffLen(packetLen);
115 this->m_fillBuffers[pktEntry].id = packetList.
list[pktEntry]->
id;
117 this->m_fillBuffers[pktEntry].level = packetList.
list[pktEntry]->
level;
119 if (packetList.
list[pktEntry]->
level > maxLevel) {
120 maxLevel = packetList.
list[pktEntry]->
level;
130 this->m_groupConfigs[
static_cast<FwSizeType>(section)][group] = defaultGroupConfig;
131 this->m_groupConfigs[
static_cast<FwSizeType>(section)][group].set_enabled(groupEnabled);
140 TlmEntry* entryToUse = this->findBucket(
id);
144 entryToUse->used =
true;
146 entryToUse->ignored =
true;
148 entryToUse->hasValue =
false;
149 entryToUse->channelSize = ignoreList.
list[channelEntry].
size;
156 this->m_configured =
true;
159 TlmPacketizer::TlmEntry* TlmPacketizer::findBucket(
FwChanIdType id) {
162 TlmEntry* entryToUse =
nullptr;
163 TlmEntry* prevEntry =
nullptr;
166 if (this->m_tlmEntries.slots[index]) {
167 entryToUse = this->m_tlmEntries.slots[index];
170 if (entryToUse->id ==
id) {
173 prevEntry = entryToUse;
174 entryToUse = entryToUse->next;
179 static_cast<FwAssertArgType>(this->m_tlmEntries.free));
181 entryToUse = &this->m_tlmEntries.buckets[this->m_tlmEntries.free++];
184 prevEntry->next = entryToUse;
186 entryToUse->next =
nullptr;
189 entryToUse->packetOffset[pktOffsetEntry] = -1;
197 static_cast<FwAssertArgType>(this->m_tlmEntries.free));
199 this->m_tlmEntries.slots[index] = &this->m_tlmEntries.buckets[this->m_tlmEntries.free++];
200 entryToUse = this->m_tlmEntries.slots[index];
201 entryToUse->next =
nullptr;
204 entryToUse->packetOffset[pktOffsetEntry] = -1;
215 void TlmPacketizer ::TlmRecv_handler(
const FwIndexType portNum,
222 TlmEntry* entryToUse =
nullptr;
225 entryToUse = this->m_tlmEntries.slots[index];
228 if (not entryToUse) {
229 this->missingChannel(
id);
235 if (entryToUse->id ==
id) {
237 if (entryToUse->ignored) {
242 entryToUse = entryToUse->next;
246 this->missingChannel(
id);
254 if (entryToUse->packetOffset[pkt] != -1) {
257 this->m_fillBuffers[pkt].updated =
true;
258 this->m_fillBuffers[pkt].latestTime = timeTag;
259 U8* ptr = &this->m_fillBuffers[pkt].buffer.getBuffAddr()[entryToUse->packetOffset[pkt]];
263 entryToUse->hasValue =
true;
269 void TlmPacketizer ::configureSectionGroupRate_handler(
FwIndexType portNum,
275 this->configureSectionGroupRate(section, tlmGroup, rateLogic, minDelta, maxDelta);
288 TlmEntry* entryToUse =
nullptr;
291 entryToUse = this->m_tlmEntries.slots[index];
294 if (not entryToUse) {
295 this->missingChannel(
id);
302 if (entryToUse->id ==
id) {
305 if (entryToUse->ignored) {
311 entryToUse = entryToUse->next;
315 this->missingChannel(
id);
321 if (!entryToUse->hasValue) {
336 if (entryToUse->packetOffset[pkt] != -1) {
339 timeTag = this->m_fillBuffers[pkt].latestTime;
340 U8* ptr = &this->m_fillBuffers[pkt].buffer.getBuffAddr()[entryToUse->packetOffset[pkt]];
341 (void)memcpy(val.
getBuffAddr(), ptr,
static_cast<size_t>(entryToUse->channelSize));
352 FW_ASSERT(0, static_cast<FwAssertArgType>(entryToUse->id));
358 void TlmPacketizer ::Run_handler(
const FwIndexType portNum, U32 context) {
365 for (
FwChanIdType pkt = 0; pkt < this->m_numPackets; pkt++) {
366 if (this->m_fillBuffers[pkt].updated ==
true) {
367 (void)(this->m_sendBuffers[pkt] = this->m_fillBuffers[pkt]);
369 this->m_fillBuffers[pkt].updated =
false;
374 for (
FwChanIdType pkt = 0; pkt < this->m_numPackets; pkt++) {
375 FwChanIdType entryGroup = this->m_sendBuffers[pkt].level;
380 if (this->m_sendBuffers[pkt].updated and
381 this->m_packetFlags[section][pkt].updateFlag != UpdateFlag::REQUESTED) {
382 this->m_packetFlags[section][pkt].updateFlag = UpdateFlag::NEW;
385 bool sendOutFlag =
false;
386 const FwIndexType outIndex = this->sectionGroupToPort(section, entryGroup);
388 PktSendCounters& pktEntryFlags = this->m_packetFlags[
static_cast<FwSizeType>(section)][pkt];
389 TlmPacketizer_GroupConfig& entryGroupConfig =
390 this->m_groupConfigs[
static_cast<FwSizeType>(section)][entryGroup];
404 if (pktEntryFlags.updateFlag == UpdateFlag::REQUESTED) {
407 if (not((entryGroupConfig.get_enabled() and
415 if (pktEntryFlags.updateFlag == UpdateFlag::NEVER_UPDATED) {
421 if (pktEntryFlags.prevSentCounter < std::numeric_limits<U32>::max()) {
422 pktEntryFlags.prevSentCounter++;
430 if (pktEntryFlags.updateFlag == UpdateFlag::NEW and
432 pktEntryFlags.prevSentCounter >= entryGroupConfig.get_min()) {
441 pktEntryFlags.prevSentCounter >= entryGroupConfig.get_max()) {
453 &this->m_sendBuffers[pkt]
458 this->
PktSend_out(outIndex, this->m_sendBuffers[pkt].buffer, pktEntryFlags.prevSentCounter);
459 pktEntryFlags.prevSentCounter = 0;
460 pktEntryFlags.updateFlag = UpdateFlag::PAST;
463 this->m_sendBuffers[pkt].updated =
false;
467 void TlmPacketizer ::controlIn_handler(
FwIndexType portNum,
473 (void)(this->m_sectionEnabled[static_cast<FwSizeType>(section)] = enabled);
479 void TlmPacketizer ::pingIn_handler(
const FwIndexType portNum, U32 key) {
494 this->m_groupConfigs[
static_cast<FwSizeType>(section)][group].set_enabled(
503 void TlmPacketizer ::SEND_PKT_cmdHandler(
const FwOpcodeType opCode,
509 for (pkt = 0; pkt < this->m_numPackets; pkt++) {
510 if (this->m_fillBuffers[pkt].
id ==
id) {
512 this->m_fillBuffers[pkt].updated =
true;
513 this->m_fillBuffers[pkt].latestTime = this->
getTime();
516 this->m_packetFlags[section][pkt].updateFlag = UpdateFlag::REQUESTED;
524 if (pkt == this->m_numPackets) {
533 void TlmPacketizer ::ENABLE_SECTION_cmdHandler(
FwOpcodeType opCode,
543 (void)(this->m_sectionEnabled[section] = enable);
548 void TlmPacketizer ::ENABLE_GROUP_cmdHandler(
FwOpcodeType opCode,
560 this->m_groupConfigs[section][tlmGroup].set_enabled(enable);
565 void TlmPacketizer ::FORCE_GROUP_cmdHandler(
FwOpcodeType opCode,
576 this->m_groupConfigs[section][tlmGroup].set_forceEnabled(enable);
581 void TlmPacketizer ::CONFIGURE_GROUP_RATES_cmdHandler(
FwOpcodeType opCode,
594 this->configureSectionGroupRate(section, tlmGroup, rateLogic, minDelta, maxDelta);
598 void TlmPacketizer::configureSectionGroupRate(
611 TlmPacketizer_GroupConfig& groupConfig = this->m_groupConfigs[section][tlmGroup];
612 groupConfig.set_rateLogic(rateLogic);
613 groupConfig.set_min(minDelta);
614 groupConfig.set_max(maxDelta);
623 const FwIndexType outIndex = TlmPacketizer::TELEMETRY_SEND_PORT_MAP[
static_cast<FwSizeType>(section)][group];
638 if (this->m_missTlmCheck[slot].checked and (this->m_missTlmCheck[slot].
id ==
id)) {
640 }
else if (not this->m_missTlmCheck[slot].checked) {
641 this->m_missTlmCheck[slot].checked =
true;
642 this->m_missTlmCheck[slot].id = id;
Serialization/Deserialization operation was successful.
bool isValid() const
Check raw enum value for validity.
U16 FwPacketDescriptorType
The width of packet descriptors when they are serialized by the framework.
TlmPacketizer(const char *const compName)
REQUIRED: Counter, leave as last element.
FwIdType FwOpcodeType
The type of a command opcode.
SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG) override
Serialize an 8-bit unsigned integer value.
void setPacketList(const TlmPacketizerPacketList &packetList, const Svc::TlmPacketizerPacket &ignoreList, const FwChanIdType startLevel, const TlmPacketizer_GroupConfig &defaultGroupConfig=TlmPacketizer_GroupConfig{})
FwSizeType size
serialized size of channel in bytes
PlatformSizeType FwSizeType
FwTlmPacketizeIdType id
packet ID
void tlmWrite_GroupConfigs(const Svc::TlmPacketizer_SectionConfigs &arg, Fw::Time _tlmTime=Fw::Time()) const
static const FwChanIdType TLMPACKETIZER_HASH_BUCKETS
Serializable::SizeType getSize() const override
Get current buffer size.
const TlmPacketizerPacket * list[MAX_PACKETIZER_PACKETS]
void log_WARNING_LO_NoChan(FwChanIdType Id) const
static const FwChanIdType MAX_PACKETIZER_PACKETS
void unLock()
unlock the mutex and assert success
bool isValid() const
Check raw enum value for validity.
PlatformSignedSizeType FwSignedSizeType
void PktSend_out(FwIndexType portNum, Fw::ComBuffer &data, U32 context)
Invoke output port PktSend.
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
static const FwChanIdType TLMPACKETIZER_NUM_TLM_HASH_SLOTS
Send on updates after MIN ticks since last send.
Send every MAX ticks between sends.
const TlmPacketizerChannelEntry * list
pointer to a channel entry
static const FwChanIdType TLMPACKETIZER_MAX_MISSING_TLM_CHECK
void tlmWrite_SectionEnabled(const Svc::TlmPacketizer_SectionEnabled &arg, Fw::Time _tlmTime=Fw::Time()) const
Write telemetry channel SectionEnabled.
SerializeStatus
forward declaration for string
No logic applied. Does not send group and freezes counter.
FwChanIdType id
Id of channel.
FwChanIdType level
packet level - used to select set of packets to send
Enumeration for rate logic types for telemetry groups.
External serialize buffer with no copy semantics.
FwIdType FwChanIdType
The type of a telemetry channel identifier.
static const FwChanIdType TLMPACKETIZER_HASH_MOD_VALUE
U8 * getBuffAddr()
Get buffer address for data filling (non-const version)
void log_WARNING_LO_PacketNotFound(U32 id) const
void resetSer() override
Reset serialization pointer to beginning of buffer.
Enabled and disabled states.
U16 FwTlmPacketizeIdType
The type of a telemetry packet identifier.
Command successfully executed.
bool isValid() const
Check raw enum value for validity.
uint8_t U8
8-bit unsigned integer
void log_WARNING_LO_SectionUnconfigurable(Svc::TelemetrySection section, Fw::Enabled enable) const
Log event SectionUnconfigurable.
void log_WARNING_LO_MaxLevelExceed(FwChanIdType level, FwChanIdType max) const
PlatformIndexType FwIndexType
FwSizeType getCapacity() const
Get buffer capacity.
void log_ACTIVITY_HI_LevelSet(FwChanIdType id) const
Command failed validation.
RateGroupDivider component implementation.
bool isConnected_PktSend_OutputPort(FwIndexType portNum)
SerializeStatus setBuffLen(Serializable::SizeType length) override
Set buffer length manually.
FwChanIdType numEntries
number of channels in packet
void log_ACTIVITY_LO_PacketSent(U32 id) const
void pingOut_out(FwIndexType portNum, U32 key)
Invoke output port pingOut.
PlatformAssertArgType FwAssertArgType
The type of arguments to assert functions.
void lock()
lock the mutex and assert success
Auto-generated base for TlmPacketizer component.