python-can icon indicating copy to clipboard operation
python-can copied to clipboard

pcan interface does not use hardware filtering

Open mgiaco opened this issue 6 years ago • 6 comments

Hi,

I think it would be great if the pcan driver also supports HW-Filtering. As I found out in the PCAN Basic API Documentation that should be possible.

cheers mathias

mgiaco avatar Aug 30 '18 08:08 mgiaco

If I remember correctly, you specify a range instead of ID and mask, so it won't be portable. That being said, it is not an problem to add interface specific settings if needed.

christiansandberg avatar Aug 30 '18 13:08 christiansandberg

We could also apply a first rough level of filtering on the HW layer, but let recv_internal() return False as the second parameter, which causes the Bus class to apply the finer grained filters on top of that. I dunno whether that's worth the effort though, but it could be more efficient.

felixdivo avatar Aug 30 '18 13:08 felixdivo

Okay i understand.

mgiaco avatar Aug 31 '18 07:08 mgiaco

@mgiaco Do you want to implement that? Do you need help?

felixdivo avatar Oct 05 '18 12:10 felixdivo

@felixdivo I can try it but I am very busy these days so it will take some time.

mgiaco avatar Oct 09 '18 09:10 mgiaco

If I remember correctly, you specify a range instead of ID and mask, so it won't be portable. That being said, it is not an problem to add interface specific settings if needed.

That's technically correct when you use the FilterMessages method provided by the PCAN-Basic API. But this is actually only a "convenience" function where they try to calculate an ID+mask given a range of IDs to actually set in hardware [^1] . This can be read on the last page (Appendix D) of their parameter documentation PDF.

[^1]: See chapter 6.4.15 in the datasheet of the actual hardware CAN controller chip inside PCAN devices.

But it's also possible to manually set ID+Filter through the parameter PCAN_ACCEPTANCE_FILTER_11BIT and PCAN_ACCEPTANCE_FILTER_29BIT. This is documented in page 66 of above linked PDF (and also in their API documentation chm file you can download from their website):

This parameter allows the configuration of complex filter patterns, and it is intended for users with extended CAN knowledge. Note that the calculation of mask and code patterns is not a trivial matter. For most applications the use of the function CAN_FilterMessages for setting message reception ranges is more adequate. A simple example on code and mask calculation can be seen in the Appendix D

I tried setting a filter with self.m_objPCANBasic.SetValue(self.m_PcanHandle, PCAN_ACCEPTANCE_FILTER_11BIT, 0x00000XXX00000YYY) (where XXX denote the ID to match and YYY denote the mask). And it "kind of" works but I still got unwanted messages through which still requires the software filter to be active. I might test this more extensively why it is the case.

You can also read out the current mask + filter value set in hardware with GetValue and the same parameter:

result, value = self.m_objPCANBasic.GetValue(self.m_PcanHandle, PCAN_ACCEPTANCE_FILTER_11BIT)
hex_str = format(value, 'x').zfill(8 * 2)
print(f"Acceptance filter: id={hex_str[0:8]} mask={hex_str[8:16]})

With this method, you can also check what id+mask combination FilterMessages actually sets behind the scenes.

And even though some unwanted messages coming through, on a busy bus this filter already dramatically improves performance because of many messages not needed to be parsed by the python software "fallback" filter. In my usecase, there was often a delay of 5+ seconds for one message to appear in the application after its reception because of all the other messages on the bus spamming the software filter.

mipro98 avatar Apr 27 '24 07:04 mipro98