CAN Bench Testing¶
Normally, the CAN controllers are initialized in a “listen only” mode. They are configured as writable only if using raw CAN passthrough with a CanBus that is marked writable or if a CanSignal is writable.
This works fine in a vehicle, but when testing on a bench with a simulated CAN network (e.g. another VI sending CAN messages directly to your VI under test), there’s a problem - every CAN message must be acknowledged by the controller, and in “listen only” mode it does not send these ACKs. With nobody ACKing on the bus, the messages never propagate up from the network layer to the VI firmware.
When compiling the VI firmware to use to receive data on a bench test CAN bus, use the BENCHTEST flag to make sure CAN messages are ACked:
$ make clean $ BENCHTEST=1 make
The CAN controllers will also be write-enabled if you use the DEBUG flag, or the transmitter Makefile target. The BENCHTEST flag is useful if you want to bench test normal, non-debug operation but still send ACKs.
Simulating a CAN Network¶
Speaking of CAN bus bench testing, it’s possible to create a 2-node CAN network on your desk with 2 VIs to test your firmware. This is especially handy for prototyping new translated signals, since you can record a raw CAN bus trace from a vehicle and do all of your work inside where it’s warm and comfortable.
- 2 VIs
- A female-female OBD-II cable, or whatever combination of cable ends you need to connect one VI directly to another
- 120 ohm resistors across the H/L CAN wires in that cable or...
- If one VI is a chipKIT, there are jumpers you can flip to enable 120 ohm resistors on each CAN controller (only one of the VIs needs the resistors)
- If one VI is a Ford prototype, that has the termination resistors enabled by default on version 1.0. In an updated version that may change, as this is actually a mistake - they should have been only available if you short a solder jumper.
We recommend building your own cable with female OBD-II connectors from Molex (with the matching crimp connectors and a crimper wired together with 120ohm resistors crimped directly into one end of the cable (some pictures of a wired cable). We also recommend including the 12v and a ground wire, and shaving off a little ring of insulation on each at one end of the connector so you can inject bus power if needed. Make sure to offset the sections of shaved off insulation by a half inch so they don’t short.
Alternatively, there are OBD-II splitter cables available online that may also work, but these have not been tested.
Preparing the Transmitter¶
- Decide which of the VIs is the transmitter, and which is the receiver (the receiver is most like your VI under test).
- Follow the normal firmware build process (the CAN signals defined don’t matter, just the bus speeds) but instead of just make run make transmitter. This changes 2 things: it configures the CAN controllers to be write-enabled and changes the USB product ID from 1 to 2, so you can address the transmitter VI independently from the receiver.
Preparing the Receiver¶
Compile the VI firmware for the receiver as usual, but instead of just make, run BENCHTEST=1 make This configures the CAN controllers as write-enabled, so that your VI under test can ACK the CAN messages. If nobody on the bus ACKs, you will receive nothing. In a car there are usually many other things ACKing, so we can be “listen only”.
Sending Data on the Bus¶
You need a pre-recorded raw CAN trace file from a vehicle. To create one, compile the firmware in the passthrough mode (see the low-level CAN docs) and flash a VI, then use openxc-dump to receive the raw messages - point that at a file on disk to create a trace.
With a raw CAN trace file named raw-can-trace.json:
$ openxc-control writeraw --usb-product 2 -f raw-can-trace.json
That will send all of the message in the file, correctly spaced according to the timestamps. If you want to send continuously, you can loop the file like this:
$ watch -n 0 openxc-control writeraw --usb-product 2 -f raw-can-trace.json
Receive data as usual from the VI under test, as if it was in real car.