$10服务是Diagnostic Session Control诊断会话控制,子功能有01、02、03三种,这三种代表10服务可以进入的3种不同的会话模式。
01 Default默认会话,02 Programming编程会话(用于解锁bootloader相关的诊断服务,即程序烧录。),03 Extended扩展会话,ECU上电时,进入的是默认会话(Default)。
SF:子功能,比如01、02、03,编程会话只能通过先进扩展会话之后再进编程会话,当前为编程会话,不能直接发10 03跳转到扩展会话。
肯定相应:50 SF sessionParameterRecord
0x40+SID=0x50
SF是对应请求的子功能,请求是什么子功能,它就显示什么子功能。
P2Server_max:指的是ECU在收到请求和给出响应之间的这个时间间隔,他描述了ECU的反应速度。
P2*Server_max:在ECU给出NRC 78(等待)之后生效,所以会需要更长的反应时间。
/********************************************************************************
* @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