1.該規范的發展概況
原始版本1997年9月3日作為公共評論的草案。
再版1999年3月29日,即修訂版1.0。
沒有大的技術改動,僅作了補充說明。增加了附錄A和B作為對一些常用執行問題的回應。
該Modbus/TCP規范在萬維網上公開發行。它表明開發者的意願是把它作為工業自動化領域具有互用性的標准。
既然MODBUS和MODBUS/TCP作為事實上的“實際”標准,而且很多生產商已經實現了它的功能,此規范主要是闡述在互連網上具有普遍可用性的基於TCP通訊協議的MODBUS報文的特殊編碼。
2. 概 述
MODBUS/TCP是簡單的、中立廠商的用於管理和控制自動化設備的MODBUS系列通訊協議的派生產品。顯而易見,它覆蓋了使用TCP/IP協議的 “Intranet”和“Internet”環境中MODBUS報文的用途。協議的最通用用途是為諸如PLC’s,I/O模塊,以及連接其它簡單域總線或 I/O模塊的網關服務的。
MODBUS/TCP協議是作為一種(實際的)自動化標准發行的。既然MODBUS已經廣為人知,該規范只將別處沒有收錄的少量信息列入其中。然而,本規 范力圖闡明MODBUS中哪種功能對於普通自動化設備的互用性有價值,哪些部分是MODBUS作為可編程的協議交替用於PLC’s的“多余部分”。
它通過將配套報文類型“一致性等級”,區別那些普遍適用的和可選的,特別是那些適用於特殊設備如PLC’s的報文。
2.1 面向連接
在MODBUS中,數據處理傳統上是無國界的,使它們對由噪音引起的中斷有高的抵抗力,而且在任一端只需要最小的維護信息。
編程操作,另一方面,期望一種面向連接的方法。這種方法對於簡單變量通過唯一的“登錄”符號完成,對於Modbus Plus變量,通過明確的“程序路徑”容量來完成,而“程序路徑”容量維持了一種雙向連接直到被徹底擊穿。
MODBUS/TCP處理兩種情況。連接在網絡協議層很容易被辨認,單一的連接可以支持多個獨立的事務。此外,TCP允許很大數量的並發連接,因而很多情況下,在請求時重新連接或復用一條長的連接是發起者的選擇。
熟悉MODBUS的開發者會感到驚訝:為什么面向連接TCP協議比面向數據報的UDP要應用廣泛。主要原因是通過封裝獨立的“事務”在一個連接中,此連接 可被識別,管理和取消而無須請求客戶和服務器采用特別的動作。這就使進程具有對網絡性能變化的適應能力,而且容許安全特色如防火牆和代理可以方便的添加。
類似的推理被最初的萬維網的開發者所采用,他們選用TCP及端口80去實現一個作為單一事務的最小的環球網詢問。
2.2 數據編碼
MODBUS 采用“big-endian”來表示地址和數據對象。
這就意味着當一個數字表示的數量大於所傳輸的單一字節,最大有效字節將首先被發送。例如:
16
|
bits
|
0x1234
|
將為
|
0x12
|
0x34
|
32
|
bits
|
0x12345678L
|
將為
|
0x12
|
0x34
|
|
|
|
|
0x56
|
0x78
|
2.3參考編號的解釋
MODBUS將其數據模型建立在一系列具有不同特征的表的基礎之上。這四個基本表如下
l 離散輸入 單比特,由I/O系統提供,只讀
l 離散輸出 單比特,由應用程序更改,讀寫
l 輸入寄存器 16比特,數值,由I/O系統提供 ,只讀
l 輸出寄存器 16比特,數值,由應用程序更改,讀寫
輸入和輸出之間以及可尋址位和可尋址代碼的數據對象之間的差別並不意味着任何應用性能的不同。如果這是我們所討論的目標機械的最自然的解釋,那么認為所有的四個基本表是相互覆蓋的看法也是非常普通而完全可以接受的。
對於每一個基本表,協議允許單獨選擇65536個數據對象中的任何一個,而且對那些對象的讀寫操作可以跨越多個連續的數據對象,直到達到基於處理事務功能代碼的數據大小限制。
這兒沒有假定數據對象代表一種真正鄰接的數據陣列,而這是大多數簡單PLC’s的解釋。
“讀寫常用參考”功能代碼被定義為攜帶32位的參考值並且能允許在“非常”大的空間里可以直接訪問數據對象。現在沒有可以利用這一特點的PLC設備。
一個易造成混亂的潛在來源是用於MODBUS功能的參考值和用於Modicon PLC’s的“寄存器值”之間的關系。由於歷史原因,用戶參考值使用從1開始的十進制數表示。而MODBUS采用更普通的從0開始的無符號整數進行軟件數 據整理分析。
於是,請求從0讀取寄存器的Modbus消息將已知值返回建立在寄存器4:00001(存儲類型4=輸出寄存器,參考值00001)中的應用程序。
2.4隱含長度基本原則
所有的MODBUS 請求和響應都被設計成在此種方法下工作,即接收者可確認消息的完整性。對於請求和響應為固定長度的功能代碼,僅發送功能代碼就足夠了。對於在請求和響應中 攜帶不定長數據的功能代碼,數據部分前將加上一個字節的數據統計。
當 Modbus通過TCP運送,前綴中攜帶附加的長度信息以便接收者識別消息的邊界,甚至消息被分成若干組進行傳輸。外在的和隱含的長度准則的存在,以及 CRC-32檢錯代碼(以太網)的使用使請求和響應消息中發生未被識別的錯誤的機率減至無限小。
3. 一致性等級概述
當從草稿開始定義一種新的協議,有可能加強編碼方式和闡述的一致性。MODBUS由於其先進的特性,已經在很多地方得到了實施,必須避免破壞它已經存在的實施。
因此,已經存在的成套的處理類型被划分出一致性等級:等級0代表普遍使用且總體上一致的功能;等級2代表有用的功能,但帶有某些特性。現存裝置的不適應於互用性的功能也已確認。
必須注意到,將來對該標准的擴充將定義附加的功能代碼來處理現存事實標准不適用的情形。然而,被提議擴充的詳細資料出現在本手冊中將會另人誤解。通過將代 碼“隨機的”發送或者即便是通過檢查異常響應的類型來確定特別的目標裝置是否支持特別的功能代碼總是可能的,而且該方法將保證引入這些擴充的現使用的 MODBUS設備的連續的互用性。事實上,這就是當前功能代碼的分級原則。
3.1等級0
這是最小的有用功能,對主站和從站來說。
讀乘法寄存器 (fc 3)
寫乘法寄存器 (fc 16)
3.2等級 1
這是附加的被普遍實現的和能共同使用的成套功能,正如前面介紹過的,許多從站把輸入,輸出,離散值和寄存器值作為同等的進行處理。
l 讀線圈 (fc 1)
l 讀離散輸入 (fc 2)
l 讀寄存器輸入 (fc 4)
l 寫線圈 (fc 5)
l 寫單一寄存器 (fc 6)
l 讀異常狀態字 (fc 7)
此功能對於每一個從站系列顯然具有不同的含義。
3.3等級 2
這些是需要HMI和管理等例行操作的數據傳送功能。
l 強制型多路線圈 (fc 15)
l 讀一般參考值 (fc 20)
該功能可以處理並發的多個請求,而且能接收32位的參考數值。當前的584和984PLC’s僅使用此功能接收類型6的參考值(擴展的寄存器文件)。
該功能最適於擴充以處理大的寄存器空間和缺少諸如“未定位”變量的參考值的數據對象。
l 寫一般參考值 (fc 21)
此功能可以處理並發的多個請求,也可接收32位的參考數值。當前的584和984PLC’s僅使用此功能接收類型6的參考值(擴展的寄存器文件)。
該功能最適於擴充以處理大的寄存器空間和缺少諸如“未定位”變量的參考值的數據對象。
l 掩膜寫寄存器 (fc 22)
l 讀/寫寄存器 (fc 23)
此功能把一定范圍的寄存器輸入和輸出當作單一的處理事務。使用MODBUS是執行規則的帶有I/O模塊的狀態影象交換的最好辦法。
如此,高性能的通用的數據采集裝置可以執行功能3,16和23,從而把快捷的數據規則交換(23)和執行特殊數據對象的需求詢問或更新的能力結合起來(3和16)。
l 讀FIFO隊列 (fc 24)
一個有點專用的功能,打算將表結構的數據象FIFO(用到584/984上的FIN和FOUT功能模塊)一樣傳送到主機。對於某種事件錄入軟件很有用。
3.4機器/廠家/網絡的特殊功能
以下所有的功能,雖然在MODBUS協議手冊中提到,但由於它們有很強的機器依賴性,因而不適於互用性的目的。
l 診斷 (fc 8)
l 編程 (484) (fc 9)
l 輪詢 (484) (fc 10)
l 獲取通訊事件計數器值(Modbus) (fc 11)
l 獲取通訊事件記錄(Modbus) (fc 12)
l 編程 (584/984) (fc 13)
l 輪詢(584/984) (fc 14)
l 通告從站 ID (fc 17)
l 編程 (884/u84) (fc 18)
l 恢復通訊連接 (884/u84) (fc 19)
l 編程 (原理) (fc 40)
l 固件置換 (fc 125)
l 編程 (584/984) (fc 126)
l 通告本地地址 (Modbus) (fc 127)
4. 協議結構
本部分闡述了通過MODBUS/TCP網絡攜帶的MODBUS請求和或響應封裝的一般格式。必須注意到請求和響應本體(從功能代碼到數據部分的末尾)的結構和其它MODBUS變量具有完全相同的版面格式和含義,如:
MODBUS 串行端口 - ASCII 編碼
MODBUS 串行端口 - RTU (二進制) 編碼
MODBUS PLUS 網絡 – 數據通道
這些其它案例僅在組幀次序,檢錯模式和地址描述等格式有所不同。
所有的請求通過TCP從寄存器端口502發出。 請求通常是在給定的連接以半雙工的方式發送。也就是說,當單一連接被響應所占用,就不能發送其它的請求。有些裝置采用多條TCP連接來維持高的傳輸速率。
然而一些客戶端設備嘗試“流水線式”的請求。允許服務器以這種方式工作的技術在附錄A中闡述。
MODBUS “從站地址”字段被單字節的“單元標識符”替換,從而用於通過網橋和網關等設備的通訊,這些設備用單一IP地址來支持多個獨立的終接單元。
請求和響應帶有六個字節的前綴,如下:
byte 0: 事務處理標識符 –由服務器復制 –通常為 0
byte 1: 事務處理標識符 –由服務器復制 –通常為 0
byte 2: 協議標識符= 0
byte 3: 協議標識符= 0
byte 4: 長度字段 (上半部分字節) = 0 (所有的消息長度小於256)
byte 5: 長度字段 (下半部分字節) = 后面字節的數量
byte 6: 單元標識符 (原“從站地址”)
byte 7: MODBUS 功能代碼
byte 8 on: 所需的數據
因而處理示例“以4的偏移從UI 9讀1寄存器”返回5的值將是
請求:00 00 00 00 00 06 09 03 00 04 00 01
響應:00 00 00 00 00 05 09 03 02 00 05
一致性等級0-2的功能代碼的應用的例子見后續部分
熟悉MODBUS的設計師將注意到MODBUS/TCP中不需要“CRC-16”或“LRC”檢查字段。而是采用TCP/IP和鏈路層(以太網)校驗和機制來校驗分組交換的准確性。
5. 一致性等級的協議參考值
注意到在例子中,請求和響應列在功能代碼字節的前面。如前所述,在MODBUS/TCP案例中有一個依賴傳輸的包含7個字節的前綴。
ref ref 00 00 00 len unit前面兩個字節的“ref ref”在服務器中沒有具體的值,只是為方便客戶端而從請求和響應中逐字的復制過來。單客戶機通常將該值置為0。
在這個例子中,請求和響應的格式如下(例子是“讀寄存器”請求,詳述見后面部分)。
03 00 00 00 01 => 03 02 12 34
這表示給前綴加上一個十六進制的串聯的字節,這樣,TCP連接上的整個消息將是(假設單元標識符還是09)
請求: 00 00 00 00 00 06 09 03 00 00 00 01
響應: 00 00 00 00 00 05 09 03 02 12 34
(所有的這些請求和響應通過查詢Modicon Quantum PLC規范采用自動工具來進行校驗。
5.1等級0指令詳述
5.1.1讀乘法寄存器(FC 3)
請求
Byte 0: FC = 03
Byte 1-2: 參考數值
Byte 3-4: 指令數(1-125)
響應
Byte 0: FC = 03
Byte 1: 響應的字節數 (B=2 x指令數)
Byte 2-(B+1): Register values
異常
Byte 0: FC = 83 (hex)
Byte 1: 異常代碼 = 01 or 02
示例:
讀參考值為0 (Modicon 984中為40001)時的1寄存器得到十六進制的值1234
03 00 00 00 01 => 03 02 12 34
5.1.2 寫乘法寄存器(FC 16)
請求
Byte 0: FC = 10 (hex)
Byte 1-2: 參考數值
Byte 3-4: 指令數 (1-100)
Byte 5: 字節數 (B=2 x word count)
Byte 6-(B+5): 寄存器值
響應
Byte 0: FC = 10 (hex)
Byte 1-2: 參考數值
Byte 3-4: 指令數
異常
Byte 0: FC = 90 (hex)
Byte 1: 異常代碼 = 01 or 02
示例:
讀參考值為0(Modicon 984中為40001)時的1寄存器得到十六進制的值1234
10 00 00 00 01 02 12 34 => 10 00 00 00 01
5.2等級1指令詳述
5.2.1 讀線圈 (FC 1)
請求
Byte 0: FC = 01
Byte 1-2: 參考數值
Byte 3-4: 比特數(1-2000)
響應
Byte 0: FC = 01
Byte 1: 響應的字節數 (B=(比特數+7)/8)
Byte 2-(B+1): 比特值(最小意義位首先繞線圈!)
異常
Byte 0: FC = 81 (hex)
Byte 1: exception code = 01 or 02
示例
讀參考值為0 (Modicon 984中為00001)時的1線圈得到的值1
01 00 00 00 01 => 01 01 01
注意到返回的數據的格式和big-endian體系結構不同。而且此請求如果調用乘法指令字且這些指令不以16位為界排列,那么該請求將在從站得到計算強化。
5.2.2讀離散輸入 (FC 2)
請求
Byte 0: FC = 02
Byte 1-2: 參考數值
Byte 3-4: 比特數 (1-2000)
響應
Byte 0: FC = 02
Byte 1: 響應的字節數 (B=(比特數+7)/8)
Byte 2-(B+1): 比特值 (最小意義位首先繞線圈!)
異常
Byte 0: FC = 82 (16進制)
Byte 1: 異常代碼 = 01 or 02
示例
讀參考值為0 (Modicon 984中為10001)時的1離散輸入得到的值1
02 00 00 00 01 => 02 01 01
注意到返回的數據的格式和big-endian體系結構不同。而且此請求如果調用乘法指令字且這些指令不以16位為界排列,那么該請求將在從站得到計算強化。
5.2.3 讀輸入寄存器 (FC 4)
請求
Byte 0: FC = 04
Byte 1-2: 參考數值
Byte 3-4: 指令數 (1-125)
響應
Byte 0: FC = 04
Byte 1: 響應的比特數 (B=2 x 指令數)
Byte 2-(B+1): 寄存器值
異常
Byte 0: FC = 84 (hex)
Byte 1: 異常代碼 = 01 or 02
示例
讀參考值為0 (Modicon 984中為30001)時的1輸入寄存器得到十六進制的值1234
04 00 00 00 01 => 04 02 12 34
5.2.4 寫線圈 (FC 5)
請求
Byte 0: FC = 05
Byte 1-2: 參考數值
Byte 3: = FF 打開線圈, =00 關閉線圈
Byte 4: = 00
響應
Byte 0: FC = 05
Byte 1-2: 參考數值
Byte 3: = FF 打開線圈, =00 關閉線圈(回波)
Byte 4: = 00
異常
Byte 0: FC = 85 (16進制)
Byte 1: 異常代碼 = 01 or 02
示例
將值1在參考值為0(Modicon 984中為00001)時寫入1線圈
05 00 00 FF 00 => 05 00 00 FF 00
5.2.5 寫單一寄存器(FC 6)
請求
Byte 0: FC = 06
Byte 1-2: 參考數值
Byte 3-4: 寄存器值
響應
Byte 0: FC = 06
Byte 1-2: 參考數值
Byte 3-4: 寄存器值
異常
Byte 0: FC = 86 (16進制)
Byte 1: 異常代碼= 01 or 02
示例
將十六進制值1234在參考值為0(Modicon 984中為40001)時寫入1線圈
06 00 00 12 34 => 06 00 00 12 34