![]()
一、會(huì)話模式與等級(jí)的意義 1.1 基本概念
UDS(Unified Diagnostic Services,ISO 14229)中的0x10服務(wù)用于控制ECU的診斷會(huì)話狀態(tài)。診斷會(huì)話模式本質(zhì)上是一種安全機(jī)制,通過劃分不同權(quán)限等級(jí),限制敏感診斷服務(wù)的訪問。
1.2 三種標(biāo)準(zhǔn)會(huì)話子功能
子功能
名稱
典型可用服務(wù)
0x01
Default Session(默認(rèn)會(huì)話)
22讀取數(shù)據(jù)、11讀取DTC、14清除DTC、3E保活
0x02
Programming Session(編程會(huì)話)
34請(qǐng)求下載、36傳輸數(shù)據(jù)、37退出傳輸
0x03
Extended Session(擴(kuò)展會(huì)話)
27安全訪問、2E寫入數(shù)據(jù)、31例行程序、85DTC控制
1.3 會(huì)話模式切換示意圖
┌─────────────────────────────────────────────────────────┐
│ ECU上電/復(fù)位 │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ Default Session │?──────────────────┐ │
│ │ (權(quán)限最低) │ │ │
│ └────────┬─────────┘ │ │
│ │ 10 03 │ │
│ ▼ │ 10 01
│ ┌──────────────────┐ │ │
│ │ Extended Session│ │ │
│ │ (中等級(jí)別) │ │ │
│ └────────┬─────────┘ │ │
│ │ 10 02 │ │
│ ▼ │ │
│ ┌──────────────────┐ │ │
│ │ Programming Session│──────────────────┘ │
│ │ (最高權(quán)限) │ │
│ └──────────────────┘ │
└─────────────────────────────────────────────────────────┘
二、會(huì)話模式跳轉(zhuǎn)規(guī)則 2.1 核心規(guī)則表當(dāng)前會(huì)話
目標(biāo)會(huì)話
是否允許
Default
Default
重新初始化默認(rèn)會(huì)話
Default
Extended
停止已配置的ResponseOnEvent
Default
Programming
必須經(jīng)過Extended
Extended
Default
重置所有會(huì)話相關(guān)設(shè)置
Extended
Extended
安全訪問需重新解鎖
Extended
Programming
單向跳轉(zhuǎn)
Programming
Default
重置并啟用安全鎖定
Programming
Extended
禁止反向跳轉(zhuǎn)
Programming
Programming
重新初始化編程會(huì)話
2.2 超時(shí)機(jī)制(S3保活)
Tester ECU
│ │
│──────── 10 03 (進(jìn)入Extended) ─────────?│
│?─────── 50 03 (肯定響應(yīng)) ─────────────│
│ │
│ (S3_client周期內(nèi)) │
│──────── 3E 00 (TesterPresent) ───────?│
│?─────── 7E 00 (保活響應(yīng)) ─────────────│
│ │
│ (超過S3_server時(shí)間無診斷請(qǐng)求) │
│ │──┐
│ │ │ 自動(dòng)切回
│ │?─┘ Default
三、C++代碼實(shí)現(xiàn) 3.1 診斷會(huì)話管理器類定義3.2 診斷會(huì)話管理器實(shí)現(xiàn)// UdsSessionManager.h
#ifndef UDS_SESSION_MANAGER_H
#define UDS_SESSION_MANAGER_H
#include
#include
#include
#include
#include
namespace Uds {
// 診斷會(huì)話類型枚舉
enum class DiagnosticSession : uint8_t {
DEFAULT_SESSION = 0x01,
PROGRAMMING_SESSION = 0x02,
EXTENDED_SESSION = 0x03
};
// 服務(wù)ID枚舉
enum class ServiceId : uint8_t {
DIAGNOSTIC_SESSION_CONTROL = 0x10,
ECU_RESET = 0x11,
READ_DATA_BY_ID = 0x22,
SECURITY_ACCESS = 0x27,
COMMUNICATION_CONTROL = 0x28,
READ_DTC_INFO = 0x19,
WRITE_DATA_BY_ID = 0x2E,
ROUTINE_CONTROL = 0x31,
REQUEST_DOWNLOAD = 0x34,
TRANSFER_DATA = 0x36,
REQUEST_TRANSFER_EXIT = 0x37,
TESTER_PRESENT = 0x3E
};
// 安全訪問狀態(tài)
enum class SecurityLevel : uint8_t {
LOCKED = 0x00,
LEVEL1_UNLOCKED = 0x01,
LEVEL2_UNLOCKED = 0x02
};
// 診斷響應(yīng)結(jié)構(gòu)體
struct DiagnosticResponse {
uint8_t serviceId;
std::vector data;
bool success;
std::string errorMessage;
DiagnosticResponse() : success(false) {}
};
// 會(huì)話管理器類
class UdsSessionManager {
public:
using TimerCallback = std::function;
UdsSessionManager();
~UdsSessionManager();
// 核心服務(wù)處理
DiagnosticResponse handleDiagnosticSessionControl(const std::vector& request);
DiagnosticResponse handleTesterPresent(const std::vector& request);
DiagnosticResponse handleEcuReset(const std::vector& request);
// 服務(wù)訪問權(quán)限檢查
bool isServiceAllowedInCurrentSession(ServiceId serviceId) const;
// 狀態(tài)查詢
DiagnosticSession getCurrentSession() const { return currentSession_; }
SecurityLevel getSecurityLevel() const { return securityLevel_; }
bool isSessionTimedOut() const;
// 定時(shí)器管理
void updateSessionActivity();
void setS3ServerTimeout(uint32_t milliseconds);
// 非易失性數(shù)據(jù)管理(模擬)
void setVin(const std::vector& vin);
std::vector getVin() const;private:
// 會(huì)話狀態(tài)
DiagnosticSession currentSession_;
SecurityLevel securityLevel_;
// 定時(shí)器相關(guān)
uint32_t s3ServerTimeoutMs_; // S3server超時(shí)時(shí)間(默認(rèn)5000ms)
std::chrono::steady_clock::time_point lastDiagnosticActivity_;
// 持久化數(shù)據(jù)(不會(huì)因會(huì)話切換而重置)
std::vector vin_; // VIN碼 (2E F1 90)
// 會(huì)話相關(guān)狀態(tài)(會(huì)話切換時(shí)可能重置)
bool responseOnEventActive_; // 0x86服務(wù)激活狀態(tài)
bool communicationControlActive_; // 0x28服務(wù)激活狀態(tài)
bool dtcControlActive_; // 0x85服務(wù)激活狀態(tài)
// 服務(wù)權(quán)限映射表
std::map std :: vector > sessionAllowedServices_;
// 跳轉(zhuǎn)規(guī)則驗(yàn)證
bool canTransitionTo(DiagnosticSession target) const ;
// 會(huì)話初始化/重置
void initializeSession(DiagnosticSession session, bool isTransition) ;
void resetSessionRelatedStates() ;
void lockSecurity() ;
// 響應(yīng)構(gòu)造
DiagnosticResponse buildPositiveResponse(uint8_t serviceId,
const std::vector& data) ;
DiagnosticResponse buildNegativeResponse(uint8_t serviceId,
uint8_t negativeCode) ;
// 定時(shí)器檢查線程
void startSessionTimeoutMonitor() ;
void stopSessionTimeoutMonitor() ;
void sessionTimeoutHandler() ;
std :: unique_ptr < std ::thread> timeoutMonitorThread_;
bool monitorRunning_;
};
} // namespace Uds
#endif // UDS_SESSION_MANAGER_H
3.3 使用示例// UdsSessionManager.cpp
#include "UdsSessionManager.h"
#include
#include
#include
#include
#include
namespace Uds {
// NRC (Negative Response Code) 定義
namespace NRC {
constexpr uint8_t GENERAL_REJECT = 0x10;
constexpr uint8_t SERVICE_NOT_SUPPORTED = 0x11;
constexpr uint8_t SUBFUNCTION_NOT_SUPPORTED = 0x12;
constexpr uint8_t INCORRECT_MESSAGE_LENGTH = 0x13;
constexpr uint8_t CONDITIONS_NOT_CORRECT = 0x22;
constexpr uint8_t REQUEST_SEQUENCE_ERROR = 0x24;
constexpr uint8_t SECURITY_ACCESS_DENIED = 0x33;
}
UdsSessionManager::UdsSessionManager()
: currentSession_(DiagnosticSession::DEFAULT_SESSION)
, securityLevel_(SecurityLevel::LOCKED)
, s3ServerTimeoutMs_(5000) // 默認(rèn)5秒
, lastDiagnosticActivity_(std::chrono::steady_clock::now())
, responseOnEventActive_(false)
, communicationControlActive_(false)
, dtcControlActive_(false)
, monitorRunning_(true)
{
// 初始化各會(huì)話允許的服務(wù)列表
// Default Session - 僅基礎(chǔ)診斷
sessionAllowedServices_[DiagnosticSession::DEFAULT_SESSION] = {
ServiceId::DIAGNOSTIC_SESSION_CONTROL,
ServiceId::ECU_RESET,
ServiceId::READ_DATA_BY_ID,
ServiceId::READ_DTC_INFO,
ServiceId::TESTER_PRESENT
};
// Extended Session - 高級(jí)診斷服務(wù)
sessionAllowedServices_[DiagnosticSession::EXTENDED_SESSION] = {
ServiceId::DIAGNOSTIC_SESSION_CONTROL,
ServiceId::ECU_RESET,
ServiceId::READ_DATA_BY_ID,
ServiceId::SECURITY_ACCESS,
ServiceId::COMMUNICATION_CONTROL,
ServiceId::READ_DTC_INFO,
ServiceId::WRITE_DATA_BY_ID,
ServiceId::ROUTINE_CONTROL,
ServiceId::TESTER_PRESENT
};
// Programming Session - Bootloader相關(guān)服務(wù)
sessionAllowedServices_[DiagnosticSession::PROGRAMMING_SESSION] = {
ServiceId::DIAGNOSTIC_SESSION_CONTROL,
ServiceId::ECU_RESET,
ServiceId::REQUEST_DOWNLOAD,
ServiceId::TRANSFER_DATA,
ServiceId::REQUEST_TRANSFER_EXIT,
ServiceId::TESTER_PRESENT
};
// 啟動(dòng)超時(shí)監(jiān)控線程
startSessionTimeoutMonitor();
}
UdsSessionManager::~UdsSessionManager() {
monitorRunning_ = false;
if (timeoutMonitorThread_ && timeoutMonitorThread_->joinable()) {
timeoutMonitorThread_->join();
}
}
//=============================================================================
// 核心服務(wù): 0x10 診斷會(huì)話控制
//=============================================================================
DiagnosticResponse UdsSessionManager::handleDiagnosticSessionControl(
const std::vector& request)
{
DiagnosticResponse response;
// 1. 長(zhǎng)度檢查: 至少2字節(jié) [SID, SubFunction]
if (request.size() < 2) {
return buildNegativeResponse(static_cast(ServiceId::DIAGNOSTIC_SESSION_CONTROL),
NRC::INCORRECT_MESSAGE_LENGTH);
}
uint8_t subFunction = request[1];
// 2. 子功能有效性檢查
DiagnosticSession targetSession;
switch (subFunction) {
case 0x01: targetSession = DiagnosticSession::DEFAULT_SESSION; break;
case 0x02: targetSession = DiagnosticSession::PROGRAMMING_SESSION; break;
case 0x03: targetSession = DiagnosticSession::EXTENDED_SESSION; break;
default:
return buildNegativeResponse(static_cast(ServiceId::DIAGNOSTIC_SESSION_CONTROL),
NRC::SUBFUNCTION_NOT_SUPPORTED);
}
// 3. 跳轉(zhuǎn)規(guī)則檢查
if (!canTransitionTo(targetSession)) {
return buildNegativeResponse(static_cast(ServiceId::DIAGNOSTIC_SESSION_CONTROL),
NRC::CONDITIONS_NOT_CORRECT);
}
// 4. 記錄舊會(huì)話用于特殊處理
DiagnosticSession oldSession = currentSession_;
// 5. 執(zhí)行會(huì)話切換
initializeSession(targetSession, true); // true表示這是跳轉(zhuǎn)切換
// 6. 構(gòu)造肯定響應(yīng)
std::vector responseData;
responseData.push_back(static_cast(targetSession));
// 可選: 添加P2/P2*定時(shí)參數(shù)(根據(jù)具體實(shí)現(xiàn))
responseData.push_back(0x00); // P2 = 0ms (使用默認(rèn))
responseData.push_back(0x00); // P2* = 0ms
response = buildPositiveResponse(
static_cast(ServiceId::DIAGNOSTIC_SESSION_CONTROL),
responseData);
// 打印日志
std::cout << "[UDS] Session transition: "
<< static_cast(oldSession) << " -> "
<< static_cast(targetSession) << std::endl;
return response;
}
//=============================================================================
// 核心服務(wù): 0x3E 保活服務(wù)
//=============================================================================
DiagnosticResponse UdsSessionManager::handleTesterPresent(
const std::vector& request)
{
DiagnosticResponse response;
// 非默認(rèn)會(huì)話需要持續(xù)接收3E來維持
updateSessionActivity();
// 標(biāo)準(zhǔn)響應(yīng): 7E 00
if (request.size() >= 2 && request[1] == 0x00) {
response = buildPositiveResponse(
static_cast(ServiceId::TESTER_PRESENT),
{0x00});
} else {
response = buildPositiveResponse(
static_cast(ServiceId::TESTER_PRESENT),
{});
}
return response;
}
//=============================================================================
// 核心服務(wù): 0x11 ECU復(fù)位
//=============================================================================
DiagnosticResponse UdsSessionManager::handleEcuReset(
const std::vector& request)
{
DiagnosticResponse response;
if (request.size() < 2) {
return buildNegativeResponse(static_cast(ServiceId::ECU_RESET),
NRC::INCORRECT_MESSAGE_LENGTH);
}
uint8_t resetType = request[1];
// 硬復(fù)位(0x01)或軟復(fù)位(0x03)后回到默認(rèn)會(huì)話
if (resetType == 0x01 || resetType == 0x03) {
// 重置會(huì)話狀態(tài)
initializeSession(DiagnosticSession::DEFAULT_SESSION, true);
response = buildPositiveResponse(
static_cast(ServiceId::ECU_RESET),
{resetType});
std::cout << "[UDS] ECU Reset (type " << static_cast(resetType)
<< "), session reset to Default" << std::endl;
} else {
response = buildNegativeResponse(static_cast(ServiceId::ECU_RESET),
NRC::SUBFUNCTION_NOT_SUPPORTED);
}
return response;
}
//=============================================================================
// 權(quán)限檢查: 當(dāng)前會(huì)話是否允許指定服務(wù)
//=============================================================================
bool UdsSessionManager::isServiceAllowedInCurrentSession(ServiceId serviceId) const
{
auto it = sessionAllowedServices_.find(currentSession_);
if (it == sessionAllowedServices_.end()) {
return false;
}
const auto& allowedServices = it->second;
return std::find(allowedServices.begin(), allowedServices.end(), serviceId)
!= allowedServices.end();
}
//=============================================================================
// 會(huì)話跳轉(zhuǎn)規(guī)則驗(yàn)證
//=============================================================================
bool UdsSessionManager::canTransitionTo(DiagnosticSession target) const
{
// 規(guī)則1: 相同會(huì)話總是允許
if (currentSession_ == target) {
return true;
}
// 規(guī)則2: 任何會(huì)話都可以回到Default
if (target == DiagnosticSession::DEFAULT_SESSION) {
return true;
}
// 規(guī)則3: Default不能直接跳轉(zhuǎn)到Programming
if (currentSession_ == DiagnosticSession::DEFAULT_SESSION &&
target == DiagnosticSession::PROGRAMMING_SESSION) {
return false;
}
// 規(guī)則4: Programming不能跳轉(zhuǎn)到Extended
if (currentSession_ == DiagnosticSession::PROGRAMMING_SESSION &&
target == DiagnosticSession::EXTENDED_SESSION) {
return false;
}
// 規(guī)則5: Extended可以跳轉(zhuǎn)到Programming
// 規(guī)則6: Default可以跳轉(zhuǎn)到Extended
return true;
}
//=============================================================================
// 會(huì)話初始化
//=============================================================================
void UdsSessionManager::initializeSession(DiagnosticSession session, bool isTransition)
{
DiagnosticSession oldSession = currentSession_;
currentSession_ = session;
// 更新活動(dòng)時(shí)間戳
updateSessionActivity();
if (!isTransition) {
// 首次啟動(dòng)初始化
return;
}
// --- 根據(jù)ISO 14229定義的跳轉(zhuǎn)規(guī)則處理 ---
// 3.1 從Default到Default: 重置所有會(huì)話相關(guān)設(shè)置
if (oldSession == DiagnosticSession::DEFAULT_SESSION &&
session == DiagnosticSession::DEFAULT_SESSION) {
resetSessionRelatedStates();
// 注意: 非易失性存儲(chǔ)器內(nèi)容(如VIN)保持不變
return;
}
// 3.2 從Default到非Default: 停止ResponseOnEvent
if (oldSession == DiagnosticSession::DEFAULT_SESSION &&
session != DiagnosticSession::DEFAULT_SESSION) {
responseOnEventActive_ = false;
// 其他狀態(tài)保持
return;
}
// 3.3 從非Default到非Default: 重新鎖定安全訪問
if (oldSession != DiagnosticSession::DEFAULT_SESSION &&
session != DiagnosticSession::DEFAULT_SESSION) {
// 安全訪問重新鎖定
lockSecurity();
// 停止ResponseOnEvent
responseOnEventActive_ = false;
// CommunicationControl和ControlDTCSetting狀態(tài)保持
// (communicationControlActive_, dtcControlActive_ 不重置)
return;
}
// 3.4 從非Default到Default: 重置所有會(huì)話相關(guān)設(shè)置
if (oldSession != DiagnosticSession::DEFAULT_SESSION &&
session == DiagnosticSession::DEFAULT_SESSION) {
resetSessionRelatedStates();
lockSecurity();
// 禁用所有非默認(rèn)會(huì)話特有的功能
communicationControlActive_ = false;
dtcControlActive_ = false;
return;
}
}
//=============================================================================
// 重置會(huì)話相關(guān)狀態(tài)(不重置非易失性數(shù)據(jù))
//=============================================================================
void UdsSessionManager::resetSessionRelatedStates()
{
responseOnEventActive_ = false;
// 周期性調(diào)度器等被禁用
// 所有OutputControl被禁用
}
//=============================================================================
// 鎖定安全訪問
//=============================================================================
void UdsSessionManager::lockSecurity()
{
securityLevel_ = SecurityLevel::LOCKED;
std::cout << "[UDS] Security locked" << std::endl;
}
//=============================================================================
// 超時(shí)管理
//=============================================================================
void UdsSessionManager::updateSessionActivity()
{
lastDiagnosticActivity_ = std::chrono::steady_clock::now();
}
bool UdsSessionManager::isSessionTimedOut() const
{
auto now = std::chrono::steady_clock::now();
auto elapsed = std::chrono::duration_cast(
now - lastDiagnosticActivity_);
return elapsed.count() > s3ServerTimeoutMs_;
}
void UdsSessionManager::setS3ServerTimeout(uint32_t milliseconds)
{
s3ServerTimeoutMs_ = milliseconds;
}
void UdsSessionManager::startSessionTimeoutMonitor()
{
timeoutMonitorThread_ = std::make_unique([this]() {
while (monitorRunning_) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// 僅在非默認(rèn)會(huì)話時(shí)檢查超時(shí)
if (currentSession_ != DiagnosticSession::DEFAULT_SESSION) {
if (isSessionTimedOut()) {
std::cout << "[UDS] Session timeout! Switching to Default" << std::endl;
initializeSession(DiagnosticSession::DEFAULT_SESSION, true);
}
}
}
});
}
//=============================================================================
// 非易失性數(shù)據(jù)管理
//=============================================================================
void UdsSessionManager::setVin(const std::vector& vin)
{
vin_ = vin;
std::cout << "[UDS] VIN written to non-volatile memory" << std::endl;
}
std::vector UdsSessionManager::getVin() const
{
return vin_;
}
//=============================================================================
// 響應(yīng)構(gòu)造
//=============================================================================
DiagnosticResponse UdsSessionManager::buildPositiveResponse(
uint8_t serviceId, const std::vector& data)
{
DiagnosticResponse resp;
resp.serviceId = serviceId | 0x40; // 肯定響應(yīng)SID = 請(qǐng)求SID + 0x40
resp.data = data;
resp.success = true;
return resp;
}
DiagnosticResponse UdsSessionManager::buildNegativeResponse(
uint8_t serviceId, uint8_t negativeCode)
{
DiagnosticResponse resp;
resp.serviceId = 0x7F; // 否定響應(yīng)SID
resp.data = {serviceId, negativeCode};
resp.success = false;
std::stringstream ss;
ss << "NRC: 0x" << std::hex << static_cast(negativeCode);
resp.errorMessage = ss.str();
return resp;
}} // namespace Uds
3.4 編譯與運(yùn)行// main.cpp - 演示UDS 0x10服務(wù)的使用
#include "UdsSessionManager.h"
#include
#include
using namespace Uds;
void printResponse(const DiagnosticResponse& resp, const std::string& context)
{
std::cout << "\n=== " << context << " ===" << std::endl;
std::cout << "SID: 0x" << std::hex << static_cast(resp.serviceId) << std::endl;
if (!resp.data.empty()) {
std::cout << "Data: ";
for (uint8_t byte : resp.data) {
std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0')
<< static_cast(byte) << " ";
}
std::cout << std::endl;
}
if (resp.success) {
std::cout << "Status: SUCCESS" << std::endl;
} else {
std::cout << "Status: FAILED - " << resp.errorMessage << std::endl;
}
}int main()
{
UdsSessionManager ecu;
std::cout << "========== UDS 0x10 Diagnostic Session Control Demo ==========" << std::endl;
// 1. 查詢初始狀態(tài)
std::cout << "\n[Initial] Session: "
<< static_cast(ecu.getCurrentSession())
<< " (Default)" << std::endl;
// 2. Default -> Extended (合法)
auto resp1 = ecu.handleDiagnosticSessionControl({0x10, 0x03});
printResponse(resp1, "Default -> Extended (10 03)");
// 驗(yàn)證服務(wù)權(quán)限
std::cout << "2E (WriteData) allowed in Extended? "
<< ecu.isServiceAllowedInCurrentSession(ServiceId::WRITE_DATA_BY_ID)
<< std::endl;
// 3. Extended -> Programming (合法)
auto resp2 = ecu.handleDiagnosticSessionControl({0x10, 0x02});
printResponse(resp2, "Extended -> Programming (10 02)");
// 驗(yàn)證編程服務(wù)權(quán)限
std::cout << "34 (RequestDownload) allowed in Programming? "
<< ecu.isServiceAllowedInCurrentSession(ServiceId::REQUEST_DOWNLOAD)
<< std::endl;
std::cout << "2E (WriteData) allowed in Programming? "
<< ecu.isServiceAllowedInCurrentSession(ServiceId::WRITE_DATA_BY_ID)
<< std::endl;
// 4. Programming -> Extended (非法 - 應(yīng)被拒絕)
auto resp3 = ecu.handleDiagnosticSessionControl({0x10, 0x03});
printResponse(resp3, "Programming -> Extended (10 03) [SHOULD FAIL]");
// 5. Programming -> Default (合法)
auto resp4 = ecu.handleDiagnosticSessionControl({0x10, 0x01});
printResponse(resp4, "Programming -> Default (10 01)");
// 6. Default -> Programming (非法 - 必須經(jīng)過Extended)
auto resp5 = ecu.handleDiagnosticSessionControl({0x10, 0x02});
printResponse(resp5, "Default -> Programming (10 02) [SHOULD FAIL]");
// 7. 重新進(jìn)入Extended,演示3E保活
ecu.handleDiagnosticSessionControl({0x10, 0x03});
std::cout << "\n[Extended Session Active] Sending TesterPresent..." << std::endl;
for (int i = 0; i < 3; i++) {
auto resp6 = ecu.handleTesterPresent({0x3E, 0x00});
std::cout << "3E #" << (i+1) << " response: 0x" << std::hex
<< static_cast(resp6.serviceId) << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
// 8. 模擬超時(shí)(設(shè)置短超時(shí)用于演示)
ecu.setS3ServerTimeout(2000); // 2秒超時(shí)
std::cout << "\n[Timeout Demo] Waiting 3 seconds without diagnostic request..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
std::cout << "Session after timeout: "
<< static_cast(ecu.getCurrentSession())
<< " (should be Default)" << std::endl;
// 9. 演示非易失性數(shù)據(jù)持久化
std::cout << "\n[Persistence Demo] Writing VIN to NVM..." << std::endl;
ecu.setVin({'W','V','W','Z','Z','Z','1','Z','Z','1','2','3','4','5','6','7','8'});
// 切換到不同會(huì)話再回來
ecu.handleDiagnosticSessionControl({0x10, 0x03});
ecu.handleDiagnosticSessionControl({0x10, 0x01});
auto vin = ecu.getVin();
std::cout << "VIN after session cycle: ";
for (uint8_t c : vin) std::cout << static_cast(c);
std::cout << " (preserved!)" << std::endl;
return 0;
}
四、關(guān)鍵要點(diǎn)總結(jié)# 編譯命令
g++ -std=c++17 -pthread UdsSessionManager.cpp main.cpp -o uds_demo# 運(yùn)行
./uds_demo
要點(diǎn)
安全機(jī)制
高權(quán)限服務(wù)需要先切換到對(duì)應(yīng)會(huì)話并完成安全解鎖
跳轉(zhuǎn)路徑
Default → Extended → Programming(單向)
超時(shí)保活
非默認(rèn)會(huì)話需周期性發(fā)送3E,否則自動(dòng)切回Default
安全鎖定
會(huì)話切換時(shí)安全訪問狀態(tài)會(huì)被重置(除非規(guī)則明確要求保持)
狀態(tài)保持
CommunicationControl和ControlDTCSetting在非默認(rèn)會(huì)話間切換時(shí)保持
持久化
NVM寫入的數(shù)據(jù)(如VIN)不受會(huì)話切換影響
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
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.