Acquisition and clearing of DTC diagnostic trouble codes - 0x19 service, 0x14 service

1. 01 sub service - find the number of faults matching it through the status mask.

        Through this service, the diagnostic instrument can request the number of fault codes in ECU whose DTC status matches the DTC status mask. If the actual status bit of a fault code is 1 and the corresponding bit in the DTC status mask is 1,    Then it is considered that the status of the fault code matches the DTC status mask (that is, if the result of logical "bit and" operation between the DTC status mask byte and the DTC actual status byte is non-zero, then they match); At this time, the number of faults will be + 1. If the diagnostic instrument defines a status mask, which contains bits not supported by ECU, ECU only uses the bits supported by itself to process fault information. The request format is as follows:

  After receiving the request, the format of ECU response message is as follows:

  Some examples of 19 01 service code are as follows (for understanding and reference only):

uint16 DTC_GetDtcCountByStatusMask(uint8 status_mask)               /*Count the number of matching DTC s in ECU according to the status mask*/    
{
    uint16 Dtc_count = 0;
    uint8 Record_count;

    for(Record_count = 0; Record_count < DTC_CODE_MAX_NUM; Record_count++)/*Retrieve all DTC s*/
    {
        if((Dtc_dtc_status_record[Record_count].dtc_status.status_byte & status_mask) != 0)
        {
            Dtc_count++;
    }
    }    
    return Dtc_count;
}

FUNC(void,DCM_CODE) App_Fault_Memory_Read_Number(P2VAR(Dcm_MsgContextType,AUTOMATIC,DCM_APPL_DATA) pMsgContext)
{
    uint16 Counter = 0U;
    uint8  DtcStatus_Temp;
    DtcStatus_Temp = pMsgContext->reqData[DCM_INDEX_2];             /*Send the status mask through the 3rd byte of 19 01 service;*/
    
    Counter = DTC_GetDtcCountByStatusMask(DtcStatus_Temp);          /*Count the number of matching DTC s in ECU according to the status mask (code above)*/
    
    pMsgContext->resData[DCM_INDEX_2] = DTCStatusAvailabilityMask;  /*Return the status bit supported by ECU*/
    /* Change below data if necessary */
    /* 0x00 ISO15031-6Format,0x01 ISO14229-1Format,0x02 J1939 Format */
    pMsgContext->resData[DCM_INDEX_3] = 0x00U;                      /*Return the DTC format identifier used by ECU,
                                                                      00:15031-6;01:14229-1;02: J1939*/
    pMsgContext->resData[DCM_INDEX_4] = (uint8)(Counter >> 8U);     /*Returns the number of DTC s counted according to the status mask*/
    pMsgContext->resData[DCM_INDEX_5] = (uint8)(Counter);
    /* Always equals 6, don't change it */
    pMsgContext->resDataLen = 6U;
    DsdInternal_ProcessingDone(pMsgContext);  
}

PS: the DTC status mask parameter contains 8 DTC status bits, which are defined as follows:

  2. 02 sub service

Find the matching fault in the form of defined status mask, and return the matching DTC identifier (3 bytes) and DTC status (1 byte) information. The 01 sub service in the previous section only counts the number of DTCs matching the status mask, and the 02 sub service will return these matching DTC information. The request format is as follows:

  After receiving the request, the format of ECU response message is as follows:

  Some examples of 19 02 service codes are as follows (for understanding and reference only):

uint16 DTC_GetDtcByStatusMask(uint8 *p_dtc, uint8 status_mask)  /*Count the matching DTCs in ECU according to the status mask and return the DTC information*/
{
    uint16 dtc_count = 0;
    uint8 record_count;

    for(record_count = 0; record_count < DTC_CODE_MAX_NUM; record_count++)
    {
        if((Dtc_dtc_status_record[record_count].dtc_status.status_byte & status_mask) != 0)
        {
            *p_dtc++ = Dtc_dtc_code_data[record_count].dtc_high_byte;
            *p_dtc++ = Dtc_dtc_code_data[record_count].dtc_middle_byte;
            *p_dtc++ = Dtc_dtc_code_data[record_count].dtc_low_byte;
  
            *p_dtc++ = Dtc_dtc_status_record[record_count].dtc_status.status_byte;
            dtc_count++;
        }
    }    
    return dtc_count;
}

FUNC(void,DCM_CODE) App_Fault_Memory_Read_identified_errors(P2VAR(Dcm_MsgContextType,AUTOMATIC,DCM_APPL_DATA) pMsgContext)
{  
    uint16 counter = 0U;
    uint8  DtcStatus_Temp;
    DtcStatus_Temp = pMsgContext->reqData[DCM_INDEX_2];             /*Send the status mask through the 3rd byte of 19 02 service;*/

    /*Count the matching DTCs in ECU according to the status mask and return their DTC information (code above)*/
    counter = DTC_GetDtcByStatusMask(&(pMsgContext->resData[DCM_INDEX_3]),DtcStatus_Temp);
   
    pMsgContext->resData[DCM_INDEX_2] = DTCStatusAvailabilityMask;  /*Return the status bit supported by ECU*/
    pMsgContext->resDataLen = DCM_INDEX_3 + (counter * 4U);         /*Update the length of response message;*/
    DsdInternal_ProcessingDone(pMsgContext);
}

3. 04 sub service

In order to find the cause of the fault easily, the depot will generally define some information in the diagnosis questionnaire as snapshot information, such as fault occurrence time, voltage, driving mileage, vehicle speed, etc. When the corresponding fault occurs, the ECU side shall record the snapshot information when the fault occurs; The 04 service is used to request the snapshot information of the specified fault code (DTC), and analyze the cause of the fault by finding the data at the time of the fault. The request format is as follows:

Where, DTCSnapshotRecordNumber represents the DTC snapshot record code, accounting for one byte, and represents the specific DTC snapshot data record number. For example, when we need to record the snapshot data of the first occurrence (assumed to be represented by 1) and the last occurrence of a DTC (assumed to be represented by 2); When DTCSnapshotRecordNumber is 1, it means that the snapshot information when the DTC first occurs is requested.

If ECU supports multiple DTC snapshot data records, the record code shall use the value within the range of 0x01~0xFE. When the parameter value is FF hex, ECU is required to report all stored DTC snapshot data records at one time.

After receiving the request, the format of ECU response message is as follows:

 

As above, DTCSnapshotRecordNumber in the response message indicates which snapshot record of the DTC is returned; DTCSnapshotRecordNumberOfIdentifiers indicates the number of members defined in the snapshot information; For example, the snapshot data defined includes vehicle speed, voltage, speed and mileage; The value is 4.

As follows, suppose there are two snapshot record information, and the number of members of the snapshot record is 4; The corresponding 19 04 service diagnostic code is designed as follows (for understanding and reference only):

FUNC(void,DCM_CODE) App_Fault_Memory_Read_snapshot(P2VAR(Dcm_MsgContextType,AUTOMATIC,DCM_APPL_DATA) pMsgContext)
{
    uint8 error = 0U;
    uint32 Dtc;
    uint32 i;
    uint8 DTCSnapshotRecordNumber;
    uint8 DTCSnapshotRecordLength = 0U;
    uint8 status = 0U;
    uint8 snap_data_len = 0U;

    DTCSnapshotRecordNumber = pMsgContext->reqData[DCM_INDEX_5];

    Dtc = Make32Bit(pMsgContext->reqData[DCM_INDEX_2], pMsgContext->reqData[DCM_INDEX_3], pMsgContext->reqData[DCM_INDEX_4]);
    /* Check DTC */
    error = DTC_GetStatusByDtcNumber(Dtc, &status);     /*Get the status bit of DTC and store it in status*/
    if(error == 0U)
    {
       pMsgContext->resData[DCM_INDEX_5] = status;      /*Returns the status bit of the DTC*/
       
       if(Dtc_Fault_IsConfirmed(status))
       {
           switch(DTCSnapshotRecordNumber)
           {
               /* Add your code here. Below codes should be changed as Spec */               
               case 0x01:                               /*Returns the snapshot record information of the corresponding number*/
               case 0x02:
                {
                    pMsgContext->resData[DCM_INDEX_6] = DTCSnapshotRecordNumber;  /* Snapshot record code number*/
                    pMsgContext->resData[DCM_INDEX_7] = 4U;                       /* Number of snapshot members defined*/
                    
                    /*Obtain the ID information and numerical information of the snapshot member; Start storage from the address pmsgcontext - > resdata [dcm_index_8]*/
                    DTC_GetDtcSnapData(DTCSnapshotRecordNumber, &pMsgContext->resData[DCM_INDEX_8], Dtc, &snap_data_len);
                    DTCSnapshotRecordLength = DCM_INDEX_8 + snap_data_len;/*Length of update response message*/
                    break;
                }

               case 0xFF:                               /*Returns all snapshot record information*/
                {
                    pMsgContext->resData[DCM_INDEX_6] = 0x01;  /* First snapshot record*/
                    pMsgContext->resData[DCM_INDEX_7] = 4U;    /* Number of snapshot members defined*/
                    DTCSnapshotRecordLength = DCM_INDEX_8;
                    /*Obtain the ID information and numerical information of the first snapshot member;*/
                    DTC_GetDtcSnapData(0x01, &pMsgContext->resData[DTCSnapshotRecordLength], Dtc, &snap_data_len);
                    DTCSnapshotRecordLength += snap_data_len;
                    pMsgContext->resData[DTCSnapshotRecordLength++] = 0x02;  /* Second snapshot record*/
                    pMsgContext->resData[DTCSnapshotRecordLength++] = 4U; 
                    /*Obtaining the ID information and numerical information of the second snapshot member;*/
                    DTC_GetDtcSnapData(0x02, &pMsgContext->resData[DTCSnapshotRecordLength], Dtc, &snap_data_len);
                    DTCSnapshotRecordLength += snap_data_len;/*Length of update response message*/
                    break;
                }
               default:
                {
                    DsdInternal_SetNegResponse(pMsgContext,DCM_E_REQUESTOUTOFRANGE); 
                    error = 1U;
                    break;
                }
           }            
       }    
       else
       {
           DTCSnapshotRecordLength = 6u;
       }
    }
    else
    {
       DsdInternal_SetNegResponse(pMsgContext,DCM_E_REQUESTOUTOFRANGE); 
    }
    
    if(error == 0U)
    {
       pMsgContext->resDataLen = DTCSnapshotRecordLength;
       DsdInternal_ProcessingDone(pMsgContext);
    }
    else
    {
       DsdInternal_ProcessingDone(pMsgContext);
    }
}

4. 06 sub service

In addition to the snapshot information described in the previous 04 service; Generally, an extension information will be defined to record some other fault information, such as fault occurrence times, aging times, aging times, etc. The 06 service described below is used to request extended information of specified fault code (DTC). The request format is as follows:

Where, dtcextended datarecordnumber represents the extended data record code, accounting for one byte, and represents the extended data record number of the specified fault code requested by the diagnostic instrument. (i.e. the extended data of the specified number in the fault code to be requested)

After receiving the request, the format of ECU response message is as follows:

Take the return of the first extended data record as an example. The examples of the 19 06 service code are as follows (for understanding and reference only):

FUNC(void,DCM_CODE) App_Fault_Memory_Read_DTC_Extended_Data_Records_By_DTC_Number(P2VAR(Dcm_MsgContextType,AUTOMATIC,DCM_APPL_DATA) pMsgContext)
{
    uint8 error = 0U;
    uint32 Dtc;
    uint8 status = 0;
    uint8 extern_data_len = 0;
    
    /* change below length according to App*/
    if(pMsgContext->reqData[DCM_INDEX_5] >= 1U) 
    {
        Dtc = Make32Bit(pMsgContext->reqData[DCM_INDEX_2], pMsgContext->reqData[DCM_INDEX_3], pMsgContext->reqData[DCM_INDEX_4]);
        /* Check DTC */
        error = DTC_GetStatusByDtcNumber(Dtc, &status);/*Get the status bit of DTC and store it in status*/

        if(error == 0U)
        {
            pMsgContext->resData[DCM_INDEX_5] = status;/*Returns the status bit of the DTC*/

        }
        else
        {
            DsdInternal_SetNegResponse(pMsgContext,DCM_E_REQUESTOUTOFRANGE);
        }        
    }
    else
    {
        error = 1U;
        DsdInternal_SetNegResponse(pMsgContext,DCM_E_REQUESTOUTOFRANGE);
    }

    if(error == 0U)
    {
        pMsgContext->resData[DCM_INDEX_6] = 0x01;  /* Extended data record code, dtceextendeddatarecordnumber  */    
        DTC_GetDtcExternData(&(pMsgContext->resData[DCM_INDEX_7]), Dtc, &extern_data_len);/*Get the extended data information in this function and define it yourself*/    
        
        pMsgContext->resDataLen = DCM_INDEX_7 + extern_data_len; /* Update the length of the returned message*/    
        DsdInternal_ProcessingDone(pMsgContext);
    }
    else
    {
        DsdInternal_ProcessingDone(pMsgContext); 
    }
}

5. 0A sub service

The service is used to request all supported DTC information (3-byte DTC identifier + 1-byte DTC status bit), and its response message is consistent with 02 service; However, it should be distinguished that the service returns the information of all DTCs; The 02 service returns DTC information that is different from the status mask at the time of request. The request format is as follows:

After receiving the request, the format of ECU response message is as follows:

Some examples of 190A service code are as follows (for understanding and reference only):

void DTC_GetSupportedDtc(uint8 *p_dtc, uint16 *pCount)      /*Return all supported DTC information*/
{
    uint8 record_count;
    uint8 *pDtc = NULL;
    
    if((p_dtc == NULL) || (pCount == NULL))
    {
        return;
    }

    pDtc = p_dtc;    
    *pCount = 0;
    for(record_count = 0; record_count < DTC_CODE_MAX_NUM; record_count++)
    {
        *pDtc++ = DTC_dtc_code_data[record_count].dtc_high_byte;
        *pDtc++ = DTC_dtc_code_data[record_count].dtc_middle_byte;
        *pDtc++ = DTC_dtc_code_data[record_count].dtc_low_byte;
        *pDtc++ = DTC_dtc_status_record[record_count].dtc_status.status_byte;
        
        (*pCount)++;
    }
}

FUNC(void,DCM_CODE) App_Fault_Memory_Read_supported_errors(P2VAR(Dcm_MsgContextType,AUTOMATIC,DCM_APPL_DATA) pMsgContext)
{
    uint16 count = 0;

    pMsgContext->resData[DCM_INDEX_2] = DTCStatusAvailabilityMask;  /*Return the status bit supported by ECU*/
    DTC_GetSupportedDtc(&pMsgContext->resData[DCM_INDEX_3], &count);/*Return all supported DTC information*/
    pMsgContext->resDataLen = 3U + count * 4U;                      /*Length of update response message*/
    
    DsdInternal_ProcessingDone(pMsgContext);
}

2. 14 Service - clear diagnostic information

14 service is used to clear the stored fault diagnosis information. The service content is very simple. The request format is as follows:

groupOfDTC refers to a category of diagnostic trouble codes to be cleared (such as power P, body B and chassis C), or a specific fault code to be cleared; It consists of 3 bytes.

After receiving the request, the format of ECU response message is as follows:

Posted by ricroma on Fri, 03 Dec 2021 01:51:09 -0800