• [AUTOSAR][诊断管理][$10] 会话模式控制


    一、简介

    在这里插入图片描述

    1. $10服务是Diagnostic Session Control诊断会话控制,子功能有01、02、03三种,这三种代表10服务可以进入的3种不同的会话模式。
      在这里插入图片描述

    2. 01 Default默认会话,02 Programming编程会话(用于解锁bootloader相关的诊断服务,即程序烧录。),03 Extended扩展会话,ECU上电时,进入的是默认会话(Default)。
      在这里插入图片描述

    二、指令格式

    请求: 10 SF

    SF:子功能,比如01、02、03,编程会话只能通过先进扩展会话之后再进编程会话,当前为编程会话,不能直接发10 03跳转到扩展会话。
    肯定相应:50 SF sessionParameterRecord
    0x40+SID=0x50

    SF是对应请求的子功能,请求是什么子功能,它就显示什么子功能。

    会话参数记录有P2Server_max(2byte)和P2*Server_max(2byte),高位在前的表示方式。

    1. P2Server_max:指的是ECU在收到请求和给出响应之间的这个时间间隔,他描述了ECU的反应速度。

    2. P2*Server_max:在ECU给出NRC 78(等待)之后生效,所以会需要更长的反应时间。

    否定相应:7F SID NRC(否定相应码)

    1. 否定相应格式一定,SID对应请求的SID,NRC为Negative Response Code,即会有一些类似于一个指令格式或数据是否正确的判断,在发送不是一个正常指令时,ECU就会给你这个NRC,相当于一个提示,可以通过不同的NRC判断指令的错误原因。
    2. 比如常见的7E表示SF在此会话不支持(在编程会话发10 03即会出现)、12表示SF不支持(发10 FF这种不支持的SF)、13表示发出的此SID格式长度不符合标准定义的SID的格式(10服务定义的两个byte,发10 01 01,即会得到此NRC)。

    三、示例代码

    (1) uds10_session_ctl.c

    /********************************************************************************
    * @file    uds10_session_ctl.c
    * @author  jianqiang.xue
    * @version V1.0.0
    * @date    2023-05-29
    * @brief   会话模式控制
    ********************************************************************************/
    /* Includes ------------------------------------------------------------------*/
    #include 
    #include 
    #include 
    #include 
    #include "modules.h"
    #include "os_api.h"
    #include "edebug.h"
    #include "kv_sys.h"
    /* Private includes ----------------------------------------------------------*/
    #include "std_math.h"
    #include "app_can.h"
    #include "can_nm.h"
    #include "app_nm.h"
    #include "diag_main.h"
    /* Private define ------------------------------------------------------------*/
    #define UDS_ID     0x10
    
    /* Private typedef -----------------------------------------------------------*/
    /* Private macro -------------------------------------------------------------*/
    /* Private variables ---------------------------------------------------------*/
    extern uint16_t g_session_time_remaining; // P3服务剩余时间,超时切换为默认会话
    extern dfu_info_t g_dfu_info;
    /***************软定时器创建***************/
    
    /* Private func --------------------------------------------------------------*/
    
    void uds10_main(nwl_msg_t* p) {
        uint16_t did = 0;
        uint8_t data[20];
        uint8_t d_len = 0;
        uint8_t pos = 1; // 当前数据指针位置
        uint16_t len = 0; // 报文参数长度
        LOGD("ta_type:%u, %02x", p->ta_type, p->len);
        // 长度检测 8.6.3要求一次只可以读一个标识符
        if (p->len != 2) {
            send_nrc_data(UDS_ID, NRC_INCORRECT_MESSAGE_LENTH);
            goto end;
        } else if (p->data[1] > 3 || p->data[1] == 0) {
            send_nrc_data(UDS_ID, NRC_SUBFUNCTION_NOT_SUPPORTED);
            goto end;
        }
        switch (p->data[1]) {
            case 0x01: // 请求进入默认会话
                g_diag_info.session = DEFAULT_SESSION;
                g_diag_info.security_level = DIAG_NO_SECURITY_LEVEL;
                g_dfu_info.crc32 = INITIAL_REMAINDER;
                LOGI("Enter default session");
                break;
            case 0x02: // 请求进入编程会话
                if (p->ta_type == DIAG_PHYS_REQ) {
                    if (g_diag_info.session == PROGRAMMING_SESSION) {
                    }else if ((g_car_ste.IPB.bit.VehicleSpeedVld == 1) && (get_car_speed() > 3)) {
                        LOGE("The vehicle does not meet the conditions.%u", get_car_speed());
                        send_nrc_data(UDS_ID, NRC_CONDITION_NOT_CORRECT);
                        goto end;
                    } else if (g_diag_info.session != EXTENDED_SESSION) {
                        LOGE("Isn't extended session.%u", g_diag_info.session);
                        send_nrc_data(UDS_ID, NRC_SUBFUNCTION_NOT_SUPPORTED_INACTIVE_SESSION);
                        goto end;
                    }
                    g_diag_info.session = PROGRAMMING_SESSION;
                    g_diag_info.security_level = DIAG_NO_SECURITY_LEVEL;
                    LOGI("Jmp boot, enter programming session.%u", g_diag_info.session);
                    diag_main_send_signal(SIGNAL_P3_SESSION_START);
                } else {
                    send_nrc_data(UDS_ID, NRC_SERVICE_NOT_SUPPORTED);
                    goto end;
                }
                break;
            case 0x03: // 请求进入扩展会话
                if ((g_car_ste.IPB.bit.VehicleSpeedVld == 1) && (get_car_speed() > 3)) {
                    send_nrc_data(UDS_ID, NRC_CONDITION_NOT_CORRECT);
                    goto end;
                } else if (g_diag_info.session == PROGRAMMING_SESSION) {
                    send_nrc_data(UDS_ID, NRC_SUBFUNCTION_NOT_SUPPORTED_INACTIVE_SESSION);
                    goto end;
                }
                g_diag_info.session = EXTENDED_SESSION;
                g_diag_info.security_level = DIAG_NO_SECURITY_LEVEL;
                LOGI("Enter extended session.%u", g_diag_info.session);
                diag_main_send_signal(SIGNAL_P3_SESSION_START);
                break;
            default:
                send_nrc_data(UDS_ID, NRC_SUBFUNCTION_NOT_SUPPORTED);
                goto end;
                break;
        }
        // 回复正响应码  单帧格式: len, 服务ID|0x40, session_id, 服务时间_H,, 服务时间_L, 应答时间_H,, 应答时间_L
        data[0] = 3;  // 数据总长度=数据长度+服务号
        data[1] = UDS_ID | 0x40;   // 服务号,回复上位机需要 |0x40
        data[2] = p->data[1];
        data[3] = (uint8_t)(P2_SERVER_MAX >> 8);
        data[4] = (uint8_t)(P2_SERVER_MAX);
        data[5] = (uint8_t)((P2_SERVER_EXTEND_MAX / 10) >> 8);
        data[6] = (uint8_t)(P2_SERVER_EXTEND_MAX / 10);
        data[7] = 0xAA;
        app_can_enqueue_msg(CAN_MSG_EVENT_SEND, NWL_RES_ADDR, data, 8);
        g_p2_service_time_remaining = 0; // 如果发送诊断报文,则清除倒计时。P2_SERVER_MAX
    end:
        return;
    }
    
    #if AUTOSAR_DIAG_SWITCH && USE_UDS_10
    DIAG_SERVICE_REG(UDS_ID, DIAG_NO_SECURITY_LEVEL, (DEFAULT_SESSION|PROGRAMMING_SESSION|EXTENDED_SESSION),
                     (DIAG_PHYS_REQ|DIAG_FUNC_REQ), NULL, NULL, uds10_main);
    
    
    #endif
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
  • 相关阅读:
    Llama改进之——RoPE旋转位置编码
    Unity DOTS技术(五)Archetype,Chunk,NativeArray
    如何正确使用多线程和锁机制来构建可靠的程序
    Java面试八股文整理
    【C++】map和set——树形结构的关联式容器
    Floxif蠕虫病毒分析与处置
    VSCode远程连接Linux系统并使用远程终端
    【老文新发】Otsu大津法详解及python实现
    负载均衡技术全景:理论、实践与案例研究
    heapdump泄露Shiro key从而RCE
  • 原文地址:https://blog.csdn.net/qq_29246181/article/details/133963341