Libuavcan RX timestamps on S32K

Answering @noxuz here about the FlexCAN peripheral’s 16-bit timestamps (see of the S32K reference manual:

My assumption is that you can clock this timer externally using the first channel of a timer chain that adds up to 48-64 bits of resolution. If so then you can setup something like this:

The trick then is to figure out how to assign the upper channels of the timer to the received messages. The simplest strategy would seem to enable the RX ISR and to record the full resolution from within that ISR. That, however, is a huge mistake for two reasons: 1) too many ISRs that make the application sensitive to bus load and 2) the first channel may have rolled over between the time the second ID bit was received and the ISR fired.

Another strategy is to enable the rollover ISR for that first channel. This strategy has a deterministic use of CPU resources so, as long as an application can tolerate some ISRs, it should be acceptable. However, this strategy fails when the rollover occurs while a CAN message is still being received since that message will only become visible after the rollover ISR has exited but will be marked with the pre-rollover value of the first timer channel.

The best strategy is to use the knowledge of the CAN bit timing, the fact that the timer is recorded at the second bit of the received message, and a knowledge of the time delta between the last time the received message queue was updated with full resolution time stamps and the current time. Using these as inputs you can configure two modes:

  1. Rollover ISR always keeps the timestamps updated
  2. CPU time is borrowed from a driver service call to perform the updates.

Either mode will use the same logic but mode (1) makes the driver run without caveats other than it has a periodic ISR. Mode (2) can be enabled for hard-realtime applications with the caveat that the CAN driver must be serviced at a rate < rollover-time - time-from-2nd-bit-till-DMA-update or the RX timestamps will become invalid.

So, yes, enabling high-resolution hardware timestamps on MCUs where only 16-bit hardware timestamps are provided is very complex but possible. A simple first approach for the s32K driver is to not use hardware timestamps and instead provide software timestamps using a simple system timer. I’d start there and then we can iterate on the high-accuracy hardware timestamps later.

1 Like