How is the CAN ID filtering logic implemented?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How is the CAN ID filtering logic implemented?

Jump to solution
2,895 Views
gberthiaume
Contributor III

Hi, 

I want to improve my understanding of the CAN message ID filtering with the S32K SDK.
More specifically, I want to understand how to only accept a range of IDs.

Thanks to the table in this answer, I know that to only accept a range of message ID from 0x404 to 0x407, I need to configure the mailbox as follows:

#define ACCEPTED_ID   0x404
#define MAILBOX_MASK  0x7FC

CAN_ConfigRxBuff(/* Other parameters */, ACCEPTED_ID);
CAN_SetRxFilter(/* Other parameters */,  MAILBOX_MASK);‍‍‍‍‍‍‍‍‍

To be honest, I don't fully understand what is happening inside the CAN peripheral.


For learning purposes, here's my attempt at describing the ID filtering logic with C pseudo-code.

// This is how the CAN peripherals filters the RX message ID.
bool is_id_valid(uint16_t id)
{
    return (id & MAILBOX_MASK) == (ACCEPTED_ID & MAILBOX_MASK);
}‍‍‍‍

Would you agree with this masking logic?


Thanks,
Gabriel

Labels (1)
1 Solution
2,807 Views
kef2
Senior Contributor IV

Hi,

Strictly speaking CAN ID filtering doesn't support contiguous ranges of ID's. Mask_bit_n=1 means that corresponding ID_bit_n has to match filter_bit_n setting to pass the filter. Mask_bit_n=0 means that corresponding ID_bit_n is don't care, could be either 0 or 1 and still pass the filter. If all bits from 0 to N fulfil above requirements then message is accepted. Usually you can set up more than one filter. Message has to pass just single filter to be accepted. Hardware ID filters may check not only ID bits, but as well they may check some special message bits like IDE or RTR.

bool is_id_valid(uint16_t id)
{
    return (id & MAILBOX_MASK) == (ACCEPTED_ID & MAILBOX_MASK);
}

Yes, your pseudocode is correct.

I your case of contiguous 0x404 to 0x407 ID's, only bits 0 and 1 are changing. Mask 0x7FC has bits 0 ant 1 in "don't care" state and all other 11-2 bits in "check it" state. Just single filter and range of ID's perfectly filtered! But you couldn't repeat such success story for ID range like 0x403 to 0x407. Either more filters are needed (for ID 0x403) or you need to accept ID's 0x400..0x407 using single filter and then filter out not our ID's 0x400..0x402 in software.

Edward

View solution in original post

2 Replies
2,808 Views
kef2
Senior Contributor IV

Hi,

Strictly speaking CAN ID filtering doesn't support contiguous ranges of ID's. Mask_bit_n=1 means that corresponding ID_bit_n has to match filter_bit_n setting to pass the filter. Mask_bit_n=0 means that corresponding ID_bit_n is don't care, could be either 0 or 1 and still pass the filter. If all bits from 0 to N fulfil above requirements then message is accepted. Usually you can set up more than one filter. Message has to pass just single filter to be accepted. Hardware ID filters may check not only ID bits, but as well they may check some special message bits like IDE or RTR.

bool is_id_valid(uint16_t id)
{
    return (id & MAILBOX_MASK) == (ACCEPTED_ID & MAILBOX_MASK);
}

Yes, your pseudocode is correct.

I your case of contiguous 0x404 to 0x407 ID's, only bits 0 and 1 are changing. Mask 0x7FC has bits 0 ant 1 in "don't care" state and all other 11-2 bits in "check it" state. Just single filter and range of ID's perfectly filtered! But you couldn't repeat such success story for ID range like 0x403 to 0x407. Either more filters are needed (for ID 0x403) or you need to accept ID's 0x400..0x407 using single filter and then filter out not our ID's 0x400..0x402 in software.

Edward

2,807 Views
gberthiaume
Contributor III

Thanks; this is exactly the answer I was looking for.

Your examples were great.


Regards,

Gabriel

0 Kudos