[hal,wpilib] Rename FPGA clock to monotonic clock (#8672)

- Remove status return from HAL level (clock getting should never fail)
- Remove 32-bit timestamp expand function
- Make monotonic_clock.hpp (formerly fpga_clock.hpp) header-only and
move to root hal include directory
This commit is contained in:
Peter Johnson
2026-03-15 15:08:41 -07:00
committed by GitHub
parent 1a5b023235
commit e944ae9aca
59 changed files with 233 additions and 358 deletions

View File

@@ -75,7 +75,7 @@ void HAL_SetAlertActive(HAL_AlertHandle alertHandle, HAL_Bool active,
// Already active, do nothing (avoids cost of getting time)
return;
}
int64_t now = HAL_GetFPGATime(status);
int64_t now = HAL_GetMonotonicTime();
int64_t expected = 0;
// use compare-exchange to avoid potential race
alert->activeStartTime.compare_exchange_strong(expected, now);

View File

@@ -20,7 +20,7 @@
#include "mockdata/DriverStationDataInternal.hpp"
#include "wpi/hal/DriverStationTypes.h"
#include "wpi/hal/Errors.h"
#include "wpi/hal/cpp/fpga_clock.hpp"
#include "wpi/hal/monotonic_clock.hpp"
#include "wpi/hal/simulation/MockHooks.h"
#include "wpi/util/EventVector.hpp"
#include "wpi/util/mutex.hpp"
@@ -155,16 +155,16 @@ int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
static constexpr int KEEP_MSGS = 5;
std::scoped_lock lock(msgMutex);
static std::string prevMsg[KEEP_MSGS];
static fpga_clock::time_point prevMsgTime[KEEP_MSGS];
static monotonic_clock::time_point prevMsgTime[KEEP_MSGS];
static bool initialized = false;
if (!initialized) {
for (int i = 0; i < KEEP_MSGS; i++) {
prevMsgTime[i] = fpga_clock::now() - std::chrono::seconds(2);
prevMsgTime[i] = monotonic_clock::now() - std::chrono::seconds(2);
}
initialized = true;
}
auto curTime = fpga_clock::now();
auto curTime = monotonic_clock::now();
int i;
for (i = 0; i < KEEP_MSGS; ++i) {
if (prevMsg[i] == details) {

View File

@@ -254,32 +254,8 @@ int32_t HAL_GetTeamNumber(void) {
return HALSIM_GetRoboRioTeamNumber();
}
uint64_t HAL_GetFPGATime(int32_t* status) {
return wpi::hal::GetFPGATime();
}
uint64_t HAL_ExpandFPGATime(uint32_t unexpandedLower, int32_t* status) {
// Capture the current FPGA time. This will give us the upper half of the
// clock.
uint64_t fpgaTime = HAL_GetFPGATime(status);
if (*status != 0) {
return 0;
}
// Now, we need to detect the case where the lower bits rolled over after we
// sampled. In that case, the upper bits will be 1 bigger than they should
// be.
// Break it into lower and upper portions.
uint32_t lower = fpgaTime & 0xffffffffull;
uint64_t upper = (fpgaTime >> 32) & 0xffffffff;
// The time was sampled *before* the current time, so roll it back.
if (lower < unexpandedLower) {
--upper;
}
return (upper << 32) + static_cast<uint64_t>(unexpandedLower);
uint64_t HAL_GetMonotonicTime(void) {
return wpi::hal::GetMonotonicTime();
}
HAL_Bool HAL_GetSystemActive(int32_t* status) {

View File

@@ -25,7 +25,7 @@ static std::atomic<uint64_t> programStepTime{0};
namespace wpi::hal::init {
void InitializeMockHooks() {
wpi::util::SetNowImpl(GetFPGATime);
wpi::util::SetNowImpl(GetMonotonicTime);
}
} // namespace wpi::hal::init
@@ -59,7 +59,7 @@ void StepTiming(uint64_t delta) {
programStepTime += delta;
}
uint64_t GetFPGATime() {
uint64_t GetMonotonicTime() {
uint64_t curTime = programPauseTime;
if (curTime == 0) {
curTime = wpi::util::NowDefault();
@@ -67,10 +67,6 @@ uint64_t GetFPGATime() {
return curTime + programStepTime - programStartTime;
}
double GetFPGATimestamp() {
return GetFPGATime() * 1.0e-6;
}
void SetProgramStarted(bool started) {
programStarted = started;
}
@@ -131,8 +127,7 @@ void HALSIM_StepTiming(uint64_t delta) {
WaitNotifiers();
while (delta > 0) {
int32_t status = 0;
uint64_t curTime = HAL_GetFPGATime(&status);
uint64_t curTime = HAL_GetMonotonicTime();
uint64_t nextTimeout = HALSIM_GetNextNotifierTimeout();
uint64_t step = (std::min)(delta, nextTimeout - curTime);

View File

@@ -17,9 +17,7 @@ bool IsTimingPaused();
void StepTiming(uint64_t delta);
uint64_t GetFPGATime();
double GetFPGATimestamp();
uint64_t GetMonotonicTime();
void SetProgramStarted();
} // namespace wpi::hal

View File

@@ -93,8 +93,7 @@ void NotifierThread::Main() {
// Wait until next alarm
const Alarm& alarm = m_alarmQueue.top();
int32_t status = 0;
uint64_t curTime = HAL_GetFPGATime(&status);
uint64_t curTime = HAL_GetMonotonicTime();
if (alarm.notifier->alarmTime > curTime) {
m_cond.wait_for(
lock, std::chrono::microseconds{alarm.notifier->alarmTime - curTime});
@@ -114,8 +113,7 @@ void NotifierThread::Main() {
void NotifierThread::ProcessAlarms(
wpi::util::SmallVectorImpl<HAL_NotifierHandle>* signaled) {
int32_t status = 0;
uint64_t curTime = HAL_GetFPGATime(&status);
uint64_t curTime = HAL_GetMonotonicTime();
// Process alarms
while (!m_alarmQueue.empty() &&
@@ -264,7 +262,7 @@ void HAL_SetNotifierAlarm(HAL_NotifierHandle notifierHandle, uint64_t alarmTime,
}
if (!absolute) {
alarmTime += HAL_GetFPGATime(status);
alarmTime += HAL_GetMonotonicTime();
}
uint64_t prevWakeup = UINT64_MAX;