2
\$\begingroup\$

I am working on some CAN communication project which allows us to control some external device attached to one node from some other node. The CAN bus is a broadcast network and hence a message sent by a node will be received by every other CAN node on the bus.

My requirement is that I need to implement a filtration mechanism for the nodes so that a node will only act upon those received messages for which it is configured (using some GUI utility). So I need to implement this filter mechanism in my code. I am using an STM8SAF52Ax microcontroller with IAR Embedded Workbench as my development environment.

How could I implement this filter process of CAN messages? I also did web search and read many other tutorials, but still I am unable to figure out what is to be done. There are use of CAN filter ID and filter mask, but I am unable to decide what value to be loaded in these and how to calculate these values.

\$\endgroup\$
  • \$\begingroup\$ That's a CAN gateway, don't think it's an easy task to make the mentioned device from scratch. \$\endgroup\$ – Marko Buršič Jun 10 '16 at 12:40
  • \$\begingroup\$ Are you sure about that part number, STM8SAF52Ax? Isn't it "STM8AF52Ax"? E.g. STM8AF52A6, STM8AF52A8, STM8AF52A9, or STM8AF52AA. \$\endgroup\$ – Peter Mortensen Jun 11 '16 at 13:05
5
\$\begingroup\$

It is very straight-forward: only act when you receive a message you want, and ignore everything else. Simply keep a list of CAN identifiers and then take action based on them. It is a pure software problem.

CAN controllers always have built-in filter registers, but these are almost always too crude to be used in semi-advanced applications, because they use bit masking. The only use of such filters in practice, is when you have a CAN node which should only listen to one or maybe two CAN messages.

EDIT: note that these filters typically use a bitwise NOR of all existing CAN identifiers. Which is why the filters make less and less sense, the more CAN identifiers you need to support. It is a fundamental design mistake in the CAN filter mechanism in most CAN controllers.

The reason why you would want to use such filters is to reduce the work load of the CPU. Yet some of the dumber CAN controllers will still yield an interrupt for message received, even when the message didn't pass the filter.

So my advise for this case is to forget all about hardware filters and do all checks of CAN id in software.

For a large amount of different CAN ids, you will need to use a sorted table and efficiently search (binary search) through it to see if they received CAN id was valid.

The real question here is if you have a CAN driver for the given MCU or not. Coding a CAN driver yourself is not trivial, it usually takes 1-2 months to develop a fully functional CAN driver, given that you already know CAN and C programming.

\$\endgroup\$
  • \$\begingroup\$ Thanks Ludin for your valuable suggestions. Actually you are correct that i need to implement the filter mechanism through hardware to reduce the consumption of cpu resources and its our priority in the developement process. So for this reason i need to implement this through hardware filter to reduce the unwanted interruption to the cpu. \$\endgroup\$ – amit kr Jun 10 '16 at 13:33
  • \$\begingroup\$ So could you site some examples as how to use the mask and filter registers.Suppose i want to receive message id 0x01,0x02,0x03 and i want to block every other message id ,so what values will be loaded in filter and mask registers and how to calculate these values. \$\endgroup\$ – amit kr Jun 10 '16 at 13:42
  • \$\begingroup\$ @amitkr This is MCU specific, you will have to read up about how the driver and/or registers work. Usually they just use simple bit masking, in which case you can't use that method, because according to your spec you will have a variable amount of messages. The more combinations of CAN identifiers there are, the less does bit masking make sense. \$\endgroup\$ – Lundin Jun 10 '16 at 14:23
  • \$\begingroup\$ @amitkr If you wish to reduce CPU load, it makes more sense to either pick a MCU with "mailbox" functionality on CAN (see this, or pick a MCU which can DMA from CAN. \$\endgroup\$ – Lundin Jun 10 '16 at 14:23
  • \$\begingroup\$ 1-2 months for a CAN driver in a microcontroller is gross overkill. I just checked, and my driver layer on a PIC 18 for the ECAN hardware is just 1000 lines of code, with probably half of those comments. This provides are complete hardware-independent procedural interface for sending CAN frames, and a asynchronous thread that makes makes received CAN frames available to the rest of the system in a hardware-independent way. It's really not that hard. Two dsPIC versions are also about the same size. \$\endgroup\$ – Olin Lathrop Jun 10 '16 at 15:21
4
\$\begingroup\$

As you say, every node receives every message. In CAN, messages are tagged as to what data they contain. This is done using the ID field for that purpose. This can be either 11 or 29 bits, decided by the sender.

The basic answer is then to examine the ID and discard message that are not relevant. Many CAN hardware implementations have masks and filters for exactly this purpose. Check the documentation of your CAN receiver to see what exactly the hardware can do for you.

However, you don't actually need hardware for this. I don't usually bother with the hardware masks and filters since they are architecturally in the wrong place and therefore difficult to use for generalized firmware. Usually, the application-level CAN receiving task examines the ID and dispatches to the particular routine to handle the message. Ignoring CAN messages with IDs the code is not equipped to interpret falls out naturally from this, and really requires no extra code.

\$\endgroup\$
  • \$\begingroup\$ Thanks Olin.The mcu STM8 i am using is having the inbuilt hardware support for message filter mechanism.So for this reason i tried to utilise it to prevent unwanted interrupts to cpu. \$\endgroup\$ – amit kr Jun 10 '16 at 13:45
  • \$\begingroup\$ I do not bother with HW ID's also, but one should keep in mind that really crappy nodes could be connected to bus and the CAN ISR on your module could be triggering much more often than you expect. I've seen this couple of times! \$\endgroup\$ – Bip Jun 12 '16 at 21:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.