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