SERVICE TX ERROR

A free API for the communication with control devices according to UDS (ISO 14229-1)
Post Reply
ValeV

SERVICE TX ERROR

Post by ValeV » Wed 5. May 2021, 16:32

Hello,

I am getting stuck on building basic functionality with PCAN-UDS library, hopefully we will solve this quickly.

I am using Windows 10 with mingw, IDE is Codeblocks.

Basically I am calling functions:

Code: Select all

UDS_Initialize();
UDS_removeMappings();
UDS_AddMapping)();
UDS_RemovePadding();
UDS_WaitForServiceWithReadDID(&uds);
Code for each function:

Code: Select all

uds_status UDS_Initialize(UDS_t *this, cantp_handle channel)
{
    uds_status retval;

    this->channel = channel;
    this->sett->dongle = channel;

    retval = UDS_Initialize_2013(this->channel, this->baudrate, this->hw_type, this->io_port, this->interrupt);

    return retval;
}

Code: Select all

uds_status UDS_removeMappings(UDS_t* this)
{
    uds_mapping mappings[256];
    uint16_t count;
    uds_status status;
    uint16_t i;

    status = UDS_GetMappings_2013(this->channel, mappings, 256, &count);
    if(!UDS_StatusIsOk_2013(status,  PUDS_STATUS_OK, 0))
    {
        return status;
    }

    for (i = 0; i < count; i++)
    {
        status = UDS_GetMappings_2013(this->channel, mappings, 256, &count);
        if(!UDS_StatusIsOk_2013(status,  PUDS_STATUS_OK, 0))
        {
            return status;
        }
        status = UDS_RemoveMapping_2013(this->channel, mappings[0]);
    }

    return status;
}

Code: Select all

uds_status UDS_AddMapping(UDS_t *this)
{
    uds_status status;
    uds_mapping mapping = {};
    uds_mapping mapping2 = {};

    // Add mapping for physical request from external equipment to ECU_1
    mapping.can_id = this->sett->uds_start.canid_req; //0x30B;
    mapping.can_id_flow_ctrl = this->sett->uds_start.canid_resp; //0x28B;
    mapping.can_msgtype = PCANTP_CAN_MSGTYPE_STANDARD;
    mapping.can_tx_dlc = 8;
    mapping.nai.extension_addr = 0;
    mapping.nai.protocol = PUDS_MSGPROTOCOL_ISO_15765_2_11B_NORMAL;
    mapping.nai.source_addr = PUDS_ISO_15765_4_ADDR_TEST_EQUIPMENT;
    mapping.nai.target_addr = PUDS_ISO_15765_4_ADDR_ECU_1;
    mapping.nai.target_type = PCANTP_ISOTP_ADDRESSING_PHYSICAL;
    status = UDS_AddMapping_2013(this->channel, &mapping);
    if (!UDS_StatusIsOk_2013(status, PUDS_STATUS_OK, 0))
    {
        return status;
    }

    // Add mapping for physical response from ECU_1 to external equipment
    mapping2.can_id = this->sett->uds_start.canid_resp; //0x28B;
    mapping2.can_id_flow_ctrl = this->sett->uds_start.canid_req; //0x30B;
    mapping2.can_msgtype = PCANTP_CAN_MSGTYPE_STANDARD;
    mapping2.can_tx_dlc = 8;
    mapping2.nai.extension_addr = 0;
    mapping2.nai.protocol = PUDS_MSGPROTOCOL_ISO_15765_2_11B_NORMAL;
    mapping2.nai.source_addr = PUDS_ISO_15765_4_ADDR_ECU_1;
    mapping2.nai.target_addr = PUDS_ISO_15765_4_ADDR_TEST_EQUIPMENT;
    mapping2.nai.target_type = PCANTP_ISOTP_ADDRESSING_PHYSICAL;
    status = UDS_AddMapping_2013(this->channel, &mapping2);
    if (!UDS_StatusIsOk_2013(status, PUDS_STATUS_OK, 0))
    {
        return status;
    }

    return status;
}

Code: Select all

uds_status UDS_RemovePadding(UDS_t* this)
{
    uint8_t buffer = PUDS_CAN_DATA_PADDING_NONE;
    return UDS_SetValue_2013(this->channel, PUDS_PARAMETER_CAN_DATA_PADDING, &buffer, 1);
}

Code: Select all

uds_status UDS_WaitForServiceWithReadDID(UDS_t *this)
{
    uds_status result;
    uds_msg request = {};
    uds_msg request_confirmation = {};
    uds_msg response = {};
    uds_msgconfig config = {};

    config.can_id = PUDS_ISO_15765_4_CAN_ID_PHYSICAL_REQUEST_1;
    config.can_msgtype = PCANTP_CAN_MSGTYPE_STANDARD;
    config.nai.extension_addr = 0x0;
    config.nai.protocol = PUDS_MSGPROTOCOL_ISO_15765_2_11B_NORMAL;
    config.nai.source_addr = PUDS_ISO_15765_4_ADDR_TEST_EQUIPMENT;
    config.nai.target_addr = PUDS_ISO_15765_4_ADDR_ECU_1;
    config.nai.target_type = PCANTP_ISOTP_ADDRESSING_PHYSICAL;
    config.type = PUDS_MSGTYPE_USDT;

    // Sends a physical ReadDataByIdentifier message
    uint16_t buffer[1] = {0xF195};
    result = UDS_SvcReadDataByIdentifier_2013(this->channel, config, &request, buffer, 1);
    if (UDS_StatusIsOk_2013(result, PUDS_STATUS_OK, 0))
    {
        result = UDS_WaitForService_2013(this->channel, &request, &response, &request_confirmation);
        if (UDS_StatusIsOk_2013(result, PUDS_STATUS_OK, 0))
        {
            printf("Response was received: ");
            uint8_t *data2 = response.msg.msgdata.can->data;
            printf("%02X %02X %02X %02X %02X %02X %02X %02X", data2[0], data2[1], data2[2], data2[3],data2[4], data2[5], data2[6],data2[7]);
            printf("\n");
            UDS_MsgFree_2013(&response);
            UDS_MsgFree_2013(&request_confirmation);
        }
        else
        {
            char str_msg[256] = "";
            result = UDS_GetErrorText_2013(result, 0x0, str_msg, 256);
            printf("An error occurred: %s\n", str_msg);
        }
        UDS_MsgFree_2013(&request);
    }
    else
    {
        char str_msg[256] = "";
        result = UDS_GetErrorText_2013(result, 0x0, str_msg, 256);
        printf("An error occurred while sending the request: %s\n", str_msg);
    }

    return result;
}
I get the response, but UDS_WaitForServiceWithReadDID() prints ""An error occurred while sending the request:" and returns error code "SERVICE TX ERROR", eventhough I get the response from the ECU (as seen on screenshot below).
Screenshot 2021-05-05 162903.jpg
Screenshot 2021-05-05 162903.jpg (18.71 KiB) Viewed 3689 times
I am guessing I messed up with mappings, but I can't find where I went wrong. :oops:

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

Re: SERVICE TX ERROR

Post by F.Vergnaud » Wed 5. May 2021, 17:14

Hello ValeV,

I think there is something wrong with your UDS_removeMappings (there are too many calls to UDS_GetMappings_2013 and you use a fixed index 0 instead of your loop variable when calling UDS_RemoveMapping_2013).
Here is a proposition:

Code: Select all

uds_status UDS_removeMappings(UDS_t* this)
{
    uds_mapping mappings[256];
    uint16_t count;
    uds_status status;
    uint16_t i;

    status = UDS_GetMappings_2013(this->channel, mappings, 256, &count);
    if(!UDS_StatusIsOk_2013(status,  PUDS_STATUS_OK, 0))
    {
        return status;
    }

    for (i = 0; i < count; i++)
    {
        status = UDS_RemoveMapping_2013(this->channel, mappings[i]);
    }

    return status;
}
Next there is an inconsistency between the mapping you are adding and the configuration you are using to send the UDS request.
I would change the uds_msgconfig to:

Code: Select all

   uds_msgconfig config = {};

    // can_id is optionnal, simply let the API find it for you based on the registered mappings
    // config.can_id = this->sett->uds_start.canid_req; //0x30B;
    config.can_msgtype = PCANTP_CAN_MSGTYPE_STANDARD;
    config.nai.extension_addr = 0x0;
    config.nai.protocol = PUDS_MSGPROTOCOL_ISO_15765_2_11B_NORMAL;
    config.nai.source_addr = PUDS_ISO_15765_4_ADDR_TEST_EQUIPMENT;
    config.nai.target_addr = PUDS_ISO_15765_4_ADDR_ECU_1;
    config.nai.target_type = PCANTP_ISOTP_ADDRESSING_PHYSICAL;
    config.type = PUDS_MSGTYPE_USDT;
Let me know if you still get an error. If that is the case you should check the "request" variable:
- it is initialized by UDS_SvcReadDataByIdentifier_2013 (assert that the created request match your mapping)
- and UDS_WaitForService_2013 will update the network status member of the cantp_msg (see request.msg.msgdata.any->netstatus), this holds ISO-TP networking information.
Best regards,
Fabrice

ValeV

Re: SERVICE TX ERROR

Post by ValeV » Thu 6. May 2021, 12:59

F.Vergnaud wrote:
Wed 5. May 2021, 17:14
Hello ValeV,

I think there is something wrong with your UDS_removeMappings (there are too many calls to UDS_GetMappings_2013 and you use a fixed index 0 instead of your loop variable when calling UDS_RemoveMapping_2013).
Here is a proposition:

Code: Select all

uds_status UDS_removeMappings(UDS_t* this)
{
    uds_mapping mappings[256];
    uint16_t count;
    uds_status status;
    uint16_t i;

    status = UDS_GetMappings_2013(this->channel, mappings, 256, &count);
    if(!UDS_StatusIsOk_2013(status,  PUDS_STATUS_OK, 0))
    {
        return status;
    }

    for (i = 0; i < count; i++)
    {
        status = UDS_RemoveMapping_2013(this->channel, mappings[i]);
    }

    return status;
}
I agree, my code is different than one that PEAK provides in PCAN-UDS-API_UserMan_eng.pdf file. It's because when I was debugging, I noticed mappings array was strange, and I got error code back for a lot of mappings in the array. For instance, UDS_RemoveMapping_2013() call for mappings[1] returned with "PCANTP mapping parameters are invalid" error code text. On the screenshot below you can see debug information for the array.
Screenshot 2021-05-05 162903.jpg
Screenshot 2021-05-05 162903.jpg (74.37 KiB) Viewed 3673 times
Although I suppose I can use your code and not theck the returned uds_status and always return PUDS_STATUS_OK.
F.Vergnaud wrote:
Wed 5. May 2021, 17:14
Next there is an inconsistency between the mapping you are adding and the configuration you are using to send the UDS request, like so.

I would change the uds_msgconfig to:

Code: Select all

   uds_msgconfig config = {};

    // can_id is optionnal, simply let the API find it for you based on the registered mappings
    // config.can_id = this->sett->uds_start.canid_req; //0x30B;
    config.can_msgtype = PCANTP_CAN_MSGTYPE_STANDARD;
    config.nai.extension_addr = 0x0;
    config.nai.protocol = PUDS_MSGPROTOCOL_ISO_15765_2_11B_NORMAL;
    config.nai.source_addr = PUDS_ISO_15765_4_ADDR_TEST_EQUIPMENT;
    config.nai.target_addr = PUDS_ISO_15765_4_ADDR_ECU_1;
    config.nai.target_type = PCANTP_ISOTP_ADDRESSING_PHYSICAL;
    config.type = PUDS_MSGTYPE_USDT;
Let me know if you still get an error. If that is the case you should check the "request" variable:
- it is initialized by UDS_SvcReadDataByIdentifier_2013 (assert that the created request match your mapping)
- and UDS_WaitForService_2013 will update the network status member of the cantp_msg (see request.msg.msgdata.any->netstatus), this holds ISO-TP networking information.
I replaced my code with yours and now I get error code text SERVICE TIMEOUT RESPONSE, so we're going somewhere. :)

I debugged to line

Code: Select all

printf("An error occurred: %s\n", str_msg);
and checked variable 'request.msg.msgdata.any->netstatus', which's value is PCANTP_NETSTATUS_OK. I don't understand what you mean by "it is initialized by UDS_SvcReadDataByIdentifier_2013", could you explain it on a simpler level?

ValeV

Re: SERVICE TX ERROR

Post by ValeV » Thu 6. May 2021, 14:05

I noticed that my mapping2 is replacing the first mapping. I printed "can_id - can_id_flow_ctrl" for whole array from getMappings() and got this:

28b - 30b <- this one i added, but "30b - 28b" is missing
0 - 8
1 - 2
100f1 - 0
7cba60 - 0
7e3 - 7eb
0 - 0
1 - 1
700f1 - 0
7cbce0 - 0
7e9 - 7e1
0 - 0
1 - 1
f10005 - 0
74dda0 - 0
7ef - 7e7
150000 - 0
2 - 0
60ced9 - 0

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

Re: SERVICE TX ERROR

Post by F.Vergnaud » Thu 6. May 2021, 14:57

In fact there is something wrong with the mapping list you are outputting... Starting from mappings[1] data seems corrupted.
It seems to be a problem with mingw, I'll let you know if I can confirm this.
Best regards,
Fabrice

ValeV

Re: SERVICE TX ERROR

Post by ValeV » Thu 6. May 2021, 16:11

I found the error. In PCAN-ISO-TP_2016.h file I had "#include <stdint.h>" commented out, because my company uses their own header file of typedefs compatible with MISRA C guidelines. Problem was I included the wrong such header file, so everything was messed up. I included correct header file now and so far everything works fine.

Thank you for your help, I still improved the code thanks to you.

Post Reply