20 static_assert(std::numeric_limits<FwChanIdType>::max() >= TLMCHAN_HASH_BUCKETS,
21 "Cannot have more hash buckets than maximum telemetry ids in the system");
23 static_assert(std::numeric_limits<FwChanIdType>::max() >= TLMCHAN_NUM_TLM_HASH_SLOTS,
24 "Cannot have more hash slots than maximum telemetry ids in the system");
28 for (
FwChanIdType entry = 0; entry < TLMCHAN_NUM_TLM_HASH_SLOTS; entry++) {
29 this->m_tlmEntries[0].slots[entry] =
nullptr;
30 this->m_tlmEntries[1].slots[entry] =
nullptr;
33 for (
FwChanIdType entry = 0; entry < TLMCHAN_HASH_BUCKETS; entry++) {
34 this->m_tlmEntries[0].buckets[entry].used =
false;
35 this->m_tlmEntries[0].buckets[entry].updated =
false;
36 this->m_tlmEntries[0].buckets[entry].bucketNo = entry;
37 this->m_tlmEntries[0].buckets[entry].next =
nullptr;
38 this->m_tlmEntries[0].buckets[entry].id = 0;
39 this->m_tlmEntries[1].buckets[entry].used =
false;
40 this->m_tlmEntries[1].buckets[entry].updated =
false;
41 this->m_tlmEntries[1].buckets[entry].bucketNo = entry;
42 this->m_tlmEntries[1].buckets[entry].next =
nullptr;
43 this->m_tlmEntries[1].buckets[entry].id = 0;
46 this->m_tlmEntries[0].free = 0;
47 this->m_tlmEntries[1].free = 0;
53 return (
id % TLMCHAN_HASH_MOD_VALUE) % TLMCHAN_NUM_TLM_HASH_SLOTS;
56 void TlmChan::pingIn_handler(
const FwIndexType portNum, U32 key) {
69 TlmEntry* activeEntry = this->m_tlmEntries[this->m_activeBuffer].slots[index];
70 for (
FwChanIdType bucket = 0; bucket < TLMCHAN_HASH_BUCKETS; bucket++) {
72 if (activeEntry->id ==
id) {
75 activeEntry = activeEntry->next;
82 TlmEntry* inactiveEntry = this->m_tlmEntries[1 - this->m_activeBuffer].slots[index];
83 for (
FwChanIdType bucket = 0; bucket < TLMCHAN_HASH_BUCKETS; bucket++) {
85 if (inactiveEntry->id ==
id) {
88 inactiveEntry = inactiveEntry->next;
95 if (activeEntry && inactiveEntry) {
98 if (cmp == Fw::Time::Comparison::GT) {
100 val = inactiveEntry->buffer;
101 timeTag = inactiveEntry->lastUpdate;
103 }
else if (cmp != Fw::Time::Comparison::INCOMPARABLE) {
105 val = activeEntry->buffer;
106 timeTag = activeEntry->lastUpdate;
112 if (inactiveEntry->updated) {
113 val = inactiveEntry->buffer;
114 timeTag = inactiveEntry->lastUpdate;
117 val = activeEntry->buffer;
118 timeTag = activeEntry->lastUpdate;
122 }
else if (activeEntry) {
124 val = activeEntry->buffer;
125 timeTag = activeEntry->lastUpdate;
127 }
else if (inactiveEntry) {
129 val = inactiveEntry->buffer;
130 timeTag = inactiveEntry->lastUpdate;
142 TlmEntry* entryToUse =
nullptr;
143 TlmEntry* prevEntry =
nullptr;
146 if (this->m_tlmEntries[this->m_activeBuffer].slots[index]) {
147 entryToUse = this->m_tlmEntries[this->m_activeBuffer].slots[index];
149 for (
FwChanIdType bucket = 0; bucket < TLMCHAN_HASH_BUCKETS + 1; bucket++) {
151 if (entryToUse->id ==
id) {
154 prevEntry = entryToUse;
155 entryToUse = entryToUse->next;
159 FW_ASSERT(this->m_tlmEntries[this->m_activeBuffer].free < TLMCHAN_HASH_BUCKETS);
162 &this->m_tlmEntries[this->m_activeBuffer].buckets[this->m_tlmEntries[this->m_activeBuffer].free++];
164 prevEntry->next = entryToUse;
166 entryToUse->next =
nullptr;
172 FW_ASSERT(this->m_tlmEntries[this->m_activeBuffer].free < TLMCHAN_HASH_BUCKETS);
174 this->m_tlmEntries[this->m_activeBuffer].slots[index] =
175 &this->m_tlmEntries[this->m_activeBuffer].buckets[this->m_tlmEntries[this->m_activeBuffer].free++];
176 entryToUse = this->m_tlmEntries[this->m_activeBuffer].slots[index];
177 entryToUse->next =
nullptr;
182 entryToUse->used =
true;
184 entryToUse->updated =
true;
185 entryToUse->lastUpdate = timeTag;
186 entryToUse->buffer = val;
189 void TlmChan::Run_handler(
FwIndexType portNum, U32 context) {
198 this->m_activeBuffer = 1 - this->m_activeBuffer;
200 for (U32 entry = 0; entry < TLMCHAN_HASH_BUCKETS; entry++) {
201 this->m_tlmEntries[this->m_activeBuffer].buckets[entry].updated =
false;
209 for (U32 entry = 0; entry < TLMCHAN_HASH_BUCKETS; entry++) {
210 TlmEntry* p_entry = &this->m_tlmEntries[1 - this->m_activeBuffer].buckets[entry];
211 if ((p_entry->updated) && (p_entry->used)) {
220 stat = pkt.
addValue(p_entry->id, p_entry->lastUpdate, p_entry->buffer);
228 FW_ASSERT(0, static_cast<FwAssertArgType>(stat));
231 p_entry->updated =
false;
Serialization/Deserialization operation was successful.
void resetSer()
reset to beginning of buffer to reuse for serialization
TlmChan(const char *compName)
No room left in the buffer to serialize data.
void PktSend_out(FwIndexType portNum, Fw::ComBuffer &data, U32 context)
Invoke output port PktSend.
Fw::ComBuffer & getBuffer()
get buffer to send to the ground
Auto-generated base for TlmChan component.
Component that stores telemetry channel values.
FwSizeType getNumEntries()
get the number of packets added via addValue()
Comparison
The type of a comparison result.
SerializeStatus
forward declaration for string
SerializeStatus addValue(FwChanIdType id, Time &timeTag, TlmBuffer &buffer)
Add telemetry value to buffer.
virtual void lock()
Lock the guarded mutex.
bool isConnected_PktSend_OutputPort(FwIndexType portNum)
void pingOut_out(FwIndexType portNum, U32 key)
Invoke output port pingOut.
FwIdType FwChanIdType
The type of a telemetry channel identifier.
SerializeStatus resetPktSer()
Reset serialization of values. This should be done when starting to accumulate a new set of values...
virtual FwChanIdType doHash(FwChanIdType id)
PlatformIndexType FwIndexType
virtual void unLock()
Unlock the guarded mutex.
static Comparison compare(const Time &time1, const Time &time2)
RateGroupDivider component implementation.