smoltcp
smoltcp copied to clipboard
Support for hardware timestamp
I'm working on an embedded project (STM32H7) that requires hardware packet timestamping (transmit and receive). I have a working prototype, but it's pretty messy.
With the STM32H7 operating in DMA mode, receive timestamps are placed in an 'extended descriptor' (which is essentially just an unused receive descriptor after the packet descriptor), and transmit timestamps are placed in the transmit descriptor.
It was pretty easy to pass the receive timestamp up the stack (I modified the phy::RxToken trait to include a second Option<u64> argument, and then dropped the timestamp in an Endpoint- yes I know that isn't where it should go!). The transmit timestamp was a lot harder- I was hoping to use some kind of callback, but couldn't figure out how to keep ownership around long enough, so I ended up using a global for my prototype.
So I have a couple questions:
- Has anyone tried doing something like this before? Any hints on a cleaner way to pass transmit metadata up the stack after the packet has been moved into DMA?
- Is this a feature that people would find useful? If there's interest I'd be willing to spend a bit more time on it and share a cleaner implementation
Is that for PTP? PTP on the H7 ist something I'd like to look at if I ever find the time. And I also have wondered how to ferry the metadata up and down the stack.
This is very useful!
Yes, this is for PTP!
I'm interested to know if there are other use cases though (industrial controls perhaps)?
If PTP is the only application, it might make more sense to implement PTP at the driver layer, rather than passing timestamps all the way up the stack (and potentially breaking interfaces). I think it could be done reasonably cleanly there, and reading between the lines of the ST documentation that seems to be what they have in mind.
I'm also very interested in this; I have an old demo here and here that did time sync using PTP on an F4, but the STM32F4/F7 has a different MAC and PTP implementation to the STM32H7. I've since implemented a more production-level version in C and lwip which was pretty hateful too.
As you've identified, getting transmit timestamps back to the application is a real pain. In my implementations I essentially sneak in between smoltcp/lwip and the MAC, intercepting packets going either way. For received packets which should be timestamped I append the timestamp data to the packet payload (and fix up the length and checksum fields), so the application appears to receive the timestamp as part of the packet. For transmit I was able to use a callback into the application, which included an ID from the transmitted message.
I don't think implementing PTP at the driver layer is likely to be a good solution - it's a lot of code and work and will have a lot of application specific complications too. Really you'd want a whole separate PTP crate to handle the protocol, the best master selection, the database stuff, and you'd also still need to implement a control law too, which isn't specified by the standard. There are definitely other use cases where you just want the timestamps for whatever reason, so I would focus on trying to get the tx/rx timestamps available to the application.
I think #628 is something you can look at (if you still need it).
Closing this issue because #628 merged