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.
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...
void resetSer() override
Reset serialization pointer to beginning of buffer.
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.