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 
14 #include <Fw/FPrimeBasicTypes.hpp>
15 #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) {
31  static_assert((HealthComponentBase::NUM_PINGSEND_OUTPUT_PORTS >= 0) && (HealthComponentBase::NUM_PINGSEND_OUTPUT_PORTS <= std::numeric_limits<FwIndexType>::max()), "NUM_PINGSEND_OUTPUT_PORTS must fit in the positive range of FwIndexType");
32  // clear tracker by disabling pings
33  for (FwIndexType entry = 0;
34  entry < static_cast<FwIndexType>(FW_NUM_ARRAY_ELEMENTS(this->m_pingTrackerEntries));
35  entry++) {
36  this->m_pingTrackerEntries[entry].enabled = Fw::Enabled::DISABLED;
37  }
38  }
39 
40  void HealthImpl::init(const FwSizeType queueDepth, const FwEnumStoreType instance) {
41  HealthComponentBase::init(queueDepth, instance);
42  this->queue_depth = queueDepth;
43 
44  }
45 
46  void HealthImpl::setPingEntries(PingEntry* pingEntries, FwIndexType numPingEntries, U32 watchDogCode) {
47 
48  FW_ASSERT(pingEntries);
49  // make sure not asking for more pings than ports
50  FW_ASSERT(numPingEntries <= NUM_PINGSEND_OUTPUT_PORTS);
51 
52  this->m_numPingEntries = numPingEntries;
53  this->m_watchDogCode = watchDogCode;
54 
55  // copy entries to private data
56  for (FwIndexType entry = 0; entry < numPingEntries; entry++) {
57  FW_ASSERT(
58  pingEntries[entry].warnCycles <= pingEntries[entry].fatalCycles,
59  static_cast<FwAssertArgType>(pingEntries[entry].warnCycles),
60  static_cast<FwAssertArgType>(pingEntries[entry].fatalCycles));
61  this->m_pingTrackerEntries[entry].entry = pingEntries[entry];
62  this->m_pingTrackerEntries[entry].cycleCount = 0;
63  this->m_pingTrackerEntries[entry].enabled = Fw::Enabled::ENABLED;
64  this->m_pingTrackerEntries[entry].key = 0;
65  }
66  }
67 
69 
70  }
71 
72  // ----------------------------------------------------------------------
73  // Handler implementations for user-defined typed input ports
74  // ----------------------------------------------------------------------
75 
76  void HealthImpl::PingReturn_handler(const FwIndexType portNum, U32 key) {
77  // verify the key value
78  if (key != this->m_pingTrackerEntries[portNum].key) {
79  Fw::LogStringArg _arg = this->m_pingTrackerEntries[portNum].entry.entryName;
80  this->log_FATAL_HLTH_PING_WRONG_KEY(_arg,key);
81  } else {
82  // reset the counter and clear the key
83  this->m_pingTrackerEntries[portNum].cycleCount = 0;
84  this->m_pingTrackerEntries[portNum].key = 0;
85  }
86 
87  }
88 
89  void HealthImpl::Run_handler(const FwIndexType portNum, U32 context) {
90  //dispatch messages
91  for (FwSizeType i = 0; i < this->queue_depth; i++) {
92  MsgDispatchStatus stat = this->doDispatch();
93  if (MSG_DISPATCH_EMPTY == stat) {
94  break;
95  }
96  FW_ASSERT(MSG_DISPATCH_OK == stat);
97  }
98 
99  if (this->m_enabled == Fw::Enabled::ENABLED) {
100  // cycle through ping table, pinging ports that are not awaiting a reply
101  // for ports that are awaiting a reply, decrement their counters
102  // and check for violations
103 
104  for (FwIndexType entry = 0; entry < this->m_numPingEntries; entry++) {
105  if (Fw::Enabled::ENABLED == this->m_pingTrackerEntries[entry].enabled) {
106  // If clear entry
107  if (0 == this->m_pingTrackerEntries[entry].cycleCount) {
108  // start a ping
109  this->m_pingTrackerEntries[entry].key = this->m_key;
110  // send ping
111  this->PingSend_out(static_cast<FwIndexType>(entry), this->m_pingTrackerEntries[entry].key);
112  // increment key
113  this->m_key++;
114  // increment cycles for the entry
115  this->m_pingTrackerEntries[entry].cycleCount++;
116  } else {
117  // check to see if it is at warning threshold
118  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  } else {
124  // check for FATAL timeout value
125  if (this->m_pingTrackerEntries[entry].entry.fatalCycles ==
126  this->m_pingTrackerEntries[entry].cycleCount) {
127  Fw::LogStringArg _arg = this->m_pingTrackerEntries[entry].entry.entryName;
128  this->log_FATAL_HLTH_PING_LATE(_arg);
129  }
130  } // if at warning or fatal threshold
131 
132  this->m_pingTrackerEntries[entry].cycleCount++;
133  } // if clear entry
134  } // if entry has ping enabled
135  } // for each entry
136 
137  // do other specialized platform checks (e.g. VxWorks suspended tasks)
138  this->doOtherChecks();
139 
140  } // If health checking is enabled
141 
142  // stroke watchdog.
143  if (this->isConnected_WdogStroke_OutputPort(0)) {
144  this->WdogStroke_out(0,this->m_watchDogCode);
145  }
146  }
147 
148  // ----------------------------------------------------------------------
149  // Command handler implementations
150  // ----------------------------------------------------------------------
151 
152  void HealthImpl::HLTH_ENABLE_cmdHandler(const FwOpcodeType opCode, U32 cmdSeq, Fw::Enabled enable) {
153  this->m_enabled = enable;
155  if (enable == Fw::Enabled::ENABLED) {
156  isEnabled = Fw::Enabled::ENABLED;
157  }
158  this->log_ACTIVITY_HI_HLTH_CHECK_ENABLE(isEnabled);
159  this->cmdResponse_out(opCode,cmdSeq,Fw::CmdResponse::OK);
160  }
161 
162 
163  void HealthImpl::HLTH_PING_ENABLE_cmdHandler(const FwOpcodeType opCode, U32 cmdSeq, const Fw::CmdStringArg& entry, Fw::Enabled enable) {
164  // check to see if entry is in range
165  FwIndexType entryIndex = this->findEntry(entry);
166 
167  if (-1 == entryIndex) {
169  return;
170  }
171 
172  this->m_pingTrackerEntries[entryIndex].enabled = enable.e;
174  if (enable == Fw::Enabled::ENABLED) {
175  isEnabled = Fw::Enabled::ENABLED;
176  }
177  Fw::LogStringArg arg;
178  arg = entry;
179  this->log_ACTIVITY_HI_HLTH_CHECK_PING(isEnabled,arg);
180  this->cmdResponse_out(opCode,cmdSeq,Fw::CmdResponse::OK);
181  }
182 
183  void HealthImpl::HLTH_CHNG_PING_cmdHandler(const FwOpcodeType opCode, U32 cmdSeq, const Fw::CmdStringArg& entry, U32 warningValue, U32 fatalValue) {
184  // check to see if entry is in range
185  FwIndexType entryIndex = this->findEntry(entry);
186  if (-1 == entryIndex) {
188  return;
189  }
190 
191  //check to see if warningValue less than or equal to fatalValue
192  if (warningValue > fatalValue) {
193  Fw::LogStringArg arg;
194  arg = entry;
195  this->log_WARNING_HI_HLTH_PING_INVALID_VALUES(arg,warningValue,fatalValue);
197  return;
198  }
199 
200  this->m_pingTrackerEntries[entryIndex].entry.warnCycles = warningValue;
201  this->m_pingTrackerEntries[entryIndex].entry.fatalCycles = fatalValue;
202  Fw::LogStringArg arg = entry;
203  this->log_ACTIVITY_HI_HLTH_PING_UPDATED(arg,warningValue,fatalValue);
204  this->cmdResponse_out(opCode,cmdSeq,Fw::CmdResponse::OK);
205  }
206 
207  FwIndexType HealthImpl::findEntry(const Fw::CmdStringArg& entry) {
208  static_assert(std::numeric_limits<FwIndexType>::is_signed, "FwIndexType must be signed to return -1 for error");
209  // walk through entries
210  for (FwIndexType tableEntry = 0; tableEntry < NUM_PINGSEND_OUTPUT_PORTS; tableEntry++) {
211  if (entry == this->m_pingTrackerEntries[tableEntry].entry.entryName) {
212  return static_cast<FwIndexType>(tableEntry);
213  }
214  }
215  Fw::LogStringArg arg = entry;
217 
218  return -1;
219  }
220 
221 
222 
223 } // end namespace Svc
Auto-generated base for Health component.
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
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
struct for ping entry
void init()
Object initializer.
Definition: ObjBase.cpp:26
virtual void doOtherChecks()
additional checks function
T e
The raw enum value.
~HealthImpl()
Component destructor.
U32 FwOpcodeType
The type of a command opcode.
void setPingEntries(PingEntry *pingEntries, FwIndexType numPingEntries, U32 watchDogCode)
Set ping entry tables.
void log_ACTIVITY_HI_HLTH_CHECK_PING(Fw::Enabled enabled, const Fw::StringBase &entry) const
void WdogStroke_out(FwIndexType portNum, U32 code)
Invoke output port WdogStroke.
Enabled and disabled states.
Command successfully executed.
bool isConnected_WdogStroke_OutputPort(FwIndexType portNum)
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:93
Command failed validation.
RateGroupDivider component implementation.
Enabled and disabled state.
void log_ACTIVITY_HI_HLTH_CHECK_ENABLE(Fw::Enabled enabled) const
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Disabled state.
void log_WARNING_HI_HLTH_PING_WARN(const Fw::StringBase &entry) const
void PingSend_out(FwIndexType portNum, U32 key)
Invoke output port PingSend.
void log_ACTIVITY_HI_HLTH_PING_UPDATED(const Fw::StringBase &entry, U32 warn, U32 fatal) const