
1. 協議概述
歐姆龍(Omron)是來自日本的知名電子和自控設備制造商,其中、小型PLC在國內市場有較高的占有率,有CJ、CM等系列。PLC可以支持Fins、Host link等協議進行通信。
支持以太網的歐姆龍PLC CPU、以太網通信模塊根據型號的不同,一般都會支持FINS(Factory Interface Network Service)協議,一些模塊也會支持EtherNet/IP協議。Omron fins協議缺省TCP/UDP端口號為9600。Fins協議封裝在TCP/UDP之上,需要注意的是基於TCP的Fins數據包和基於UDP的包在頭部上差異較大。協議的具體構造可以參考歐姆龍官方文檔。
FINS協議實現了OMRON PLC與上位機以太網通信。Fins基於TCP/UDP的報文的概覽如下:
1 |
Fins over TCP |
由上圖可知,Fins/TCP實際上是將Fins/UDP報文作為其負載,在其前面加了一個Fins/TCP報頭。需要注意的是,Fins/TCP報文中負載即Fins/UDP部分不一定會出現,它可以只有一個簡單的Fins/TCP報頭。
因此我們先介紹Fins/UDP報文的組成,然后再介紹Fins/TCP結構。
2. 協議詳解
2.1 Fins over UDP
基於UDP的Fins協議的結構相對簡單,整體結構由報頭和數據兩部分組成,如下所示:
1 |
Fins over UDP |
其中報頭部分為必要組成部分,為固定長度12個字節,數據部分非必現。
2.1.1 Fins/UDP Header
報頭部分由11個定長字段組合而成,前面10個字段分別簡稱為:ICF、RSV、GCT、DNA、DA1、DA2、SNA、SA1、SA2、SID,如下所示:
1 |
0 1 2 6 7 |
上述11個字段中,除最后一個Command Code字段為2個字節外,其余所有字段均只占1個字節。
2.1.2 ICF字段
第一個字段被稱為ICF字段(即Information control filed,信息控制字段),1個字節,由4個子字段組成,分述如下:
- 1… …. = Gateway bit,是否使用網關,
0x01表示使用; - .1.. …. = Data Type bit,數據類型比特位,
0x01表示為響應,0x00表示命令; - ..0. …. = Reserved bit,第一個保留比特位,默認置0;
- …0 …. = Reserved bit,第二個保留比特位,默認置0;
- …. 0… = Reserved bit,第三個保留比特位,默認置0;
- …. .0.. = Reserved bit,第四個保留比特位,默認置0;
- …. ..0. = Reserved bit,第五個保留比特位,默認置0;
- …. …1 = Response setting bit,第一個保留比特位響應標志為,
0x01表示非必需回應,0x00表示必須進行回應。
2.1.3 RSV字段
第二個字段被稱為RSV(即Reserved,保留字段),1個字節,置0x00。
2.1.4 GCT字段
第三個字段被稱為GCT(即Gateway count ,網關計數),1個字節,置為0x02。
2.1.5 DNA字段
第四個字段被稱為DNA(即Destination network adrress,目標網絡地址),1個字節,取值如下:
00:表示本地網絡;0x01~0x7F:表示遠程網絡。
2.1.6 DA1字段
第五個字段被稱為DA1(即Destination node number,目標節點編號),1個字節,取值如下:
0x01~0x3E:SYSMAC LINK網絡中的節點號;0x01~0x7E:YSMAC NET網絡中的節點號;0xFF: 廣播傳輸。
Omron的官方手冊中,該字段只能取上述值,然而網上的實際抓包發現會有其它值出現,被wireshark標記為unknown。
2.1.7 DA2字段
第六個字段被稱為DA2(即Destination unit address,目標單元地址),1個字節,取值如下:
0x00:PC(CPU);0xFE: SYSMAC NET Link Unit or SYSMAC LINK Unit connected to network;0x10~0x1F:CPU總線單元 ,其值等於10 + 單元號(前端面板中配置的單元號)。
Omron的官方手冊中,該字段只能取上述值,然而網上的實際抓包發現會有其它值出現,被wireshark標記為unknown。
2.1.8 SNA字段
第七個字段被稱為SNA(即Source network address,源網絡地址),1個字節,取值及含義同DNA字段。
2.1.9 SA1字段
第八個字段被稱為SA1(即Source node number,源節點編號),1個字節,取值及含義同DA1字段。
2.1.10 SA2字段
第九個字段被稱為SA2(即Source unit addess,源單元地址),1個字節,取值及含義同DA2字段。
2.1.11 SID字段
第十個字段被稱為SID(即Service ID,服務ID**),1個字節,取值0x00~0xFF,產生會話的進程的唯一標識。
2.1.12 Command Code字段
這個字段占2個字節,其取值由第一個字節表示的大分類和第二個字節表示的子分類復合而成,取值及其含義如下表:
| Command Code | 英文釋義 | 中文釋義 | |
|---|---|---|---|
| 1st Byte | 2nd Byte | ||
| 0x01 | 0x01 | MEMORY AREA READ | 內存區域讀取 |
| 0x02 | MEMORY AREA WRITE | 內存區域寫入 | |
| 0x03 | MEMORY AREA FILL | 內存區域填充 | |
| 0x04 | MULTIPLE MEMORY AREA READ |
多內存區域讀取 | |
| 0x05 | MEMORY AREA TRANSFER | 內存區域傳輸 | |
| 0x02 | 0x01 | PARAMETER AREA READ | 參數區域讀取 |
| 0x02 | PARAMETER AREA WRITE | 參數區域寫入 | |
| 0x03 | PARAMETER AREA CLEAR | 參數區域清除 | |
| 0x20 | DATA LINK TABLE READ | 數據鏈表讀取 | |
| 0x21 | DATA LINK TABLE WRITE | 內存區域傳輸 | |
| 0x03 | 0x04 | PROGRAM AREA PROTECT | 程序區保護 |
| 0x05 | PROGRAM AREA PROTECT CLEAR | 程序區保護清除 | |
| 0x06 | PROGRAM AREA READ | 程序區讀取 | |
| 0x07 | PROGRAM AREA WRITE | 程序區寫入 | |
| 0x08 | PROGRAM AREA CLEAR | 程序區清除 | |
| 0x04 | 0x01 | RUN | 執行 |
| 0x02 | STOP | 停止 | |
| 0x03 | RESET | 重置 | |
| 0x05 | 0x01 | CONTROLLER DATA READ | 控制器數據讀取 |
| 0x02 | CONNECTION DATA READ | 連接數據讀取 | |
| 0x06 | 0x01 | CONTROLLER STATUS READ |
控制器狀態讀取 |
| 0x02 | NETWORK STATUS READ | 網絡狀態讀取 | |
| 0x03 | DATA LINK STATUS READ | 數據連接狀態讀取 | |
| 0x20 | CYCLE TIME READ | 循環次數讀取 | |
| 0x07 | 0x01 | CLOCK READ | 時鍾讀取 |
| 0x02 | CLOCK WRITE | 時鍾寫入 | |
| 0x08 | 0x01 | LOOP-BACK TEST/ INTERNODE ECHO TEST |
環路測試/內部節點響應測試 |
| 0x02 | BROADCAST TEST RESULTS READ |
廣播測試/結果讀取 | |
| 0x03 | BROADCAST TEST DATA SEND |
廣播測試數據發送 | |
| 0x09 | 0x20 | MESSAGE READ | 消息讀取 |
| MESSAGE CLEAR | 消息清除 | ||
| FAL/FALS READ | FAL/FALS讀取 | ||
| 0x0C | 0x01 | ACCESS RIGHT ACQUIRE | 訪問權限獲取 |
| 0x02 | ACCESS RIGHT FORCED ACQUIRE |
訪問權限強制獲取 | |
| 0x03 | ACCESS RIGHT RELEASE | 訪問權限釋放 | |
| 0x21 | 0x01 | ERROR CLEAR | 錯誤清除 |
| 0x02 | ERROR LOG READ | 錯誤日志讀取 | |
| 0x03 | ERROR LOG CLEAR | 錯誤日志清除 | |
| 0x22 | 0x01 | FILE NAME READ | 文件名讀取 |
| 0x02 | SINGLE FILE READ | 單文件讀取 | |
| 0x03 | SINGLE FILE WRITE | 單文件寫入 | |
| 0x04 | MEMORY CARD FORMAT | 記憶卡格式化 | |
| 0x05 | FILE DELETE | 文件刪除 | |
| 0x06 | VOLUME LABEL CREATE/DELETE |
卷標創建/刪除 | |
| 0x07 | FILE COPY | 文件復制 | |
| 0x08 | FILE NAME CHANGE | 文件名更改 | |
| 0x09 | FILE DATA CHECK | 文件數據校核 | |
| 0x0A | MEMORY AREA FILE TRANSFER |
內存區域文件傳輸 | |
| 0x0B | PARAMETER AREA FILE TRANSFER/td> |
參數區域文件傳輸 | |
| 0x0C | PROGRAM AREA FILE TRANSFER |
程序區域文件傳輸 | |
| 0x0F | FILE MEMORY INDEX READ | 文件內存索引讀取 | |
| 0x10 | FILE MEMORY READ | 文件內存塊讀取 | |
| 0x11 | FILE MEMORY WRITE | 文件內存塊寫入 | |
| 0x23 | 0x01 | FORCED SET/RESET | 強制設置/重置 |
| 0x02 | FORCED SET/RESET CANCEL |
取消強制設置/重置 | |
| 0x0A | MULTIPLE FORCED STATUS READ |
多強制狀態讀取 | |
| 0x26 | 0x01 | NAME SET | 名稱設置 |
| 0x02 | NAME DELETE | 名稱刪除 | |
| 0x03 | NAME READ | 名稱讀取 | |
合計:14個大類,57個子類,共57個Command Code。
2.2 Fins Over TCP
基於TCP的FINS報文結構也不復雜,無非就是一個FINS/TCP頭部(必選),加上FINS/UDP報文(可選),如下所示:
1 |
Fins over TCP |
2.2.1 Fins/TCP Header
Fins/TCP的報頭與Fins/UDP不同的是,它由4個固定字段和2個可選字段組成,如下所示:
1 |
Fins/TCP Header |
因此Fins/TCP的頭部長度范圍為[16,24]
字節,每個字段的長度均為固定的4個字節。
2.2.2 Magic字段
第一個字段為Magic Bytes字段,從字面意思看是魔數字段,其ASCII碼(0x46494E53)剛好是FINS這個單詞,因此可以推測這個字段的值是恆定的。
2.2.3 Length字段
第二個字段為Length字段,這個字段的值表示其后所有字段(包括可能出現的Fins/UDP包)的總長度,用公式表達為:
Length=len(TCPPAYLOAD)−len(MagicBytes)−len(Length)=len(TCPPAYLOAD)−4−4=len(TCPPAYLOAD)−8(2 - 1)
也就是說,該字段的值等於TCP負載的總長度減去8個字節。
2.2.4 Command字段
第三個字段為Command字段,這個字段表示消息中隨附的命令的類型。這個字段的取值直接決定了后續可選的字段Client Node Address、Server Node Address是否出現,具體情況如下所示:
0x00000000:節點地址數據已發送(C->S),此時僅有Client Node Address字段;0x00000001:節點地址數據已發送(S->C),此時Client/Server Node Address字段均出現;- 其它:不會出現上述兩個字段。
2.2.5 Error Code字段
第四個字段為Error Code字段,這個字段表示錯誤代碼。根據wireshark源代碼所提供的信息,錯誤代碼目前共定義了10種類型,如下所示:
| 錯誤碼 | 對應含義 |
|---|---|
| 0x00000000 | Normal |
| 0x00000001 | The header is not ‘FINS’ (ASCII code) |
| 0x00000002 | The data length is too long |
| 0x00000003 | The command is not supported |
| 0x00000020 | All connections are in use |
| 0x00000021 | The specified node is already connected |
| 0x00000022 | Attempt to access a protected node from an unspecified IP address |
| 0x00000023 | The client FINS node address is out of range |
| 0x00000024 | The same FINS node address is being used by the client and server |
| 0x00000025 | All the node addresses available for allocation have been used |
2.2.6 Client/Server Node Address字段
這兩個字段是Fins/TCP的客戶端/服務器建立連接的時候的類似DHCP協議客戶端獲取IP地址的時候才會出現的,如下所示:
由上可以看出,Fins/TCP協議的客戶端/服務器在傳輸有效的命令數據之前,由客戶端先向服務器發送一個包含Client Node Address字段的報文申請節點地址,如下圖所示:

類似DHCP協議,由於客戶端申請的時候還沒有節點地址,因此該字段被置為0x00000000。
服務器收到客戶端請求后,給客戶端分配相應的節點地址並通告給客戶端,同時在報文中包含服務器自己的節點地址信息,如下所示:

客戶端收到服務器的響應報文后,即使用分配的節點地址與服務器進行通信,由此客戶端/服務器之間就建立起了有效的長連接。
2.3 Command Data
這個字段是Fins/UDP、Fins/TCP協議的實際負載部分,鑒於其涵蓋內容較多(官方手冊就有兩百多頁),目前未對其進行深入解析,后續根據需要再深入解析。
