fix: correct PCAN timestamps (uptime-based backends)#1087
Open
minoseigenheer wants to merge 2 commits into
Open
fix: correct PCAN timestamps (uptime-based backends)#1087minoseigenheer wants to merge 2 commits into
minoseigenheer wants to merge 2 commits into
Conversation
PCAN provides hardware timestamps relative to device power-on (uptime), not Unix epoch. Previous approaches tried to anchor this uptime clock to the wall clock, but an unavoidable ~3ms software lag created a fixed bias that made Rx timestamps appear after Tx in override-mode delta calculations, breaking correct Tx/Rx alignment. Fix: - For uptime-based backends (hwTimestamp < timeBasis), use CANConManager::getElapsedUs() directly for Rx timestamps instead of the PCAN hw clock. This is the identical monotonic source used for Tx timestamps, so Tx and Rx are always on the same clock with no drift or bias. - Add CANConManager::getElapsedUs() helper exposing mElapsedTimer. - Remove the first-frame anchor members (mFirstHwTimestamp, mFirstElapsedUs) that are no longer needed. - Revert the timestamp sort in refreshConnection() that was a workaround for the bias; natural emission order is now always correct.
When 'Clear Frames' is clicked while frames are arriving, resetTimeBasis() restarts mElapsedTimer but frames already queued by the working thread carry timestamps from the old (pre-reset) elapsed timer. These get drained on the next 20ms tick and appear with large incorrect timestamps, breaking timestamp alignment with subsequent frames. Fix: flush every connection's queue inside resetTimeBasis() so all pre-reset frames are discarded before the timer fires.
This was referenced May 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
PCAN/PeakCAN hardware provides timestamps relative to device power-on (uptime), not the Unix epoch. The existing code subtracted
timeBasis(a Unix epoch value in µs) from this small uptime value, causing unsigned integer underflow and producing large negative-looking timestamps (e.g. -1777429996593330 µs).A secondary problem existed even after detecting the uptime clock: using a
QDateTimewall-clock anchor to convert the PCAN uptime to session-relative time introduced a systematic ~3 ms bias (macOS monotonic vs. wall clock drift ~14 ppm). This made every Rx timestamp appear slightly after its corresponding Tx timestamp in override-mode delta calculations, breaking the expected request/response order.A third problem: clicking Clear Frames while frames are arriving restarts
mElapsedTimer, but frames already queued by the hardware thread carry timestamps from the old timer epoch. Those frames are drained ~20 ms later by the refresh tick and appear with incorrect (large) timestamps relative to subsequent frames.Fix
Commit 1 — correct PCAN timestamps for uptime-based backends
hwTimestamp < timeBasis.CANConManager::getElapsedUs()directly instead of the PCAN hw clock. This is the identicalQElapsedTimermonotonic source used for Tx timestamps, so Tx and Rx are always on the same clock with zero drift or bias.CANConManager::getElapsedUs()helper (exposesmElapsedTimer.nsecsElapsed() / 1000).mFirstHwTimestamp,mFirstElapsedUs) that are no longer needed.Commit 2 — prevent incorrect timestamps after Clear Frames
resetTimeBasis()now flushes every connection's frame queue immediately after restartingmElapsedTimer, so pre-reset frames are discarded before the drain timer fires.Files changed
connections/serialbusconnection.cpp— uptime detection +getElapsedUs()for Rxconnections/serialbusconnection.h— removed obsolete anchor membersconnections/canconmanager.cpp— addedgetElapsedUs(), queue flush inresetTimeBasis()connections/canconmanager.h— addedgetElapsedUs()declarationTesting
Verified with a PCAN-USB on macOS: