Can't get messages from bus in loop
DoctorZIP opened this issue · 7 comments
Hi, trying to deal with CanBroker by still vain.
Here is the code:
CanBroker canBroker = new CanBroker(Executors.defaultThreadFactory(), Duration.ofMillis(10)); canBroker.addDevice(canNetworkDevice, (ch, frame) -> LOG.debug("Frame {}", frame));
The result is 3 CAN frames but candump receives messages from MCU all the time. Please help
Can you reproduce the same behavior using a RawCanChannel in blocking mode?
Also what version of JavaCAN are you using, what architecture are you using it on and what kind of device is generating the messages you are missing?
Thank you for your reply! Just fix that with canBroker.addFilter(CanFilter.ANY); But one issue is still exists:
If I set canBroker.addFilter(CanFilter.NONE); Linux is still marking all CAN messages as acknowledged.
JavaCAN v 2.3.0
JDK 11
Raspbian Linux on Raspberry PI 3 with Waveshare CAN module
Just fix that with canBroker.addFilter(CanFilter.ANY);
Ah, good that you found that out. I had the suspicion that it might be wrong filters, but haven't invested the time to properly look into it. In case you are using CanFilter.ANY you might actually be better of using the EventLoop interface directly instead of the CANBroker.
Linux is still marking all CAN messages as acknowledged.
Not entirely sure how JavaCAN is involved there. The CANBroker configures the the filter on each device it manages and that is pretty much it. Can you elaborate on what you mean by acknowledged ? This might also be a question that could be asked over at the linux-can kernel mailing list, if we can't find a solution here.
Can you elaborate on what you mean by acknowledged ?
Sure. As you may know CAN frame consists of a few parts line ID, DLC, DATA, CRC, etc. One of these parts is ACK that setting by the frame receiver and indicates that the frame was accepted by the receiver. Usually, separation of frames is achieving by frame filtering. After frame is passed filtering stage CAN transceiver sets ACK bit to 1 and other CAN bus devices should ignore them. So, if Linux accepts and, therefore, ACKs all frames these frames could be lost by other CAN bus devices. The main question is: Can JavaCAN apply filters on hardware level instead of software level? I have found workaround here https://github.com/craigpeacock/mcp251x but it would be great to have ability change hardware filtering properties just from java code. Anyway your lib are awesome :)
Ah OK, got it. JavaCAN is doing all it can, hardware filtering will work, if the kernel driver supports it. JavaCAN is just a SocketCAN wrapper. I'm kinda surprised, that the MCP251x driver in the kernel does not support hardware filters since its fairly popular on SBCs. Someone should try getting that patch into the upstream kernel.
Ah OK, got it. JavaCAN is doing all it can, hardware filtering will work, if the kernel driver supports it. JavaCAN is just a SocketCAN wrapper. I'm kinda surprised, that the MCP251x driver in the kernel does not support hardware filters since its fairly popular on SBCs. Someone should try getting that patch into the upstream kernel.
Btw, do you know which CAN devices/chips/etc support hardware filtering on SocketCAN?
Thank you!
Nope, I only used MCP251x myself and for me it didn't really matter how the filtering is implemented. The linux-can kernel mailing list will definitely be able to answer this.