Open codytrey opened 2 years ago
Hi,
is there an existing generic trait crate for CAN bus (I vaguely remember seeing one at some point)? If yes, it would of course be great to also support it here. You're welcome to send a PR :)
That's great to hear! I've got a theoretically working implementation that I plan to test tomorrow if the work day is slow. One issue I know of now is that embedded-hal-mock doesn't currently support can. If not having tests is an issue, it doesn't look like like it should be too hard to add can support there too.
If not having tests is an issue, it doesn't look like like it should be too hard to add can support there too.
Of course tests would be great but in this case I don't think we're missing too much without the tests here...
After some more testing it seems non-trivial to add support for can bus because while embedded-hal does have a generic trait for it, the hal crates that implement it (stm32f1xx-hal at least, as that's the only one I'm currently able to test) also depend on bxcan and the bxcan::Can trait would also need to be implemented.
There's also a more fundamental issue of how to handle can frames received for other device drivers while the bus is being used another device driver. I can think of a few ways to handle that, but are probably out of scope for this crate.
Fair warning, my experience with CAN is very limited...
I think I see the problem. Arbitrating Can::transmit()
would be "easy" as its contract states that it should block until the frame is written. But Can::receive()
is essentially impossible without additional logic and buffering because we need to make sure the right messages reach the right receiving code. That said, even the naive implementation for Can::transmit()
would be suboptimal because it blocks unnecessarily, which probably makes it infeasible for a lot of usecases as well.
So I agree that shared-bus
probably doesn't fit CAN... What we need is something smarter, a kind of routing layer with an interface similar to the one in Linux (the only reference I have here ^^): https://www.kernel.org/doc/html/latest/networking/can.html
I.e. client code can create an arbitrary number of sockets with different filters and the routing layer does the right thing with incoming frames (any maybe even set the hardware filter to the union of all socket's filters where possible).
What comes to mind is the smoltcp
crate which implements socket networking for tcp/udp/ip. I think its design is quite well thought out and works quite nicely for embedded systems. Maybe copying the design pattern from there into a can-routing
crate would be a good idea. The crate then consumes an embedded_hal::can::nb::Can
and routes frames between multiple socket clients which are connected to it.
What do you think?
Is there anything that would prevent adding support for can bus? If not and this would be a welcome addition I'll plan to start working on it as it would be useful in my own project(s).