I am writing a wrapper DLL in C# for UDS services. One of the services which I plan to use is the "Write Data by Identifier" service. I need to use CAN FD protocol, with varying length of data to be written to certain ID-s. If I have no more than 64 data bytes to be sent, then I would like to send them in one single CAN FD frame, if I have more data bytes to be sent then I would like to use segmented data transfer. I have an idea how this can be achieved, but so far it did not work. Here is my code (the init_FD and the WDBI functions):
Code: Select all
using cantp_bitrate = System.String; // Alias' declaration for System.String
cantp_handle CAN_Channel;
uint CAN_request_ID;
uint CAN_response_ID;
uds_status result;
public const int OK = 0;
public int PEAK_UDS_init_FD(cantp_handle CAN_CH, cantp_bitrate CanBaudFD, uint CAN_Req_ID, uint CAN_Resp_ID, uint CAN_TO_Req, uint CAN_TO_Resp, ref string message)
{
message = "UDSApi.InitializeFD_2013 OK.";
uds_mapping UDS_Mapping_Request = new uds_mapping();
uds_mapping UDS_Mapping_Response = new uds_mapping();
CAN_Channel = CAN_CH; // set the selected CAN channel to a globally applied CAN channel for the DLL instance
try
{
// Initializing of the UDS Communication session
result = UDSApi.InitializeFD_2013(CAN_Channel, CanBaudFD);
if (!UDSApi.StatusIsOk_2013(result)) throw new Exception("UDSApi.InitializeFD_2013 failed.");
// set timeout values
result = UDSApi.SetValue_2013(CAN_Channel, uds_parameter.PUDS_PARAMETER_TIMEOUT_REQUEST, ref CAN_TO_Req, sizeof(UInt32));
if (!UDSApi.StatusIsOk_2013(result)) throw new Exception("Set CAN_TO_Req failed.");
result = UDSApi.SetValue_2013(CAN_Channel, uds_parameter.PUDS_PARAMETER_TIMEOUT_RESPONSE, ref CAN_TO_Resp, sizeof(UInt32));
if (!UDSApi.StatusIsOk_2013(result)) throw new Exception("Set CAN_TO_Resp failed.");
// Add mappings
UDS_Mapping_Request.can_id = CAN_Req_ID;
UDS_Mapping_Request.can_id_flow_ctrl = CAN_Resp_ID;
UDS_Mapping_Request.can_msgtype = cantp_can_msgtype.PCANTP_CAN_MSGTYPE_STANDARD;
UDS_Mapping_Request.can_msgtype |= (cantp_can_msgtype.PCANTP_CAN_MSGTYPE_FD | cantp_can_msgtype.PCANTP_CAN_MSGTYPE_BRS);
UDS_Mapping_Request.can_tx_dlc = 8;
UDS_Mapping_Request.nai.extension_addr = 0;
UDS_Mapping_Request.nai.protocol = uds_msgprotocol.PUDS_MSGPROTOCOL_ISO_15765_2_11B_NORMAL;
UDS_Mapping_Request.nai.source_addr = (ushort) uds_address.PUDS_ADDRESS_ISO_15765_4_ADDR_TEST_EQUIPMENT;
UDS_Mapping_Request.nai.target_addr = (ushort) uds_address.PUDS_ADDRESS_ISO_15765_4_ADDR_ECU_1;
UDS_Mapping_Request.nai.target_type = cantp_isotp_addressing.PCANTP_ISOTP_ADDRESSING_PHYSICAL;
UDS_Mapping_Response.can_id = CAN_Resp_ID;
UDS_Mapping_Response.can_id_flow_ctrl = CAN_Req_ID;
UDS_Mapping_Response.can_msgtype = cantp_can_msgtype.PCANTP_CAN_MSGTYPE_STANDARD;
UDS_Mapping_Response.can_msgtype |= (cantp_can_msgtype.PCANTP_CAN_MSGTYPE_FD | cantp_can_msgtype.PCANTP_CAN_MSGTYPE_BRS);
UDS_Mapping_Response.can_tx_dlc = 8;
UDS_Mapping_Response.nai.extension_addr = 0;
UDS_Mapping_Response.nai.protocol = uds_msgprotocol.PUDS_MSGPROTOCOL_ISO_15765_2_11B_NORMAL;
UDS_Mapping_Response.nai.source_addr = (ushort) uds_address.PUDS_ADDRESS_ISO_15765_4_ADDR_ECU_1;
UDS_Mapping_Response.nai.target_addr = (ushort) uds_address.PUDS_ADDRESS_ISO_15765_4_ADDR_TEST_EQUIPMENT;
UDS_Mapping_Response.nai.target_type = cantp_isotp_addressing.PCANTP_ISOTP_ADDRESSING_PHYSICAL;
result = UDSApi.AddMapping_2013(CAN_Channel, ref UDS_Mapping_Request);
if (!UDSApi.StatusIsOk_2013(result)) throw new Exception("Request mapping failed.");
result = UDSApi.AddMapping_2013(CAN_Channel, ref UDS_Mapping_Response);
if (!UDSApi.StatusIsOk_2013(result)) throw new Exception("Response mapping failed.");
CAN_request_ID = CAN_Req_ID;
CAN_response_ID = CAN_Resp_ID;
}
catch (Exception e)
{
message = e.Message + " Return code: " + ((int)result).ToString();
return (int)result;
}
return OK;
}
public int PEAK_UDS_wdbi_FD(UDSApi.uds_svc_param_di di, byte[] dataBuffer, ref string message)
{
uds_msg request = new uds_msg();
uds_msg request_confirmation = new uds_msg();
uds_msg response = new uds_msg();
uds_msgconfig config = new uds_msgconfig();
// Set request message configuration
config.can_id = (UInt16)CAN_request_ID;
config.can_msgtype = cantp_can_msgtype.PCANTP_CAN_MSGTYPE_STANDARD;
config.can_msgtype |= (cantp_can_msgtype.PCANTP_CAN_MSGTYPE_FD | cantp_can_msgtype.PCANTP_CAN_MSGTYPE_BRS);
config.nai.extension_addr = 0x0;
config.nai.protocol = uds_msgprotocol.PUDS_MSGPROTOCOL_ISO_15765_2_11B_NORMAL;
config.nai.source_addr = (UInt16)uds_address.PUDS_ADDRESS_ISO_15765_4_ADDR_TEST_EQUIPMENT;
config.nai.target_addr = (UInt16)uds_address.PUDS_ADDRESS_ISO_15765_4_ADDR_ECU_1;
config.nai.target_type = cantp_isotp_addressing.PCANTP_ISOTP_ADDRESSING_PHYSICAL;
if (dataBuffer.Length < 65)
{
if (dataBuffer.Length < 9) config.can_tx_dlc = (byte)dataBuffer.Length;
else if (dataBuffer.Length < 13) config.can_tx_dlc = 9;
else if (dataBuffer.Length < 17) config.can_tx_dlc = 10;
else if (dataBuffer.Length < 21) config.can_tx_dlc = 11;
else if (dataBuffer.Length < 25) config.can_tx_dlc = 12;
else if (dataBuffer.Length < 33) config.can_tx_dlc = 13;
else if (dataBuffer.Length < 49) config.can_tx_dlc = 14;
else config.can_tx_dlc = 15;
config.type = uds_msgtype.PUDS_MSGTYPE_UUDT;
}
else config.type = uds_msgtype.PUDS_MSGTYPE_USDT;
result = UDSApi.SvcWriteDataByIdentifier_2013(CAN_Channel, config, out request, di, dataBuffer, (uint)dataBuffer.Length);
if (UDSApi.StatusIsOk_2013(result))
{
result = UDSApi.WaitForService_2013(CAN_Channel, ref request, out response, out request_confirmation);
if (UDSApi.StatusIsOk_2013(result))
{
UDSApi.MsgFree_2013(ref request);
UDSApi.MsgFree_2013(ref response);
UDSApi.MsgFree_2013(ref request_confirmation);
message = "UDSApi.SvcWriteDataByIdentifier_2013 OK.";
return OK;
}
else
{
UDSApi.MsgFree_2013(ref request);
UDSApi.MsgFree_2013(ref response);
UDSApi.MsgFree_2013(ref request_confirmation);
message = "UDSApi.SvcWriteDataByIdentifier_2013 failed. Return code: " + ((int)result).ToString();
return -2;
}
}
else
{
UDSApi.MsgFree_2013(ref request);
UDSApi.MsgFree_2013(ref response);
UDSApi.MsgFree_2013(ref request_confirmation);
message = "UDSApi.SvcWriteDataByIdentifier_2013 failed. Return code: " + ((int)result).ToString();
return -1;
}
}
reading out (using "Read Data By Identifier" service) the same ID looks like this:
Type=FD,BRS; Length=8, Data=03 22 F1 8C 55 55 55 55
Type=FD,BRS; Length=24, Data=00 13 62 F1 8C 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 CC CC CC
CAN capture of WDBI:
Type=FD,BRS; Length=20, Data=2E F1 8C 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 55
What am I doing wrong?
If that would work, as a next step:
Can I use UDS + ISO-TP APIs in a way where I need to send more than 64 bytes of data with WDBI, and still use segmented message type (uds_msgtype.PUDS_MSGTYPE_USDT)? Because this would be the most efficient way of sending lot of data bytes (to be able to use segmentation and also send the maximum amount of data bytes a single CAN FD frame can send = 64).
Thank you for your help,
Best Regards:
Balazs