F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 FwSizeType queueDepth, const NATIVE_INT_TYPE instance) {
40  HealthComponentBase::init(queueDepth, instance);
41  this->queue_depth = 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:55
#define FW_NUM_ARRAY_ELEMENTS(a)
number of elements in an array
Definition: BasicTypes.h:70
PlatformUIntType NATIVE_UINT_TYPE
Definition: BasicTypes.h:56
PlatformAssertArgType FwAssertArgType
Definition: FpConfig.h:39
U32 FwOpcodeType
Definition: FpConfig.h:91
PlatformSizeType FwSizeType
Definition: FpConfig.h:35
PlatformIndexType FwIndexType
Definition: FpConfig.h:25
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