在很多人眼里,可能認(rèn)為我就是Modbus的“死忠粉”,今天我要“反骨”一下,“揭露”一下Modbus協(xié)議的缺點(diǎn)。
作為工控人,Modbus通訊協(xié)議應(yīng)該都不陌生,Modbus通訊協(xié)議可以說(shuō)是工業(yè)自動(dòng)化領(lǐng)域應(yīng)用最為廣泛的通訊協(xié)議,因?yàn)樗拈_(kāi)放性、可擴(kuò)充性和標(biāo)準(zhǔn)化,使它成為通用工業(yè)標(biāo)準(zhǔn)。
大家如果對(duì)Modbus協(xié)議不熟悉的,可以看下這篇文章:
10年工程師的Modbus總結(jié)
Modbus協(xié)議的優(yōu)點(diǎn)我覺(jué)得不用多說(shuō),一個(gè)四十多年前的協(xié)議,能夠廣泛應(yīng)用到今天,必然有它的道理,這比一個(gè)公司存活40多年可能還要不容易。
但是這篇文章,主要是想跟大家聊聊Modbus協(xié)議的缺點(diǎn)。
凡事都有雙面性,任何協(xié)議都有自身的不足之處,Modbus有缺點(diǎn),并不意味它就是一個(gè)不好的協(xié)議,希望大家理性看待。
1、讀取數(shù)據(jù)量的限制
下面這張圖表示的是ModbusRTU協(xié)議03功能碼的數(shù)據(jù)格式:
從圖中我們可以看到從站返回?cái)?shù)據(jù)的數(shù)據(jù)個(gè)數(shù)(字節(jié)計(jì)數(shù))只占了一個(gè)字節(jié)。
由于字節(jié)計(jì)數(shù)只占用1個(gè)字節(jié),導(dǎo)致讀取輸入/保持寄存器時(shí),一次性最多只能讀取127個(gè)寄存器,這個(gè)對(duì)于某些數(shù)據(jù)量非常大的場(chǎng)合,就需要讀取多次,才能讀取到所有的數(shù)據(jù),這樣通信效率必然會(huì)降低。
2、不支持分區(qū)讀區(qū)和同時(shí)讀寫(xiě)
Modbus只能一次性讀取連續(xù)的地址,如果地址不連續(xù),就可能需要分批來(lái)讀取。當(dāng)然如果地址間隔不大,在一次性讀取的長(zhǎng)度范圍內(nèi),也應(yīng)該一次性連續(xù)讀取。
另外,Modbus協(xié)議不允許同時(shí)進(jìn)行讀寫(xiě)操作,必須分時(shí)操作。 例如03H是讀寄存器,06H是寫(xiě)寄存器,這兩個(gè)指令必須通過(guò)兩個(gè)通訊幀分開(kāi)執(zhí)行,而且不能連續(xù)執(zhí)行,必須等待各自的回應(yīng)之后才可以執(zhí)行下一條指令。
3、不支持寄存器位的寫(xiě)入
Modbus常用的8個(gè)功能碼當(dāng)中,是沒(méi)有針對(duì)寄存器的位寫(xiě)入的。所以當(dāng)我們需要給某個(gè)寄存器的某個(gè)位置位或者復(fù)位時(shí),就會(huì)變得非常麻煩。
我們一般的處理方式有兩種:
第一種方式:我們需要先讀取這個(gè)寄存器的值,然后再將這個(gè)值的某個(gè)位處理之后,將處理后的值進(jìn)行寫(xiě)入,相當(dāng)于需要交互兩次才可以實(shí)現(xiàn),并且這種方式從某種角度上來(lái)說(shuō)是不安全的。
第二種方式:我們可以用一個(gè)寄存器代替一個(gè)位,寫(xiě)入1表示為T(mén)rue,寫(xiě)入0表示為False,這種方式可以單次交互實(shí)現(xiàn),但是會(huì)浪費(fèi)一些內(nèi)存空間。
Modbus協(xié)議是1979年誕生,現(xiàn)在已經(jīng)應(yīng)用在成千上萬(wàn)個(gè)設(shè)備當(dāng)中了,我們都能想到,專(zhuān)家們肯定也知道這樣的問(wèn)題,但是無(wú)法統(tǒng)一去更改。
最后還是強(qiáng)調(diào)一點(diǎn):
凡事都有雙面性,Modbus有缺點(diǎn),但并不妨礙它是工業(yè)里應(yīng)用最廣泛的協(xié)議之一,希望大家理性看待。
也許某一天Modbus協(xié)議可以解決這些問(wèn)題......
也許有的人會(huì)說(shuō)Modbus協(xié)議存在安全漏洞,我覺(jué)得Modbus協(xié)議作為工業(yè)現(xiàn)場(chǎng)應(yīng)用,它的目的是實(shí)現(xiàn)數(shù)據(jù)交互,在不聯(lián)網(wǎng)的環(huán)境下,沒(méi)有攻擊就沒(méi)有傷害。