先知道這台設備回報了什麼身分
維護人員接上設備後,常先問型號與韌體版本是否和圖面相符。若產品支援Read Device Identification,可用功能碼2Bh搭配MEI Type 0Eh讀取識別物件,建立通訊端點與資產資料的對照。這是讀取設備宣告的身分,不是驗證設備真偽的密碼學機制,也不能取代銘牌與實際硬體版本核對。
| 物件ID十六進位 | 標準名稱 | 使用方式 |
|---|---|---|
| 00 | VendorName | 保存廠商宣告字串 |
| 01 | ProductCode | 與資產表產品碼比對 |
| 02 | MajorMinorRevision | 保存修訂字串,不擅自改格式 |
| 03至06 | Regular物件 | 網址、產品名、型號名、應用名等選用項 |
| 80至FF | Extended私人定義 | 必須另查廠商物件文件 |
基本類別的00、01、02是這個識別介面的必要物件;不代表每一台支援Modbus的設備都必須實作整個識別功能。若回覆例外01,先核對產品支援度,而不是把它當成站號錯。私人物件也不能只因編號相同就跨品牌套用語意。
本文以虛構產品字串做離線PDU練習,不含RTU站號CRC或TCP MBAP。先記錄TCP端點或串列站號、日期、設備手冊版本與原始回覆,再整理文字;只抄畫面上的產品名會丟失分頁、長度與來源證據。
存取方式與支援等級要分開看
請求中的Read Device ID code選擇讀取方式。01讀基本類別,02讀一般類別,03讀擴充類別,這三種屬串流存取,可分多次交易取得物件;04是指定單一物件的個別存取。這個code不是物件編號,也不是裝置站號。第一次串流讀取由物件00開始,再依回覆指示續讀。
| 回覆Conformity Level | 支援類別 | 支援存取 |
|---|---|---|
| 01 | Basic | 串流 |
| 02 | Regular | 串流 |
| 03 | Extended | 串流 |
| 81 | Basic | 串流與個別 |
| 82 | Regular | 串流與個別 |
| 83 | Extended | 串流與個別 |
因此讀到Conformity=01,不能直接送code04並假定設備一定會接受。先依表確認存取能力,才能安排後續查詢。請求較高類別而設備只有較低支援等級時,須依規範和實際回覆處理,不能把不存在的擴充物件填成零或空字串,造成資產資料看似完整。
自訂第一次請求為2B 0E 01 00,四byte依序是功能碼、MEI、讀取方式與起始物件ID。如果只想取得某個物件,先完成基本識別並確認個別存取支援,再使用文件允許的code04。把這兩個階段寫在操作步驟,比一開始掃描所有物件編號更容易追查。
從回覆長度讀出三個字串
虛構測試設備回報VendorName為LAB,ProductCode為T1,MajorMinorRevision為1.2。正常基本回覆可寫成2B 0E 01 01 00 00 03 00 03 4C 41 42 01 02 54 31 02 03 31 2E 32,共二十一byte。這些名稱不是任何品牌的真實產品宣告。
| 回覆欄位 | 本例值 | 解析重點 |
|---|---|---|
| Function / MEI / code | 2B / 0E / 01 | 核對原請求 |
| Conformity | 01 | Basic且串流存取 |
| More Follows / Next ID | 00 / 00 | 這輪沒有續頁 |
| Number of objects | 03 | 後面有三組物件 |
| 物件00 | 00 03 4C 41 42 | 長度3,字串LAB |
| 物件01 | 01 02 54 31 | 長度2,字串T1 |
| 物件02 | 02 03 31 2E 32 | 長度3,字串1.2 |
每組物件都由ID一byte、長度一byte、指定長度的值組成。固定回覆欄位七byte,加上三組的5、4、5byte,總長為21。長度計的是bytes,不是畫面中文字數;此處標準基本字串採ASCII,不應擅自把兩byte當成Unicode字元,或靠結尾零字元尋找下一物件。
解析時先確認剩餘buffer足夠容納物件ID與長度,再確認資料長度沒有超過本次PDU。處理完三個物件後也要驗算整體消耗量。若宣告長度五卻只剩三byte,拒絕這次識別結果並保留原始資料,不把殘缺字串寫入正式資產表。
保存字串時也保留原始bytes,遇到設備回傳不符合宣告編碼的內容,標記解碼異常供查證,不用刪字或自動補字的方法把資產名稱修成看似合理。
多次交易如何收齊而不混入舊設備
長識別資料可能無法放進一個PDU。以下另作分次回覆的欄位流程假設,不是宣稱前頁三個短字串需要分頁:第一回覆More Follows=FF、Next Object ID=02,已回物件00與01;客戶端下一請求應為2B 0E 01 02。第二回覆帶物件02,More Follows=00、Next=00,才結束此次集合。
| 交易 | 請求PDU | 回覆摘要 | 客戶端動作 |
|---|---|---|---|
| 第一筆 | 2B 0E 01 00 | More=FF,Next=02 | 暫存00與01,標未完成 |
| 第二筆 | 2B 0E 01 02 | More=00,Next=00 | 加入02,驗證後提交 |
| 錯誤續讀 | 反覆送2B 0E 01 00 | 每次重新回第一段 | 記錄不前進,有限次數終止 |
| 途中換設備 | 來源世代改變 | 舊00/01加新02 | 放棄舊集合,重新開始 |
物件不能跨兩個回覆拆成半個字串;每個物件都要在其回覆內完整。Number of objects是本次回覆的組數,不是整台設備的物件總數。續讀用Next Object ID,不是上一組ID自行加一,也不是TCP封包序號。收到More=00時Next應為00,不能因Next非零就擅自繼續掃描。
對續讀設定總次數、總資料量與總時間上限,記錄已收到的物件及Next序列。若伺服器反覆回相同Next而沒有進度,就停止並報不完整,避免無限迴圈;若途中逾時,保留診斷用部分資料,但正式資產記錄標示未完成。重連後重新建立整套集合,比把不同世代的物件拼在一起可靠。
完成後應看到原始PDU、解析後三個基本字串、資料來源與完整性狀態。比對資產表時保留原文大小寫與修訂字串;可以另外建立搜尋用正規化欄位,但不要把1.10擅自變成小數1.1,版本字串不能按一般浮點數比較。
失敗先查哪裡與FAQ
如果完全無回覆,先回到通訊端點、站號、格式與逾時排查;若收到AB開頭的例外回覆,表示這次2B功能發生例外,還要讀下一個例外碼。MEI錯誤、存取code錯誤、物件不存在與資料長度不符是不同問題,診斷報告不能只寫「讀型號失敗」。
FAQ1:VendorName正確就代表設備可信嗎?不能。這是設備自行回報的字串,沒有替你做身分認證。需要安全通道或設備真偽核對時,另外採用符合系統需求的方法。
FAQ2:物件02一定是PLC韌體版本嗎?它是此介面的MajorMinorRevision字串。實際代表哪一軟體或產品修訂,應對照該產品文件,不要自動當成整台機器所有元件的韌體版號。
FAQ3:Next為02就代表第二頁嗎?不是,它是下一次要要求的物件ID。物件ID與頁碼、站號、交易TID各有不同用途,操作表必須分欄記錄。
FAQ4:未知物件一律回同一種錯誤嗎?不一樣。串流存取的未知起點與code04個別存取的未知物件,在標準中處理方式不同;個別存取未知物件可回例外02,不能因此推論所有續讀失敗都同義。
本文適用於明示支援2B/0E的Modbus設備識別及資產盤點,未選定PLC指令與串列通訊程式。支援類別、可用私人物件與產品限制須逐型號確認。所有字串、分次流程及長度為離線示範,未取得實機識別回覆,亦未執行PLC編譯或模擬。
參考:Modbus Application Protocol V1.1b3,第6.21節Read Device Identification。