| 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 | 12 | HealthImpl::HealthImpl(const char* const compName) | |
| 24 | : HealthComponentBase(compName), | ||
| 25 | 12 | m_numPingEntries(0), | |
| 26 | 12 | m_key(0), | |
| 27 | 12 | m_watchDogCode(0), | |
| 28 | 12 | m_warnings(0), | |
| 29 |
1/1✓ Branch 4 taken 12 times.
|
12 | m_enabled(Fw::Enabled::ENABLED), |
| 30 |
3/9✓ Branch 9 taken 300 times.
✓ Branch 12 taken 300 times.
✓ Branch 13 taken 12 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.
|
324 | 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 300 times.
✓ Branch 2 taken 12 times.
|
312 | for (FwIndexType entry = 0; entry < static_cast<FwIndexType>(FW_NUM_ARRAY_ELEMENTS(this->m_pingTrackerEntries)); |
| 36 | entry++) { | ||
| 37 | 300 | this->m_pingTrackerEntries[entry].enabled = Fw::Enabled::DISABLED; | |
| 38 | } | ||
| 39 | 12 | } | |
| 40 | |||
| 41 | 12 | void HealthImpl::init(const FwSizeType queueDepth, const FwEnumStoreType instance) { | |
| 42 | 12 | HealthComponentBase::init(queueDepth, instance); | |
| 43 | 12 | this->queue_depth = queueDepth; | |
| 44 | 12 | } | |
| 45 | |||
| 46 | 13 | void HealthImpl::setPingEntries(PingEntry* pingEntries, FwIndexType numPingEntries, U32 watchDogCode) { | |
| 47 | 13 | FW_ASSERT(pingEntries != nullptr); | |
| 48 | // make sure not asking for more pings than ports | ||
| 49 | 13 | FW_ASSERT(numPingEntries <= NUM_PINGSEND_OUTPUT_PORTS); | |
| 50 | |||
| 51 | 13 | this->m_numPingEntries = numPingEntries; | |
| 52 | 13 | this->m_watchDogCode = watchDogCode; | |
| 53 | |||
| 54 | // copy entries to private data | ||
| 55 |
2/2✓ Branch 0 taken 325 times.
✓ Branch 1 taken 13 times.
|
338 | for (FwIndexType entry = 0; entry < numPingEntries; entry++) { |
| 56 | 325 | FW_ASSERT(pingEntries[entry].warnCycles <= pingEntries[entry].fatalCycles, | |
| 57 | static_cast<FwAssertArgType>(pingEntries[entry].warnCycles), | ||
| 58 | static_cast<FwAssertArgType>(pingEntries[entry].fatalCycles)); | ||
| 59 | 325 | this->m_pingTrackerEntries[entry].entry = pingEntries[entry]; | |
| 60 | 325 | this->m_pingTrackerEntries[entry].cycleCount = 0; | |
| 61 | 325 | this->m_pingTrackerEntries[entry].fatalReported = false; | |
| 62 | 325 | this->m_pingTrackerEntries[entry].enabled = Fw::Enabled::ENABLED; | |
| 63 | 325 | this->m_pingTrackerEntries[entry].key = 0; | |
| 64 | } | ||
| 65 | 13 | } | |
| 66 | |||
| 67 |
3/4✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 17 taken 300 times.
✓ Branch 18 taken 12 times.
|
624 | HealthImpl::~HealthImpl() {} |
| 68 | |||
| 69 | // ---------------------------------------------------------------------- | ||
| 70 | // Handler implementations for user-defined typed input ports | ||
| 71 | // ---------------------------------------------------------------------- | ||
| 72 | |||
| 73 | 1828 | void HealthImpl::PingReturn_handler(const FwIndexType portNum, U32 key) { | |
| 74 | // verify the key value | ||
| 75 |
2/2✓ Branch 5 taken 25 times.
✓ Branch 6 taken 1803 times.
|
1828 | if (key != this->m_pingTrackerEntries[portNum].key) { |
| 76 |
1/1✓ Branch 6 taken 25 times.
|
25 | Fw::LogStringArg _arg = this->m_pingTrackerEntries[portNum].entry.entryName; |
| 77 |
1/1✓ Branch 5 taken 25 times.
|
25 | this->log_FATAL_HLTH_PING_WRONG_KEY(_arg, key); |
| 78 | 25 | } else { | |
| 79 | // reset the counter and FATAL reporting state, and clear the key | ||
| 80 | 1803 | this->m_pingTrackerEntries[portNum].cycleCount = 0; | |
| 81 | 1803 | this->m_pingTrackerEntries[portNum].fatalReported = false; | |
| 82 | 1803 | this->m_pingTrackerEntries[portNum].key = 0; | |
| 83 | } | ||
| 84 | 1828 | } | |
| 85 | |||
| 86 | 1085 | void HealthImpl::Run_handler(const FwIndexType portNum, U32 context) { | |
| 87 | // dispatch messages | ||
| 88 |
1/2✓ Branch 4 taken 2861 times.
✗ Branch 5 not taken.
|
2861 | for (FwSizeType i = 0; i < this->queue_depth; i++) { |
| 89 | 2861 | MsgDispatchStatus stat = this->doDispatch(); | |
| 90 |
2/2✓ Branch 0 taken 1085 times.
✓ Branch 1 taken 1776 times.
|
2861 | if (MSG_DISPATCH_EMPTY == stat) { |
| 91 | 1085 | break; | |
| 92 | } | ||
| 93 | 1776 | FW_ASSERT(MSG_DISPATCH_OK == stat); | |
| 94 | } | ||
| 95 | |||
| 96 |
2/2✓ Branch 6 taken 935 times.
✓ Branch 7 taken 150 times.
|
1085 | if (this->m_enabled == Fw::Enabled::ENABLED) { |
| 97 | // cycle through ping table, pinging ports that are not awaiting a reply | ||
| 98 | // for ports that are awaiting a reply, increment their counters | ||
| 99 | // and check for violations | ||
| 100 | |||
| 101 |
2/2✓ Branch 4 taken 23375 times.
✓ Branch 5 taken 935 times.
|
24310 | for (FwIndexType entry = 0; entry < this->m_numPingEntries; entry++) { |
| 102 |
3/4✗ Branch 4 not taken.
✓ Branch 5 taken 23375 times.
✓ Branch 6 taken 22750 times.
✓ Branch 7 taken 625 times.
|
23375 | if (Fw::Enabled::ENABLED == this->m_pingTrackerEntries[entry].enabled) { |
| 103 | // If clear entry | ||
| 104 |
2/2✓ Branch 5 taken 2653 times.
✓ Branch 6 taken 20097 times.
|
22750 | if (0 == this->m_pingTrackerEntries[entry].cycleCount) { |
| 105 | // start a ping with a fresh timeout reporting state | ||
| 106 | 2653 | this->m_pingTrackerEntries[entry].fatalReported = false; | |
| 107 | 2653 | this->m_pingTrackerEntries[entry].key = this->m_key; | |
| 108 | // send ping | ||
| 109 | 2653 | this->PingSend_out(static_cast<FwIndexType>(entry), this->m_pingTrackerEntries[entry].key); | |
| 110 | // increment key | ||
| 111 | 2653 | this->m_key++; | |
| 112 | // increment cycles for the entry | ||
| 113 | 2653 | this->m_pingTrackerEntries[entry].cycleCount++; | |
| 114 | } else { | ||
| 115 | // Check FATAL first: equal warning and FATAL thresholds are valid. | ||
| 116 | // A zero FATAL threshold disables timeout detection (legacy behavior). | ||
| 117 | // Once FATAL is reported, this ping must not emit another FATAL or | ||
| 118 | // be downgraded to WARNING if the thresholds are raised. | ||
| 119 |
2/2✓ Branch 5 taken 20095 times.
✓ Branch 6 taken 2 times.
|
20097 | if (this->m_pingTrackerEntries[entry].entry.fatalCycles > 0 && |
| 120 | 20095 | this->m_pingTrackerEntries[entry].cycleCount >= | |
| 121 |
2/2✓ Branch 5 taken 679 times.
✓ Branch 6 taken 19416 times.
|
20095 | this->m_pingTrackerEntries[entry].entry.fatalCycles) { |
| 122 |
3/4✗ Branch 4 not taken.
✓ Branch 5 taken 679 times.
✓ Branch 6 taken 77 times.
✓ Branch 7 taken 602 times.
|
679 | if (!this->m_pingTrackerEntries[entry].fatalReported) { |
| 123 |
1/1✓ Branch 6 taken 77 times.
|
77 | Fw::LogStringArg _arg = this->m_pingTrackerEntries[entry].entry.entryName; |
| 124 | 77 | this->m_pingTrackerEntries[entry].fatalReported = true; | |
| 125 |
1/1✓ Branch 5 taken 77 times.
|
77 | this->log_FATAL_HLTH_PING_LATE(_arg); |
| 126 | 77 | } | |
| 127 |
3/4✗ Branch 4 not taken.
✓ Branch 5 taken 19418 times.
✓ Branch 6 taken 19417 times.
✓ Branch 7 taken 1 times.
|
20097 | } else if (!this->m_pingTrackerEntries[entry].fatalReported && |
| 128 | 19417 | this->m_pingTrackerEntries[entry].cycleCount == | |
| 129 |
2/2✓ Branch 5 taken 77 times.
✓ Branch 6 taken 19340 times.
|
19417 | this->m_pingTrackerEntries[entry].entry.warnCycles) { |
| 130 |
1/1✓ Branch 6 taken 77 times.
|
77 | Fw::LogStringArg _arg = this->m_pingTrackerEntries[entry].entry.entryName; |
| 131 |
1/1✓ Branch 5 taken 77 times.
|
77 | this->log_WARNING_HI_HLTH_PING_WARN(_arg); |
| 132 |
2/2✓ Branch 6 taken 77 times.
✓ Branch 17 taken 77 times.
|
77 | this->tlmWrite_PingLateWarnings(++this->m_warnings); |
| 133 | 77 | } // if at warning or fatal threshold | |
| 134 | |||
| 135 | 20097 | this->m_pingTrackerEntries[entry].cycleCount++; | |
| 136 | } // if clear entry | ||
| 137 | } // if entry has ping enabled | ||
| 138 | } // for each entry | ||
| 139 | } // If health checking is enabled | ||
| 140 | |||
| 141 | // stroke watchdog. | ||
| 142 |
1/2✓ Branch 5 taken 1085 times.
✗ Branch 6 not taken.
|
1085 | if (this->isConnected_WdogStroke_OutputPort(0)) { |
| 143 | 1085 | this->WdogStroke_out(0, this->m_watchDogCode); | |
| 144 | } | ||
| 145 | 1085 | } | |
| 146 | |||
| 147 | // ---------------------------------------------------------------------- | ||
| 148 | // Command handler implementations | ||
| 149 | // ---------------------------------------------------------------------- | ||
| 150 | |||
| 151 | 6 | void HealthImpl::HLTH_ENABLE_cmdHandler(const FwOpcodeType opCode, U32 cmdSeq, const Fw::Enabled& enable) { | |
| 152 |
1/1✓ Branch 6 taken 6 times.
|
6 | this->m_enabled = enable; |
| 153 |
1/1✓ Branch 2 taken 6 times.
|
6 | Fw::Enabled isEnabled = Fw::Enabled::DISABLED; |
| 154 |
2/2✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3 times.
|
6 | if (enable == Fw::Enabled::ENABLED) { |
| 155 |
1/1✓ Branch 2 taken 3 times.
|
3 | isEnabled = Fw::Enabled::ENABLED; |
| 156 | } | ||
| 157 |
1/1✓ Branch 5 taken 6 times.
|
6 | this->log_ACTIVITY_HI_HLTH_CHECK_ENABLE(isEnabled); |
| 158 |
2/2✓ Branch 6 taken 6 times.
✓ Branch 9 taken 6 times.
|
6 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 159 | 12 | } | |
| 160 | |||
| 161 | 52 | void HealthImpl::HLTH_PING_ENABLE_cmdHandler(const FwOpcodeType opCode, | |
| 162 | U32 cmdSeq, | ||
| 163 | const Fw::CmdStringArg& entry, | ||
| 164 | const Fw::Enabled& enable) { | ||
| 165 | // check to see if entry is in range | ||
| 166 |
1/1✓ Branch 4 taken 52 times.
|
52 | FwIndexType entryIndex = this->findEntry(entry); |
| 167 | |||
| 168 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 51 times.
|
52 | if (-1 == entryIndex) { |
| 169 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR); |
| 170 | 1 | return; | |
| 171 | } | ||
| 172 | 51 | FW_ASSERT( | |
| 173 | entryIndex >= 0 && entryIndex < static_cast<FwIndexType>(FW_NUM_ARRAY_ELEMENTS(this->m_pingTrackerEntries)), | ||
| 174 | static_cast<FwAssertArgType>(entryIndex)); | ||
| 175 | |||
| 176 |
1/2✗ Branch 6 not taken.
✓ Branch 7 taken 51 times.
|
51 | this->m_pingTrackerEntries[entryIndex].enabled = enable.e; |
| 177 |
1/1✓ Branch 2 taken 51 times.
|
51 | Fw::Enabled isEnabled(Fw::Enabled::DISABLED); |
| 178 |
2/2✓ Branch 4 taken 25 times.
✓ Branch 5 taken 26 times.
|
51 | if (enable == Fw::Enabled::ENABLED) { |
| 179 |
1/1✓ Branch 2 taken 25 times.
|
25 | isEnabled = Fw::Enabled::ENABLED; |
| 180 | } | ||
| 181 |
1/1✓ Branch 2 taken 51 times.
|
51 | Fw::LogStringArg arg; |
| 182 |
1/1✓ Branch 5 taken 51 times.
|
51 | arg = entry; |
| 183 |
1/1✓ Branch 5 taken 51 times.
|
51 | this->log_ACTIVITY_HI_HLTH_CHECK_PING(isEnabled, arg); |
| 184 |
2/2✓ Branch 6 taken 51 times.
✓ Branch 9 taken 51 times.
|
51 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 185 | 51 | } | |
| 186 | |||
| 187 | 32 | void HealthImpl::HLTH_CHNG_PING_cmdHandler(const FwOpcodeType opCode, | |
| 188 | U32 cmdSeq, | ||
| 189 | const Fw::CmdStringArg& entry, | ||
| 190 | U32 warningValue, | ||
| 191 | U32 fatalValue) { | ||
| 192 | // check to see if entry is in range | ||
| 193 |
1/1✓ Branch 4 taken 32 times.
|
32 | FwIndexType entryIndex = this->findEntry(entry); |
| 194 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 31 times.
|
32 | if (-1 == entryIndex) { |
| 195 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR); |
| 196 | 1 | return; | |
| 197 | } | ||
| 198 | |||
| 199 | // check to see if warningValue less than or equal to fatalValue | ||
| 200 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 30 times.
|
31 | if (warningValue > fatalValue) { |
| 201 |
1/1✓ Branch 2 taken 1 times.
|
1 | Fw::LogStringArg arg; |
| 202 |
1/1✓ Branch 5 taken 1 times.
|
1 | arg = entry; |
| 203 |
1/1✓ Branch 5 taken 1 times.
|
1 | this->log_WARNING_HI_HLTH_PING_INVALID_VALUES(arg, warningValue, fatalValue); |
| 204 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR); |
| 205 | 1 | return; | |
| 206 | 1 | } | |
| 207 | |||
| 208 | 30 | this->m_pingTrackerEntries[entryIndex].entry.warnCycles = warningValue; | |
| 209 | 30 | this->m_pingTrackerEntries[entryIndex].entry.fatalCycles = fatalValue; | |
| 210 |
1/1✓ Branch 5 taken 30 times.
|
30 | Fw::LogStringArg arg = entry; |
| 211 |
1/1✓ Branch 5 taken 30 times.
|
30 | this->log_ACTIVITY_HI_HLTH_PING_UPDATED(arg, warningValue, fatalValue); |
| 212 |
2/2✓ Branch 6 taken 30 times.
✓ Branch 9 taken 30 times.
|
30 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 213 | 30 | } | |
| 214 | |||
| 215 | 84 | FwIndexType HealthImpl::findEntry(const Fw::CmdStringArg& entry) { | |
| 216 | static_assert(std::numeric_limits<FwIndexType>::is_signed, "FwIndexType must be signed to return -1 for error"); | ||
| 217 | // walk through entries | ||
| 218 |
2/2✓ Branch 4 taken 1032 times.
✓ Branch 5 taken 2 times.
|
1034 | for (FwIndexType tableEntry = 0; tableEntry < this->m_numPingEntries; tableEntry++) { |
| 219 |
3/3✓ Branch 11 taken 1032 times.
✓ Branch 13 taken 82 times.
✓ Branch 14 taken 950 times.
|
1032 | if (entry == this->m_pingTrackerEntries[tableEntry].entry.entryName) { |
| 220 | 82 | return static_cast<FwIndexType>(tableEntry); | |
| 221 | } | ||
| 222 | } | ||
| 223 |
1/1✓ Branch 5 taken 2 times.
|
2 | Fw::LogStringArg arg = entry; |
| 224 |
1/1✓ Branch 5 taken 2 times.
|
2 | this->log_WARNING_LO_HLTH_CHECK_LOOKUP_ERROR(arg); |
| 225 | |||
| 226 | 2 | return -1; | |
| 227 | 2 | } | |
| 228 | |||
| 229 | } // end namespace Svc | ||
| 230 |