<tr id="tp1vn"><td id="tp1vn"><dl id="tp1vn"></dl></td></tr>
  1. <p id="tp1vn"></p>
  2. <sub id="tp1vn"><p id="tp1vn"></p></sub>
    <u id="tp1vn"><rp id="tp1vn"></rp></u>
    <meter id="tp1vn"></meter>
      <wbr id="tp1vn"><sup id="tp1vn"></sup></wbr>
      日韩第一页浮力,欧美a在线,中文字幕无码乱码人妻系列蜜桃 ,国产成人精品三级麻豆,国产男女爽爽爽免费视频,中文字幕国产精品av,两个人日本www免费版,国产v精品成人免费视频71pao
      網易首頁 > 網易號 > 正文 申請入駐

      UDS診斷協議:詳解例程控制-0x31服務

      0
      分享至


      一、服務概述

      例程控制(RoutineControl,0x31)服務是UDS協議中用于觸發ECU內部預定義程序執行的核心服務。與寫入數據(0x2E)服務不同,0x31服務執行的是動態過程而非靜態數據寫入,例如:

      • 軟件刷寫場景:擦除內存、CRC校驗、完整性驗證

      • 生產下線場景:底盤標定、傳感器校準、ECU自檢

      • 診斷維護場景:電池健康檢測、電機角度自學習、閥門執行器動作測試

      二、請求報文格式 2.1 報文結構

      字節位置    參數名稱                    說明
      Byte RoutineControl Request SID = 0x31
      Byte sub-function 例程控制類型(高4位保留,低4位有效)
      Byte -4 routineIdentifier 例程標識符(RID,2字節)
      Byte -N routineControlOptionRecord 可選參數(長度由RID定義)
      2.2 子功能定義(sub-function)

      子功能值

      名稱

      0x01

      startRoutine

      啟動例程

      0x02

      stopRoutine

      停止例程

      0x03

      requestRoutineResults

      請求例程執行結果


      注意:子功能字節的Bit 7抑制肯定響應位(suppressPosRspMsgIndicationBit)僅在0x01-0x03作為RoutineControlType使用時有效。
      2.3 例程的三種類型

      類型

      支持子功能

      生命周期

      典型應用

      短例程

      僅0x01

      同步執行,響應0x01時即完成

      內存擦除、CRC計算

      長例程

      0x01/0x02/0x03

      異步執行,運行固定時長后自結束

      攝像頭標定(10s)、電池檢測

      持續例程

      0x01/0x02/0x03

      無固定時長,需0x02主動停止

      閥門動作測試、故障注入


      三、響應報文格式 3.1 肯定響應

      字節位置    參數名稱                    說明
      Byte RoutineControl Response SID = 0x71
      Byte sub-function 與請求相同
      Byte -4 routineIdentifier 例程標識符
      Byte -N routineInfo/statusRecord 可選(狀態信息/結果數據)
      3.2 否定響應

      字節位置    參數名稱
      Byte 0x7F(否定響應標識)
      Byte 0x31(請求服務ID)
      Byte NRC(否定響應碼)
      3.3 支持的NRC列表

      NRC

      名稱

      觸發條件

      0x12

      sub-function not supported

      RID不支持當前請求的控制類型(如對短例程請求0x02)

      0x13

      incorrect message length

      報文長度錯誤(過短/過長)

      0x22

      conditions not correct

      前置條件不滿足(如車速未歸零、引擎未熄火)

      0x24

      request sequence error

      順序錯誤(如未發start直接發stop)

      0x31

      request out of range

      RID無效或參數超范圍

      0x33

      security access denied

      需要安全訪問但未解鎖


      四、C++代碼實現示例 4.1 枚舉和結構體定義

      #include  
      
      #include
      #include
      #include
      #include
      #include

      // UDS服務ID定義
      constexpr uint8_t UDS_SID_ROUTINE_CONTROL = 0x31;
      constexpr uint8_t UDS_SID_ROUTINE_CONTROL_RESP = 0x71;
      constexpr uint8_t UDS_NEGATIVE_RESPONSE = 0x7F;

      // 子功能定義
      enum class RoutineControlType : uint8_t {
      START_ROUTINE = 0x01,
      STOP_ROUTINE = 0x02,
      REQUEST_RESULTS = 0x03
      };

      // 否定響應碼(NRC)
      enum class NRC : uint8_t {
      NONE = 0x00,
      SUB_FUNCTION_NOT_SUPPORTED = 0x12,
      INCORRECT_MESSAGE_LENGTH = 0x13,
      CONDITIONS_NOT_CORRECT = 0x22,
      REQUEST_SEQUENCE_ERROR = 0x24,
      REQUEST_OUT_OF_RANGE = 0x31,
      SECURITY_ACCESS_DENIED = 0x33
      };

      // 例程類型枚舉
      enum class RoutineType {
      SHORT, // 短例程:同步執行,響應即完成
      LONG, // 長例程:異步執行,固定時長后自結束
      PERSISTENT // 持續例程:需主動停止
      };

      // 例程狀態
      enum class RoutineState {
      IDLE, // 未啟動
      RUNNING, // 運行中
      COMPLETED, // 已完成
      STOPPED // 已停止
      };

      // 例程信息結構體
      struct RoutineInfo {
      uint16_t id; // 例程標識符
      RoutineType type; // 例程類型
      bool needSecurity; // 是否需要安全訪問
      std::vector requiredSessionIds; // 支持的診斷會話
      std::function(const std::vector&)> startFunc; // 啟動回調
      std::function()> stopFunc; // 停止回調
      std::function()> resultFunc; // 結果回調
      std::chrono::steady_clock::time_point startTime; // 啟動時間(用于長例程超時檢測)
      int executionTimeMs; // 執行時長(毫秒,僅長例程有效)
      RoutineState state; // 當前狀態
      };

      // 診斷請求消息結構體
      struct DiagnosticRequest {
      uint8_t sid;
      uint8_t subFunction;
      std::vector data;
      };

      // 診斷響應消息結構體
      struct DiagnosticResponse {
      bool isPositive;
      uint8_t sid; // 肯定響應時為0x71,否定響應時為0x7F
      uint8_t requestSid; // 否定響應時原服務ID
      uint8_t nrc; // 否定響應碼
      std::vector responseData;
      };
      4.2 例程控制服務實現類

      class RoutineControlService {
      private:
      std::map m_routines;
      bool m_securityAccessGranted; // 簡化的安全訪問狀態
      uint8_t m_currentSessionId; // 當前診斷會話
      std::mutex m_mutex;

      // 檢查安全訪問(簡化實現)
      NRC checkSecurityAccess(const RoutineInfo& routine) {
      if (routine.needSecurity && !m_securityAccessGranted) {
      return NRC::SECURITY_ACCESS_DENIED;
      }
      return NRC::NONE;
      }

      // 檢查診斷會話支持
      NRC checkSessionSupport(const RoutineInfo& routine) {
      for (auto sessionId : routine.requiredSessionIds) {
      if (m_currentSessionId == sessionId) {
      return NRC::NONE;
      }
      }
      return NRC::REQUEST_OUT_OF_RANGE;
      }

      // 檢查前置條件(示例:車速、引擎狀態等)
      virtual NRC checkPreconditions(uint16_t routineId) {
      // 子類可重寫此方法實現具體的前置條件檢查
      // 例如檢查車速是否為0、引擎是否熄火等
      return NRC::NONE;
      }

      // 檢查請求順序
      NRC checkRequestSequence(RoutineControlType requestType, const RoutineInfo& routine) {
      if (requestType == RoutineControlType::START_ROUTINE) {
      if (routine.state != RoutineState::IDLE && routine.state != RoutineState::STOPPED) {
      return NRC::REQUEST_SEQUENCE_ERROR;
      }
      } else if (requestType == RoutineControlType::STOP_ROUTINE ||
      requestType == RoutineControlType::REQUEST_RESULTS) {
      if (routine.state != RoutineState::RUNNING && routine.state != RoutineState::COMPLETED) {
      return NRC::REQUEST_SEQUENCE_ERROR;
      }
      }
      return NRC::NONE;
      }

      // 異步后臺任務(用于長例程)
      void asyncRoutineExecution(RoutineInfo& routine) {
      std::this_thread::sleep_for(std::chrono::milliseconds(routine.executionTimeMs));
      std::lock_guard lock(m_mutex);
      auto it = m_routines.find(routine.id);
      if (it != m_routines.end() && it->second.state == RoutineState::RUNNING) {
      it->second.state = RoutineState::COMPLETED;
      std::cout << "[Async] Routine 0x" << std::hex << routine.id
      << " completed after " << std::dec << routine.executionTimeMs << "ms" << std::endl;
      }
      }

      public:
      RoutineControlService() : m_securityAccessGranted(false), m_currentSessionId(0x01) {}

      // 注冊例程
      void registerRoutine(const RoutineInfo& info) {
      std::lock_guard lock(m_mutex);
      m_routines[info.id] = info;
      }

      // 設置診斷會話
      void setDiagnosticSession(uint8_t sessionId) {
      m_currentSessionId = sessionId;
      }

      // 設置安全訪問狀態
      void setSecurityAccessGranted(bool granted) {
      m_securityAccessGranted = granted;
      }

      // 主處理函數
      DiagnosticResponse handleRequest(const DiagnosticRequest& request) {
      std::lock_guard lock(m_mutex);
      DiagnosticResponse response;

      // 1. 最小長度檢查(至少SID + subFunction + 2字節RID)
      if (request.data.size() < 3) {
      response.isPositive = false;
      response.sid = UDS_NEGATIVE_RESPONSE;
      response.requestSid = request.sid;
      response.nrc = static_cast(NRC::INCORRECT_MESSAGE_LENGTH);
      return response;
      }

      uint8_t subFuncByte = request.subFunction;
      uint8_t routineControlType = subFuncByte & 0x1F; // 提取低5位
      bool suppressPosRsp = (subFuncByte & 0x80) != 0; // Bit7抑制肯定響應
      // 2. 提取RID
      uint16_t routineId = (request.data[0] << 8) | request.data[1];
      // 3. 提取可選參數
      std::vector optionRecord;
      if (request.data.size() > 2) {
      optionRecord.assign(request.data.begin() + 2, request.data.end());
      }
      // 4. 檢查RID是否存在
      auto it = m_routines.find(routineId);
      if (it == m_routines.end()) {
      response.isPositive = false;
      response.sid = UDS_NEGATIVE_RESPONSE;
      response.requestSid = request.sid;
      response.nrc = static_cast(NRC::REQUEST_OUT_OF_RANGE);
      return response;
      }
      RoutineInfo& routine = it->second;
      // 5. 檢查子功能是否支持
      bool subFuncSupported = false;
      switch (static_cast (routineControlType)) {
      case RoutineControlType::START_ROUTINE:
      subFuncSupported = true;
      break;
      case RoutineControlType::STOP_ROUTINE:
      subFuncSupported = (routine.type != RoutineType::SHORT);
      break;
      case RoutineControlType::REQUEST_RESULTS:
      subFuncSupported = (routine.type != RoutineType::SHORT);
      break;
      default:
      subFuncSupported = false;
      break;
      }
      if (!subFuncSupported) {
      response.isPositive = false;
      response.sid = UDS_NEGATIVE_RESPONSE;
      response.requestSid = request.sid;
      response.nrc = static_cast(NRC::SUB_FUNCTION_NOT_SUPPORTED);
      return response;
      }
      // 6. 檢查診斷會話
      NRC sessionCheck = checkSessionSupport(routine);
      if (sessionCheck != NRC::NONE) {
      response.isPositive = false;
      response.sid = UDS_NEGATIVE_RESPONSE;
      response.requestSid = request.sid;
      response.nrc = static_cast(sessionCheck);
      return response;
      }
      // 7. 檢查安全訪問
      NRC securityCheck = checkSecurityAccess(routine);
      if (securityCheck != NRC::NONE) {
      response.isPositive = false;
      response.sid = UDS_NEGATIVE_RESPONSE;
      response.requestSid = request.sid;
      response.nrc = static_cast(securityCheck);
      return response;
      }
      // 8. 檢查前置條件
      NRC preConditionCheck = checkPreconditions(routineId);
      if (preConditionCheck != NRC::NONE) {
      response.isPositive = false;
      response.sid = UDS_NEGATIVE_RESPONSE;
      response.requestSid = request.sid;
      response.nrc = static_cast(preConditionCheck);
      return response;
      }
      // 9. 檢查請求順序
      NRC sequenceCheck = checkRequestSequence(static_cast (routineControlType), routine);
      if (sequenceCheck != NRC::NONE) {
      response.isPositive = false;
      response.sid = UDS_NEGATIVE_RESPONSE;
      response.requestSid = request.sid;
      response.nrc = static_cast(sequenceCheck);
      return response;
      }
      // 10. 執行例程控制邏輯
      std::vector resultData;
      switch (static_cast (routineControlType)) {
      case RoutineControlType::START_ROUTINE:
      routine.state = RoutineState::RUNNING;
      routine.startTime = std::chrono::steady_clock::now();
      if (routine.startFunc) {
      resultData = routine.startFunc(optionRecord);
      }
      if (routine.type == RoutineType::SHORT) {
      routine.state = RoutineState::COMPLETED;
      } else if (routine.type == RoutineType::LONG) {
      // 啟動異步任務
      std::thread(&RoutineControlService::asyncRoutineExecution, this, std::ref(routine)).detach();
      }
      break;
      case RoutineControlType::STOP_ROUTINE:
      if (routine.stopFunc) {
      resultData = routine.stopFunc();
      }
      routine.state = RoutineState::STOPPED;
      break;
      case RoutineControlType::REQUEST_RESULTS:
      if (routine.resultFunc) {
      resultData = routine.resultFunc();
      }
      break;
      }
      // 11. 構造肯定響應
      if (!suppressPosRsp) {
      response.isPositive = true;
      response.sid = UDS_SID_ROUTINE_CONTROL_RESP;
      response.responseData.push_back(routineControlType);
      response.responseData.push_back((routineId >> 8) & 0xFF);
      response.responseData.push_back(routineId & 0xFF);
      // 添加結果數據
      response.responseData.insert(response.responseData.end(), resultData.begin(), resultData.end());
      } else {
      // 抑制肯定響應
      response.isPositive = true;
      response.responseData.clear();
      }
      return response;
      }
      };
      4.3 具體例程注冊示例

      class ECUApplication {
      private:
      RoutineControlService m_routineService;
      bool m_memoryErased = false;
      bool m_cameraCalibrated = false;
      float m_calibrationResult[4] = {0};

      public:
      ECUApplication() {
      registerMemoryEraseRoutine();
      registerCameraCalibrationRoutine();
      registerValveActuatorRoutine();
      }

      // 示例1:短例程 - 內存擦除
      void registerMemoryEraseRoutine() {
      RoutineInfo eraseRoutine;
      eraseRoutine.id = 0xFF00;
      eraseRoutine.type = RoutineType::SHORT;
      eraseRoutine.needSecurity = true; // 需要安全訪問
      eraseRoutine.requiredSessionIds = {0x01, 0x02, 0x03}; // 支持默認、編程擴展、擴展會話
      eraseRoutine.state = RoutineState::IDLE;
      eraseRoutine.startFunc = [this](const std::vector& params) -> std::vector {
      // 參數解析:起始地址(4字節) + 長度(4字節)
      if (params.size() >= 8) {
      uint32_t startAddr = (params[0] << 24) | (params[1] << 16) | (params[2] << 8) | params[3];
      uint32_t length = (params[4] << 24) | (params[5] << 16) | (params[6] << 8) | params[7];
      std::cout << "[Routine] Erasing memory at 0x" << std::hex << startAddr
      << " size: " << std::dec << length << " bytes" << std::endl;
      // 模擬內存擦除操作
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
      m_memoryErased = true;
      // 返回例程信息
      return {0x01}; // routineInfo = 0x01 表示短例程完成
      }
      return {};
      };
      m_routineService.registerRoutine(eraseRoutine);
      }

      // 示例2:長例程 - 攝像頭標定(異步執行10秒)
      void registerCameraCalibrationRoutine() {
      RoutineInfo calibrationRoutine;
      calibrationRoutine.id = 0x1234;
      calibrationRoutine.type = RoutineType::LONG;
      calibrationRoutine.needSecurity = false;
      calibrationRoutine.requiredSessionIds = {0x01, 0x03}; // 默認和擴展會話
      calibrationRoutine.executionTimeMs = 10000; // 10秒
      calibrationRoutine.state = RoutineState::IDLE;
      calibrationRoutine.startFunc = [this](const std::vector& params) -> std::vector {
      // 標定參數:AA BB CC
      std::cout << "[Routine] Starting camera calibration with params: ";
      for (auto b : params) printf("%02X ", b);
      std::cout << std::endl;
      // 啟動標定異步任務(實際業務邏輯)
      std::thread([this]() {
      std::this_thread::sleep_for(std::chrono::seconds(10));
      // 模擬標定完成,存儲結果
      m_cameraCalibrated = true;
      m_calibrationResult[0] = 0.123f;
      m_calibrationResult[1] = 45.678f;
      m_calibrationResult[2] = 9.012f;
      m_calibrationResult[3] = 30.040f;
      std::cout << "[Routine] Camera calibration completed!" << std::endl;
      }).detach();
      return {}; // 無額外參數
      };
      calibrationRoutine.resultFunc = [this]() -> std::vector {
      // 返回標定結果:4個float各轉4字節(小端序示例)
      std::vector results;
      if (m_cameraCalibrated) {
      for (int i = 0; i < 4; i++) {
      uint32_t val = *reinterpret_cast(&m_calibrationResult[i]);
      results.push_back(val & 0xFF);
      results.push_back((val >> 8) & 0xFF);
      results.push_back((val >> 16) & 0xFF);
      results.push_back((val >> 24) & 0xFF);
      }
      }
      return results;
      };
      m_routineService.registerRoutine(calibrationRoutine);
      }

      // 示例3:持續例程 - 閥門動作測試
      void registerValveActuatorRoutine() {
      RoutineInfo valveRoutine;
      valveRoutine.id = 0x5678;
      valveRoutine.type = RoutineType::PERSISTENT;
      valveRoutine.needSecurity = true;
      valveRoutine.requiredSessionIds = {0x03}; // 僅擴展會話
      valveRoutine.state = RoutineState::IDLE;
      bool valveActive = false;
      valveRoutine.startFunc = [&valveActive](const std::vector& params) -> std::vector {
      uint8_t testMode = (params.size() > 0) ? params[0] : 0x01;
      std::cout << "[Routine] Starting valve actuator test, mode: " << (int)testMode << std::endl;
      valveActive = true;
      // 啟動閥門持續動作線程
      std::thread([&valveActive, testMode]() {
      int cycle = 0;
      while (valveActive) {
      std::cout << "[Valve] Cycle " << ++cycle << ": OPEN -> CLOSE" << std::endl;
      std::this_thread::sleep_for(std::chrono::seconds(2));
      }
      std::cout << "[Valve] Actuator test stopped" << std::endl;
      }).detach();
      return {testMode}; // 返回啟動的模式
      };
      valveRoutine.stopFunc = [&valveActive]() -> std::vector {
      valveActive = false;
      std::cout << "[Routine] Stopping valve actuator test" << std::endl;
      return {0x00, 0x01}; // 狀態記錄:停止碼 0x01
      };
      m_routineService.registerRoutine(valveRoutine);
      }

      // 處理診斷請求
      void runDiagnosticTest() {
      // 設置診斷環境
      m_routineService.setDiagnosticSession(0x03); // 擴展會話
      m_routineService.setSecurityAccessGranted(true); // 已解鎖
      // 測試1:內存擦除(短例程)
      std::cout << "\n========== Test 1: Memory Erase (Short Routine) ==========" << std::endl;
      DiagnosticRequest req1;
      req1.sid = UDS_SID_ROUTINE_CONTROL;
      req1.subFunction = static_cast(RoutineControlType::START_ROUTINE);
      req1.data = {0xFF, 0x00, 0x44, 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB}; // RID+起始地址+長度
      auto resp1 = m_routineService.handleRequest(req1);
      printResponse(resp1);
      // 測試2:攝像頭標定啟動(長例程)
      std::cout << "\n========== Test 2: Camera Calibration Start (Long Routine) ==========" << std::endl;
      DiagnosticRequest req2;
      req2.sid = UDS_SID_ROUTINE_CONTROL;
      req2.subFunction = static_cast(RoutineControlType::START_ROUTINE);
      req2.data = {0x12, 0x34, 0xAA, 0xBB, 0xCC};
      auto resp2 = m_routineService.handleRequest(req2);
      printResponse(resp2);
      // 等待長例程執行
      std::this_thread::sleep_for(std::chrono::seconds(12));
      // 測試3:請求標定結果
      std::cout << "\n========== Test 3: Request Calibration Results ==========" << std::endl;
      DiagnosticRequest req3;
      req3.sid = UDS_SID_ROUTINE_CONTROL;
      req3.subFunction = static_cast(RoutineControlType::REQUEST_RESULTS);
      req3.data = {0x12, 0x34};
      auto resp3 = m_routineService.handleRequest(req3);
      printResponse(resp3);
      // 測試4:閥門動作測試啟動(持續例程)
      std::cout << "\n========== Test 4: Valve Actuator Start (Persistent Routine) ==========" << std::endl;
      DiagnosticRequest req4;
      req4.sid = UDS_SID_ROUTINE_CONTROL;
      req4.subFunction = static_cast(RoutineControlType::START_ROUTINE);
      req4.data = {0x56, 0x78, 0x02}; // RID + 測試模式2
      auto resp4 = m_routineService.handleRequest(req4);
      printResponse(resp4);
      // 等待閥門動作幾秒鐘
      std::this_thread::sleep_for(std::chrono::seconds(5));
      // 測試5:停止閥門測試
      std::cout << "\n========== Test 5: Stop Valve Actuator ==========" << std::endl;
      DiagnosticRequest req5;
      req5.sid = UDS_SID_ROUTINE_CONTROL;
      req5.subFunction = static_cast(RoutineControlType::STOP_ROUTINE);
      req5.data = {0x56, 0x78};
      auto resp5 = m_routineService.handleRequest(req5);
      printResponse(resp5);
      // 測試6:錯誤場景 - RID不存在
      std::cout << "\n========== Test 6: Invalid RID (Negative Test) ==========" << std::endl;
      DiagnosticRequest req6;
      req6.sid = UDS_SID_ROUTINE_CONTROL;
      req6.subFunction = static_cast(RoutineControlType::START_ROUTINE);
      req6.data = {0x99, 0x99}; // 不存在的RID
      auto resp6 = m_routineService.handleRequest(req6);
      printResponse(resp6);
      }
      void printResponse(const DiagnosticResponse& resp) {
      if (!resp.isPositive) {
      std::cout << "[Response] NEGATIVE: 0x" << std::hex << (int)resp.sid
      << " 0x" << (int)resp.requestSid << " NRC=0x" << (int)resp.nrc << std::dec << std::endl;
      } else if (!resp.responseData.empty()) {
      std::cout << "[Response] POSITIVE: 0x" << std::hex << (int)UDS_SID_ROUTINE_CONTROL_RESP << " ";
      for (auto b : resp.responseData) {
      printf("%02X ", b);
      }
      std::cout << std::dec << std::endl;
      } else {
      std::cout << "[Response] POSITIVE (suppressed)" << std::endl;
      }
      }
      };

      int main() {
      ECUApplication app;
      app.runDiagnosticTest();
      return 0;
      }
      五、輸出示例

      ========== Test 1: Memory Erase (Short Routine) ==========
      [Routine] Erasing memory at 0x44AAAAAA size: 3131963051 bytes
      [Response] POSITIVE: 0x71 01 FF 00 01

      ========== Test 2: Camera Calibration Start (Long Routine) ==========
      [Routine] Starting camera calibration with params: AA BB CC
      [Response] POSITIVE: 0x71 01 12 34

      ========== Test 3: Request Calibration Results ==========
      [Async] Routine 0x1234 completed after 10000ms
      [Routine] Camera calibration completed!
      [Response] POSITIVE: 0x71 03 12 34 D9 CE F4 3E 68 12 37 42 7B 14 10 41 F5 28 F0 41

      ========== Test 4: Valve Actuator Start (Persistent Routine) ==========
      [Routine] Starting valve actuator test, mode: 2
      [Response] POSITIVE: 0x71 01 56 78 02

      [Valve] Cycle 1: OPEN -> CLOSE
      [Valve] Cycle 2: OPEN -> CLOSE
      [Valve] Cycle 3: OPEN -> CLOSE

      ========== Test 5: Stop Valve Actuator ==========
      [Routine] Stopping valve actuator test
      [Response] POSITIVE: 0x71 02 56 78 00 01

      [Valve] Actuator test stopped

      ========== Test 6: Invalid RID (Negative Test) ==========
      [Response] NEGATIVE: 0x7F 0x31 NRC=0x31
      六、關鍵實現要點
      1. 同步vs異步處理:長例程必須使用異步執行,避免阻塞診斷通信

      2. 順序檢查:持續例程必須檢查start→stop的順序合法性

      3. 狀態管理:需維護每個RID的生命周期狀態

      4. 超時處理:長例程應支持超時自動完成并更新狀態

      5. 抑制肯定響應:支持sub-function的Bit7位來控制是否響應

      以上實現了符合ISO 14229標準的0x31服務完整處理邏輯,可應用于ECU量產診斷棧的開發。

      特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。

      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.

      相關推薦
      熱點推薦
      5人4杰青!全是名校領導,被舉報學術造假,評論區怒火徹底壓不住

      5人4杰青!全是名校領導,被舉報學術造假,評論區怒火徹底壓不住

      譚談社會
      2026-05-14 22:46:49
      時隔9年再進西決!馬刺4比2淘汰森林狼 下輪戰雷霆

      時隔9年再進西決!馬刺4比2淘汰森林狼 下輪戰雷霆

      體壇周報
      2026-05-16 12:32:10
      深圳一建筑工地兩名工人從6樓墜亡?當地住建確認涉事項目有安全事故發生致2人死亡,已要求項目停工整改

      深圳一建筑工地兩名工人從6樓墜亡?當地住建確認涉事項目有安全事故發生致2人死亡,已要求項目停工整改

      大風新聞
      2026-05-15 17:32:44
      支付寶回應“扣款捐贈184萬元”:涉事賬戶存在與他人共用嫌疑,正在向警方尋求幫助

      支付寶回應“扣款捐贈184萬元”:涉事賬戶存在與他人共用嫌疑,正在向警方尋求幫助

      每日經濟新聞
      2026-05-15 13:22:06
      老人不死,孩子遭罪,如果八九十歲的雙親還在,要牢記這三條準則

      老人不死,孩子遭罪,如果八九十歲的雙親還在,要牢記這三條準則

      吃貨的分享
      2026-05-16 07:40:50
      我去!詹姆斯只值720萬了!?不簽了!?找濃眉去!

      我去!詹姆斯只值720萬了!?不簽了!?找濃眉去!

      柚子說球
      2026-05-15 10:27:52
      國務院常務會議:努力保持適度生育水平和人口規模,持續積累和釋放人力資源紅利

      國務院常務會議:努力保持適度生育水平和人口規模,持續積累和釋放人力資源紅利

      新京報
      2026-05-15 20:19:21
      德約紀錄雖破,但當年的決賽四連殺納達爾依舊偉大!

      德約紀錄雖破,但當年的決賽四連殺納達爾依舊偉大!

      網球之家
      2026-05-15 23:32:33
      馬斯克為啥到哪都帶著小兒子?最喜小兒亡賴:偏愛之外還有大計劃

      馬斯克為啥到哪都帶著小兒子?最喜小兒亡賴:偏愛之外還有大計劃

      老方
      2026-05-15 20:49:47
      1952年許世友返鄉,不顧老母親下跪勸阻,掏出槍對準三叔:斃了你

      1952年許世友返鄉,不顧老母親下跪勸阻,掏出槍對準三叔:斃了你

      云端小院
      2026-05-12 06:41:03
      要打奉陪到底,中方當面插旗,沉默72小時后,日本在境外發射導彈

      要打奉陪到底,中方當面插旗,沉默72小時后,日本在境外發射導彈

      靜兒家
      2026-05-16 09:54:33
      北京官方收廢品小程序上線!上門回收

      北京官方收廢品小程序上線!上門回收

      家住昌平
      2026-05-15 18:18:36
      王楚欽捐MVP獎金!許昕喊梁靖崑"梁哥" 孫穎莎穿小西裝破圈登頂《尚流》

      王楚欽捐MVP獎金!許昕喊梁靖崑"梁哥" 孫穎莎穿小西裝破圈登頂《尚流》

      好乒乓
      2026-05-16 10:32:42
      王菊回應床戲尺度大:男女正常需求,說出了多少女性的心聲

      王菊回應床戲尺度大:男女正常需求,說出了多少女性的心聲

      觀察鑒娛
      2026-05-14 11:13:31
      5月15日俄烏最新:烏克蘭的報復行動來了

      5月15日俄烏最新:烏克蘭的報復行動來了

      西樓飲月
      2026-05-15 18:44:45
       著名皮膚性病學家王仁林逝世,享年101歲

      著名皮膚性病學家王仁林逝世,享年101歲

      澎湃新聞
      2026-05-15 18:48:26
      從傲慢到沉默再到承認,三天中國行后,魯比奧給了解放軍一個排名

      從傲慢到沉默再到承認,三天中國行后,魯比奧給了解放軍一個排名

      小樾說歷史
      2026-05-16 11:17:23
      A股:大家系好安全帶了,不出意外的話,A股或將迎來黑色星期一?

      A股:大家系好安全帶了,不出意外的話,A股或將迎來黑色星期一?

      趨勢清風俠
      2026-05-16 11:02:29
      未雨綢繆!即將擔任皇馬主帥的穆帥,要求皇馬今夏補強后防線

      未雨綢繆!即將擔任皇馬主帥的穆帥,要求皇馬今夏補強后防線

      福醬的小時光
      2026-05-16 07:26:54
      愛吃楊梅的人一覺睡醒天塌了!泡藥水增甜,還說浙江人吃的最多

      愛吃楊梅的人一覺睡醒天塌了!泡藥水增甜,還說浙江人吃的最多

      一口娛樂
      2026-05-16 11:01:11
      2026-05-16 12:52:49
      新能源自動駕駛 incentive-icons
      新能源自動駕駛
      專注于半導體行業資訊
      977文章數 347關注度
      往期回顧 全部

      科技要聞

      漲的是車價,要的是老命

      頭條要聞

      30歲女子用爬樓機鍛煉幾分鐘摔倒 搶救110分鐘后身亡

      頭條要聞

      30歲女子用爬樓機鍛煉幾分鐘摔倒 搶救110分鐘后身亡

      體育要聞

      35歲坎特,干了一件這輩子最吵的事

      娛樂要聞

      張嘉譯和老婆的差距讓人心酸

      財經要聞

      造詞狂魔賈躍亭

      汽車要聞

      高爾夫GTI刷新紐北紀錄 ID. Polo GTI迎全球首秀

      態度原創

      手機
      藝術
      家居
      游戲
      軍事航空

      手機要聞

      CounterPoint稱三星Galaxy S26系列手機首發全球銷量增長13%

      藝術要聞

      19位當代畫家油畫作品欣賞

      家居要聞

      110㎡淡而有致的生活表達

      電影收獲好評后 《真人快打11》玩家數逼近最新作

      軍事要聞

      聯合國安理會審議敘利亞局勢

      無障礙瀏覽 進入關懷版 主站蜘蛛池模板: 久久一二三四区中文字幕| 亚洲最大福利视频网| 欧洲肉欲k8播放毛片| 青青av| 国产 亚洲 制服 无码 中文| 亚洲一区二区三区av免费| 国产成人无码A区在线观| 精品香蕉久久久午夜福利| 亚洲熟妇自偷自拍另欧美| 绝美人妻被夫前侵犯| 亚洲精品aⅴ无码精品丝袜足| 麻豆精品国产自产在线| 成片免费观看视频大全| 中文字幕人妻中文AV不卡专区| 日韩精品网站| 中文字幕日韩精品欧美一区| 精品欧洲av无码一区二区男男 | 国产精品亚洲精品日韩已满 | 狠狠色狠狠色综合久久第一次| 一级成人a做片免费| 激情一区二区三区成人文| 东京热无码大乱AV| 丰满熟女人妻中出系列| 精品午夜中文字幕熟女人妻在线 | 国产成人午夜福利院| 人妻熟妇乱又伦精品无码专区| 五月。。激情綜合老漢色| 久久成人黄色| 久久久久久久综合综合狠狠| 久久天天躁狠狠躁夜夜2019| 亚洲国产成人无码网站大全| 西西人体做爰大胆gogo| 国产高清A片| 中文日产乱幕九区无线码| 国产成人亚洲精品无码影院bt| 日本抽搐一进一出gif免费| 性一交一乱一伧国产女士spa| 日韩中文字幕V亚洲中文字幕| 脱岳裙子从后面挺进去在线观看 | 性男女做视频观看网站| 极品粉嫩福利午夜在线播放|