又一次成爲懶蛋了,標題就這麼改了改又是一篇新文章。數據庫
網上也有不少S7comm協議的解析,但仍是如同我上一篇同樣我只是作報文的解析對於S7comm的原理並進行闡述。編程
有些地方有錯誤的地方盡請你們指出,共同進步。編程語言
好了,言歸正題。咱們開始吧。函數
我仍是按照功能碼的順序進行介紹吧。測試
TPKT層和COTP層我也很少作介紹了,有興趣的能夠本身去了解。今天咱們主要是解析S7comm這一層。編碼
功能碼附錄:spa
0x00 CPU services CPU服務操作系統
0xf0 Setup communication 創建通訊3d
0x04 Read Var 讀取值調試
0x05 Write Var 寫入值
0x1a Request download 請求下載
0x1b Download block 下載塊
0x1c Download ended 下載結束
0x1d Start upload 開始上傳
0x1e Upload 上傳
0x1f End upload 上傳結束
0x28 PI-Service 程序調用服務
0x29 PLC Stop 關閉PLC
發包
咱們來先看Header頭部分。
Byte[0] 32 爲協議ID 通常指定爲0x32
Byte[1] 01 爲 PDU類型 通常有0x01 Job 主設備發起請求 0x02 Ack 確認響應 0x03 Ack_data 確認數據響應通常做爲確認0x01的請求 0x07 USERDATA 協議的擴展,參數字段包含請求/響應ID
Byte[2]Byte[3] 00 00冗餘數據,一般爲0×0000
Byte[4]Byte[5] 3e 02協議數據單元的參考、經過請求事件增長
Byte[6]Byte[7] 00 08參數的總長度也就是parameter的長度
Byte[8]Byte[9] 00 00數據的長度、也就是data部分數據的長度若是無即爲0
繼續看Parmeter部分。
根據上面的length得知,咱們的Parameter部分應該是8個位,數一數看看是否是8位
Byte[0] f0 爲PDU的類型也就是功能碼
Byte[1] 00 冗餘數據,一般爲0×0000
Byte[2] Byte[3] 發送鏈接請求
Byte[4] Byte[5] 發送通訊請求
Byte[6] Byte[7] 協商的PDU長度
回包
紅框內跟發包是同樣的,就再也不描述了。
從Error Class開始。
Byte[10] 00 爲錯誤類型 、錯誤類型也有不少種、如下是錯誤類型附錄。
0x00 No error 沒有錯誤
0x81 Application relationship 應用關係
0x82 Object definition 對象定義
0x83 No resources available 沒有可用資源
0x84 Error on service processing 服務處理中錯誤
0x85 Error on supplies 請求錯誤
0x87 Access error 訪問錯誤
Byte[11] 00 爲錯誤碼 文章最後會附錄一下所有錯誤碼(很長不貼在這裏了,搜索 附錄一)
這裏能夠理解爲 錯誤類型規定錯誤的大致方向而錯誤碼規定錯誤的具體事件。
接下來咱們看Parameter這一部分
能夠看出跟發包是徹底同樣的,仍是那句話百變不離其宗,協議嘛逃脫不了一發一收對吧。
Byte[0] f0 爲PDU的類型也就是功能碼
Byte[1] 00 冗餘數據,一般爲0×0000
Byte[2] Byte[3] 確認鏈接請求
Byte[4] Byte[5] 確認通訊請求
Byte[6] Byte[7] 協商的PDU長度
發包
Header頭部與以前都同樣的再也不描述了
咱們直接看Parameter部分吧。
Byte[0] 04 功能碼
Byte[1] 01 表明了Item的個數 爲1 即爲 一個
再繼續往下扒。
Item部分
Byte[0] 12 結構標識一般都爲0x12,表明變量規範
Byte[1] 0a 長度規範、自此日後的長度
Byte[2] 10 IDS的地址規範的格式類型常見值如下表
0x10 S7ANY Address data S7-Any pointer-like DB1.DBX10.2
0x13 PBC-R_ID R_ID for PBC
0x15 ALARM_LOCKFREE Alarm lock/free dataset
0x16 ALARM_IND Alarm indication dataset
0x19 ALARM_ACK Alarm acknowledge message dataset
0x1a ALARM_QUERYREQ Alarm query request dataset
0x1c NOTIFY_IND Notify indication dataset
0xa2 DRIVEESANY seen on Drive ES Starter with routing over S7
0xb2 1200SYM Symbolic address mode of S7-1200
0xb0 DBREAD Kind of DB block read, seen only at an S7-400
0x82 NCK Sinumerik NCK HMI access
Byte[3] 02 爲數據傳輸的大小、常見值如下表
0 NULL
3 BIT bit access, len is in bits
4 BYTE/WORD/DWORD byte/word/dword access, len is in bits
5 INTEGER integer access, len is in bits
6 DINTEGER integer access, len is in bytes
7 REAL real access, len is in bytes
9 OCTET STRING octet string, len is in bytes
Byte[4]Byte[5] 00 01 即數據的長度
Byte[6]byte[7] 00 01 即 DB 編號,若是訪問的不是DB區域,此處爲0x0000
Byte[8] 84 即數據的區域經常使用的如下表
Byte[9] Byte[10]Byte[11] 要讀取數據的地址
圖示總體標註一下
回包
Header部分
除了紅框內的其餘都與發包一致
Error class 即錯誤類型
Error code 即具體錯誤碼這兩個在上面已經介紹了都有哪些錯誤類型,沒有錯誤即0x00
Parameter部分
Byte[0] 04 功能碼 Byte[1] 01 表明一個Item
Data部分
Byte[0] FF 爲返回碼 返回碼經常使用值如下表
0x00 Reserved 未定義,預留
0x01 Hardware error 硬件錯誤
0x03 Accessing the object not allowed 對象不容許訪問
0x05 Invalid address 無效地址,所需的地址超出此PLC的極限
0x06 Data type not supported 數據類型不支持
0x07 Data type inconsistent 日期類型不一致
0x0a Object does not exist 對象不存在
0xff Success 成功
Byte[1] 04 爲數據傳輸大小 data數據傳輸大小值如下表
0 NULL
3 BIT bit access, len is in bits
4 BYTE/WORD/DWORD byte/word/dword access, len is in bits
5 INTEGER integer access, len is in bits
6 DINTEGER integer access, len is in bytes
7 REAL real access, len is in bytes
9 OCTET STRING octet string, len is in bytes
Byte[2]Byte[3] 爲data數據的長度
Byte[4] 即數據
有時候會有填充數據即在byte[4]以後、若是數據長度不知足length的話會填充0x00
列如 byte[2]byte[3] 的長度值爲3 就會在byte[4]後填充兩個0x00
仍是總體在圖示一遍吧
好了,這個功能算是啃完了,其餘的功能也大體都同樣,因此呢剩下的時候我可能會比較懶了哈哈。
這就很好理解了吧,有讀必有寫。那寫咱們去推斷一下,是否是在發包的時候比讀數據會多一個Data段做爲寫入的值呢。答案是確定的!
發包
Header 都與讀取值同樣的就不在說了
Parameter也同樣圖示一次吧
叮叮叮,Data段來了
Byte[0] 00 返回碼未定義就爲00
Byte[1] 04 數據傳輸的大小
Byte[2]Byte[3] 數據的長度
Byte[4] 數據
是否是感受這些都差很少同樣,
計算機跟人類也是同樣的。
我對你說「你好帥啊」 你是否是也會回我一句「你也好帥」,假設說你回了一句「我很帥,你很醜」
這是否是不符合常理了,有可能你還要捱罵對吧。
那計算機也是啊,服務端發送數值,客戶端不但不接受還罵服務端一句,那是否是服務端這邊要報錯呢。
可能例子不太恰當,意思到了就闊儀了。
言歸正傳,別愛我,沒結果。
回包
引用上面我舉的例子,那徹底能夠推斷出來回包會會什麼對吧。
發包寫入了數據,那我回包是否是要回複寫入成功或者失敗呢。
Header部分和parameter部分都同樣仍是懶了些就不在描述了。
來看Data部分吧
Byte[0] FF 即爲返回碼
上面介紹有返回碼的類型 整段的意思就是向0x000000地址寫入成功
還有好多個功能碼沒有寫,我會放到下一篇文章裏。
緣由:懶了懶了懶了
未完待續....
附錄一:錯誤碼具體含義
0x0000 |
沒有錯誤 |
0x0110 |
塊號無效 |
0x0111 |
請求長度無效 |
0x0112 |
參數無效 |
0x0113 |
塊類型無效 |
0x0114 |
找不到塊 |
0x0115 |
塊已存在 |
0x0116 |
塊被寫保護 |
0x0117 |
塊/操做系統更新太大 |
0x0118 |
塊號無效 |
0x0119 |
輸入的密碼不正確 |
0x011A |
PG資源錯誤 |
0x011B |
PLC資源錯誤 |
0x011C |
協議錯誤 |
0x011D |
塊太多(與模塊相關的限制) |
0x011E |
再也不與數據庫創建鏈接,或者S7DOS句柄無效 |
0x011F |
結果緩衝區過小 |
0x0120 |
塊結束列表 |
0x0140 |
可用內存不足 |
0x0141 |
因爲缺乏資源,沒法處理做業 |
0x8001 |
當塊處於當前狀態時,沒法執行請求的服務 |
0x8003 |
S7協議錯誤:傳輸塊時發生錯誤 |
0x8100 |
應用程序,通常錯誤:遠程模塊未知的服務 |
0x8104 |
未在模塊上實現此服務或報告了幀錯誤 |
0x8204 |
對象的類型規範不一致 |
0x8205 |
複製的塊已存在且未連接 |
0x8301 |
模塊上的內存空間或工做內存不足,或者指定的存儲介質不可訪問 |
0x8302 |
可用資源太少或處理器資源不可用 |
0x8304 |
沒法進一步並行上傳。存在資源瓶頸 |
0x8305 |
功能不可用 |
0x8306 |
工做內存不足(用於複製,連接,加載AWP) |
0x8307 |
保持性工做記憶不夠(用於複製,連接,加載AWP) |
0x8401 |
S7協議錯誤:無效的服務序列(例如,加載或上載塊) |
0x8402 |
因爲尋址對象的狀態,服務沒法執行 |
0x8404 |
S7協議:沒法執行該功能 |
0x8405 |
遠程塊處於DISABLE狀態(CFB)。該功能沒法執行 |
0x8500 |
S7協議錯誤:幀錯誤 |
0x8503 |
來自模塊的警報:服務過早取消 |
0x8701 |
尋址通訊夥伴上的對象時出錯(例如,區域長度錯誤) |
0x8702 |
模塊不支持所請求的服務 |
0x8703 |
拒絕訪問對象 |
0x8704 |
訪問錯誤:對象已損壞 |
0xD001 |
協議錯誤:非法的做業號 |
0xD002 |
參數錯誤:非法的做業變體 |
0xD003 |
參數錯誤:模塊不支持調試功能 |
0xD004 |
參數錯誤:做業狀態非法 |
0xD005 |
參數錯誤:做業終止非法 |
0xD006 |
參數錯誤:非法鏈路斷開ID |
0xD007 |
參數錯誤:緩衝區元素數量非法 |
0xD008 |
參數錯誤:掃描速率非法 |
0xD009 |
參數錯誤:執行次數非法 |
0xD00A |
參數錯誤:非法觸發事件 |
0xD00B |
參數錯誤:非法觸發條件 |
0xD011 |
調用環境路徑中的參數錯誤:塊不存在 |
0xD012 |
參數錯誤:塊中的地址錯誤 |
0xD014 |
參數錯誤:正在刪除/覆蓋塊 |
0xD015 |
參數錯誤:標籤地址非法 |
0xD016 |
參數錯誤:因爲用戶程序錯誤,沒法測試做業 |
0xD017 |
參數錯誤:非法觸發號 |
0xD025 |
參數錯誤:路徑無效 |
0xD026 |
參數錯誤:非法訪問類型 |
0xD027 |
參數錯誤:不容許此數據塊數 |
0xD031 |
內部協議錯誤 |
0xD032 |
參數錯誤:結果緩衝區長度錯誤 |
0xD033 |
協議錯誤:做業長度錯誤 |
0xD03F |
編碼錯誤:參數部分出錯(例如,保留字節不等於0) |
0xD041 |
數據錯誤:非法狀態列表ID |
0xD042 |
數據錯誤:標籤地址非法 |
0xD043 |
數據錯誤:找不到引用的做業,檢查做業數據 |
0xD044 |
數據錯誤:標籤值非法,檢查做業數據 |
0xD045 |
數據錯誤:HOLD中不容許退出ODIS控制 |
0xD046 |
數據錯誤:運行時測量期間非法測量階段 |
0xD047 |
數據錯誤:「讀取做業列表」中的非法層次結構 |
0xD048 |
數據錯誤:「刪除做業」中的非法刪除ID |
0xD049 |
「替換做業」中的替換ID無效 |
0xD04A |
執行'程序狀態'時出錯 |
0xD05F |
編碼錯誤:數據部分出錯(例如,保留字節不等於0,...) |
0xD061 |
資源錯誤:沒有做業的內存空間 |
0xD062 |
資源錯誤:做業列表已滿 |
0xD063 |
資源錯誤:觸發事件佔用 |
0xD064 |
資源錯誤:沒有足夠的內存空間用於一個結果緩衝區元素 |
0xD065 |
資源錯誤:沒有足夠的內存空間用於多個結果緩衝區元素 |
0xD066 |
資源錯誤:可用於運行時測量的計時器被另外一個做業佔用 |
0xD067 |
資源錯誤:「修改標記」做業過多(特別是多處理器操做) |
0xD081 |
當前模式下不容許使用的功能 |
0xD082 |
模式錯誤:沒法退出HOLD模式 |
0xD0A1 |
當前保護級別不容許使用的功能 |
0xD0A2 |
目前沒法運行,由於正在運行的函數會修改內存 |
0xD0A3 |
I / O上活動的「修改標記」做業太多(特別是多處理器操做) |
0xD0A4 |
'強制'已經創建 |
0xD0A5 |
找不到引用的做業 |
0xD0A6 |
沒法禁用/啓用做業 |
0xD0A7 |
沒法刪除做業,例如由於當前正在讀取做業 |
0xD0A8 |
沒法替換做業,例如由於當前正在讀取或刪除做業 |
0xD0A9 |
沒法讀取做業,例如由於當前正在刪除做業 |
0xD0AA |
處理操做超出時間限制 |
0xD0AB |
進程操做中的做業參數無效 |
0xD0AC |
進程操做中的做業數據無效 |
0xD0AD |
已設置操做模式 |
0xD0AE |
做業是經過不一樣的鏈接設置的,只能經過此鏈接進行處理 |
0xD0C1 |
訪問標籤時至少檢測到一個錯誤 |
0xD0C2 |
切換到STOP / HOLD模式 |
0xD0C3 |
訪問標記時至少檢測到一個錯誤。模式更改成STOP / HOLD |
0xD0C4 |
運行時測量期間超時 |
0xD0C5 |
塊堆棧的顯示不一致,由於塊被刪除/從新加載 |
0xD0C6 |
做業已被刪除,由於它所引用的做業已被刪除 |
0xD0C7 |
因爲退出了STOP模式,所以做業被自動刪除 |
0xD0C8 |
因爲測試做業和正在運行的程序之間不一致,「塊狀態」停止 |
0xD0C9 |
經過復位OB90退出狀態區域 |
0xD0CA |
經過在退出前重置OB90並訪問錯誤讀取標籤退出狀態範圍 |
0xD0CB |
外設輸出的輸出禁用再次激活 |
0xD0CC |
調試功能的數據量受時間限制 |
0xD201 |
塊名稱中的語法錯誤 |
0xD202 |
函數參數中的語法錯誤 |
0xD205 |
RAM中已存在連接塊:沒法進行條件複製 |
0xD206 |
EPROM中已存在連接塊:沒法進行條件複製 |
0xD208 |
超出模塊的最大複製(未連接)塊數 |
0xD209 |
(至少)模塊上找不到給定塊之一 |
0xD20A |
超出了能夠與一個做業連接的最大塊數 |
0xD20B |
超出了一個做業能夠刪除的最大塊數 |
0xD20C |
OB沒法複製,由於關聯的優先級不存在 |
0xD20D |
SDB沒法解釋(例如,未知數) |
0xD20E |
沒有(進一步)阻止可用 |
0xD20F |
超出模塊特定的最大塊大小 |
0xD210 |
塊號無效 |
0xD212 |
標頭屬性不正確(與運行時相關) |
0xD213 |
SDB太多。請注意對正在使用的模塊的限制 |
0xD216 |
無效的用戶程序 - 重置模塊 |
0xD217 |
不容許在模塊屬性中指定的保護級別 |
0xD218 |
屬性不正確(主動/被動) |
0xD219 |
塊長度不正確(例如,第一部分或整個塊的長度不正確) |
0xD21A |
本地數據長度不正確或寫保護錯誤 |
0xD21B |
模塊沒法壓縮或壓縮早期中斷 |
0xD21D |
傳輸的動態項目數據量是非法的 |
0xD21E |
沒法爲模塊(例如FM,CP)分配參數。系統數據沒法連接 |
0xD220 |
編程語言無效。請注意對正在使用的模塊的限制 |
0xD221 |
鏈接或路由的系統數據無效 |
0xD222 |
全局數據定義的系統數據包含無效參數 |
0xD223 |
通訊功能塊的實例數據塊錯誤或超出最大背景數據塊數 |
0xD224 |
SCAN系統數據塊包含無效參數 |
0xD225 |
DP系統數據塊包含無效參數 |
0xD226 |
塊中發生結構錯誤 |
0xD230 |
塊中發生結構錯誤 |
0xD231 |
至少有一個已加載的OB沒法複製,由於關聯的優先級不存在 |
0xD232 |
加載塊的至少一個塊編號是非法的 |
0xD234 |
塊在指定的內存介質或做業中存在兩次 |
0xD235 |
該塊包含不正確的校驗和 |
0xD236 |
該塊不包含校驗和 |
0xD237 |
您將要加載塊兩次,即CPU上已存在具備相同時間戳的塊 |
0xD238 |
指定的塊中至少有一個不是DB |
0xD239 |
至少有一個指定的DB在裝載存儲器中不可用做連接變量 |
0xD23A |
至少有一個指定的DB與複製和連接的變體有很大不一樣 |
0xD240 |
違反了協調規則 |
0xD241 |
當前保護級別不容許該功能 |
0xD242 |
處理F塊時的保護衝突 |
0xD250 |
更新和模塊ID或版本不匹配 |
0xD251 |
操做系統組件序列不正確 |
0xD252 |
校驗和錯誤 |
0xD253 |
沒有可用的可執行加載程序; 只能使用存儲卡進行更新 |
0xD254 |
操做系統中的存儲錯誤 |
0xD280 |
在S7-300 CPU中編譯塊時出錯 |
0xD2A1 |
塊上的另外一個塊功能或觸發器處於活動狀態 |
0xD2A2 |
塊上的觸發器處於活動狀態。首先完成調試功能 |
0xD2A3 |
塊未激活(連接),塊被佔用或塊當前被標記爲刪除 |
0xD2A4 |
該塊已被另外一個塊函數處理 |
0xD2A6 |
沒法同時保存和更改用戶程序 |
0xD2A7 |
塊具備「未連接」屬性或未處理 |
0xD2A8 |
激活的調試功能阻止將參數分配給CPU |
0xD2A9 |
正在爲CPU分配新參數 |
0xD2AA |
當前正在爲模塊分配新參數 |
0xD2AB |
當前正在更改動態配置限制 |
0xD2AC |
正在運行的激活或取消激活分配(SFC 12)暫時阻止R-KiR過程 |
0xD2B0 |
在RUN(CiR)中配置時發生錯誤 |
0xD2C0 |
已超出最大工藝對象數 |
0xD2C1 |
模塊上已存在相同的技術數據塊 |
0xD2C2 |
沒法下載用戶程序或下載硬件配置 |
0xD401 |
信息功能不可用 |
0xD402 |
信息功能不可用 |
0xD403 |
服務已登陸/註銷(診斷/ PMC) |
0xD404 |
達到的最大節點數。再也不須要登陸診斷/ PMC |
0xD405 |
不支持服務或函數參數中的語法錯誤 |
0xD406 |
當前不可用的必需信息 |
0xD407 |
發生診斷錯誤 |
0xD408 |
更新已停止 |
0xD409 |
DP總線錯誤 |
0xD601 |
函數參數中的語法錯誤 |
0xD602 |
輸入的密碼不正確 |
0xD603 |
鏈接已合法化 |
0xD604 |
已啓用鏈接 |
0xD605 |
因爲密碼不存在,所以沒法進行合法化 |
0xD801 |
至少有一個標記地址無效 |
0xD802 |
指定的做業不存在 |
0xD803 |
非法的工做狀態 |
0xD804 |
非法循環時間(非法時基或多個) |
0xD805 |
不能再設置循環讀取做業 |
0xD806 |
引用的做業處於沒法執行請求的功能的狀態 |
0xD807 |
功能因過載而停止,這意味着執行讀取週期所需的時間比設置的掃描週期時間長 |
0xDC01 |
日期和/或時間無效 |
0xE201 |
CPU已是主設備 |
0xE202 |
因爲閃存模塊中的用戶程序不一樣,沒法進行鏈接和更新 |
0xE203 |
因爲固件不一樣,沒法鏈接和更新 |
0xE204 |
因爲內存配置不一樣,沒法鏈接和更新 |
0xE205 |
因爲同步錯誤致使鏈接/更新停止 |
0xE206 |
因爲協調違規而拒絕鏈接/更新 |
0xEF01 |
S7協議錯誤:ID2錯誤; 工做中只容許00H |
0xEF02 |
S7協議錯誤:ID2錯誤; 資源集不存在 |