![]()
在汽车电子诊断领域(如 UDS、OBD),服务标识符(Service Identifier, SID)是诊断报文的核心字段,用于区分不同的诊断服务或响应类型。SID 占用 1 字节,取值范围 0x00~0xFF。理解 SID 的划分是开发诊断栈、解析诊断报文的基础。
1. 整体地址空间划分
根据 ISO 14229(UDS)、ISO 15031-5(OBD)以及行业惯例,0x00~0xFF 可划分为以下主要区域:
范围
类型
典型协议/说明
0x00 – 0x3E
诊断请求 SID
UDS (ISO 14229-1) 定义的服务请求
0x3F
未应用 / 保留
0x40 – 0x4F
诊断响应 SID
OBD 模式响应(ISO 15031-5)及部分 UDS 正响应
0x50 – 0x7E
UDS 正响应 SID
对应请求 SID + 0x40
0x7F
负响应标识符
否定响应报文(Negative Response)
0x80 – 0xBF
保留 / 制造商自定义
ISO 14229 保留区域,部分供 OEM 使用
0xC0 – 0xFF
制造商特定 / 系统特定
由汽车或系统制造商定义,不属于标准 UDS/OBD 服务
注意:UDS 正响应 SID = 请求 SID + 0x40。例如请求 0x10(DiagnosticSessionControl)的正响应是 0x50。2. 各区间详细说明 2.1 0x00 – 0x3E:UDS 请求 SID
ISO 14229-1 定义了此区间内的服务,常见的有:
SID(十六进制)
服务名称
0x10
DiagnosticSessionControl
0x11
ECUReset
0x22
ReadDataByIdentifier
0x2E
WriteDataByIdentifier
0x27
SecurityAccess
0x3E
TesterPresent
0x3E(TesterPresent)是实际使用的请求 SID,0x3F未定义。
2.2 0x40 – 0x4F:OBD 响应 & UDS 早期响应
0x40 – 0x4F在 OBD 中对应模式请求的响应。例如 OBD 模式
0x01(请求当前动力总成数据)的响应 SID 为0x41。在 UDS 中,此区间也作为部分正响应使用(如
0x44、0x45等,但较少见)。
此区间完全对应请求 SID0x10~0x3E的正响应。例如:
0x10请求 →0x50正响应0x22请求 →0x62正响应0x3E请求 →0x7E正响应
当 ECU 无法处理某请求时,返回负响应报文,其第一个字节固定为0x7F,随后是请求的 SID 和负响应码(NRC)。例如:
7F 22 13 → 对 ReadDataByIdentifier (0x22) 的负响应,NRC=0x13(invalidLength)
2.5 0x80 – 0xFF:保留 & 制造商特定0x80 – 0xBF:ISO 14229 保留为未来使用,部分被 AUTOSAR 或特定 OEM 占用。
0xC0 – 0xFF:完全由制造商自定义,可用于私有诊断服务或扩展功能。
以下代码演示如何识别 SID 类型并提供基础解析框架。
#include
#include
// 服务标识符类型枚举
enum class SidType {
UDS_REQUEST,
OBD_RESPONSE, // 0x40-0x4F 中的 OBD 响应
UDS_POSITIVE_RESPONSE,
NEGATIVE_RESPONSE,
RESERVED,
MANUFACTURER_SPECIFIC
};
// 判断 SID 的类型
SidType getSidType(uint8_t sid) {
if (sid >= 0x00 && sid <= 0x3E)
return SidType::UDS_REQUEST;
else if (sid >= 0x40 && sid <= 0x4F)
return SidType::OBD_RESPONSE; // 也可以统一归为正响应,但 OBD 特殊
else if (sid >= 0x50 && sid <= 0x7E)
return SidType::UDS_POSITIVE_RESPONSE;
else if (sid == 0x7F)
return SidType::NEGATIVE_RESPONSE;
else if (sid >= 0x80 && sid <= 0xBF)
return SidType::RESERVED;
else // 0xC0-0xFF
return SidType::MANUFACTURER_SPECIFIC;
}
// 根据 SID 获得服务名称(仅示例部分常用值)
std::string getServiceName(uint8_t sid, SidType type) {
if (type == SidType::UDS_REQUEST) {
switch (sid) {
case 0x10: return "DiagnosticSessionControl";
case 0x11: return "ECUReset";
case 0x22: return "ReadDataByIdentifier";
case 0x2E: return "WriteDataByIdentifier";
case 0x27: return "SecurityAccess";
case 0x3E: return "TesterPresent";
default: return "Unknown UDS request";
}
}
else if (type == SidType::UDS_POSITIVE_RESPONSE) {
uint8_t reqSid = sid - 0x40;
return "Positive response to request " + std::to_string(reqSid);
}
else if (type == SidType::OBD_RESPONSE) {
uint8_t mode = sid - 0x40;
return "OBD response for mode " + std::to_string(mode);
}
else if (type == SidType::NEGATIVE_RESPONSE) {
return "Negative response identifier";
}
else if (type == SidType::RESERVED) {
return "Reserved (ISO 14229)";
}
else {
return "Manufacturer specific";
}
}
// 解析一条诊断报文(仅针对 SID 部分)
void diagnoseMessage(const uint8_t* msg, size_t len) {
if (len == 0) return;
uint8_t sid = msg[0];
SidType type = getSidType(sid);
std::string name = getServiceName(sid, type);
std::cout << "SID: 0x" << std::hex << std::setw(2) << std::setfill('0') << (int)sid << std::dec;
std::cout << " -> Type: ";
switch (type) {
case SidType::UDS_REQUEST: std::cout << "UDS Request"; break;
case SidType::OBD_RESPONSE: std::cout << "OBD Response"; break;
case SidType::UDS_POSITIVE_RESPONSE: std::cout << "UDS Positive Response"; break;
case SidType::NEGATIVE_RESPONSE: std::cout << "Negative Response"; break;
case SidType::RESERVED: std::cout << "Reserved"; break;
case SidType::MANUFACTURER_SPECIFIC: std::cout << "Manufacturer Specific"; break;
}
std::cout << ", Name: " << name << std::endl;
// 负响应时建议继续解析后续字节(NRC)
if (type == SidType::NEGATIVE_RESPONSE && len >= 3) {
std::cout << " >> Request SID that caused negative: 0x" << std::hex << (int)msg[1] << std::dec;
std::cout << ", NRC: 0x" << std::hex << (int)msg[2] << std::dec << std::endl;
}
}
// 示例测试
int main() {
// 模拟几个诊断报文(仅首字节为 SID)
uint8_t request[] = {0x22, 0xF1, 0x90}; // ReadDataByIdentifier
uint8_t positive[] = {0x62, 0xF1, 0x90, 0x01, 0x02}; // 正响应
uint8_t negative[] = {0x7F, 0x22, 0x13}; // 负响应
uint8_t obdResp[] = {0x41, 0x05, 0x7F}; // OBD mode 1 response
uint8_t vendor[] = {0xE0, 0x01, 0x02}; // 制造商自定义
diagnoseMessage(request, sizeof(request));
diagnoseMessage(positive, sizeof(positive));
diagnoseMessage(negative, sizeof(negative));
diagnoseMessage(obdResp, sizeof(obdResp));
diagnoseMessage(vendor, sizeof(vendor));return 0;
}
输出示例:
SID: 0x22 -> Type: UDS Request, Name: ReadDataByIdentifier
SID: 0x62 -> Type: UDS Positive Response, Name: Positive response to request 34
SID: 0x7F -> Type: Negative Response, Name: Negative response identifier
>> Request SID that caused negative: 0x22, NRC: 0x13
SID: 0x41 -> Type: OBD Response, Name: OBD response for mode 1
SID: 0xE0 -> Type: Manufacturer Specific, Name: Manufacturer specific
4. 总结0x00–0x3E:UDS 请求服务,是诊断仪主动发出的指令。
0x40–0x7E:正响应,其中 0x40–0x4F 多为 OBD 响应,0x50–0x7E 为 UDS 正响应。
0x7F:负响应的固定标识,后面跟随原请求 SID 和错误码。
0x80–0xFF:保留或制造商自定义,扩展性强。
掌握 SID 的划分,能帮助开发者快速判断报文方向、解析协议一致性,并编写健壮的车载诊断软件。上述 C++ 代码给出了一个轻量级的 SID 识别器,可嵌入到实际诊断栈或工具链中,根据需求继续补充更多服务名称和解析逻辑。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.