F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
LinuxTimerFd.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title LinuxTimerImpl.cpp
3 // \author tim
4 // \brief cpp file for LinuxTimer 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 
13 #include <sys/timerfd.h>
14 #include <unistd.h>
15 #include <Fw/FPrimeBasicTypes.hpp>
16 #include <Fw/Logger/Logger.hpp>
18 #include <cerrno>
19 #include <cstring>
20 
21 namespace Svc {
22 
24  int fd;
25  struct itimerspec itval;
26 
27  /* Create the timer */
28  fd = timerfd_create(CLOCK_MONOTONIC, 0);
29  if (fd == -1) {
30  Fw::Logger::log("timer create error: %s\n", strerror(errno));
31  return;
32  }
33  time_t seconds_value = static_cast<time_t>(interval.getSeconds());
34  // Ensure an overflow did not occur
35  FW_ASSERT(seconds_value == interval.getSeconds());
36  itval.it_interval.tv_sec = static_cast<time_t>(seconds_value);
37  itval.it_interval.tv_nsec = static_cast<long>(interval.getUSeconds() * 1000);
38  itval.it_value.tv_sec = static_cast<time_t>(seconds_value);
39  itval.it_value.tv_nsec = static_cast<long>(interval.getUSeconds() * 1000);
40 
41  const int settimeStatus = timerfd_settime(fd, 0, &itval, nullptr);
42  if (settimeStatus == -1) {
43  Fw::Logger::log("timer settime error: %s\n", strerror(errno));
44  }
45 
46  while (true) {
47  unsigned long long missed;
48  int ret = static_cast<int>(read(fd, &missed, sizeof(missed)));
49  if ((-1 == ret) && (errno != EINTR)) {
50  // A non-interrupt read error will not clear itself; stop rather than spin on it
51  Fw::Logger::log("timer read error: %s\n", strerror(errno));
52  (void)::close(fd);
53  return;
54  }
55  this->m_mutex.lock();
56  bool quit = this->m_quit;
57  this->m_mutex.unLock();
58  if (quit) {
59  itval.it_interval.tv_sec = 0;
60  itval.it_interval.tv_nsec = 0;
61  itval.it_value.tv_sec = 0;
62  itval.it_value.tv_nsec = 0;
63 
64  (void)timerfd_settime(fd, 0, &itval, nullptr); // best-effort disarm on shutdown
65  (void)::close(fd);
66  return;
67  }
68  Os::RawTime::Status rawTimeStatus = this->m_rawTime.now();
69  if ((rawTimeStatus != Os::RawTime::Status::OP_OK) && !this->m_rawTimeErrorLogged) {
70  // Latch the report so a persistent failure does not flood the console at the timer rate
71  this->m_rawTimeErrorLogged = true;
72  Fw::Logger::log("timer raw time error: %d\n", static_cast<I32>(rawTimeStatus));
73  }
74  this->CycleOut_out(0, this->m_rawTime);
75  }
76 }
77 
78 } // end namespace Svc
void startTimer(const Fw::TimeInterval &interval)
Start timer.
Operation succeeded.
Definition: Os.hpp:27
Status now() override
Get the current time.
void unLock()
unlock the mutex and assert success
Definition: Mutex.cpp:41
static void log(const char *format,...)
log a formated string with supplied arguments
Definition: Logger.cpp:21
void quit()
Quit timer.
U32 getUSeconds() const
RateGroupDivider component implementation.
void CycleOut_out(FwIndexType portNum, Os::RawTime &cycleStart) const
Invoke output port CycleOut.
#define FW_ASSERT(...)
Definition: Assert.hpp:14
U32 getSeconds() const
void lock()
lock the mutex and assert success
Definition: Mutex.cpp:34