F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
HealthComponentImpl.cpp
Go to the documentation of this file.
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>
16 
17 namespace Svc {
18 
19 // ----------------------------------------------------------------------
20 // Construction, initialization, and destruction
21 // ----------------------------------------------------------------------
22 
23 HealthImpl::HealthImpl(const char* const compName)
24  : HealthComponentBase(compName),
25  m_numPingEntries(0),
26  m_key(0),
27  m_watchDogCode(0),
28  m_warnings(0),
29  m_enabled(Fw::Enabled::ENABLED),
30  queue_depth(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  for (FwIndexType entry = 0; entry < static_cast<FwIndexType>(FW_NUM_ARRAY_ELEMENTS(this->m_pingTrackerEntries));
36  entry++) {
37  this->m_pingTrackerEntries[entry].enabled = Fw::Enabled::DISABLED;
38  }
39 }
40 
41 void HealthImpl::init(const FwSizeType queueDepth, const FwEnumStoreType instance) {
42  HealthComponentBase::init(queueDepth, instance);
43  this->queue_depth = queueDepth;
44 }
45 
46 void HealthImpl::setPingEntries(PingEntry* pingEntries, FwIndexType numPingEntries, U32 watchDogCode) {
47  FW_ASSERT(pingEntries != nullptr);
48  // make sure not asking for more pings than ports
49  FW_ASSERT(numPingEntries <= NUM_PINGSEND_OUTPUT_PORTS);
50 
51  this->m_numPingEntries = numPingEntries;
52  this->m_watchDogCode = watchDogCode;
53 
54  // copy entries to private data
55  for (FwIndexType entry = 0; entry < numPingEntries; entry++) {
56  FW_ASSERT(pingEntries[entry].warnCycles <= pingEntries[entry].fatalCycles,
57  static_cast<FwAssertArgType>(pingEntries[entry].warnCycles),
58  static_cast<FwAssertArgType>(pingEntries[entry].fatalCycles));
59  this->m_pingTrackerEntries[entry].entry = pingEntries[entry];
60  this->m_pingTrackerEntries[entry].cycleCount = 0;
61  this->m_pingTrackerEntries[entry].enabled = Fw::Enabled::ENABLED;
62  this->m_pingTrackerEntries[entry].key = 0;
63  }
64 }
65 
67 
68 // ----------------------------------------------------------------------
69 // Handler implementations for user-defined typed input ports
70 // ----------------------------------------------------------------------
71 
72 void HealthImpl::PingReturn_handler(const FwIndexType portNum, U32 key) {
73  // verify the key value
74  if (key != this->m_pingTrackerEntries[portNum].key) {
75  Fw::LogStringArg _arg = this->m_pingTrackerEntries[portNum].entry.entryName;
76  this->log_FATAL_HLTH_PING_WRONG_KEY(_arg, key);
77  } else {
78  // reset the counter and clear the key
79  this->m_pingTrackerEntries[portNum].cycleCount = 0;
80  this->m_pingTrackerEntries[portNum].key = 0;
81  }
82 }
83 
84 void HealthImpl::Run_handler(const FwIndexType portNum, U32 context) {
85  // dispatch messages
86  for (FwSizeType i = 0; i < this->queue_depth; i++) {
87  MsgDispatchStatus stat = this->doDispatch();
88  if (MSG_DISPATCH_EMPTY == stat) {
89  break;
90  }
91  FW_ASSERT(MSG_DISPATCH_OK == stat);
92  }
93 
94  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  for (FwIndexType entry = 0; entry < this->m_numPingEntries; entry++) {
100  if (Fw::Enabled::ENABLED == this->m_pingTrackerEntries[entry].enabled) {
101  // If clear entry
102  if (0 == this->m_pingTrackerEntries[entry].cycleCount) {
103  // start a ping
104  this->m_pingTrackerEntries[entry].key = this->m_key;
105  // send ping
106  this->PingSend_out(static_cast<FwIndexType>(entry), this->m_pingTrackerEntries[entry].key);
107  // increment key
108  this->m_key++;
109  // increment cycles for the entry
110  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  if (this->m_pingTrackerEntries[entry].entry.fatalCycles ==
115  this->m_pingTrackerEntries[entry].cycleCount) {
116  Fw::LogStringArg _arg = this->m_pingTrackerEntries[entry].entry.entryName;
117  this->log_FATAL_HLTH_PING_LATE(_arg);
118  } else if (this->m_pingTrackerEntries[entry].cycleCount ==
119  this->m_pingTrackerEntries[entry].entry.warnCycles) {
120  Fw::LogStringArg _arg = this->m_pingTrackerEntries[entry].entry.entryName;
121  this->log_WARNING_HI_HLTH_PING_WARN(_arg);
122  this->tlmWrite_PingLateWarnings(++this->m_warnings);
123  } // if at warning or fatal threshold
124 
125  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  if (this->isConnected_WdogStroke_OutputPort(0)) {
133  this->WdogStroke_out(0, this->m_watchDogCode);
134  }
135 }
136 
137 // ----------------------------------------------------------------------
138 // Command handler implementations
139 // ----------------------------------------------------------------------
140 
141 void HealthImpl::HLTH_ENABLE_cmdHandler(const FwOpcodeType opCode, U32 cmdSeq, const Fw::Enabled& enable) {
142  this->m_enabled = enable;
144  if (enable == Fw::Enabled::ENABLED) {
145  isEnabled = Fw::Enabled::ENABLED;
146  }
147  this->log_ACTIVITY_HI_HLTH_CHECK_ENABLE(isEnabled);
148  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
149 }
150 
151 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  FwIndexType entryIndex = this->findEntry(entry);
157 
158  if (-1 == entryIndex) {
159  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
160  return;
161  }
162  FW_ASSERT(
163  entryIndex >= 0 && entryIndex < static_cast<FwIndexType>(FW_NUM_ARRAY_ELEMENTS(this->m_pingTrackerEntries)),
164  static_cast<FwAssertArgType>(entryIndex));
165 
166  this->m_pingTrackerEntries[entryIndex].enabled = enable.e;
168  if (enable == Fw::Enabled::ENABLED) {
169  isEnabled = Fw::Enabled::ENABLED;
170  }
171  Fw::LogStringArg arg;
172  arg = entry;
173  this->log_ACTIVITY_HI_HLTH_CHECK_PING(isEnabled, arg);
174  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
175 }
176 
177 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  FwIndexType entryIndex = this->findEntry(entry);
184  if (-1 == entryIndex) {
185  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
186  return;
187  }
188 
189  // check to see if warningValue less than or equal to fatalValue
190  if (warningValue > fatalValue) {
191  Fw::LogStringArg arg;
192  arg = entry;
193  this->log_WARNING_HI_HLTH_PING_INVALID_VALUES(arg, warningValue, fatalValue);
194  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
195  return;
196  }
197 
198  this->m_pingTrackerEntries[entryIndex].entry.warnCycles = warningValue;
199  this->m_pingTrackerEntries[entryIndex].entry.fatalCycles = fatalValue;
200  Fw::LogStringArg arg = entry;
201  this->log_ACTIVITY_HI_HLTH_PING_UPDATED(arg, warningValue, fatalValue);
202  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
203 }
204 
205 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  for (FwIndexType tableEntry = 0; tableEntry < NUM_PINGSEND_OUTPUT_PORTS; tableEntry++) {
209  if (entry == this->m_pingTrackerEntries[tableEntry].entry.entryName) {
210  return static_cast<FwIndexType>(tableEntry);
211  }
212  }
213  Fw::LogStringArg arg = entry;
215 
216  return -1;
217 }
218 
219 } // end namespace Svc
Auto-generated base for Health component.
Enabled and disabled state.
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
FwIdType FwOpcodeType
The type of a command opcode.
void tlmWrite_PingLateWarnings(U32 arg, Fw::Time _tlmTime=Fw::Time()) const
void log_FATAL_HLTH_PING_WRONG_KEY(const Fw::StringBase &entry, U32 badKey) const
PlatformSizeType FwSizeType
I32 FwEnumStoreType
Enabled state.
virtual MsgDispatchStatus doDispatch()
Called in the message loop to dispatch a message from the queue.
void log_WARNING_LO_HLTH_CHECK_LOOKUP_ERROR(const Fw::StringBase &entry) const
void log_WARNING_HI_HLTH_PING_INVALID_VALUES(const Fw::StringBase &entry, U32 warn, U32 fatal) const
void log_ACTIVITY_HI_HLTH_CHECK_PING(const Fw::Enabled &enabled, const Fw::StringBase &entry) const
void log_ACTIVITY_HI_HLTH_CHECK_ENABLE(const Fw::Enabled &enabled) const
enum T e
The raw enum value.
void PingSend_out(FwIndexType portNum, U32 key) const
Invoke output port PingSend.
struct for ping entry
bool isConnected_WdogStroke_OutputPort(FwIndexType portNum) const
void init()
Object initializer.
Definition: ObjBase.cpp:24
void WdogStroke_out(FwIndexType portNum, U32 code) const
Invoke output port WdogStroke.
~HealthImpl()
Component destructor.
void setPingEntries(PingEntry *pingEntries, FwIndexType numPingEntries, U32 watchDogCode)
Set ping entry tables.
Enabled and disabled states.
Command successfully executed.
HealthImpl(const char *const compName)
HealthImpl constructor.
void log_FATAL_HLTH_PING_LATE(const Fw::StringBase &entry) const
PlatformIndexType FwIndexType
#define FW_NUM_ARRAY_ELEMENTS(a)
number of elements in an array
Definition: BasicTypes.h:94
Command failed validation.
RateGroupDivider component implementation.
Implementation of malloc based allocator.
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Disabled state.
void log_WARNING_HI_HLTH_PING_WARN(const Fw::StringBase &entry) const
void log_ACTIVITY_HI_HLTH_PING_UPDATED(const Fw::StringBase &entry, U32 warn, U32 fatal) const