CCP / XCP on CAN Explained - A Simple Intro [2023]

CAN Calibration Protocol CCP XCP on CAN

Need a simple intro to CCP/XCP on CAN bus?

In this practical tutorial, we introduce the basics of the CAN Calibration Protocol (CCP) and the Universal Measurement and Calibration Protocol (XCP) on CAN. In particular, we'll focus on the CCP/XCP frame structures, trace examples and A2L files.

We also cover practical ECU data logging via polling/DAQ - and how to decode the data.




What is CCP/XCP?

The CAN Calibration Protocol (CCP) is an interface that enables read/write access to an Electronic Control Unit (ECU). It enables calibration, data measurement, flashing and more.

The Universal Measurement and Calibration Protocol (XCP) is the successor to CCP with various improvements - including support for more transport layers such as Ethernet, FlexRay and SxL.

The CCP/XCP protocols have extensive overlaps, but also important differences. To avoid confusion, we will first focus on covering the CCP protocol - and subsequently go through XCP on CAN with explicit clarification on important differences.

CAN Bus Calibration Protocol Data Logger



Record ECU signal data via CCP XCP on CAN

To understand the motivation for CCP/XCP, let's revisit our simple intro to CAN bus. As explained here, CAN enables communication of data between different ECUs in a vehicle/machine. Inputs and outputs of every ECU will be broadcast on the CAN bus. However, the inner workings of an ECU is a blackbox.

Here, CCP/XCP provides direct access to the inner workings of an ECU. This lets you request high-frequency parameter data that may otherwise only be known to the ECU. Further, it also lets you modify the ECU algorithms and variables, making it easy to test and calibrate ECUs. Importantly, CCP/XCP enables these interfaces in a standardized way across ECU manufacturers.

History of CCP/XCP

The CAN Calibration Protocol (CCP) was originally developed by a calibration systems company, Helmut Kleinknecht. Within a few years, it was improved by a working group, ASAP (Arbeitskreis zur Standardisierung von Applikationssystemen) that included Audi, BMW, VW and others. Later ASAP was renamed to ASAM (Association for Standardization of Automation and Measuring Systems).

Below are the key milestones:

  • 1992: CCP 1.0 initial release by Helmut Kleinknecht
  • 1995: CCP 1.01 standardized by ASAP
  • 1996: CCP 2.0 released by ASAP
  • 1998: Drafts of CCP 2.01 and CCP 2.1 were prepared
  • 1999: CCP 2.1 was released in February
  • 2003: XCP 1.0 incl. support for CAN, Ethernet, SPI, USB
  • 2008: XCP 1.1 incl. support for FlexRay
  • 2013: XCP 1.2 incl. ECU description file updates + CAN FD
  • 2015: XCP 1.3 incl. ECU states, bypass handling, time correlation
  • 2017: XCP 1.4 incl. Improvements and new DAQ mode
  • 2017: XCP 1.5 incl. software debugging without a debug adapter

Today, XCP (aka ASAM MCD-1 XCP) is the successor to CCP (aka ASAM MCD-1 CCP). However, in practice many ECUs still use CCP, which makes it relevant to understand both protocols and key differences.

CCP XCP on CAN bus
CCP XCP on CAN Bus History Timeline


CCP XCP Master Slave Hierarchy Architecture

Master-slave architecture

The CCP/XCP protocol is based on a single-master/multi-slave concept. An external measurement & calibration tool (e.g. a PC/device/data logger) serves as the master and is able to read/write from one or more ECUs aka slaves.

The interface between the master and slave is called ASAP1 or ASAM MCD-1. The CCP/XCP standard also describes the ASAP2 or ASAM MCD-2 MC interface between the master and an ECU description file. In practice, this database describes all relevant information about an ECU in a standardized file format called A2L (ECU Description Files) - which we will cover shortly.

CCP/XCP use cases

The CCP/XCP protocol enables multiple use cases:

  • Plug & play ECU measurement and calibration
  • Recording of ECU data at microsecond resolution
  • Access to data internal to the ECU (not broadcast on CAN)
  • Measurement via polling or based on events (time, triggers)
  • Real-time calibration/adjustment of ECU algorithm variables
  • Flash programming of ECUs
  • Optional authentication for secure access
  • Mainly for OEM development - rarely used post production
XCP on CAN bus data measurement



CAN Calibration Protocol vs XCP transport layers

Major changes in XCP vs. CCP

  • XCP adds support for CAN FD, Ethernet, FlexRay, SxL and more
  • Less interpretation - more consistent implementations
  • New 'stimulation' (STIM) mode for bypassing ECU calculations
  • Predefined/dynamic DAQ lists for efficient communication
  • Support for synchronous use of different DAQ modes
  • ECU auto detection (master can poll slaves for information)
  • More precise data acquisition by measuring ECU timestamps
  • More data throughput via new optional commands



CCP/XCP vs. UDS

Before we deep-dive further on CCP/XCP, it can be useful to understand the role of these communication protocols vs. a slightly similar protocol, Unified Diagnostic Services (UDS).

As evident from the illustration, CCP/XCP is designed specifically for pre-launch measurement and calibration by the OEMs. Typically, the CCP/XCP access to ECUs is disabled once vehicles are ready for launch. In contrast, UDS is typically not available in early stage prototype development and only later added - also being available for communication post launch.

UDS focuses on diagnostics, whereas the diagnostics capabilities of CCP/XCP are light-weight. UDS may also be used by e.g. field technicians and in OEM specific scan tools.

The two protocols do share similarities, though - e.g. in their support for polling/cyclic data acquisition, ECU flashing and read/write access by address (CCP/XCP) or ID (UDS).

CCP vs UDS differences comparison




CCP message types

To understand how CCP communication works we will first review the CCP message types.

Overall, CCP communication is done through a request/response logic - similar to what is used in OBD2, UDS etc. This communication consists of two types of messages: The Command Receive Object (CRO) and the Data Transmission Object (DTO).



CRO - Command Receive Object

The Command Receive Object (CRO) is a CAN frame sent by the master to an ECU. The 1st byte of the data payload is the command byte (CMD). This controls what command is being issued by the master to the ECU as per the table overview.

CCP CRO Command Receive Object CAN bus frame

To track the commands issued, the 2nd byte is a counter (CTR). It is indented by +1 for every command sent by the master and is mirrored in the response from the slave ECU. The remaining 6 bytes depend on the command.


For a list of CRO commands used in CCP, see below table.

CCP CRO Command CMD table



CCP CAN frame identifiers

In CCP, two CAN identifiers are used: One for messages sent by the master (e.g. 0x701) and one for messages sent by the slave (e.g. 0x702). These identifiers will be specified as part of the A2L (aka ECU Description File), meaning that the master will acquire this information prior to initiating the connection.

Typically low priority IDs are used for CCP to avoid disturbing safety critical info on the bus.

Importantly, this means that the master does not target specific ECUs through various CAN IDs - but rather through a connection sequence as shown below.

CCP CAN bus identifier addressing


Example: CCP CRO CONNECT message

Below is an example of a CRO used for initializing communication with a specific ECU:

CCP Trace Example CONNECT CAN message

Here, the CAN ID reflects the ID used by the CCP master for communication. The 1st byte is 0x01, corresponding to the CONNECT command as evident from the previous table. The 2nd byte is the CTR value. The 3rd and 4th bytes are specific to the CONNECT command and correspond to the target ECU's station address in INTEL byte order. In other words, the above CRO is used by the master to establish a connection with ECU 0x0139. All subsequent communication will in this case be with this specific ECU until the master terminates the connection or connects to another ECU.



DTO - Data Transmission Object

The Data Transmission Object (DTO) is a CAN frame sent by the ECU to the master. Three types of DTOs exist as outlined below:



#1 CRM-DTO: Command Response Message

The CRM-DTO is sent by the ECU in response to a CRO from the master. Here, the CAN ID reflects the CAN ID used by the ECU (e.g. 0x702).

The data payload for the CRM can be broken down as follows:

  • The 1st byte is the Packet Identifier (PID). For the CRM-DTO, the PID always equals 0xFF
  • The 2nd byte is the error code (ERR), which can be used to e.g. inform the master of an invalid request.
  • The 3rd byte is the counter (CTR), which will match the CTR value from the master's CRO
  • The structure of the remaining 5 bytes depend on the original request made in the CRO
CCP CRM DTO Command Response Object

Below is the previous connection example trace, including a positive response CRM.

CCP CRM-DTO CONNECT OK Trace

The trace shows a connection to the ECU with station address 0x0139, which responds to the initialization command sent by the master. As evident, the 1st byte is 0xFF (as the message is a CRM). The 2nd byte shows that no errors occurred, while the 3rd byte matches the CTR of the CRO. With this sequence, the connection between the master and ECU 0x0139 is established.


In the table below we show a set of CRM-DTO/EV-DTO error code values.

Note that error codes can be sent in both CRM-DTOs (if they happen in direct response to a CRO from the master) or in EV-DTOs (if they happen asynchronously to the master's CRO commands).

CCP CRM DTO Table EV ERR



#2 EV-DTO: Event Message

The EV-DTO is sent by the ECU in response to an internal event causing a status change in the ECU. This can be used to inform the master of errors that occurred since the last CRO.

The structure of the EV-DTO is identical to the CRM-DTO from before, with the EV PID always equal to 0xFE. Note that the CTR does not have relevance for EV-DTOs.

CCP EV DTO Event Message Frame


#3 DAQ-DTO: Data Acquisition Message

The DAQ-DTO is used by the ECU to automatically send data to the master in response to a specific event (e.g. a cyclic counter, a button or similar).

In DAQ communication, the master starts out by 'configuring' the ECU for a specific measurement sequence. Once initiated, the ECU will output DAQ-DTOs without further CROs from the master.

In the DAQ-DTO the PID is a reference to an 'Object Descriptor Table' (ODT), while up to 7 bytes carry data related to the ODT. More on this shortly.

CCP DAQ DTO Data Acquisition Frame

Below is an example of a DAQ-DTO message sent by an ECU to a master.

DAQ DTO trace frame example CAN bus

The trace shows the DAQ-DTO communication from a slave following an initial configuration sequence. The data relates to ODT list #37 (0x25) with a payload of 5 bytes. Note how we do not pad the unused bytes (as this is not required for DAQ-DTOs). Note also how a new CAN ID is introduced for this DAQ response (more on this later).


CRO, CRM-DTO and EV-DTO messages must have a payload length of 8. Any unused bytes are padded with arbitrary values (we use 0xAA in this intro). DAQ-DTO messages may use the actual payload size.


To recap: A master tool uses CRO messages to send various commands to a slave ECU. The slave ECU can in turn use DTO messages to respond to the master. Next we'll show how data measurement can be done via these messages.





How to record ECU data via CCP

Let's imagine that you're an engineer working at an automotive OEM. You've been tasked to extract the value of a specific parameter from an ECU over an extended period.

How do you do it? In the following sections we outline two methods: Polling and DAQ.


Data acquisition via CCP polling

The simplest solution would be to use a CCP measurement concept called polling.

Below we illustrate how such a communication flow may look:

CCP Polling CAN Bus Data Logging ECU

Here, the master sends a request to the slave for 0x04 bytes of data stored at the 'source address' 0x12345678. The 4th byte is 0x00, which reflects the 'address extension' for this ECU source address, which can e.g. reflect a specific memory segment.

The slave responds with the 4 bytes of data, 0xF12A712F, for this particular source address.

This above flow can be used to e.g. extract real-time parameter data, such as an RPM signal. It's somewhat similar to how you can request RPM via an OBD2 request/response flow in most cars.

Effectively, 'polling' is simply a sequence of CRO/CRM-DTOs with the master using a command called SHORT_UP (short upload).

CCP polling ECU signal data


Pros & cons of CCP polling

Polling is simple to set up - simply establish an ECU connection and send the correct request message every X ms. For many practical use cases this can be a perfectly viable solution.

However, polling has two significant downsides.



#1 Polling is inefficient

Polling requires a request message for every response. If you e.g. need to measure a 2-byte signal at 100 Hz, that increases the busload by 200 frames/second.

The inefficiency is both due to the need for requesting every single response - but also the fact that response messages are forced to be 8 bytes long, with 3 bytes spent on overhead.

CCP Polling Busload Issue


#2 Polling is asynchronous

When polling for multiple signals, the request/responses need to be sent sequentially with a small delay between each request.

As a result, the signal observations are not time synchronized. This makes data analysis and post processing more difficult and less precise.

CCP Polling Asynchronous Signal Data Issue


CCP DAQ measurement synchronous signal data

Data acquisition via CCP DAQ

CCP offers an alternative data measurement technique called DAQ (Synchronous Data Acquisition). DAQ is a bit more complex to initiate, but solves both the downsides of polling.

In simple terms, DAQ works as follows:

The master specifies what measurements to record from the slave, as well as what event should trigger the communication of data. For example, the master could request that signals A and B are broadcast every 10 ms, while signal C may be broadcast every 100 ms. The master can even configure slaves to broadcast signals based on events such as a button push or angle change.

Once the DAQ configuration is complete, the master 'starts' the sequence and the slave now autonomously broadcasts the requested signals using DAQ-DTO messages.

This eliminates the request messages from the master. In addition, the signal data is packaged more efficiently in the DAQ-DTOs vs. the CRM-DTOs, reducing the busload.

Further, with DAQ it is possible to package related signals in the same DAQ-DTO frames - ensuring that the requested signals are measured in a time synchronous manner - improving the quality of the data for analysis.



How to configure a DAQ sequence

In order to use the DAQ mode for data measurement, the master has to first configure the ECU accordingly.

In practice, this process is typically handled by sophisticated GUI tools (more on this later). However, to fully understand what is going on we'll review what happens 'under the hood'.

Two concepts are key in DAQ: Object Descriptor Tables (ODT) and DAQ lists.



Object Descriptor Table

The Object Descriptor Table (ODT) is a list of references to data elements from the ECU memory.

If we take the 'short upload' example used in CCP polling, the master sends a request specifying three elements: The data length (in bytes), address extension and source address. With this info, the ECU finds the data and sends it to the master.

The concept of an ODT is similar:

An ODT is simply a list of element references. Each entry in the ODT reflects an ECU source address - and optionally also an address extension and data length. In other words, an ODT entry contains the same info that we used to poll a signal.

CCP XCP Object Descriptor Table DAQ

Let's take an example:

We wish to record 7 signals, each of them with a length of 1 byte. To do so, we define a new ODT #0 (PID 0x00) with 7 element entries. Element 1 refers to signal 1 with a specific ECU source address. Element 2 refers to signal 2 with another source address etc.

When we use the DAQ mode for data measurement, we can now refer to ODT #0 in order to get the ECU to provide us with time synced data on all 7 signals - within a single DAQ-DTO CAN frame. In other words: The ODT we defined describes the structure of a DAQ-DTO message, meaning that the ECU will now know how to package the 7 signal bytes in a single CAN frame - and the master knows how to extract the 7 signal bytes from that CAN frame.

Notice the impact on the busload: If we were to poll all 7 signals, it would require 14 CRO/CRM-DTO CAN frames per cycle - now it only requires 1 DAQ-DTO CAN frame.

Further, we can easily plot these 7 signals together as they share the same CAN frame timestamp - making it much easier to perform analysis. For the same reason, ODT lists are typically defined so as to group related signals together.

In practice, a master will often define multiple ODT lists and assign PIDs for each of them in the range of 0x00 to 0xFD. Each ODT then defines the structure of a separate DAQ-DTO.



DAQ lists

When working with multiple ODT lists, it's useful to group them together. These groups of ODT lists are referred to as DAQ lists. For example DAQ list #0 may contain ODT #0, ODT #1 and ODT #2.

CCP DAQ lists ODT

A DAQ list is characterized by the way in which the data is sampled:

  • DAQ list #0 may be set up so that all DAQ-DTOs within it are sampled every 10 ms
  • DAQ list #1 might be configured so that DAQ-DTOs in it are sampled when a button is pressed
  • ...

In other words, a separate DAQ list is required for each unique sampling logic requested for the data measurement.

We will describe the DAQ and ODT initialization shortly, but first consider below example trace for an already initiated DAQ sequence:

CCP DAQ trace example multiple lists

In this example, the target ECU is broadcasting data across three ODT lists in total, as evident from the 1st bytes spanning from 0x00 to 0x02. While it's not explicitly clear from the trace, the three ODTs are split into two DAQ lists: One DAQ list contains ODT #0 with a sampling frequency of 10 ms - while DAQ list #1 contains the remaining ODT lists #1 to #2 with a sampling frequency of 100 ms. This is why the DAQ-DTO with PID 0x00 is observed more frequently in the trace vs. the other DAQ-DTOs.



How to initialize a DAQ sequence

We've now looked at both the ODT and DAQ lists - but how do we define these over CAN?

In simple terms, the configuration of DAQ lists is done through a (potentially long) sequence of CRO/CRM-DTO frames. Here, the master essentially specifies the entire DAQ/ODT/element structure element-by-element. To define a new signal (aka element), the master specifies the address, length and address extension. Next, the master informs informs the ECU how to package the element in DAQ-DTOs by linking the element to an ODT# and DAQ#.

To understand this in detail, see below trace example and subsequent explanation:

CCP DAQ initialization sequence trace example

So we have quite a bit going on here, but let's break it down:

We start by using the CRO command GET_DAQ_SIZE. This has two purposes: It informs us about the size of the specified DAQ list in terms of ODT lists - and it clears the current list. Essentially, this works like a 'reset' command for the DAQ list, in this case DAQ list #5.

As part of the GET_DAQ_SIZE command we also provide the 11-bit CAN ID 0x712 in the last 4 bytes. This informs the ECU that it should use CAN ID 0x712 to broadcast the subsequent DAQ-DTOs. This is subtle, but an important aspect: Essentially, the master is able to specify the CAN ID for every DAQ list, which in turn also enables the master to initiate DAQ measurement across multiple ECUs in parallel.

The ECU confirms the CRO from the master and informs us that the DAQ list #5 has 3 ODTs with the first PID being 0x07.

Next, the master starts populating DAQ list #5 and ODT list #7 with the source address information for 7 x 1-byte signals. This is done through a simple loop consisting of 7 repetitions of two commands: SET_DAQ_PTR and WRITE_DAQ.

First, the master uses SET_DAQ_PTR to "select" DAQ list #5, ODT list #7 and element #0 of the ODT list. Next, the master uses WRITE_DAQ to write the contents of this element reference: A length of 1, an address extension of 0 and a source address of 0x00001000.

Basically, we have now told the ECU to "package" the value of our 1st signal (which is stored in the specified source address) into the 2nd byte of the DAQ-DTO that corresponds to DAQ list #5 and ODT list #7 (the 1st byte of the DAQ-DTO being the PID 0x07).

After this, we repeat the process for the remaining 6 signals until the ODT #7 has been completed.

In this simplistic case we only care about this particular DAQ and ODT list. Therefore, the final step is to start the DAQ measurement via the START_STOP command. Here, we specify that we wish to start DAQ list #5 and ODT list #7. As part of this, we specify the timing parameters, namely that event channel 0x03 should be used with a prescaler of 10. The ECU specific event channel details are specified in the ECU description file.

As evident, the ECU will now start broadcasting data from DAQ list #5 and ODT list #7 at the specified frequency. The CAN frame payloads include the ODT PID 0x05 in the 1st byte and the 7 'element' signal values in the remaining payload.

Note also that you can alternatively use the START_STOP command to 'prepare' multiple DAQ lists and ODT lists for measurement and then use the START_STOP_ALL command to simultaneously start or stop all of them.



How to disconnect from an ECU

Once the data acquisition has completed, the master may disconnect from the ECU via the DISCONNECT command.

Let's look at an example trace:

CCP disconnect from ECU trace

Here, the 3rd byte 0x01 means that we end the session entirely (in contrast to a temporary disconnection). This effectively resets the ECU including our previous configuration. To target the specific ECU of interest, we specify the station address (Intel format) of the ECU, i.e. 0x702.

As evident, DAQ is more convoluted to set up - but enables efficient time synced communication of ECU data.





Decoding CCP signal data from ECUs

In CCP polling/DAQ, you are in practice recording raw CAN frames with specific signal encoding structures.

In order to make sense of the recorded data, you need to decode it to human-readable form aka physical values. This is the same concept as we've explained in several other CAN-related intros, incl. our intro to CAN bus, J1939, OBD2 and DBC files.

However, CCP decoding involves some extra complexities that we will explain below.



Decoding CCP polling data

Let's review an extended version of the CCP polling request/response from before:

CCP polling DBC decoding

This reflects a decoding challenge: The ECU sends different signals with the same CAN ID - with no way to identify them in the payload.


In the above example, the master is requesting two different 4-byte signal values from the ECU, namely from source addresses 0x12345678 and 0xABCDEF00. In both cases, the ECU responds with CAN ID 0x702.

In most CAN bus decoding scenarios, you would be able to simply lookup the response CAN ID and find the 'start bit' and 'bit length' of a given signal to extract the raw data from the payload.

However, that is not possible here as the ECU uses the same CAN ID across two different signals. In other words, the CAN ID is not sufficient to distinguish between the signal coming from 0x12345678 and the one coming from 0xABCDEF00.

To some extent, this is similar to how OBD2 responses from an ECU use the same CAN ID (typically 0x7E8) across different signals like speed and RPM. In the case of OBD2 we can, however, easily solve this because the OBD2 PID (Parameter Identifier) is included in the payload. Together with the CAN ID, this serves as a unique identifier within the response frame - enabling us to view the response as a case of multiplexing.

We cannot directly do this in CCP polling because the response payload does not include the ECU source address. In other words: In use cases with multiple CCP polling signals we need to combine information from the request & response message.


In simplistic terms, we can solve this by "repackaging" the payloads as follows:

CCP polling reassembly reconstruction frame trace

By doing so, we can process this using multiplexing logic - similar to how we handle OBD2 and UDS decoding. Here, the CAN ID to look up is 0x702 and the multiplexor is found in the 5th to 8th byte, while the signal value is found in the 12th to 15th byte. Two separate decoding rules can now be specified, with the relevant one dependent on the value of the 4-byte multiplexor.

In practice such a reconstruction of CAN frames can be done in e.g. a Python script, assuming the CAN trace includes both the request and response data. Once the CAN frames are reconstructed, it is possible to use DBC files for decoding the data via multiplexing. Alternatively, the data can be loaded into a software tool supporting CCP/XCP decoding directly.



Decoding CCP DAQ data

Let's briefly review a snippet of the post-initialization DAQ trace from before:

CCP DAQ DBC decoding example

As evident, the DAQ-DTO messages have a pre-specified CAN identifier (0x712 above) and a payload in which the 1st byte equals the ODT list identifier aka ODT PID (0x07 above). As a result, it is not necessary to "combine" the DAQ-DTO response frames to uniquely identify which frames contain which signals - this can directly be identified through a combination of the CAN ID and the ODT PID.

This fact makes the decoding of DAQ-DTO messages simpler than the polling messages. In fact, you can directly create a DBC file with multiplexing as long as you know the signal encoding in the remaining bytes of each ODT list.


In most practical applications, it is reasonable to assume that you will know this signal encoding. This is because the master itself controls (via the initialization sequence) how to package each signal into the DAQ and ODT lists, as explained in the previous section.

For example, we know that the DAQ-DTOs with CAN ID 0x712 and ODT PID 0x07 contain the signal with source address 0x00001000 in the 2nd byte - because that is how we packaged it during the initialization. From the ECU description file we can then review how to interpret this 1-byte signal value. The description may state that this signal is a temperature measured in degC and it should be multiplied by a factor of 0.8 and offset by 20. If you're familiar with DBC files, you'll note that such information can easily be entered into a DBC, allowing for quick decoding of the trace data in most CAN software tools.

Naturally, if the master changes the initialization to package the data differently on another test run, the implication will be that the DBC file must be updated accordingly.



The above should make it clear that CCP polling/DAQ can be treated within the normal logic of CAN bus frame decoding - though both involve some tweaks. DBC files can be used to process the data - but this format is not the most common choice for working with CCP data. Below we explore another file format that is generally used, the A2L or ASAP2 format.





A2L - ECU Description Files

In the prior sections, we've occasionally referred to "ECU description files". An ECU description file contains everything a master tool needs to know to communicate with an ECU. From a data measurement perspective, this includes information on CAN identifiers, available signals, signal decoding rules, DAQ/ODT information etc.

In practice, the ASAP2 description format (*.A2L) is used to structure this information. The ASAP2 data definition was standardized by ASAM in the ASAM MCD-2 MC, with the first version 1.3.1 being released June 15 1999, i.e. the same year that the CCP 2.1 standard was released. The latest version of the standard, 1.7.0, was released in 2015.

You can view an example A2L file here.

A2L ASAP2 ECU Description File

In practice, the A2L file is used to "configure" the master device, enabling communication with the ECU. For example, in our previous examples we used the CAN IDs 0x701 and 0x702 for the CRO/DTO communication between the master and ECU. These IDs would be specified in the A2L file.

The A2L file also describes how signals are stored in the ECU and how to decode them. See e.g. below snippet from the A2L example file:

A2L example signal

As before, we can compare this to the logic of signal encoding in other CAN protocols and in DBC files. The 'MEASUREMENT' tag is used to envelop the description of a measurement signal, in this case Airflow. It has a detailed description and a min/max defined by the lower/upper limit.

The signal also has a 4-byte source address, 0x40000144. If we recall the CCP polling outline, this source address could be used in a SHORT_UP command polling sequence to request the raw value for this particular ECU signal. Similarly, in the context of DAQ measurement, this source address would be used in the initialization process. In other words, an engineer can lookup the signal of interest (Airflow) in a A2L file or A2L GUI tool - and configure his master tool to request this.

Assuming we've now recorded a trace of raw values, we'd need to decode the information. As explained before, the first step would be to extract the raw bytes from the response payload - and the method for doing this will depend on whether we're using polling or DAQ measurement. Further, the byte ordering is not specified by the CCP protocol - but will be specified within the A2L file at a global or signal level.



Once we've extracted the signal bytes and converted them to decimal form, we need to know how to convert them.

In the DBC file context, this would always be done in the form of a 'linear' equation, i.e. y = bx + c, where b equals a scale factor and c equals an offset - both specified in the DBC file for each signal.

In contrast to DBC files, the A2L files allow for more complex conversion methods. As evident from the signal description, it refers to a conversion rule defined as "CompuMethod_6". We can look this up in another section of the A2L file:

CCP A2L ASAP2 description example

As outlined, this conversion rule uses a conversion type called RAT_FUNC. This is one of multiple supported conversion types and is defined as below:

y =(axx + bx + c)/(dxx + ex + f)

As evident, the rational function is a more sophisticated version of the linear function used in DBC files. In particular, it supports 5 coefficients, which need to be specified in the computation method. Above, they are set to 0 1 0 0 0 1, meaning the function simplifies to below:

y = x

In this simple case, the rational function simplifies to a linear function, similar to the one used in DBC files. A2L files in fact also support another conversion type, LINEAR, which is simply y = ax + b. In the case of the Airflow signal, this could have been used instead.

Finally, the unit is also specified in the measurement details, meaning we can now plot the Airflow physical value as measured in kg/s.

The Format field is %6.2, which should be read as %Length.Layout, with Length reflecting the overall length of the decoded signal and Layout reflecting the number of decimal places.


As is probably clear, one does not normally look through the A2L file via a text editor. Rather, the A2L file is simply loaded in a compatible tool (e.g. a PC GUI tool with a connected CAN interface, or a CAN data logger). This then allows the engineer to use the tool to perform the relevant measurement from the ECU without having to understand the A2L file structure and syntax.


This particular signal is simplistic enough to be described within the restrictive DBC file format - but A2L files clearly allow for more complex decoding rules. For more details on A2L file format, see the ASAM MCD-2 MC standard, as well as a practical overview.






Seed & key authorization

As explained previously, CCP communication is typically used by automotive OEM engineers to facilitate communication with ECUs in pre-production applications.

In some cases all it takes to communicate with an ECU is the A2L file and a suitable CAN tool. As evident, one can also simply extract a subset of the A2L file to configure a device e.g. for measurement of specific signals. However, without the A2L file, it's practically impossible to perform communication and hence many OEMs do not require any additional security measures beyond keeping the A2L file under lock.

However, some use cases warrant additional security.

CCP seed and key authorization unlock

CCP supports this via a concept called 'seed & key' authorization. Here, the master requests a random seed from the ECU as part of the initialization of the ECU communication. The master receives the seed from the ECU and uses it as input for an internal security algorithm to calculate a key. The master then sends the key to the ECU via CAN - and if it matches the key calculated internally by the ECU, authorization is provided for further communication.

Below is an example trace for such a communication:

CCP seed and key trace example CAN bus

In this example, the master requests the seed via the GET_SEED command 0x12, specifying a 'resource mask' of 0x02 in the 3rd byte. The resource mask references the level of access requested - with 0x02 being DAQ access only (see the CCP 2.1 standard for details).

The ECU responds with a frame in which the 4th byte is 0x01, implying that DAQ access is protected (in contrast to 0x00 which would imply that authentication would not be required). The ECU provides the requested seed in the remaining 4 bytes.

Based on the seed, the ECU calculates the key and provides it via the UNLOCK command, 0x13. The key is in this case 4 bytes long. The ECU responds positively including the requested resource mask 0x02, meaning that DAQ access is now unlocked.


The most common implementation of the security algorithm is via a *.dll file, since the master device is frequently a Windows PC with a GUI tool and a CAN interface. The use of a *.dll file also enables standardization across CCP tools, while eliminating the need for the master tool to know the underlying algorithm used.

It is, however, challenging to use *.dll files in standalone CAN bus data loggers and telematics devices (as they do not run Windows), hence some companies use alternative solutions - e.g. proprietary file formats better suited for embedded devices.





XCP on CAN - the basics

We have now gone through the basics of CCP. Next, we'll consider XCP on CAN with focus on frame structures.


The XCP packet

To understand the structural changes in XCP on CAN vs. CCP, consider below comparison of the CCP CRO/DTO and the XCP CTO/DTO. As evident, XCP packets include the XCP CTO (with a similar role as the CCP CRO and CRM-DTO) and the XCP DTO (with the XCP DAQ-DTO playing a similar role as the CCP DAQ-DTO).

CCP XCP CAN bus frame comparison CRO DTO CTO DTO

An alternative way to illustrate the role of the CCP vs. XCP messages is via below architecture comparison:

CAN Calibration Protocol CCP Architecture
XCP on CAN Universal Measurement Calibration Protocol

We will cover the XCP on CAN message types in more detail below.


XCP CTO - Command Transfer Object

In XCP on CAN, the CTO is a CAN frame for transferring control commands, incl. commands (CMD), command responses (RES), errors (ERR), events (EV) and service requests (SERV).

In contrast to the CRO in CCP, the CTO is used by both the master and ECU. Note also that a CMD packet from the master must be answered with a RES or ERR packet from the ECU, while the other packet types are sent asynchronously.

If we look at the CTO payload, the 1st byte reflects a Packet Identifier (PID). The remaining 7 bytes in an XCP on CAN CTO payload consists of data, specific to the type of CTO packet.

If we compare this structure to the CRO of CCP, it's similar, except for the exclusion of the command counter byte in XCP.


XCP communication requires at least two CAN bus identifiers: One for the master (e.g. 0x551) and one for the ECU (e.g. 0x552). If the master needs to communicate via XCP with more than one ECU, an additional set of identifiers will be required.


XCP CTO Command Transfer Object


XCP CTO PID list table

The actual values of the CMD byte across XCP and CCP differ as well. For example, CCP uses 0x01 for the CONNECT command, while XCP uses 0xFF. See also the table overview for the assignment of CTO PIDs depending on whether messages are sent from the master or slave.

See also below comparison of CCP vs. XCP CMD codes:


The below table compares a subset of the command codes between CCP and XCP:

CCP XCP Command Table Comparison CMD


Example: XCP CTO CONNECT message

As in CCP, let's look at how a CONNECT sequence may look in XCP on CAN:

XCP on CAN trace example CONNECT

Note that the example does not use the 0xAA padding, as this is optional in XCP on CAN.

In the trace, the master sends a CONNECT CMD (0xFF) to the ECU with the communication mode set to normal (0x00). Note that, in contrast to CCP, the master does not need to specify a station address in the payload of the CONNECT frame. This is because the CAN identifiers already uniquely identify which ECU the master is communicating with.

The ECU responds with a CAN frame in which the 1st byte equals the positive response PID (RES). The 2nd byte is the resource availability, similar to the seed & key CCP communication with 0x04 e.g. meaning that DAQ is available. The 3rd byte relates to the 'communication mode' (here 'optional'), while the 4th byte is the maximum CTO size (here 8 bytes). The 5th and 6th byte equal the maximum DTO size (here 8 bytes), while the 7th and 8th bytes equal the XCP protocol layer version and transport layer version respectively (both 1 in this case).



Example: XCP Polling

With a connection established, the master can e.g. initiate polling. As in CCP, this can be done via a SHORT_UPLOAD command:

XCP on CAN bus polling trace example

Here, the master sends a SHORT_UPLOAD CMD (PID 0xF4) for 2 bytes of data. The 3rd byte is reserved, while the 4th byte of the CTO is the address extension (in this case 0). The remaining 4 bytes equal the source address 0x12345678 (INTEL byte order).

In response to the command CTO, the ECU sends a response CTO with the value of the 2 bytes of data.



XCP DTO: Data Transfer Object

The XCP DTO is used for sending synchronous data. In particular, the DTO is used in DAQ measurement (similar to the role of the DAQ-DTO in CCP). In XCP, it also enables the transfer of 'stimulation' (STIM) data that can be used in bypassing the normal algorithm within an ECU. Stimulation and bypassing are topics that we will not cover here.

We will also not go into detail on the XCP DAQ measurement as it's similar in concept to CCP DAQ.

XCP on CAN DTO DAQ frame example
XCP DAQ DTO frame timestamp CAN bus

The XCP DTO timestamp

One important thing to note about XCP DAQ measurement, however, is that it enables the ECU to write the measurement time in the XCP DTO packets. The implication is that the master is able to correctly sync ECU data split across multiple frames by utilising the ECU measurement timestamp, rather than the master's own internal timestamp.

The XCP DTO timestamp is optional and is implemented as an incrementing counter, with the incrementation logic specified in the A2L file. If a timestamp is to be included for a specific DAQ list, it will be written into the 1st ODT list (but not subsequent ones if more ODT lists exist within the same DAQ list).


It is also worth noting that multiple methods exist for packing the DAQ list # and ODT list # information in the DAQ DTOs. The simplest case is 'absolute ODT numbers', where the ODT list # is unique across all DAQ lists. Here, the PID (i.e. ODT #) is sufficient for globally identifying an ODT list.

Another method exists, however, where relative ODT list numbers are used across DAQ lists. Thus, you could e.g. have two ODT lists with PID = 0x00, meaning that they cannot be uniquely identified as the CAN ID is identical across the two DTOs. Here, a 1 or 2 byte DAQ list identifier can be added in the 2nd to 3rd bytes of the CAN frame payload. With this, one can again uniquely identify a specific ODT list.

The A2L file and ECU will provide information on what method is used.


A 1-byte counter field may optionally be used in the communication of XCP DTOs. If a CTR field is used in XCP DTO DAQ packets, the slave will only insert the value of the CTR in the 1st frame of a DAQ list, i.e. in the 1st ODT list.


CCP/XCP of course contain numerous more topics that we have not taken the time to discuss here. Deliberately, we've focused on the basic topics and concepts related to data logging. However, below you'll find useful links for further reading.





Using the CANedge for CCP/XCP data acquisition

The CANedge is a series of low cost, compact 2 x CAN/LIN bus data loggers. The CANedge is commonly used by automotive OEMs - and for this reason a frequently asked question is whether the device supports CCP/XCP on CAN communication.

The answer to this is 'yes, depending on your use case'. For details, see below.

If you wish to use the CANedge for CCP/XCP on CAN, contact us.


As we've seen in the previous sections, all it takes to facilitate CCP/XCP polling and CCP/XCP DAQ measurement is to be able to transmit a specific sequence of CAN frames, based on information that can be identified from an A2L file.

As long as you know how to construct the request frames, you can use the CANedge transmit functionality to set up a list of single-shot or periodic custom CAN frames to e.g. achieve the CCP/XCP initialization and CCP/XCP polling/DAQ measurement. The recorded MF4 log files with measurement data can then be processed in e.g. Vector tools or via our free open source software solutions. In the former case, you could e.g. use our MF4 converters to get the data into Vector tools and use A2L files for decoding the data. In the latter case, you could process the data via our Python API (for polling) and/or via asammdf. These tools would currently require creating a DBC file with the decoding rules as explained previously.

In other words, you can use the CANedge to measure signal data via CCP/XCP on CAN in standalone field deployments, which offers a low cost method for collecting this information at scale.

In contrast, standalone CAN bus data loggers are not ideally suited for CCP/XCP calibration, except for very specific use cases such as remote calibration of variables via over-the-air updates.


The CANedge does not currently support seed & key authentication, so OEMs intending to use it for CCP communication would need to temporarily disable the authentication or to unlock it using a separate device.

We are, however, potentially going to add support for this later on. If you have use cases that involve this functionality, feel free to contact us for further discussion.





CCP/XCP data logging - applications

In this section we provide brief examples of how CCP/XCP data logging may be useful in practice.

CCP/XCP telematics for prototype vehicle fleet

As an OEM, you may need to collect e.g. CAN, CAN FD or LIN bus data from prototype vehicles in the field. In addition, you may need to collect specific data internal to an ECU, which can only be measured via CCP or XCP on CAN. Here, a CAN logger like the CANedge can be configured with a custom 'transmit list' consisting of single shot and/or periodic CAN frames. When deployed in the vehicle, the CANedge will then automatically transmit the pre-defined frames, allowing it to e.g. perform CCP/XCP polling of ECU data - or initialize DAQ measurement. The collected CCP/XCP data can be combined with the general CAN data in MF4 log files - and sent via WiFi/3G/4G to the OEM's own cloud server.

CCP XCP on CAN bus data logging telematics


CCP XCP on CAN calibration remote over-the-air OTA

Remote CCP/XCP calibration via OTA updates

As a more sophisticated use case, an OEM could utilize a CANedge3 to perform over-the-air updates to an ECU. For example, a CANedge3 may be deployed in a prototype vehicle in which an OEM engineer would like to re-calibrate certain variables in the ECU. To achieve this, the engineer constructs the relevant sequence of single-shot CAN frames in a new configuration file for the CANedge. Next, the engineer deploys the new configuration file on the CANedge S3 server, thus triggering an OTA update - allowing the CANedge3 to transmit the sequence into the vehicle remotely.



For more intros, see our guides section - or download the 'Ultimate Guide' PDF.




Ready to log your CCP/XCP data?

Get your CANedge today!







Recommended for you