GCC Code Coverage Report


Directory: ./
File: Svc/Health/HealthComponentImpl.cpp
Date: 2026-09-03 21:13:48
Exec Total Coverage
Lines: 112 112 100.0%
Functions: 10 10 100.0%
Branches: 84 95 88.4%

Line Branch Exec Source
1 // ======================================================================
2 // \title Health.hpp
3 // \author Tim
4 // \brief hpp file for Health component implementation class
5 //
6 // \copyright
7 // Copyright 2009-2015, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12
13 #include <Fw/FPrimeBasicTypes.hpp>
14 #include <Fw/Types/Assert.hpp>
15 #include <Svc/Health/HealthComponentImpl.hpp>
16
17 namespace Svc {
18
19 // ----------------------------------------------------------------------
20 // Construction, initialization, and destruction
21 // ----------------------------------------------------------------------
22
23 11 HealthImpl::HealthImpl(const char* const compName)
24 : HealthComponentBase(compName),
25 11 m_numPingEntries(0),
26 11 m_key(0),
27 11 m_watchDogCode(0),
28 11 m_warnings(0),
29
1/1
✓ Branch 4 taken 11 times.
11 m_enabled(Fw::Enabled::ENABLED),
30
3/9
✓ Branch 9 taken 275 times.
✓ Branch 12 taken 275 times.
✓ Branch 13 taken 11 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
297 queue_depth(0) {
31 static_assert((HealthComponentBase::NUM_PINGSEND_OUTPUT_PORTS >= 0) &&
32 (HealthComponentBase::NUM_PINGSEND_OUTPUT_PORTS <= std::numeric_limits<FwIndexType>::max()),
33 "NUM_PINGSEND_OUTPUT_PORTS must fit in the positive range of FwIndexType");
34 // clear tracker by disabling pings
35
2/2
✓ Branch 1 taken 275 times.
✓ Branch 2 taken 11 times.
286 for (FwIndexType entry = 0; entry < static_cast<FwIndexType>(FW_NUM_ARRAY_ELEMENTS(this->m_pingTrackerEntries));
36 entry++) {
37 275 this->m_pingTrackerEntries[entry].enabled = Fw::Enabled::DISABLED;
38 }
39 11 }
40
41 11 void HealthImpl::init(const FwSizeType queueDepth, const FwEnumStoreType instance) {
42 11 HealthComponentBase::init(queueDepth, instance);
43 11 this->queue_depth = queueDepth;
44 11 }
45
46 12 void HealthImpl::setPingEntries(PingEntry* pingEntries, FwIndexType numPingEntries, U32 watchDogCode) {
47 12 FW_ASSERT(pingEntries != nullptr);
48 // make sure not asking for more pings than ports
49 12 FW_ASSERT(numPingEntries <= NUM_PINGSEND_OUTPUT_PORTS);
50
51 12 this->m_numPingEntries = numPingEntries;
52 12 this->m_watchDogCode = watchDogCode;
53
54 // copy entries to private data
55
2/2
✓ Branch 0 taken 300 times.
✓ Branch 1 taken 12 times.
312 for (FwIndexType entry = 0; entry < numPingEntries; entry++) {
56 300 FW_ASSERT(pingEntries[entry].warnCycles <= pingEntries[entry].fatalCycles,
57 static_cast<FwAssertArgType>(pingEntries[entry].warnCycles),
58 static_cast<FwAssertArgType>(pingEntries[entry].fatalCycles));
59 300 this->m_pingTrackerEntries[entry].entry = pingEntries[entry];
60 300 this->m_pingTrackerEntries[entry].cycleCount = 0;
61 300 this->m_pingTrackerEntries[entry].enabled = Fw::Enabled::ENABLED;
62 300 this->m_pingTrackerEntries[entry].key = 0;
63 }
64 12 }
65
66
3/4
✓ Branch 10 taken 11 times.
✗ Branch 11 not taken.
✓ Branch 17 taken 275 times.
✓ Branch 18 taken 11 times.
572 HealthImpl::~HealthImpl() {}
67
68 // ----------------------------------------------------------------------
69 // Handler implementations for user-defined typed input ports
70 // ----------------------------------------------------------------------
71
72 1826 void HealthImpl::PingReturn_handler(const FwIndexType portNum, U32 key) {
73 // verify the key value
74
2/2
✓ Branch 5 taken 25 times.
✓ Branch 6 taken 1801 times.
1826 if (key != this->m_pingTrackerEntries[portNum].key) {
75
1/1
✓ Branch 6 taken 25 times.
25 Fw::LogStringArg _arg = this->m_pingTrackerEntries[portNum].entry.entryName;
76
1/1
✓ Branch 5 taken 25 times.
25 this->log_FATAL_HLTH_PING_WRONG_KEY(_arg, key);
77 25 } else {
78 // reset the counter and clear the key
79 1801 this->m_pingTrackerEntries[portNum].cycleCount = 0;
80 1801 this->m_pingTrackerEntries[portNum].key = 0;
81 }
82 1826 }
83
84 968 void HealthImpl::Run_handler(const FwIndexType portNum, U32 context) {
85 // dispatch messages
86
1/2
✓ Branch 4 taken 2744 times.
✗ Branch 5 not taken.
2744 for (FwSizeType i = 0; i < this->queue_depth; i++) {
87 2744 MsgDispatchStatus stat = this->doDispatch();
88
2/2
✓ Branch 0 taken 968 times.
✓ Branch 1 taken 1776 times.
2744 if (MSG_DISPATCH_EMPTY == stat) {
89 968 break;
90 }
91 1776 FW_ASSERT(MSG_DISPATCH_OK == stat);
92 }
93
94
2/2
✓ Branch 6 taken 868 times.
✓ Branch 7 taken 100 times.
968 if (this->m_enabled == Fw::Enabled::ENABLED) {
95 // cycle through ping table, pinging ports that are not awaiting a reply
96 // for ports that are awaiting a reply, decrement their counters
97 // and check for violations
98
99
2/2
✓ Branch 4 taken 21700 times.
✓ Branch 5 taken 868 times.
22568 for (FwIndexType entry = 0; entry < this->m_numPingEntries; entry++) {
100
3/4
✗ Branch 4 not taken.
✓ Branch 5 taken 21700 times.
✓ Branch 6 taken 21075 times.
✓ Branch 7 taken 625 times.
21700 if (Fw::Enabled::ENABLED == this->m_pingTrackerEntries[entry].enabled) {
101 // If clear entry
102
2/2
✓ Branch 5 taken 2576 times.
✓ Branch 6 taken 18499 times.
21075 if (0 == this->m_pingTrackerEntries[entry].cycleCount) {
103 // start a ping
104 2576 this->m_pingTrackerEntries[entry].key = this->m_key;
105 // send ping
106 2576 this->PingSend_out(static_cast<FwIndexType>(entry), this->m_pingTrackerEntries[entry].key);
107 // increment key
108 2576 this->m_key++;
109 // increment cycles for the entry
110 2576 this->m_pingTrackerEntries[entry].cycleCount++;
111 } else {
112 // check for FATAL timeout value first: warnCycles == fatalCycles is a legal
113 // configuration, and the FATAL takes precedence over the warning
114 18499 if (this->m_pingTrackerEntries[entry].entry.fatalCycles ==
115
2/2
✓ Branch 5 taken 75 times.
✓ Branch 6 taken 18424 times.
18499 this->m_pingTrackerEntries[entry].cycleCount) {
116
1/1
✓ Branch 6 taken 75 times.
75 Fw::LogStringArg _arg = this->m_pingTrackerEntries[entry].entry.entryName;
117
1/1
✓ Branch 5 taken 75 times.
75 this->log_FATAL_HLTH_PING_LATE(_arg);
118 18499 } else if (this->m_pingTrackerEntries[entry].cycleCount ==
119
2/2
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 18373 times.
18424 this->m_pingTrackerEntries[entry].entry.warnCycles) {
120
1/1
✓ Branch 6 taken 51 times.
51 Fw::LogStringArg _arg = this->m_pingTrackerEntries[entry].entry.entryName;
121
1/1
✓ Branch 5 taken 51 times.
51 this->log_WARNING_HI_HLTH_PING_WARN(_arg);
122
2/2
✓ Branch 6 taken 51 times.
✓ Branch 17 taken 51 times.
51 this->tlmWrite_PingLateWarnings(++this->m_warnings);
123 51 } // if at warning or fatal threshold
124
125 18499 this->m_pingTrackerEntries[entry].cycleCount++;
126 } // if clear entry
127 } // if entry has ping enabled
128 } // for each entry
129 } // If health checking is enabled
130
131 // stroke watchdog.
132
1/2
✓ Branch 5 taken 968 times.
✗ Branch 6 not taken.
968 if (this->isConnected_WdogStroke_OutputPort(0)) {
133 968 this->WdogStroke_out(0, this->m_watchDogCode);
134 }
135 968 }
136
137 // ----------------------------------------------------------------------
138 // Command handler implementations
139 // ----------------------------------------------------------------------
140
141 5 void HealthImpl::HLTH_ENABLE_cmdHandler(const FwOpcodeType opCode, U32 cmdSeq, const Fw::Enabled& enable) {
142
1/1
✓ Branch 6 taken 5 times.
5 this->m_enabled = enable;
143
1/1
✓ Branch 2 taken 5 times.
5 Fw::Enabled isEnabled = Fw::Enabled::DISABLED;
144
2/2
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 3 times.
5 if (enable == Fw::Enabled::ENABLED) {
145
1/1
✓ Branch 2 taken 2 times.
2 isEnabled = Fw::Enabled::ENABLED;
146 }
147
1/1
✓ Branch 5 taken 5 times.
5 this->log_ACTIVITY_HI_HLTH_CHECK_ENABLE(isEnabled);
148
2/2
✓ Branch 6 taken 5 times.
✓ Branch 9 taken 5 times.
5 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
149 10 }
150
151 52 void HealthImpl::HLTH_PING_ENABLE_cmdHandler(const FwOpcodeType opCode,
152 U32 cmdSeq,
153 const Fw::CmdStringArg& entry,
154 const Fw::Enabled& enable) {
155 // check to see if entry is in range
156
1/1
✓ Branch 4 taken 52 times.
52 FwIndexType entryIndex = this->findEntry(entry);
157
158
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 51 times.
52 if (-1 == entryIndex) {
159
2/2
✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
1 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
160 1 return;
161 }
162 51 FW_ASSERT(
163 entryIndex >= 0 && entryIndex < static_cast<FwIndexType>(FW_NUM_ARRAY_ELEMENTS(this->m_pingTrackerEntries)),
164 static_cast<FwAssertArgType>(entryIndex));
165
166
1/2
✗ Branch 6 not taken.
✓ Branch 7 taken 51 times.
51 this->m_pingTrackerEntries[entryIndex].enabled = enable.e;
167
1/1
✓ Branch 2 taken 51 times.
51 Fw::Enabled isEnabled(Fw::Enabled::DISABLED);
168
2/2
✓ Branch 4 taken 25 times.
✓ Branch 5 taken 26 times.
51 if (enable == Fw::Enabled::ENABLED) {
169
1/1
✓ Branch 2 taken 25 times.
25 isEnabled = Fw::Enabled::ENABLED;
170 }
171
1/1
✓ Branch 2 taken 51 times.
51 Fw::LogStringArg arg;
172
1/1
✓ Branch 5 taken 51 times.
51 arg = entry;
173
1/1
✓ Branch 5 taken 51 times.
51 this->log_ACTIVITY_HI_HLTH_CHECK_PING(isEnabled, arg);
174
2/2
✓ Branch 6 taken 51 times.
✓ Branch 9 taken 51 times.
51 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
175 51 }
176
177 28 void HealthImpl::HLTH_CHNG_PING_cmdHandler(const FwOpcodeType opCode,
178 U32 cmdSeq,
179 const Fw::CmdStringArg& entry,
180 U32 warningValue,
181 U32 fatalValue) {
182 // check to see if entry is in range
183
1/1
✓ Branch 4 taken 28 times.
28 FwIndexType entryIndex = this->findEntry(entry);
184
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 27 times.
28 if (-1 == entryIndex) {
185
2/2
✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
1 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
186 1 return;
187 }
188
189 // check to see if warningValue less than or equal to fatalValue
190
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 26 times.
27 if (warningValue > fatalValue) {
191
1/1
✓ Branch 2 taken 1 times.
1 Fw::LogStringArg arg;
192
1/1
✓ Branch 5 taken 1 times.
1 arg = entry;
193
1/1
✓ Branch 5 taken 1 times.
1 this->log_WARNING_HI_HLTH_PING_INVALID_VALUES(arg, warningValue, fatalValue);
194
2/2
✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
1 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
195 1 return;
196 1 }
197
198 26 this->m_pingTrackerEntries[entryIndex].entry.warnCycles = warningValue;
199 26 this->m_pingTrackerEntries[entryIndex].entry.fatalCycles = fatalValue;
200
1/1
✓ Branch 5 taken 26 times.
26 Fw::LogStringArg arg = entry;
201
1/1
✓ Branch 5 taken 26 times.
26 this->log_ACTIVITY_HI_HLTH_PING_UPDATED(arg, warningValue, fatalValue);
202
2/2
✓ Branch 6 taken 26 times.
✓ Branch 9 taken 26 times.
26 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
203 26 }
204
205 80 FwIndexType HealthImpl::findEntry(const Fw::CmdStringArg& entry) {
206 static_assert(std::numeric_limits<FwIndexType>::is_signed, "FwIndexType must be signed to return -1 for error");
207 // walk through entries
208
2/2
✓ Branch 4 taken 1028 times.
✓ Branch 5 taken 2 times.
1030 for (FwIndexType tableEntry = 0; tableEntry < this->m_numPingEntries; tableEntry++) {
209
3/3
✓ Branch 11 taken 1028 times.
✓ Branch 13 taken 78 times.
✓ Branch 14 taken 950 times.
1028 if (entry == this->m_pingTrackerEntries[tableEntry].entry.entryName) {
210 78 return static_cast<FwIndexType>(tableEntry);
211 }
212 }
213
1/1
✓ Branch 5 taken 2 times.
2 Fw::LogStringArg arg = entry;
214
1/1
✓ Branch 5 taken 2 times.
2 this->log_WARNING_LO_HLTH_CHECK_LOOKUP_ERROR(arg);
215
216 2 return -1;
217 2 }
218
219 } // end namespace Svc
220