F´ Flight Software - C/C++ Documentation  NASA-v2.0.1
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 "Fw/Types/BasicTypes.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(HLTH_CHK_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 = HLTH_PING_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 = 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 = 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(pingEntries[entry].warnCycles <= pingEntries[entry].fatalCycles, pingEntries[entry].warnCycles, pingEntries[entry].fatalCycles);
57  this->m_pingTrackerEntries[entry].entry = pingEntries[entry];
58  this->m_pingTrackerEntries[entry].cycleCount = 0;
59  this->m_pingTrackerEntries[entry].enabled = HLTH_PING_ENABLED;
60  this->m_pingTrackerEntries[entry].key = 0;
61  }
62  }
63 
65 
66  }
67 
68  // ----------------------------------------------------------------------
69  // Handler implementations for user-defined typed input ports
70  // ----------------------------------------------------------------------
71 
72  void HealthImpl::PingReturn_handler(const NATIVE_INT_TYPE 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 
85  void HealthImpl::Run_handler(const NATIVE_INT_TYPE portNum, NATIVE_UINT_TYPE context) {
86  //dispatch messages
87  for (NATIVE_UINT_TYPE i = 0; i < this->queue_depth; i++) {
88  MsgDispatchStatus stat = this->doDispatch();
89  if (MSG_DISPATCH_EMPTY == stat) {
90  break;
91  }
92  FW_ASSERT(MSG_DISPATCH_OK == stat);
93  }
94 
95  if (this->m_enabled) {
96  // cycle through ping table, pinging ports that are not awaiting a reply
97  // for ports that are awaiting a reply, decrement their counters
98  // and check for violations
99 
100  for (NATIVE_UINT_TYPE entry = 0; entry < this->m_numPingEntries; entry++) {
101  if (HLTH_PING_ENABLED == this->m_pingTrackerEntries[entry].enabled) {
102  // If clear entry
103  if (0 == this->m_pingTrackerEntries[entry].cycleCount) {
104  // start a ping
105  this->m_pingTrackerEntries[entry].key = this->m_key;
106  // send ping
107  this->PingSend_out(entry, this->m_pingTrackerEntries[entry].key);
108  // increment key
109  this->m_key++;
110  // increment cycles for the entry
111  this->m_pingTrackerEntries[entry].cycleCount++;
112  } else {
113  // check to see if it is at warning threshold
114  if (this->m_pingTrackerEntries[entry].cycleCount ==
115  this->m_pingTrackerEntries[entry].entry.warnCycles) {
116  Fw::LogStringArg _arg = this->m_pingTrackerEntries[entry].entry.entryName;
117  this->log_WARNING_HI_HLTH_PING_WARN(_arg);
118  this->tlmWrite_PingLateWarnings(++this->m_warnings);
119  } else {
120  // check for FATAL timeout value
121  if (this->m_pingTrackerEntries[entry].entry.fatalCycles ==
122  this->m_pingTrackerEntries[entry].cycleCount) {
123  Fw::LogStringArg _arg = this->m_pingTrackerEntries[entry].entry.entryName;
124  this->log_FATAL_HLTH_PING_LATE(_arg);
125  }
126  } // if at warning or fatal threshold
127 
128  this->m_pingTrackerEntries[entry].cycleCount++;
129  } // if clear entry
130  } // if entry has ping enabled
131  } // for each entry
132 
133  // do other specialized platform checks (e.g. VxWorks suspended tasks)
134  this->doOtherChecks();
135 
136  } // If health checking is enabled
137 
138  // stroke watchdog.
139  if (this->isConnected_WdogStroke_OutputPort(0)) {
140  this->WdogStroke_out(0,this->m_watchDogCode);
141  }
142  }
143 
144  // ----------------------------------------------------------------------
145  // Command handler implementations
146  // ----------------------------------------------------------------------
147 
148  void HealthImpl::HLTH_ENABLE_cmdHandler(const FwOpcodeType opCode, U32 cmdSeq, HealthEnabled enable) {
149  this->m_enabled = enable;
150  HealthIsEnabled isEnabled = HEALTH_CHECK_DISABLED;
151  if (enable) {
152  isEnabled = HEALTH_CHECK_ENABLED;
153  }
154  this->log_ACTIVITY_HI_HLTH_CHECK_ENABLE(isEnabled);
155  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
156  }
157 
158 
159  void HealthImpl::HLTH_PING_ENABLE_cmdHandler(const FwOpcodeType opCode, U32 cmdSeq, const Fw::CmdStringArg& entry, PingEnabled enable) {
160  // check to see if entry is in range
161  NATIVE_INT_TYPE entryIndex = this->findEntry(entry);
162 
163  if (-1 == entryIndex) {
164  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_VALIDATION_ERROR);
165  return;
166  }
167 
168  // check enable value
169  if (enable != HealthImpl::HLTH_PING_DISABLED && enable != HealthImpl::HLTH_PING_ENABLED) {
170  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_VALIDATION_ERROR);
171  return;
172  }
173 
174  this->m_pingTrackerEntries[entryIndex].enabled = enable;
175  HealthPingIsEnabled isEnabled = HEALTH_PING_DISABLED;
176  if (enable) {
177  isEnabled = HEALTH_PING_ENABLED;
178  }
179  Fw::LogStringArg arg;
180  arg = entry;
181  this->log_ACTIVITY_HI_HLTH_CHECK_PING(isEnabled,arg);
182  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
183  }
184 
185  void HealthImpl::HLTH_CHNG_PING_cmdHandler(const FwOpcodeType opCode, U32 cmdSeq, const Fw::CmdStringArg& entry, U32 warningValue, U32 fatalValue) {
186  // check to see if entry is in range
187  NATIVE_INT_TYPE entryIndex = this->findEntry(entry);
188  if (-1 == entryIndex) {
189  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_VALIDATION_ERROR);
190  return;
191  }
192 
193  //check to see if warningValue less than or equal to fatalValue
194  if (warningValue > fatalValue) {
195  Fw::LogStringArg arg;
196  arg = entry;
197  this->log_WARNING_HI_HLTH_PING_INVALID_VALUES(arg,warningValue,fatalValue);
198  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_VALIDATION_ERROR);
199  return;
200  }
201 
202  this->m_pingTrackerEntries[entryIndex].entry.warnCycles = warningValue;
203  this->m_pingTrackerEntries[entryIndex].entry.fatalCycles = fatalValue;
204  Fw::LogStringArg arg = entry;
205  this->log_ACTIVITY_HI_HLTH_PING_UPDATED(arg,warningValue,fatalValue);
206  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
207  }
208 
209  NATIVE_INT_TYPE HealthImpl::findEntry(Fw::CmdStringArg entry) {
210 
211  // walk through entries
212  for (NATIVE_UINT_TYPE tableEntry = 0; tableEntry < NUM_PINGSEND_OUTPUT_PORTS; tableEntry++) {
213  if (entry == this->m_pingTrackerEntries[tableEntry].entry.entryName) {
214  return tableEntry;
215  }
216  }
217  Fw::LogStringArg arg = entry;
218  this->log_WARNING_LO_HLTH_CHECK_LOOKUP_ERROR(arg);
219 
220  return -1;
221  }
222 
223 
224 
225 } // end namespace Svc
Svc::HealthImpl::doOtherChecks
virtual void doOtherChecks(void)
additional checks function
Definition: HealthComponentStubChecks.cpp:24
FW_NUM_ARRAY_ELEMENTS
#define FW_NUM_ARRAY_ELEMENTS(a)
number of elements in an array
Definition: BasicTypes.hpp:103
Fw::LogStringArg
Definition: LogString.hpp:11
Fw::CmdStringArg
Definition: CmdString.hpp:11
Assert.hpp
Svc::HealthImpl::~HealthImpl
~HealthImpl(void)
Component destructor.
Definition: HealthComponentImpl.cpp:64
HealthComponentImpl.hpp
FwOpcodeType
#define FwOpcodeType
Type representation for a command opcode.
Definition: FpConfig.hpp:62
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:30
Svc::HealthImpl::setPingEntries
void setPingEntries(PingEntry *pingEntries, NATIVE_INT_TYPE numPingEntries, U32 watchDogCode)
Set ping entry tables.
Definition: HealthComponentImpl.cpp:45
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Svc::HealthImpl::HealthImpl
HealthImpl(const char *const compName)
HealthImpl constructor.
Definition: HealthComponentImpl.cpp:23
Svc::HealthImpl::init
void init(const NATIVE_INT_TYPE queueDepth, const NATIVE_INT_TYPE instance)
HealthImpl initialization function.
Definition: HealthComponentImpl.cpp:39
Svc::HealthImpl::PingEntry
struct for ping entry
Definition: HealthComponentImpl.hpp:45
Svc
Definition: ActiveRateGroupImplCfg.hpp:18
BasicTypes.hpp
Declares ISF basic types.
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29