3
\$\begingroup\$

TL;DR: This question is about saving unnecessary CAN transceivers by sharing one among 3-4 equal MCUs on a small, single board.

Imaginary situation: A board with multiple, equal, CAN-capable STM32-MCUs needs to chat with other equally-made boards via CAN bus. There's one transceiver on each board (most probably an MCP2562FD), meant to be connected to all MCUs in parallel, sharing bus access. Please see the following pseudo-schematic for clarification:

Pseudoschematic of two multi-MCU-boards connected via CAN

The "secondary MCUs" on the left half will "just passively listen" and use individual ID filters to only get relevant data for their task.

The respective "main MCU" will be the only active communicator on each board, officially talk / respond / ACK on the bus.

The point is to reduce transceiver IC count per board. Normally, I would put a dedicated transceiver for each MCU. To me, however, a CAN transceiver (not: controller) looks like an "active access point" / "medium translator" that's not necessarily bound to be connected to a single client MCU only. I further assume, that if the main MCU was able to understand a message (and "ACKed" it), the secondary µCs should have received it correctly, too - since all lines are kept short and away from noise, and interference should be most likely to happen on the other side of the transmitter. The tx lines of the secondaries will be omitted, most probably, to enforce passivity.

To me, this concept looks feasible, electronically and logically. Yet, I'm unable to find any resource describing that it could work or wouldn't at all. If any CAN / STM32 pro could shed some light on this, point me to the right direction (*), name pitfalls, confirm or refute my thoughts, I'd highly appreciate that!

Thank you for your time and attention!

(*) without discussing the multi-MCU-approach as a whole or switching to / introducing other means of multi processor communication - I love and want the high abstraction level by ID filtering and mailboxes all-in-hardware goodness ;)

\$\endgroup\$
15
  • \$\begingroup\$ You are amplifying, doubling down, and exponentiating the shared media issues that plague shared media busses like CAN and then removing the only element (transceiver) used to mitigate the trouble. But there is no technical reason you can't make this work. If you are looking for cost savings be sure to do a true decision matrix taking into account the cost of design complexity because this will cost much more than 4 transceivers a board to implement and support. \$\endgroup\$
    – crasic
    Jan 25 at 15:29
  • \$\begingroup\$ One downside is basically worrying about firmware update or any chip stepping bricking your boards due to a very fragile stack configuration that needs to synchronize multiple ucs per board. This design better be worth what you will be throwing at it. \$\endgroup\$
    – crasic
    Jan 25 at 15:32
  • \$\begingroup\$ @crasic Umm well obviously there's a lot of things to consider with every component choice. Right now ST can't deliver STM32F without huge lead time delays, for example. So right now I wouldn't use STM32 in new designs, until ST sort out their delivery times. And that is not a technical reason. \$\endgroup\$
    – Lundin
    Jan 25 at 15:33
  • \$\begingroup\$ Your design will be as fragile as a house of cards, supply chain issues aside, this is not a professional approach barring some hugely important demand. \$\endgroup\$
    – crasic
    Jan 25 at 15:34
  • \$\begingroup\$ @crasic There's not really enough information to tell. I've done similar projects where a modular design with multiple modules was redrawn with same schematics into a single, specialized PCB. They shared CAN communication which now became on-board, though in my case each node could send. But the reasoning here was "don't break the working system design just change the mechanical layout". Which in turn meant faster time to market. To merge the 4 different MCUs into one would have been a big software project, likely 1 year of extra work. \$\endgroup\$
    – Lundin
    Jan 25 at 15:39
3
\$\begingroup\$

Now, I want the "secondary µCs" on each board to "just passively listen" and use individual ID filters to only see relevant data (each free CPU cycle counts).

Yes, if you are doing this then there is no problem having multiple micro controllers with their respective CAN_TX and CAN_RX pins tied together. As you mentioned, you should ensure they are set to passive mode if possible (which the STM32 does).

Note that even if they didn't have a passive mode, it should still be okay to connect the lines together (though some series resistors on CAN_TX would be prudent) as each CAN controller will ACK every message or generate error frames at the same point anyway. Also note that most CAN controllers will ACK any valid frame they see, regardless of whether it is subsequently filtered or not. Filtering is a higher level operation whereas the ACK bit is there to provide basic connectivity checking for the transmitting node (and not a whole lot else in practice).

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for the insight and pointing out details about the ACK! This will make me consider implementing a more high-level ACK mechanism for critical msgs. \$\endgroup\$
    – Zod
    Jan 25 at 12:23
2
\$\begingroup\$

There's two circumstances in which a node's CAN controller will send things on the bus even if it hasn't been told to send any data frames:

  • To set ACK bits in any incoming frame.
  • To send error frames in case it spots errors (stuffing, bit errors etc).

So if all your MCUs share the Tx and Rx lines, you must make sure that the passive nodes do not do any of the above. Assuming ST BxCAN controller, then apparently it has a "silent mode" where any transmission from the "silent" node is internally looped to Rx and CAN Tx output is held recessive.

This assuming that the "silent" node doesn't go haywire if someone external starts pulling its Tx line to dominant level. In case doing so affects the error counter on the "silent" node then this design might not be feasible, so I'd just leave the Tx pin on each "silent" node unconnected.

And yeah it should work to have your active node only doing the ACK. The silent nodes will pick up the ACK from the CANH/CANL side.

\$\endgroup\$
2
\$\begingroup\$

Good news: I have a solution that deals brilliantly with the shared CAN problem, and it will make your overall design much simpler.

Use a single, more powerful MCU.

If you can't, you'll have to explain in some detail why, because I see your question as a yet another XY problem: you look for a solution to some detail without examining (in the question) why that detail even makes sense to begin with. Using a single MCU instead of 4 of them solves that problem, and solves a lot of other problems you don't even know you have (yet).

each free CPU cycle counts

That tells me that you're using an underpowered MCU for the job. You'll likely get higher power efficiency per MIPS from a more powerful MCU as well, so if you worry about power consumption, one more powerful chip beats several less powerful ones (assuming they were fully utilized).

I have had a "simple" design with 4 MCUs, networked via SPI. It turned out to be way more trouble than it was worth - a single, more powerful chip, made everything miles easier. That design never left the stage of a limited prototype run, and I'm glad.

I want the "secondary µCs" on each board to "just passively listen"

Passive listening is pretty much the default operating mode for CAN, since flipping acknowledgment bits isn't necessary unless the transmitter software requires them. In plenty of designs CAN can be used as pretty much a "broadcast" medium, where every node transmits as needed, and nodes interested in stuff listen to it. Since, presumably, all nodes are there for a reason, it won't be typical to have some node prolong inter-transmission periods ("back off") if there are "no listeners" as determined by lack of acknowledgments.

With a fixed network structure and a fixed function of the overall system, each node would send reports while following some link utilization budget assigned to it, and it wouldn't back off just because no listeners provide ACKs. Many CAN implementations do signal a lack of ACK as an "error", but that's an entirely arbitrary name with no other consequence typically, and is only an "error" if your code that sends the messages will treat it that way. The CAN adapter makes sure to report lack of ACK, since the spec requires it to detect and signal it to higher layers. The higher layers are free to ignore it in purely broadcast systems where the nodes don't need to establish connections on top of CAN (and thus establish state that tracks presence of receiver(s)). ACKs from very many nodes are one of worst cases for CAN signal integrity, since they dramatically lower the bus impedance.

\$\endgroup\$
7
  • \$\begingroup\$ That's where I came from - one of the most obvious approaches ;) But I'm not that much into "One big CPU for all tasks", especially when there are time critical things running. My specific needs / reasons to segment the code / load / tasks into parts for multiple MCUs working in parallel are more important than saving surplus transceivers. This is not to discuss my general design, but only about the question: can I save them, and if yes, how? ;) \$\endgroup\$
    – Zod
    Jan 25 at 18:38
  • \$\begingroup\$ Why do you think saving those transceivers will actually save you money? What's the volume? If you, for example, spend 8 weeks designing and validating the transceiver-less "fakecan", will there be savings? That's lot of transceivers for that! A single chip MCU doesn't mean that you only get one core - there are plenty of multicore designs. So you have to provide some substance to the claim that you actually need physically separate chips vs. multicores, and that dealing with those chips will be somehow easier than dealing with many cores (even if different cores, eg.. Cortex-M and Cortex-A). \$\endgroup\$ Jan 25 at 18:47
  • \$\begingroup\$ Basically it seems to me that somehow you made the decision to use multiple separate chips without considering the entirety of the system, and are now trying to "back-substantiate" this design, whereas it looks like the design was not complete to begin with. You're very focused on the transceiver-less CAN problem, but that seems like a book case of target fixation that often derails projects. \$\endgroup\$ Jan 25 at 18:50
  • 1
    \$\begingroup\$ "...since flipping acknowledgment bits isn't necessary" This is wrong, doing this is absolutely necessary in order to get a functioning bus. Suppose there is only one external node (point-to-point). If no node does an ACK, then all communication on the bus will die. This is specified by the CAN standard, you shouldn't (and probably can't) make some home-brewed version of the controller that doesn't signal errors upon no ACK. \$\endgroup\$
    – Lundin
    Jan 26 at 9:01
  • 1
    \$\begingroup\$ This is mandatory behavior, see for example the CAN2.0B "Bosch" spec p.9: "Acknowledgement. All receivers check the consistency of the message being received and will acknowledge a consistent message and flag an inconsistent message." So it isn't "Many CAN implementations do signal a lack of ACK" but rather "conforming CAN implementations do signal a lack of ACK". \$\endgroup\$
    – Lundin
    Jan 26 at 9:11

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.