Modify LinuxTimer interface for consistency (#4087)

* Use Fw::TimeInterval in LinuxTimer

* Fix Linux FD typo

* Fix interval timer UT

* Format

* Fix assert casts

* Fix ComLogger UTs

* Fix FppTest microseconds

* Fix casting

* Fix overflow
This commit is contained in:
M Starch 2025-09-02 15:22:07 -07:00 committed by GitHub
parent 8b9ac2197d
commit 10f2b49d3f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 36 additions and 31 deletions

View File

@ -20,7 +20,7 @@ ActiveTestTester ::ActiveTestTester()
arrayBuf(arrayData, sizeof(arrayData)),
structBuf(structData, sizeof(structData)),
serialBuf(serialData, sizeof(serialData)),
time(STest::Pick::any(), STest::Pick::any()) {
time(STest::Pick::any(), STest::Pick::lowerUpper(0, 999999)) {
this->initComponents();
this->connectPorts();
this->connectAsyncPorts();

View File

@ -20,7 +20,7 @@ PassiveTestTester ::PassiveTestTester()
arrayBuf(arrayData, sizeof(arrayData)),
structBuf(structData, sizeof(structData)),
serialBuf(serialData, sizeof(serialData)),
time(STest::Pick::any(), STest::Pick::any()) {
time(STest::Pick::any(), STest::Pick::lowerUpper(0, 999999)) {
this->initComponents();
this->connectPorts();
this->component.registerExternalParameters(&this->paramTesterDelegate);

View File

@ -20,7 +20,7 @@ QueuedTestTester ::QueuedTestTester()
arrayBuf(arrayData, sizeof(arrayData)),
structBuf(structData, sizeof(structData)),
serialBuf(serialData, sizeof(serialData)),
time(STest::Pick::any(), STest::Pick::any()) {
time(STest::Pick::any(), STest::Pick::lowerUpper(0, 999999)) {
this->initComponents();
this->connectPorts();
this->connectAsyncPorts();

View File

@ -19,7 +19,7 @@
// ----------------------------------------------------------------------
void Tester ::testTime() {
Fw::Time random_time(STest::Pick::any(), STest::Pick::any());
Fw::Time random_time(STest::Pick::any(), STest::Pick::lowerUpper(0, 999999));
Fw::Time zero_time(TimeBase::TB_NONE, 0, 0);
Fw::Time result;

View File

@ -39,6 +39,8 @@ Time::Time(TimeBase timeBase, FwTimeContextStoreType context, U32 seconds, U32 u
}
void Time::set(TimeBase timeBase, FwTimeContextStoreType context, U32 seconds, U32 useconds) {
// Assert microseconds portion is less than 10^6
FW_ASSERT(useconds < 1000000, static_cast<FwAssertArgType>(useconds));
this->m_val.set(timeBase, context, seconds, useconds);
}

View File

@ -11,6 +11,8 @@ TimeInterval::TimeInterval(U32 seconds, U32 useconds) : Serializable() {
}
void TimeInterval::set(U32 seconds, U32 useconds) {
// Assert microseconds portion is less than 10^6
FW_ASSERT(useconds < 1000000, static_cast<FwAssertArgType>(useconds));
this->m_val.set(seconds, useconds);
}
@ -121,6 +123,8 @@ void TimeInterval::add(U32 seconds, U32 useconds) {
newSeconds += 1;
newUSeconds -= 1000000;
}
// Assert microseconds portion is less than 10^6
FW_ASSERT(newUSeconds < 1000000, static_cast<FwAssertArgType>(newUSeconds));
this->m_val.set(newSeconds, newUSeconds);
}

View File

@ -85,12 +85,12 @@ void setupTopology(const TopologyState& state) {
}
}
void startRateGroups(Fw::TimeInterval interval) {
void startRateGroups(const Fw::TimeInterval& interval) {
// This timer drives the fundamental tick rate of the system.
// Svc::RateGroupDriver will divide this down to the slower rate groups.
// This call will block until the stopRateGroups() call is made.
// For this Linux demo, that call is made from a signal handler.
linuxTimer.startTimer(interval.getSeconds()*1000+interval.getUSeconds()/1000);
linuxTimer.startTimer(interval);
}
void stopRateGroups() {

View File

@ -77,7 +77,7 @@ void teardownTopology(const TopologyState& state);
* This loop is stopped via a stopRateGroups call.
*
*/
void startRateGroups(Fw::TimeInterval interval);
void startRateGroups(const Fw::TimeInterval& interval);
/**
* \brief stop the rate groups

View File

@ -76,9 +76,9 @@ void ComLoggerTester ::testLogging() {
for (int j = 0; j < 3; j++) {
// Test times for the different iterations:
Fw::Time testTime(TimeBase::TB_NONE, j, 9876543);
Fw::Time testTimePrev(TimeBase::TB_NONE, j - 1, 9876543);
Fw::Time testTimeNext(TimeBase::TB_NONE, j + 1, 9876543);
Fw::Time testTime(TimeBase::TB_NONE, j, 987654);
Fw::Time testTimePrev(TimeBase::TB_NONE, j - 1, 987654);
Fw::Time testTimeNext(TimeBase::TB_NONE, j + 1, 987654);
// File names for the different iterations:
memset(fileName, 0, sizeof(fileName));
@ -312,7 +312,7 @@ void ComLoggerTester ::openError() {
const U8 data[COM_BUFFER_LENGTH] = {0xde, 0xad, 0xbe, 0xef};
Fw::ComBuffer buffer(data, sizeof(data));
Fw::Time testTime(TimeBase::TB_NONE, 4, 9876543);
Fw::Time testTime(TimeBase::TB_NONE, 4, 987654);
setTestTime(testTime);
snprintf(fileName, sizeof(fileName), "%s_%d_%d_%06d.com", filePrefix, static_cast<U32>(testTime.getTimeBase()),
@ -384,7 +384,7 @@ void ComLoggerTester ::writeError() {
const U8 data[4] = {0xde, 0xad, 0xbe, 0xef};
Fw::ComBuffer buffer(data, sizeof(data));
Fw::Time testTime(TimeBase::TB_NONE, 5, 9876543);
Fw::Time testTime(TimeBase::TB_NONE, 5, 987654);
setTestTime(testTime);
for (int i = 0; i < 3; i++) {
@ -457,7 +457,7 @@ void ComLoggerTester ::closeFileCommand() {
Os::File::Status ret;
// Form filenames:
Fw::Time testTime(TimeBase::TB_NONE, 6, 9876543);
Fw::Time testTime(TimeBase::TB_NONE, 6, 987654);
setTestTime(testTime);
memset(fileName, 0, sizeof(fileName));
snprintf(fileName, sizeof(fileName), "%s_%d_%d_%06d.com", FILE_STR,
@ -541,9 +541,9 @@ void ComLoggerTester ::testLoggingWithInit() {
for (int j = 0; j < 3; j++) {
// Test times for the different iterations:
Fw::Time testTime(TimeBase::TB_NONE, j, 9876543);
Fw::Time testTimePrev(TimeBase::TB_NONE, j - 1, 9876543);
Fw::Time testTimeNext(TimeBase::TB_NONE, j + 1, 9876543);
Fw::Time testTime(TimeBase::TB_NONE, j, 987654);
Fw::Time testTimePrev(TimeBase::TB_NONE, j - 1, 987654);
Fw::Time testTimeNext(TimeBase::TB_NONE, j + 1, 987654);
// File names for the different iterations:
memset(fileName, 0, sizeof(fileName));

View File

@ -13,6 +13,7 @@
#ifndef LinuxTimer_HPP
#define LinuxTimer_HPP
#include "Fw/Time/TimeInterval.hpp"
#include "Os/Mutex.hpp"
#include "Os/RawTime.hpp"
#include "Svc/LinuxTimer/LinuxTimerComponentAc.hpp"
@ -35,7 +36,7 @@ class LinuxTimer final : public LinuxTimerComponentBase {
~LinuxTimer();
//! Start timer
void startTimer(FwSizeType interval); //!< interval in milliseconds
void startTimer(const Fw::TimeInterval& interval); //!< interval in milliseconds
//! Quit timer
void quit();

View File

@ -20,19 +20,19 @@
namespace Svc {
void LinuxTimer::startTimer(FwSizeType interval) {
void LinuxTimer::startTimer(const Fw::TimeInterval& interval) {
int fd;
struct itimerspec itval;
/* Create the timer */
fd = timerfd_create(CLOCK_MONOTONIC, 0);
const FwSizeType interval_secs = interval / 1000;
FW_ASSERT(static_cast<FwSizeType>(std::numeric_limits<I32>::max()) >= interval_secs,
static_cast<FwAssertArgType>(interval));
itval.it_interval.tv_sec = static_cast<I32>(interval_secs);
itval.it_interval.tv_nsec = static_cast<I32>((interval * 1000000) % 1000000000);
itval.it_value.tv_sec = static_cast<I32>(interval_secs);
itval.it_value.tv_nsec = static_cast<I32>((interval * 1000000) % 1000000000);
time_t seconds_value = static_cast<time_t>(interval.getSeconds());
// Ensure an overflow did not occur
FW_ASSERT(seconds_value == interval.getSeconds());
itval.it_interval.tv_sec = static_cast<time_t>(seconds_value);
itval.it_interval.tv_nsec = static_cast<long>(interval.getUSeconds() * 1000);
itval.it_value.tv_sec = static_cast<time_t>(seconds_value);
itval.it_value.tv_nsec = static_cast<long>(interval.getUSeconds() * 1000);
timerfd_settime(fd, 0, &itval, nullptr);

View File

@ -16,11 +16,9 @@
namespace Svc {
void LinuxTimer::startTimer(FwSizeType interval) {
FW_ASSERT(std::numeric_limits<U32>::max() / 1000 >= interval); // Overflow
void LinuxTimer::startTimer(const Fw::TimeInterval& interval) {
while (true) {
Os::Task::delay(
Fw::TimeInterval(static_cast<U32>(interval / 1000), static_cast<U32>((interval % 1000) * 1000)));
Os::Task::delay(interval);
this->m_mutex.lock();
bool quit = this->m_quit;
this->m_mutex.unLock();

View File

@ -35,7 +35,7 @@ LinuxTimerTester ::~LinuxTimerTester() {}
void LinuxTimerTester ::runCycles() {
this->m_numCalls = 5;
this->component.startTimer(1000);
this->component.startTimer(Fw::TimeInterval(1, 0));
}
// ----------------------------------------------------------------------