Problem with sending Diag session control using CAN FD

A free API for the communication with control devices according to UDS (ISO 14229-1)
Post Reply
Hossam Ali
Posts: 5
Joined: Tue 23. Feb 2021, 15:16

Problem with sending Diag session control using CAN FD

Post by Hossam Ali » Tue 23. Feb 2021, 15:46

Hello,
I have a problem with CAN FD while requesting any UDS Service like (SvcDiagnosticSessionControl_2013).
I set the value of DLC (can_tx_dlc) in (uds_msgconfig request_config) with 15. But when I checked the value of DLC in (uds_msg out_msg_request.msg.can_info.dlc) after sending the service I found the value become 8.
Which make the request not as expected.
req.PNG
req.PNG (2.58 KiB) Viewed 398 times
expectedReq.PNG
expectedReq.PNG (3.03 KiB) Viewed 398 times
error.PNG
error.PNG (28.45 KiB) Viewed 398 times
config.PNG
config.PNG (11.54 KiB) Viewed 398 times
This is the code I use to send the UDS Services

Code: Select all

switch (serviceInformation.Service)
            {
                case uds_service.PUDS_SERVICE_SI_DiagnosticSessionControl:
                    UDSApi.uds_svc_param_dsc paramDSC = (UDSApi.uds_svc_param_dsc)serviceInformation.ParametersOfService[0];
                    status = UDSApi.SvcDiagnosticSessionControl_2013(mConnectedPeakChannel, mRequesetMappingInfo.MessageConfig, out mRequest, paramDSC);
                    break;
                case uds_service.PUDS_SERVICE_SI_ReadDataByIdentifier:
                    UDSApi.uds_svc_param_di[] identifiers = { UDSApi.uds_svc_param_di.FD35};
                    status = UDSApi.SvcReadDataByIdentifier_2013(mConnectedPeakChannel, mRequesetMappingInfo.MessageConfig, out mRequest, identifiers, (UInt32)identifiers.Length);
                    break;
                case uds_service.PUDS_SERVICE_SI_WriteDataByIdentifier:
                    UDSApi.uds_svc_param_di DataIdentifier = (UDSApi.uds_svc_param_di)serviceInformation.ParametersOfService[0];
                    byte[] buffer = (byte[])serviceInformation.ParametersOfService[1];
                    status = UDSApi.SvcWriteDataByIdentifier_2013(mConnectedPeakChannel, mRequesetMappingInfo.MessageConfig, out mRequest, DataIdentifier, buffer, (UInt32)buffer.Length);
                    break;
                case uds_service.PUDS_SERVICE_SI_SecurityAccess:
                    byte securityAccessType = Convert.ToByte(serviceInformation.ParametersOfService[0]);
                    byteBuffer = (byte[])serviceInformation.ParametersOfService[1];
                    status = UDSApi.SvcSecurityAccess_2013(mConnectedPeakChannel, mRequesetMappingInfo.MessageConfig, out mRequest, securityAccessType, byteBuffer, (UInt32)byteBuffer.Length);
                    break;
                default:
                    break;
            }


And these are the configurations for CAN FD:

Code: Select all

"f_clock_mhz=80, nom_brp=1, nom_tseg1=127, nom_tseg2=32, nom_sjw=32, data_brp=2, data_tseg1=27, data_tseg2=12, data_sjw=12"

Code: Select all

const UInt32 canRequestID  = 0x73A;
            const UInt32 canResponseID = 0x73C;

            mRequesetMappingInfo = new MappingInformation
            (
                canRequestID,
                canResponseID,
                (UInt16)uds_address.PUDS_ADDRESS_ISO_15765_4_ADDR_TEST_EQUIPMENT,
                (UInt16)uds_address.PUDS_ADDRESS_ISO_15765_4_ADDR_ECU_1
            );

            mResponseMappingInfo = new MappingInformation
            (
                canResponseID,
                canRequestID,
                (UInt16)uds_address.PUDS_ADDRESS_ISO_15765_4_ADDR_ECU_1,
                (UInt16)uds_address.PUDS_ADDRESS_ISO_15765_4_ADDR_TEST_EQUIPMENT
            );

Code: Select all

public MappingInformation(UInt32 canId, UInt32 responseCanId, UInt16 sourceAddress, UInt16 targetAddress)
        {
            //Set Mapping parameters.
            mMappingInfo = new uds_mapping
            {
                can_id = canId,
                can_id_flow_ctrl = responseCanId,
                can_msgtype =  cantp_can_msgtype.PCANTP_CAN_MSGTYPE_FD,
                can_tx_dlc = 15
            };

            mMappingInfo.nai.protocol = uds_msgprotocol.PUDS_MSGPROTOCOL_ISO_15765_2_11B_NORMAL;
            mMappingInfo.nai.target_type = cantp_isotp_addressing.PCANTP_ISOTP_ADDRESSING_PHYSICAL;
            mMappingInfo.nai.source_addr = sourceAddress;
            mMappingInfo.nai.target_addr = targetAddress;
            mMappingInfo.nai.extension_addr = 0;


            //Set Message Configurations
            mMessageConfig = new uds_msgconfig
            {
                type = uds_msgtype.PUDS_MSGTYPE_USDT,
                nai = mMappingInfo.nai,
                can_id = mMappingInfo.can_id,
                can_msgtype = mMappingInfo.can_msgtype,
                can_tx_dlc = mMappingInfo.can_tx_dlc
            };

        }

F.Vergnaud
Software Development
Software Development
Posts: 179
Joined: Mon 9. Sep 2013, 12:21

Re: Problem with sending Diag session control using CAN FD

Post by F.Vergnaud » Tue 23. Feb 2021, 16:34

Hello,

"can_tx_dlc" is a parameter that allows you to configure the transmit data link layer data length (TX_DL) as defined in ISO 15765.
But be careful as TX_DL only configures the maximum usable payload length of the data link layer.

This means that UDS requests will actually use the smallest dlc value that allows to transmit the data (if can_data_padding is enabled the minimum value is 8).
Best regards,
Fabrice

Hossam Ali
Posts: 5
Joined: Tue 23. Feb 2021, 15:16

Re: Problem with sending Diag session control using CAN FD

Post by Hossam Ali » Tue 23. Feb 2021, 16:55

Thank you for quick reply.
And yes can_data_padding is enabled.

I tried to set the (PUDS_PARAMETER_CAN_TX_DL) with 15 but the result still the same and I can't send the FD frame which starts with (00) as in the expected request above.
Is there any idea where the problem is ?

Hossam Ali
Posts: 5
Joined: Tue 23. Feb 2021, 15:16

Re: Problem with sending Diag session control using CAN FD

Post by Hossam Ali » Tue 23. Feb 2021, 17:18

I think the problem is not in the DLC itself but in the CAN frame itself.
I noticed that its a Standard CAN frame which starts with the DLC and then followed by the data like the one in ( [02] 10 03)
But I was expecting the CAN FD frame which starts with ( [00 02] 10 03)

I need to know why the frame is standard frame even I'm using a FD frame?

F.Vergnaud
Software Development
Software Development
Posts: 179
Joined: Mon 9. Sep 2013, 12:21

Re: Problem with sending Diag session control using CAN FD

Post by F.Vergnaud » Tue 23. Feb 2021, 17:46

You can change the can data padding value to 0x00 with the parameter PUDS_PARAMETER_CAN_PADDING_VALUE.
You will then send a UDS request with the following 8 bytes data: 02 10 03 00 00 00 00 00.

However you will NOT be able to send a UDS request with an actual UDS data size of 2 in a CAN FD frame with a DLC value of 15 (0xF).
ISO standards specifically defined TX_DL as a maximum value: so that CAN bus is not polluted by ISOTP communications with huge and useless data padding.
I noticed that its a Standard CAN frame which starts with the DLC and then followed by the data like the one in ( [02] 10 03)
This is not exactly a CAN/CANFD frame issue but in fact it is related to the ISO TP protocol (ISO-15765:2016): if your ISOTP message fits in a single frame with less than 8 bytes, then it will use the protocol control information as defined in revision 2004. Only if the data is bigger than 8 bytes then it will use the "FD compatible" protocol control information.
Please let me know if you are communicating with a commercialised ECU which does not work this way (for future versions, a workaround could be handled with a new parameter).

I understand that you'd like to send the following ISO-TP single frame [00 02] 10 03 [00 00 ... => up to 64 bytes]. But you will not be able to achieve this in the current PCAN-UDS version with the UDS_Svc functions.
You could try to build your own uds_message: this means that you have to initialize the cantp_msg and configure it with a dlc=0x0f and a data length of 60 to force the use of the maximum dlc.
But I think it will still not be exactly what you want: CAN FD frame will most probably be 00 3c 10 03 00 ... 00.
Best regards,
Fabrice

Hossam Ali
Posts: 5
Joined: Tue 23. Feb 2021, 15:16

Re: Problem with sending Diag session control using CAN FD

Post by Hossam Ali » Tue 23. Feb 2021, 18:23

The problem of using your proposal of building my own uds_message is that I'm not only using a single frame. Most of the frames are Consecutive Frames specially when I'm using the "UDS_SvcWriteDataByIdentifier_2013".
I write data more than 64 bytes which are sent in multi Consecutive frame.

So, you can confirm that using the current version of PCAN-UDS, I can't use UDS_Svc functions to send any diagnostic service for CAN FD. I could only use them for Standard CAN, right?

F.Vergnaud
Software Development
Software Development
Posts: 179
Joined: Mon 9. Sep 2013, 12:21

Re: Problem with sending Diag session control using CAN FD

Post by F.Vergnaud » Wed 24. Feb 2021, 09:48

The issue I described is only valid for ISO-TP single frame.
ISO-TP segmented messages have by definition a data length bigger than the configured TX_DL, so the segmentd frames will use the dlc you set (apart from the last Consecutive frame which will adapt the dlc to fit the remaining data).
So, you can confirm that using the current version of PCAN-UDS, I can't use UDS_Svc functions to send any diagnostic service for CAN FD. I could only use them for Standard CAN, right?
As far as I understand, you want to apply a use case which goes against the standard, and this is indeed not possible.
- For UDS requests where data fit in a single frame, UDS_Svc functions will adapt the dlc to the real data length.
- Otherwise the UDS_Svc functions will use the configured can_tx_dlc.

Also be careful, you have defined a mapping with a FD flag for the can_msgtype, this means CAN FD frames are used in the transport protocol.
Even if only 8 bytes are sent, the frame has still the CAN FD type (this is not standard CAN).
Best regards,
Fabrice

Hossam Ali
Posts: 5
Joined: Tue 23. Feb 2021, 15:16

Re: Problem with sending Diag session control using CAN FD

Post by Hossam Ali » Wed 24. Feb 2021, 12:50

As far as I understand, you want to apply a use case which goes against the standard, and this is indeed not possible.
- For UDS requests where data fit in a single frame, UDS_Svc functions will adapt the dlc to the real data length.
- Otherwise the UDS_Svc functions will use the configured can_tx_dlc.
This was my problem indeed. I was using a SW which was not compliant with the STD protocol. that's why the problem happened. The SW is updated now and it worked fine according to the standard.
Thank you very much for your help and quick response.

F.Vergnaud
Software Development
Software Development
Posts: 179
Joined: Mon 9. Sep 2013, 12:21

Re: Problem with sending Diag session control using CAN FD

Post by F.Vergnaud » Wed 24. Feb 2021, 13:23

Glad to hear that!

For completeness and as knowledge base, here is an example of how one could send a UDS request with a 64 bytes single CAN FD frame (using UUDT):

Code: Select all

            // Initialize channel
            const String BITRATE = "f_clock_mhz=80, nom_brp=1, nom_tseg1=127, nom_tseg2=32, nom_sjw=32, data_brp=2, data_tseg1=27, data_tseg2=12, data_sjw=12";
            cantp_handle channel = cantp_handle.PCANTP_HANDLE_USBBUS1;
            uds_status status = UDSApi.InitializeFD_2013(channel, BITRATE);
            Console.WriteLine("Initialize channel: {0}", status);
            // Configure CAN_TX_DL and padding
            UInt32 can_tx_dl = 15;
            status = UDSApi.SetValue_2013(channel, uds_parameter.PUDS_PARAMETER_CAN_TX_DL, ref can_tx_dl, 1);
            Console.WriteLine("Set can tx dl: {0}", status);
            // Allocate request as UUDT
            uds_msgconfig uudt_config = new uds_msgconfig();
            uudt_config.can_id = 0x73a;
            uudt_config.can_msgtype = cantp_can_msgtype.PCANTP_CAN_MSGTYPE_FD;
            uudt_config.nai.protocol = uds_msgprotocol.PUDS_MSGPROTOCOL_ISO_15765_2_11B_NORMAL;
            uudt_config.nai.target_type = cantp_isotp_addressing.PCANTP_ISOTP_ADDRESSING_PHYSICAL;
            uudt_config.type = uds_msgtype.PUDS_MSGTYPE_UUDT;
            uudt_config.nai.source_addr = (UInt16)uds_address.PUDS_ADDRESS_ISO_15765_4_ADDR_TEST_EQUIPMENT;
            uudt_config.nai.target_addr = (UInt16)uds_address.PUDS_ADDRESS_ISO_15765_4_ADDR_ECU_1;
            uudt_config.nai.extension_addr = 0;
            uudt_config.can_tx_dlc = 15;
            uds_msg dsc_request = new uds_msg();
            status = UDSApi.MsgAlloc_2013(out dsc_request, uudt_config, 64);
            Console.WriteLine("Allocate request: {0}", status);
            // Fill request data
            byte[] dsc_request_data = new byte[] {
                0x00, 0x02, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
            bool set_data_result = CanTpApi.setData_2016(ref dsc_request.msg, 0, dsc_request_data, 64);
            Console.WriteLine("Set request data: {0}", set_data_result);
            // Send request 
            status = UDSApi.Write_2013(channel, ref dsc_request);
            Console.WriteLine("Write request: {0}", status);
            // Release memory
            status = UDSApi.MsgFree_2013(ref dsc_request);
            Console.WriteLine("Free request: {0}", status);
            // Uninitialize channel
            status = UDSApi.Uninitialize_2013(channel);
            Console.WriteLine("Uninitialize channel: {0}", status);
            // Exit
            Console.WriteLine("Press any key to continue...");
            Console.In.Read();
Best regards,
Fabrice

Post Reply