[ 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.
