F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
SystemResources.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title SystemResourcesComponentImpl.cpp
3 // \author sfregoso
4 // \brief cpp file for SystemResources component implementation class
5 //
6 // \copyright
7 // Copyright 2021, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 
13 #include <Fw/FPrimeBasicTypes.hpp>
15 #include <cmath> //isnan()
16 
17 namespace Svc {
18 
19 // ----------------------------------------------------------------------
20 // Construction, initialization, and destruction
21 // ----------------------------------------------------------------------
22 
23 SystemResources ::SystemResources(const char* const compName)
24  : SystemResourcesComponentBase(compName), m_cpu_count(0), m_enable(true) {
25  // Structure initializations
26  m_mem.used = 0;
27  m_mem.total = 0;
28  for (U32 i = 0; i < CPU_COUNT; i++) {
29  m_cpu[i].used = 0;
30  m_cpu[i].total = 0;
31  m_cpu_prev[i].used = 0;
32  m_cpu_prev[i].total = 0;
33  }
34 
35  const Os::Generic::Status countStatus = Os::Cpu::getCount(m_cpu_count);
36  if (countStatus == Os::Generic::ERROR) {
37  m_cpu_count = 0;
38  }
39 
40  m_cpu_count = (m_cpu_count >= CPU_COUNT) ? CPU_COUNT : m_cpu_count;
41 
42  m_cpu_tlm_functions[0] = &Svc::SystemResources::tlmWrite_CPU_00;
43  m_cpu_tlm_functions[1] = &Svc::SystemResources::tlmWrite_CPU_01;
44  m_cpu_tlm_functions[2] = &Svc::SystemResources::tlmWrite_CPU_02;
45  m_cpu_tlm_functions[3] = &Svc::SystemResources::tlmWrite_CPU_03;
46  m_cpu_tlm_functions[4] = &Svc::SystemResources::tlmWrite_CPU_04;
47  m_cpu_tlm_functions[5] = &Svc::SystemResources::tlmWrite_CPU_05;
48  m_cpu_tlm_functions[6] = &Svc::SystemResources::tlmWrite_CPU_06;
49  m_cpu_tlm_functions[7] = &Svc::SystemResources::tlmWrite_CPU_07;
50  m_cpu_tlm_functions[8] = &Svc::SystemResources::tlmWrite_CPU_08;
51  m_cpu_tlm_functions[9] = &Svc::SystemResources::tlmWrite_CPU_09;
52  m_cpu_tlm_functions[10] = &Svc::SystemResources::tlmWrite_CPU_10;
53  m_cpu_tlm_functions[11] = &Svc::SystemResources::tlmWrite_CPU_11;
54  m_cpu_tlm_functions[12] = &Svc::SystemResources::tlmWrite_CPU_12;
55  m_cpu_tlm_functions[13] = &Svc::SystemResources::tlmWrite_CPU_13;
56  m_cpu_tlm_functions[14] = &Svc::SystemResources::tlmWrite_CPU_14;
57  m_cpu_tlm_functions[15] = &Svc::SystemResources::tlmWrite_CPU_15;
58 }
59 
61 
62 // ----------------------------------------------------------------------
63 // Handler implementations for user-defined typed input ports
64 // ----------------------------------------------------------------------
65 
66 void SystemResources ::run_handler(const FwIndexType portNum, U32 tick_time_hz) {
67  if (m_enable) {
68  Cpu();
69  Mem();
70  PhysMem();
71  }
72 }
73 
74 // ----------------------------------------------------------------------
75 // Command handler implementations
76 // ----------------------------------------------------------------------
77 
78 void SystemResources ::ENABLE_cmdHandler(const FwOpcodeType opCode,
79  const U32 cmdSeq,
80  const SystemResourceEnabled& enable) {
81  m_enable = (enable == SystemResourceEnabled::ENABLED);
82  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
83 }
84 
85 F32 SystemResources::compCpuUtil(Os::Cpu::Ticks current, Os::Cpu::Ticks previous) {
86  F32 util = 100.0f;
87  // Prevent divide by zero on fast-sample
88  if ((current.total - previous.total) != 0) {
89  // Compute CPU % Utilization
90  util = (static_cast<F32>(current.used - previous.used) / static_cast<F32>(current.total - previous.total)) *
91  100.0f;
92  util = std::isnan(util) ? 100.0f : util;
93  }
94  return util;
95 }
96 
97 void SystemResources::Cpu() {
98  U32 count = 0;
99  F32 cpuAvg = 0;
100 
101  for (U32 i = 0; i < m_cpu_count && i < CPU_COUNT; i++) {
102  Os::Cpu::Status status = Os::Cpu::getTicks(m_cpu[i], i);
103  // Best-effort calculations and telemetry
104  if (status == Os::Generic::OP_OK) {
105  // Skip the sample if the counters went backwards (e.g. counter reset)
106  if ((m_cpu[i].used < m_cpu_prev[i].used) || (m_cpu[i].total < m_cpu_prev[i].total)) {
107  m_cpu_prev[i] = m_cpu[i];
108  continue;
109  }
110  F32 cpuUtil = compCpuUtil(m_cpu[i], m_cpu_prev[i]);
111  cpuAvg += cpuUtil;
112 
113  // Send telemetry using telemetry output table
114  FW_ASSERT(this->m_cpu_tlm_functions[i] != nullptr);
115  (this->*m_cpu_tlm_functions[i])(cpuUtil, Fw::Time());
116 
117  // Store cpu used and total
118  m_cpu_prev[i] = m_cpu[i];
119  count++;
120  }
121  }
122 
123  cpuAvg = (count == 0) ? 0.0f : (cpuAvg / static_cast<F32>(count));
124  this->tlmWrite_CPU(cpuAvg);
125 }
126 
127 void SystemResources::Mem() {
128  const Os::Generic::Status memStatus = Os::Memory::getUsage(m_mem);
129  if (memStatus == Os::Generic::OP_OK) {
130  this->tlmWrite_MEMORY_TOTAL(m_mem.total / 1024);
131  this->tlmWrite_MEMORY_USED(m_mem.used / 1024);
132  }
133 }
134 
135 void SystemResources::PhysMem() {
136  FwSizeType total = 0;
137  FwSizeType free = 0;
138 
139  const Os::FileSystem::Status freeSpaceStatus = Os::FileSystem::getFreeSpace("/", total, free);
140  if (freeSpaceStatus == Os::FileSystem::OP_OK) {
141  this->tlmWrite_NON_VOLATILE_FREE(free / 1024);
142  this->tlmWrite_NON_VOLATILE_TOTAL(total / 1024);
143  }
144 }
145 
146 } // end namespace Svc
static Status getCount(FwSizeType &cpu_count)
Request the count of the CPUs detected by the system.
Definition: Cpu.cpp:40
FwIdType FwOpcodeType
The type of a command opcode.
void tlmWrite_CPU_00(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
Operation succeeded.
Definition: Os.hpp:27
PlatformSizeType FwSizeType
void tlmWrite_CPU(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
static Status getFreeSpace(const char *path, FwSizeType &totalBytes, FwSizeType &freeBytes)
Get filesystem free and total space in bytes on the filesystem containing the specified path...
Definition: FileSystem.cpp:103
Operation failed.
Definition: Os.hpp:28
void tlmWrite_MEMORY_USED(U64 arg, Fw::Time _tlmTime=Fw::Time()) const
void tlmWrite_NON_VOLATILE_FREE(U64 arg, Fw::Time _tlmTime=Fw::Time()) const
void tlmWrite_CPU_09(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
static Status getTicks(Ticks &ticks, FwSizeType cpu_index)
Get the CPU tick information for a given CPU.
Definition: Cpu.cpp:44
void tlmWrite_CPU_02(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
void tlmWrite_CPU_10(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
float F32
32-bit floating point
Definition: BasicTypes.h:84
void tlmWrite_CPU_13(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
void tlmWrite_CPU_11(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
Status
Generic OK/ERROR status.
Definition: Os.hpp:26
static Status getUsage(Usage &memory)
get system memory usage
Definition: Memory.cpp:30
SystemResources(const char *const compName)
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
void tlmWrite_CPU_14(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
Command successfully executed.
void tlmWrite_CPU_15(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
FwSizeType total
Total amount.
Definition: Os.hpp:34
void tlmWrite_CPU_01(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
Auto-generated base for SystemResources component.
void tlmWrite_CPU_07(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
FwSizeType used
Used amount.
Definition: Os.hpp:33
PlatformIndexType FwIndexType
void tlmWrite_CPU_04(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
Generic used/total struct.
Definition: Os.hpp:32
void tlmWrite_CPU_08(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
RateGroupDivider component implementation.
Operation was successful.
Definition: FileSystem.hpp:24
void tlmWrite_CPU_06(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
void tlmWrite_CPU_12(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
void tlmWrite_CPU_03(F32 arg, Fw::Time _tlmTime=Fw::Time()) const
void tlmWrite_MEMORY_TOTAL(U64 arg, Fw::Time _tlmTime=Fw::Time()) const
#define FW_ASSERT(...)
Definition: Assert.hpp:14
void tlmWrite_NON_VOLATILE_TOTAL(U64 arg, Fw::Time _tlmTime=Fw::Time()) const
void tlmWrite_CPU_05(F32 arg, Fw::Time _tlmTime=Fw::Time()) const