Main Content

Calibrate XCP Characteristics

This example shows how to use the XCP protocol capability to connect and calibrate available characteristic data from an XCP Sample server. The XCP Sample Server is specially designed for XCP examples only.

Vehicle Network Toolbox™ provides MATLAB functions for interfacing with a server over multiple transport layers including Controller Area Networks (CAN), Controller Area Network Flexible Data-Rate (CAN FD), Transmission Control Protocol (TCP) and User Datagram Protocol (UDP). This example writes to calibrate the parameters then compares the measurements before and after calibration.

XCP is a high-level protocol used for accessing and modifying internal parameters and variables of a model, algorithm, or ECU. For more information, refer to the ASAM standard.

Open the A2L File

An A2L file is required to establish a connection to the XCP server. The A2L file describes all of the functionality and capability that the XCP server provides, as well as the details of how to connect to the server. Use the xcpA2L function to open the A2L file that describes the server model.

a2lInfo = xcpA2L("SampleECU.a2l")
a2lInfo = 
  A2L with properties:

   File Details
                 FileName: 'SampleECU.a2l'
                 FilePath: '/tmp/Bdoc24a_2528353_1101874/tp8faccd1d/vnt-ex60761655/SampleECU.a2l'
               ServerName: 'SampleServer'
                 Warnings: [0x0 string]

   Parameter Details
                   Events: {'Event DAQ 100ms'}
                EventInfo: [1x1 xcp.a2l.Event]
             Measurements: {'Line'  'PWM'  'Sine'}
          MeasurementInfo: [3x1 containers.Map]
          Characteristics: {'Gain'  'yData'}
       CharacteristicInfo: [2x1 containers.Map]
                 AxisInfo: [1x1 containers.Map]
            RecordLayouts: [3x1 containers.Map]
             CompuMethods: [1x1 containers.Map]
                CompuTabs: [0x1 containers.Map]
               CompuVTabs: [0x1 containers.Map]

   XCP Protocol Details
        ProtocolLayerInfo: [1x1 xcp.a2l.ProtocolLayer]
                  DAQInfo: [1x1 xcp.a2l.DAQ]
    TransportLayerCANInfo: [1x1 xcp.a2l.XCPonCAN]
    TransportLayerUDPInfo: [0x0 xcp.a2l.XCPonIP]
    TransportLayerTCPInfo: [1x1 xcp.a2l.XCPonIP]

Start the XCP Sample Server

The XCP Sample server mimics the behavior of a real XCP server in a controlled way. In this case, it serves ONLY for examples with limited functionalities. Use local SampleECU class to create the Sample server object and a Sample server will be created in the MATLAB Workspace. The XCP Sample server supports CAN, CAN FD, and TCP. This example chooses the CAN protocol for demonstration.

sampleServer = SampleECU(a2lInfo,"CAN","MathWorks","Virtual 1",1);

Create an XCP Channel

To create an active XCP connection to the server, use the xcpChannel function. The function requires a reference to the server A2L file and the type of transport protocol to use for messaging with the server. The XCP Channel must use the same device and a2l file as the Sample server to make sure they can be connected.

xcpCh = xcpChannel(a2lInfo,"CAN","MathWorks","Virtual 1",1)
xcpCh = 
  Channel with properties:

              ServerName: 'SampleServer'
             A2LFileName: 'SampleECU.a2l'
          TransportLayer: 'CAN'
    TransportLayerDevice: [1x1 struct]
              SeedKeyDLL: []
             ConnectMode: 'normal'

Connect to the Server

To make communication with the server active, use the connect function.

connect(xcpCh);

View Available Characteristics from A2L File

A characteristic in XCP represents a tunable parameter in the memory of the model. Characteristics available for calibration are defined in the A2L file and can be found in the Characteristics property. Note that the parameter Gain is the multiplier and yData specifies the output data points of the 1-D look-up table.

a2lInfo.Characteristics
ans = 1x2 cell
    {'Gain'}    {'yData'}

a2lInfo.CharacteristicInfo("Gain")
ans = 
  Characteristic with properties:
                   Name: 'Gain'
         LongIdentifier: 'Scalar SBYTE'
     CharacteristicType: VALUE
             ECUAddress: 8454145
                Deposit: [1x1 xcp.a2l.RecordLayout]
                MaxDiff: 0
             Conversion: [1x1 xcp.a2l.CompuMethod]
             LowerLimit: -100
             UpperLimit: 100
              Dimension: 1
         AxisConversion: {1x0 cell}
                BitMask: []
              ByteOrder: MSB_LAST
               Discrete: []
    ECUAddressExtension: 0
                 Format: '%6.1'
                 Number: []
               PhysUnit: ''

a2lInfo.CharacteristicInfo("yData")
ans = 
  Characteristic with properties:
                   Name: 'yData'
         LongIdentifier: 'Curve with standard axis'
     CharacteristicType: CURVE
             ECUAddress: 8454912
                Deposit: [1x1 xcp.a2l.RecordLayout]
                MaxDiff: 0
             Conversion: [1x1 xcp.a2l.CompuMethod]
             LowerLimit: 0
             UpperLimit: 255
              Dimension: 8
         AxisConversion: {[1x1 xcp.a2l.CompuMethod]}
                BitMask: []
              ByteOrder: MSB_LAST
               Discrete: []
    ECUAddressExtension: 0
                 Format: ''
                 Number: []
               PhysUnit: ''

Calibrate the Characteristic Gain Value

The characteristic Gain is used to calculate the value measurement Sine. The Gain value controls the amplitude of the measurement Sine.

Inspect Preloaded Characteristic Values

Read the current value of the characteristic Gain. The readCharacteristic function performs a direct read from the server for a given characteristic.

initialGain = readCharacteristic(xcpCh, "Gain")
initialGain = 2

Obtain Measurement Before Calibration

Create a Measurement List

This example explores the value of the measurement Sine, unmodified and modified by the two characteristics. To visualize the continuously changing value of Sine pre- and post-calibration, acquire measurement data values using a DAQ list. Use the createMeasurementList function to create a DAQ list containing the Sine measurement from the server.

createMeasurementList(xcpCh, "DAQ", "Event DAQ 100ms", "Sine", EnableTimestamps = false);

Acquire Data form XCP Server

Use the startMeasurement function and stopMeasurement function to run the DAQ list for a short period of time.

startMeasurement(xcpCh);
pause(6);
stopMeasurement(xcpCh);

Retrieve the Sine Measurement Data

To retrieve the data acquired by the DAQ list for the Sine measurement, use the readDAQList function then retrieve the Sine signal from the output DAQ list. There is one measurement list in the channel, so the index of the measurement list should be one.

DAQList = readDAQList(xcpCh);
listIndex = 1;
sineBeforeCalibration = DAQList{listIndex}.Sine;

Plot the Sine Measurement

Plot the Sine measurement which applied the Gain value. The Sine measurement values reflect being boosted with the value of Gain set to 2, as shown previously.

plot(sineBeforeCalibration, "o-");
title("Before Calibration Sine Signal");
xlabel("Data Point");
ylabel("Data Value");

Calibrate the Gain Characteristic

Write a new value to the characteristic Gain using writeCharacteristic, and perform a read to verify the change using readCharacteristic. The new value of Gain is 5, that means the Sine measurement values will be boosted by the new Gain value 5.

writeCharacteristic(xcpCh, "Gain", 5);
newGain = readCharacteristic(xcpCh, "Gain")
newGain = 5

Obtain Measurement After Calibration

Acquire Data form XCP Server

Use the startMeasurement function and stopMeasurement function to run the DAQ list for a short period of time.

startMeasurement(xcpCh);
pause(6);
stopMeasurement(xcpCh);

Retrieve the Sine Measurement Data

To retrieve the data acquired by the DAQ list for the Sine measurement, use the readDAQList function then retrieve the Sine signal from the output DAQ list. There is one measurement list in the channel, so the index of the measurement list should be one.

DAQList = readDAQList(xcpCh);
listIndex = 1;
sineAfterCalibration = DAQList{listIndex}.Sine;

Plot the Sine Measurement

Plot the SineAfterCalibration measurement against the SineBeforeCalibration measurement. Now the Sine measurement signal has higher amplitude, because the value of the characteristic Gain is set to 5 after calibration.

plot(sineBeforeCalibration, "o-"); hold on;
plot(sineAfterCalibration, "*-"); hold off;
title("Sine Signal before Calibration vs after Calibration");
legend("Before", "After");
xlabel("Data Point");
ylabel("Data Value");

Calibrate the Characteristic 1-D Look-up Table

Look-up table is widely used in the industry for control parameters. So, the following section introduces how to calibrate the 1-D look-up Table using Axis xData and Characteristic yData in the XCP Sample server.

Read the current 1-D look-up table characteristic using readAxis and readCharacteristic, then plot the mapping. This table effectively maps input values to corresponding output values.

inputBreakpoints = readAxis(xcpCh, "xData")
inputBreakpoints = 1×8

     0     1     2     3     4     5     6     7

outputPoints = readCharacteristic(xcpCh, "yData")
outputPoints = 1×8

   100   101   102   103   104   105   106   107

plot(inputBreakpoints, outputPoints);
title("Initial 1-D Look-up Table Map");
xlabel("Input Value");
ylabel("Output Value");

Write new data points to the output of the 1-D look-up table using writeCharacteristic.

writeCharacteristic(xcpCh, "yData", 103:110);

Read the new 1-D look-up table data using readAxis and readCharacteristic, then plot the mapping. Now the new yData characteristic was set to higher values.

xData = readAxis(xcpCh, "xData");
newOutputPoints = readCharacteristic(xcpCh, "yData")
newOutputPoints = 1×8

   103   104   105   106   107   108   109   110

plot(inputBreakpoints, outputPoints, "o-"); hold on
plot(inputBreakpoints, newOutputPoints, "*-"); hold off;
title("1-D Look-up Table Map before Calibration vs after Calibration");
legend("Before", "After");
xlabel("Input Value");
ylabel("Output Value");

Disconnect from the Server

To make communication with the server inactive, use the disconnect function. The XCP server can be safely closed after disconnecting.

disconnect(xcpCh);

Clean Up

clear sampleServer a2lInfo