[ Jeep CAN bus primer — first-time users guide ]

A hands-on primer for new CAN-bus hackers working on the JEEP platform (Wrangler JL / Gladiator JT specifically, but most of this transfers to other FCA / Stellantis vehicles). Covers Waveshare 2-channel CAN HAT setup, listen-only safety, what to expect from the bus, TTCAN matrix-cycle scheduling, and the first messages that are safe to send.

If you've never touched CAN before -- haven't heard of CAN-H / CAN-L, ISO-TP, UDS service numbers -- start with the generic CAN bus introduction first. It covers the protocol-level material at a vendor-neutral level; this page is the JEEP-specific applied walkthrough.

Originally written by jmccorm; page polish and cross-links by magikh0e.

[ Hardware setup — Waveshare 2-channel CAN HAT ]

Proven /boot/config.txt parameters for the Raspberry Pi with the inexpensive 2-channel Waveshare CAN HAT (MCP2515 controllers over SPI). Append to your existing config.txt:

dtparam=spi=on
# CAN0 - CAN-IHS 125kbps passenger network
dtoverlay=mcp2515,spi0-0,spimaxfrequency=2000000,interrupt=23
# CAN1 - CAN-C 500kbps critical automotive network
dtoverlay=mcp2515,spi0-1,spimaxfrequency=2000000,interrupt=25
dtoverlay=spi0-2cs

Device initialization commands (after the Pi has booted and the can0 / can1 netdevs are visible to the kernel):

ip link set can0 type can \
    bitrate 125000 listen-only on triple-sampling on
ifconfig can0 up
ip link set can1 type can \
    bitrate 500000 listen-only on triple-sampling on
ifconfig can1 up
ifconfig can0 txqueuelen 65536
ifconfig can1 txqueuelen 65536

The full hardware build — parts list, Zero2Go Omni supercap power, sleep / wake gating, thermal handling — is on the CANBus dev stack page. This primer assumes you already have working can0 and can1 devices that don't error-flood.

What you're actually probing

Whether you're using the DLC (OBD-II) port up front or the 13-way connectors behind the glovebox, knowing which pins carry which bus is half the safety story. The SGW gates BOTH CAN-C AND CAN-IHS on 2018+ vehicles — not just CAN-C as is sometimes assumed.

Quick reference (full pinout tables with wire IDs, colors, gauges, splice points, and connector part numbers in the on-site Bus & Message Reference (BMR), §SGW + CAN bus harness):

    OBD-II DLC1
        pin 6  D428 BG        Diagnostic CAN C(+)      --> SGW C1 pin 3
        pin 14 D427 YE        Diagnostic CAN C(-)      --> SGW C1 pin 10
        pin 3  D434 BG        Diagnostic CAN IHS(+)    --> SGW C2 pin 2
        pin 11 D433 BG/YE     Diagnostic CAN IHS(-)    --> SGW C2 pin 7
        -- all four pairs land on the SGW, NOT directly on the in-vehicle
        trunks; SGW policy is applied before anything reaches the bus

    Behind glovebox, 13-way connectors
        Self-terminating (no resistor needed); taps the in-vehicle
        CAN-C and CAN-IHS primary trunks directly, BEFORE the SGW
        filter from the OBD-II perspective.

    SGW C1 (12-pin, CAN-C)
        pin  3 / 10     diagnostic side  (from DLC)
        pin  4 / 11     "AT" trunk       (radio, body modules)
        pin  5 / 12     primary trunk    (PCM, ABS, ESP, MGU, BPCM)

    SGW C2 (8-pin, CAN-IHS)
        pin  2 / 7      diagnostic side  (from DLC)
        pin  1 / 6      "AT" IHS trunk
        pin  3 / 8      primary IHS trunk
        -- C2 is fed by always-on B(+), so the SGW gates IHS even
           with the ignition off (RKE wakes, etc.)

This is why the DIY OBD-II cable doc on the parent page recommends the behind-glovebox approach for write work on 2018+ vehicles — the SGW gates both OBD-II-side pairs (CAN-C and CAN-IHS) but is wholly bypassed by tapping the in-vehicle primary trunks directly. Read work is fine through either entry point; writes need to either authenticate the SGW or come in past it.

[ The basics — what you're plugging into ]

can0 vs can1 (Linux naming)

When using the Waveshare adapter, you may have physically wired the
CAN-IHS network into the can0 terminal, but inside Raspbian, it may be
given a can0 or can1 identifier. For this reason, you may find it useful
to successfully configure just the CAN-IHS adapter alone before moving on
to using both adapters.

If you want to standardize with the configuration documented on this
site, wire it up so that CAN-IHS is given the can0
identifier inside the OS, and CAN-C is given the can1
identifier. In some circumstances, yes, the labels printed on the card
itself will end up backwards. As long as the device labels in the OS are
correctly ordered, that's okay.

Terminating resistors

When connecting to the Wrangler, you do NOT need to add a terminating
resistor. The Waveshare CAN HAT has a pair of on-board jumpers which
performs this function. Behind the glovebox, both of the 13-way CAN bus
connectors are self-terminating — built into the bottom of every
slot in the 13-way connector is its own terminating resistor. You do
not need to add your own.

CAN is a broadcast protocol

CAN is a broadcast protocol where every message is sent to all other
participants, all of which may be free to ignore or use that information
as they see fit. Instead of your dash asking the vehicle's various
components for the information it needs ("how fast are we going?",
"is my turn signal on?"), it waits for those devices to send a regular
status update with that information. Anything it receives that it isn't
programmed to use is ignored.

CAN-C vs CAN-IHS — which is which

In general, the CAN-C bus is used to transmit messages that are critical
to the operation of the vehicle, and CAN-IHS is used to transmit messages
for human comfort or interaction. As with anything, there are exceptions.
You will also find that some messages will be broadcast on both buses.

A useful payload-size discriminator on the JEEP platform: you may
discover that both CAN-C and CAN-IHS contain messages with an ID of
$12B, but that the content of the messages is completely
different. If the message is one byte long, it's on CAN-IHS. If the
message is eight bytes long, it's on CAN-C. This is a quick way to
verify which network adapter is on which CAN network.

The broader bus topology, gateway behavior (TIPM / TIPMCGW), and the full message-ID catalog live on the dedicated Bus & Message Reference.

[ Sleeping bus, wake methods, and missing messages ]

Sleeping CAN bus

While the vehicle is off, you shouldn't expect to see any activity on
either CAN bus. To wake it up, put the vehicle into accessory or run
mode, or start the engine.

As an alternative, you can partially wake up the CAN-C and CAN-IHS bus
by hitting the lock/unlock buttons on your keyfob. Some (but by no
means all) CAN IDs will report in for a short time before the vehicle
goes back to sleep once again.

UPDATE (DEC 2021): You can also wake up a CAN bus by sending ANY message.
A reliable one to use is a single console-button-ID message with an
empty bitmap that shows no buttons pressed -- $2D3 with an
07 00 00 00 00 00 00 00 payload is what several
on-site scripts (battery.sh,
mute.sh, etc.) use as their bus-wake
fallback.

SIDE NOTE: If your vehicle is not going to sleep, something is wrong and you need to investigate why. Modules remaining active while the vehicle is off will continuously drain your battery, eventually causing it not to start. You'll end up with a dead battery.

Missing and ignored messages

Some CAN IDs will not be broadcast unless the vehicle's engine is
running. This is particularly true for many IDs on the CAN-C bus.

You should also be aware that while the CAN protocol supports a "request
message" (where you ask the owner of a message ID to immediately report
back with its status), to the best of my knowledge, no module responds
to the CAN request function on the Wrangler. It is not used.

[ Reading messages — what's on the wire ]

Message IDs and module ownership

A message ID is accompanied by one to eight bytes of data. The message
ID is the key which tells you what its accompanying data contains, and
how that data is encoded. (This is exactly what we're trying to reverse
engineer!)

Although it is technically possible for any module on the bus to transmit
any message using any ID it wants, in practice, a single module will
only transmit messages using a handful of pre-determined IDs, and it
will be the exclusive source for those messages. While one ID may have
only one sender, every other module will be a receiver. Of those, only
a few modules might put that information to use.

Example: Only the Transmission Control Module (TCM) will send messages
with an ID of $340, which provides the current speed of the vehicle.
But when that message is received by the dash, radio, brakes, collision
avoidance system, occupant restraint controller (airbags), and all the
other modules, they each can make use of the message (or discard it) as
they see fit.

The module-ID catalog in the BMR maps known UDS request / response pairs to their owning module (BCM, PCM, ABS, EPS, HVAC, RFH, etc.).

Time-driven vs event-driven messages

Some messages are automatically broadcast on a regular basis (time
driven). Every second, every half second, tenth of a second, all the way
down to messages which repeat every hundredth of a second. There are
other messages that are transmitted when a module has something
interesting to share (event driven).

Reports from partially-offline sensors

Many sensors will report one number while the vehicle is off (0xFF or
0xFFFF is common, otherwise 0x00 and 0x0000), and then report their
actual value when the vehicle's ignition is in run mode. Keep this in
mind as you are working with the data — an "FF" sentinel is
usually "module is awake but the sensor it speaks for isn't powered
yet," not "this byte is meaningful at value 255."

Units of measure

An open mind is helpful when considering what units the vehicle may be
reporting with. Messages with IDs $300-$3FF are typically believed to
report using the units you (the driver) have selected in the Settings
application found in the uConnect radio. There will be exceptions, such
as ID $3D2 (Odometer), which reports mileage in tenths of a kilometer.
Outside the $3xx range, resist making assumptions, but looking for
metric units may be helpful.

[ Numerical formats — bitmaps, hex, decimal ]

Knowledge of binary and hexadecimal numerical formats is helpful,
although not absolutely required. It can be helpful to have a conversion
tool handy at times (Windows calculator will do if you go into the
upper-left and set into "programmer" mode).

Understanding hexadecimal can help you to quickly understand if you're
looking at a bitmap (a series of binary switches), a numerical
representation (a number that floats up and down, like a temperature),
or a counter (a number which never decreases, like an odometer).

Converting numbers with bindechexascii

In Raspbian, there is a utility called bindechexascii
which can be installed with:

    apt-get install bindechexascii

Once installed, consult its man page for information on how to use its
many functions. As an example, to convert a string of bytes from
hexadecimal to ordinary decimal numbers:

    $ bindechexascii --h2d 0A 43 21 fe 11
    Hexadecimal to Decimal: 10 67 33 254 17

Converting numbers with printf (preferred since DEC 2021)

UPDATE (DECEMBER 2021): printf may be a better way of converting numbers
in shell scripts — it's a coreutil, always present, no extra
package needed. Example:

    value="0F"
    value=$( printf "%d" 0x$value )
    echo $value         # prints: 15

This is the pattern several on-site bash scripts use to convert candump
byte fields into decimal for arithmetic:
battery.sh
(voltage), getVehicleTime.sh
(time fields), mute.sh
(state-byte compare), and so on.

[ Interface statistics and error rates ]

In Raspbian, if you want to check an interface to see if it is
successfully receiving traffic, use the ifconfig
command and look for the can0 and
can1 sections. Keep an eye on the number of
RX packets and compare those with the RX errors. Your error rate should
be well under 1%.

If not, something may be wrong and you'll want to address this issue
BEFORE you unlock your ability to send messages. Why? A CAN module
which is allowed to transmit is also allowed to send error reports. If
your module is seeing excessive errors, those errors will be shared
across the entire network, so you want to keep your error rate low
before bringing your TX path online.

Even more detailed information can be found by running:

    ip -details -statistics link show

[ Going from read to write — exiting listen-only ]

You can unlock your ability to send messages by removing the string
listen-only on from your initialization commands
above (or setting listen-only off in the
auto-config file below).

As mentioned in the previous section, make sure you've addressed any
significant error rate before doing so.

If you are familiar with the practice of "futzing" (sending semi-random
messages with random IDs), you're strongly advised to avoid that
practice as it can have unpredictable and damaging effects to your
vehicle. See the Safety section below.

Your first cansend — a safe sample

Your initial efforts should be focused on reading and understanding the
various messages being sent on your CAN bus. But if you want to try
your hand at sending a simple message, this will darken the interior
dash and door lights and engage the clicking sound of your turn signal
for a very brief period of time:

    cansend can1 291#000000F000000000

The effect lasts less than a second because the real source of
$291 (the BCM) sends
its own update right after yours and overwrites the transient effect of
your injection. That's a useful natural property of the bus — bad
injections from a hobbyist tend to be self-healing on the very next
broadcast cycle.

[ Automating your CAN bus configuration ]

Once your configuration is stable, you can automate the initialization
commands by placing them in /etc/network/interfaces.d/
with a filename of can0 or
can1. Sample content for can0 (CAN-IHS bus),
with listen-only OFF (i.e. write-capable):

    auto can0
    iface can0 can static
        bitrate 125000 listen-only off triple-sampling on
        post-up /sbin/ifconfig can0 txqueuelen 65536

Networking will bring the interface up at boot with these parameters
instead of you having to remember to run the manual `ip link set ...`
sequence every time.

[ CAN vs TTCAN — what makes the JEEP bus different ]

While the Wrangler's CAN-C and CAN-IHS buses are CAN compliant, they
appear to be using a more complex variant known as TTCAN (Time
Triggered Controller Area Network).

In TTCAN, the majority of time units are reserved for a specific
individual message ID (and only that ID) to be sent. There are a few
time-slots (limited in length) where event-driven IDs can compete using
normal CAN arbitration.

Because the devices we are using (an MCP2515-based Pi HAT) are not
TTCAN compliant — and even if they were, they do not contain the
Wrangler's TTCAN scheduling matrix — any message we transmit may
potentially collide with another device's exclusive time slot. The
other device does not expect to be interrupted and makes no provisions
for re-transmission.

Matrix cycle — the TTCAN scheduling structure

TTCAN organises time into a hierarchy:

    BASIC CYCLE         -- the fundamental scheduling unit, divided into
                           TRANSMISSION COLUMNS (numbered slots within
                           the cycle).
    MATRIX CYCLE        -- multiple basic cycles stacked, indexed by
                           Cycle_Count. Different basic cycles in the
                           matrix can place DIFFERENT messages in the
                           same column index.
    REFERENCE MESSAGE   -- starts every basic cycle; broadcast by the
                           TTCAN time master so every other node
                           synchronises its local clock to global time.

Within a column, a slot is one of four types:

    EXCLUSIVE       a specific message ID OWNS that slot; nothing else
                    transmits there.
    ARBITRATING     normal CAN arbitration applies; any node can compete.
    FREE            slot is intentionally idle (used for late-bound
                    additions to the schedule).
    MERGED ARB.     two adjacent arbitrating windows fused into a longer
                    one for messages that don't fit a single column.

Drawn schematically (original rendering -- four basic cycles, six
columns, every row anchored by the Reference Message at column 0):

    Basic_Cycle    Col 0       Col 1   Col 2   Col 3       Col 4         Col 5
    ===========    =========   =====   =====   =====       =====         =====
    Cycle_Count=0  [REFERENCE] Msg A   Msg B   Msg B       Free          Msg E
    Cycle_Count=1  [REFERENCE] Msg G   Msg F   Msg C       Msg D         Msg E
    Cycle_Count=2  [REFERENCE] Msg E   Msg B   MergedArb   MergedArb     Msg E
    Cycle_Count=3  [REFERENCE] Free    Arb     Msg C       Msg D         Msg E
                   ^                                                     ^
                   Ref_Mark                                              Ref_Mark
                               ^       ^       ^           ^             ^
                               TM_1    TM_2    TM_3        TM_4          TM_5

Same column (e.g. Col 1) carries Msg A, Msg G, Msg E, and Free across
the four basic cycles -- so the schedule is two-dimensional, not just a
flat repeating pattern.

The above is an original textual rendering of the standard TTCAN matrix-
cycle illustration first published in G. Leen and D. Heffernan,
"TTCAN: a new time-triggered controller area network," Microprocessors
and Microsystems vol. 26 no. 2, pp. 77-94 (March 2002), Fig. 3 -- cited
for its authoritative description of the scheduling model. Refer to the
paper directly for the canonical figure and the formal TTCAN protocol
treatment.

TTCAN controller on the Wrangler

The TTCAN Controller is responsible for coordinating activity on the
CAN bus. As part of its duties, it sends the reference message (shown
above) from which all other modules coordinate their timing.

Although the Wrangler appears to have multiple TTCAN controllers (for
redundancy), the primary TTCAN Controller appears to be represented by
ID $400.

Getting started: if you're just getting started, you can behave as if
the Wrangler has an ordinary CAN network. Just be aware of TTCAN, and
know that its importance may grow as your knowledge and skill advances.

Bulk transmissions — please don't

Where possible, bulk transmissions should be avoided. More so on the
CAN-C bus than the CAN-IHS bus (which is more event driven). Where bulk
transmissions cannot be avoided, the timing of each message should be
irregularly staggered.

For the more advanced user who has configured an automatic
re-transmission interval for failed messages, they should avoid using
common intervals (0.01s, 0.1s, 0.2s, 0.5s, 1s, etc.) as they are more
likely to collide with the same exclusive slot over and over again,
producing a "we keep failing in exactly the same place" failure mode.

[ Data protection — counters, checksums, and persistence ]

Protected IDs (counters + checksums on critical messages)

The CAN protocol includes some level of basic protection for all
messages (CRC field in the standard frame). But you'll find that some
important IDs on the Wrangler — CAN-C IDs below $0100 in
particular — may contain a constantly incrementing counter
and/or a special byte at the end which sums up all seven digits before
them (a checksum).

Both of these fields are used to prevent tampering and to ensure the
integrity of those messages. This technique is most often used on
critical automotive data such as brakes, steering, acceleration, etc.

Transmitting your own messages with these protected IDs may result in
detection by the ECU, and an engine code will be generated which
documents your transgression. (It can be cleared like any other engine
code.) For benign experimentation this is annoyance-level; for sustained
spoofing it's how OEMs catch you.

Some changes don't last

If you transmit a message, sometimes you may find its effects to be
permanent, while at other times they may only last for less than a
second. This is because most modules transmit regular updates every
fraction of a second, so the effects of any changed values you transmit
may be undone when the real module you're impersonating sends its next
regularly timed update.

If this is the case, you may need to find a better way of achieving
the same goal — for example, writing into an ID which stores
the headlight relay status rather than writing a message ID that is
used to report the current headlight switch position. The
UDS Writes guide covers this distinction
in detail (Service $2F IOControlByIdentifier for momentary I/O
actuation, Service $2E WriteDataByIdentifier for persistent
configuration data).

[ Safety — what's likely vs what's possible ]

Deploying the airbag / bricking your vehicle

Someone might tell you that working on your vehicle's CAN bus is
dangerous because you could accidentally deploy the airbag. Sure
enough, the Occupant Restraint Controller (the module responsible for
the airbag) is connected via the CAN-C network. And its exact command
set is unknown.

Given what we know about airbags in general, and given what we know
about the Wrangler's use of additional data protection for its more
critical functions, it seems unlikely that you'd trigger the airbag by
accident. But no, the chances are not mathematically zero.

If you are concerned, there are a number of ways you can make this
outcome even more unlikely:

    - Don't send any messages at all -- only read existing data from
      the bus (listen-only on).
    - Restrict yourself to sending messages with IDs that are
      well-understood (and not in the protected CAN-C-below-$0100 set).
    - Avoid any program which constantly crafts random messages in an
      attempt to provoke a new response from your vehicle.

It's a best practice to avoid randomly probing your vehicle like that.
Sure, you may not deploy an airbag, but you're far more likely to brick
a component or brick your entire vehicle altogether. Don't do that.

Shorting the CAN bus

What happens in the unlikely event that you might short the CAN bus
(or pull off one of the two bus wires, or short the CAN bus to ground,
or brush a +12VDC line across it... those sorts of things)?

While none of those conditions are desirable, the Wrangler's CAN bus is
designed to continue operating through those very conditions, but not
without a slap on the wrist. It's likely that you'll throw an engine
code which documents exactly what you did. Unless you've actually cut
one of the wires, no permanent damage should have been done.

While working on the CAN bus, if you ever do see any strange messages
on your dash about a loss of communication with any module, that may
be a good time to turn off your engine and figure out what you're
doing wrong. If you can't turn off your engine, then unplug the power
from your Raspberry Pi.

[ See also ]