陳家林,賈 濤
(武漢工程大學(xué) 電 氣信息學(xué)院,湖北 武 漢 4 30000)
Modbus協(xié)議是由Modicon公司在1978年發(fā)明的,這是一個(gè)跨時(shí)代的、里程式的網(wǎng)絡(luò)協(xié)議,正式為工業(yè)網(wǎng)絡(luò)從此拉開了序幕。Modbus協(xié)議是全球第一個(gè)真正用于工業(yè)現(xiàn)場的總線協(xié)議。
本文主要是研究在μC/OS-Ⅱ?qū)崟r(shí)操作系統(tǒng)內(nèi)核上的Modbus協(xié)議主站的具體實(shí)現(xiàn),充分使用μC/OS-Ⅱ上所提供的實(shí)時(shí)性資源以及通過硬件上單片機(jī)和RS485接口實(shí)現(xiàn)與串行連接的從站設(shè)備進(jìn)行數(shù)據(jù)傳輸和交換。然而,目前市面上已經(jīng)存在的一些主站設(shè)備由于功耗、體積和通信實(shí)時(shí)性等原因限制了發(fā)展。特別是實(shí)時(shí)性要求,如果被測量的對(duì)象實(shí)時(shí)性要求很高,而測量的實(shí)時(shí)性又無法達(dá)到要求,會(huì)導(dǎo)致數(shù)據(jù)的精確度和準(zhǔn)確性大打折扣??梢姡瑢?shí)時(shí)性要求對(duì)儀器儀表的測量是非常重要的。為了實(shí)現(xiàn)準(zhǔn)確檢測這個(gè)要求,本文特此提出了一個(gè)具有實(shí)時(shí)性要求的Modbus主站協(xié)議系統(tǒng)的設(shè)計(jì)方案[1-7]。
Modbus標(biāo)準(zhǔn)定義了 OSI模型第7層上的應(yīng)用層報(bào)文傳輸協(xié)議,它在連接至不同類型總線或網(wǎng)絡(luò)的設(shè)備之間提供客戶機(jī)/服務(wù)器通信。
本文主要描述的是Modbus串行鏈路協(xié)議。Modbus串行鏈路協(xié)議是一個(gè)主/從協(xié)議。該協(xié)議位于OSI模型的第二層。在物理層,Modbus串行鏈路系統(tǒng)可以使用不同的物理接口(RS485、RS232)。在Modbus串行鏈路上客戶機(jī)的功能由主站提供而服務(wù)器功能由從站實(shí)現(xiàn)。Modbus串行鏈路協(xié)議是一個(gè)主/從協(xié)議。在同一時(shí)刻,只有一個(gè)主站連接于總線,一個(gè)或多個(gè)從站(最大編號(hào)為247)連接于同一個(gè)串行總線。
當(dāng)電源上電后,主站的初始狀態(tài)為空閑狀態(tài)。主站只有在空閑狀態(tài)下才能發(fā)送請(qǐng)求。發(fā)送一個(gè)請(qǐng)求后,主站離開空閑狀態(tài),而且不能同時(shí)發(fā)送第二個(gè)請(qǐng)求。
當(dāng)單播請(qǐng)求發(fā)送出去后,主站將進(jìn)入等待應(yīng)答狀態(tài),同時(shí)一個(gè)臨界超時(shí)定時(shí)啟動(dòng)。這個(gè)超時(shí)稱為"響應(yīng)超時(shí)"。它避免主站永遠(yuǎn)處于等待應(yīng)答狀態(tài)。當(dāng)收到一個(gè)應(yīng)答時(shí),主站在處理數(shù)據(jù)之前檢驗(yàn)應(yīng)答。在某些情況下,檢驗(yàn)的結(jié)果可能為錯(cuò)誤。當(dāng)未收到應(yīng)答響應(yīng)超時(shí),也產(chǎn)生一個(gè)錯(cuò)誤。產(chǎn)生錯(cuò)誤后,主站進(jìn)入空閑狀態(tài)并準(zhǔn)備重發(fā)。若沒有錯(cuò)誤產(chǎn)生,則正常處理數(shù)據(jù)并進(jìn)入空閑狀態(tài)。
當(dāng)廣播請(qǐng)求發(fā)送出時(shí),是沒有從站會(huì)發(fā)出響應(yīng)的。這時(shí)主站需要進(jìn)行一個(gè)轉(zhuǎn)換延時(shí)以便從站能夠有足夠時(shí)間處理這次廣播請(qǐng)求。主站需要等待轉(zhuǎn)換延時(shí)結(jié)束后才可進(jìn)入到空閑狀態(tài)。
考慮到Modbus主站與從站不同,其性質(zhì)是一個(gè)主動(dòng)性的處理過程,而實(shí)際應(yīng)用中主站每一次發(fā)送出去的數(shù)據(jù)幀在請(qǐng)求時(shí)間周期、數(shù)據(jù)幀內(nèi)容以及處理要求上都不太一致。為了解決這些問題本設(shè)計(jì)在μC/OS-Ⅱ所提供的系統(tǒng)服務(wù)功能下,將主站系統(tǒng)分為3個(gè)部分:請(qǐng)求主站服務(wù)的用戶任務(wù)、主站服務(wù)管理任務(wù)、串口底層驅(qū)動(dòng)函數(shù)。如圖1所示的主站系統(tǒng)邏輯結(jié)構(gòu)。
圖1 主站系統(tǒng)邏輯結(jié)構(gòu)圖Fig.1 Structure diagram of the simple master station system on Modbus protocol
請(qǐng)求主站服務(wù)的用戶任務(wù)是指的是那些用戶任務(wù)中有調(diào)用主站服務(wù)的需求,這類任務(wù)中包括了一個(gè)主站服務(wù)調(diào)用函數(shù),在本系統(tǒng)內(nèi)可以將它們看作是應(yīng)用層。主站系統(tǒng)中的主站管理任務(wù)是負(fù)責(zé)專門管理來自各個(gè)請(qǐng)求主站服務(wù)的任務(wù)的具體請(qǐng)求,同樣可以將它們看作是應(yīng)用層。串口底層的中斷處理實(shí)現(xiàn)了具體的數(shù)據(jù)發(fā)送與接收,可以將它們看作是數(shù)據(jù)鏈路層。這樣設(shè)計(jì)保證各個(gè)請(qǐng)求主站服務(wù)的任務(wù)按照CPU對(duì)任務(wù)調(diào)度執(zhí)行的順序依次循環(huán)調(diào)用主站服務(wù)和處理數(shù)據(jù)幀,都有平等的機(jī)會(huì)去請(qǐng)求主站服務(wù)。同時(shí)每個(gè)請(qǐng)求任務(wù)在發(fā)送出請(qǐng)求后可以繼續(xù)執(zhí)行任務(wù)代碼而不是處于等待狀態(tài),也保證了系統(tǒng)整體實(shí)時(shí)性的要求。
1)系統(tǒng)的主要硬件介紹
主站系統(tǒng)基于STM32L152RBT6為控制器的硬件環(huán)境而設(shè)計(jì)。STM32L152RBT6是屬于由ST公司的STM32L152系列微控制器,該系列屬于是超低功耗,高數(shù)據(jù)安全性,高效能的ARM Cortex-M3微控制器芯片。低功耗運(yùn)行模式電流為10.4 μA,工作電壓為 1.8~3.6 V。 能夠滿足實(shí)際的工業(yè)應(yīng)用中低功耗穩(wěn)定的需求。
主站系統(tǒng)的通信模塊采用的是SP3072EEN接口芯片。SP3072EEN是由Sipex公司設(shè)計(jì)生產(chǎn)的RS-485/RS422收發(fā)器,其工作電源電壓為 3.3 V,電源電流為 800 μA。SP3072EEN采用半雙工通訊方式,與單片機(jī)引腳連接簡單。它完成將TTL電平轉(zhuǎn)換為RS485電平的功能。
圖2 RS485轉(zhuǎn)換接口原理圖Fig.2 Principle diagram of RS485 conversion interface
2)μC/OS-Ⅱ環(huán)境的移植
μC/OS-Ⅱ移植工作主要是處理與處理器相關(guān)的源文件,即 os_cpu_c.c,os_cpu_a.s,os_cpu.h。 其中 os_cpu.h 主要包含編譯器相關(guān)的數(shù)據(jù)類型的定義、堆棧類型的定義以及幾個(gè)宏定義和函數(shù)說明,為了便于移植,須重新定義數(shù)據(jù)類型,因?yàn)椴煌木幾g器所提供的同一數(shù)據(jù)類型的數(shù)據(jù)長度并不相同。os_cpu_c.c文件中主要實(shí)現(xiàn)任務(wù)堆棧的初始化函數(shù)OSTaskStkInit(),任務(wù)創(chuàng)建函數(shù)通過調(diào)用函數(shù)OSTaskStkInit()初始化任務(wù)堆棧結(jié)構(gòu)。在os_cpu_a.s文件中需要根據(jù)具體的硬件處理器實(shí)現(xiàn)幾個(gè)匯編函 數(shù) OSstartHighRdy()、OSCtxSw()、OSIntetxsw 以 及臨 界處理函數(shù) OS_CPU_SR_Save,OS_CPU_SR_Restore。尤其需要注意的是,由于STM32是 cortex M3內(nèi)核,所以 OSCtxSw()、OSIntetxsw函數(shù)都是通過PendSV中斷來完成,它實(shí)際負(fù)責(zé)μC/OS-Ⅱ的所有上下文切換。
3)Modbus主站應(yīng)用層設(shè)計(jì)
圖3 主站系統(tǒng)軟件結(jié)構(gòu)圖Fig.3 Software structure diagram of master station system
主站應(yīng)用層設(shè)計(jì)時(shí)使用到μC/OS-Ⅱ所提供的3個(gè)系統(tǒng)服務(wù)功能:消息郵箱、消息隊(duì)列以及內(nèi)存管理功能。首先通過OSQCreate()、OSMboxCreate()函數(shù)進(jìn)行初始化,分別建立Buffaddress_Queue消息隊(duì)列和Rev_Msg郵箱。然后,為了滿足Modbus協(xié)議規(guī)定的每數(shù)據(jù)幀大小不超過256字節(jié),使用OSMemCreate()函數(shù)建立對(duì)應(yīng)的一個(gè)數(shù)據(jù)幀緩沖區(qū)塊,塊內(nèi)每個(gè)緩沖區(qū)大小設(shè)置為260字節(jié)。其中前256字節(jié)為實(shí)際Modbus緩沖區(qū)大小,后4字節(jié)用來存放各個(gè)請(qǐng)求的處理標(biāo)志和底層收發(fā)信息包括底層接收字節(jié)數(shù)Rx和發(fā)送字節(jié)數(shù)Tx以及處理標(biāo)志handle,none預(yù)留。緩沖區(qū)格式如圖4所示。
圖4 緩沖區(qū)格式圖Fig.4 Structure diagram of the buffer
消息隊(duì)列Buffaddress_Queue作為連接用戶請(qǐng)求任務(wù)和主站調(diào)用任務(wù)的橋梁,其作用是將用戶申請(qǐng)作為自身任務(wù)數(shù)據(jù)幀的內(nèi)存塊地址作為消息內(nèi)容傳遞給主站管理任務(wù)。消息郵箱Rev_Msg作為主站管理任務(wù)與底層驅(qū)動(dòng)函數(shù)之間的同步信號(hào),并啟用超時(shí)機(jī)制,實(shí)現(xiàn)Modbus上響應(yīng)超時(shí)和轉(zhuǎn)換延時(shí)功能。最后,內(nèi)存管理為各個(gè)請(qǐng)求任務(wù)分配獨(dú)立的數(shù)據(jù)幀空間,并統(tǒng)一交予主站管理任務(wù)處理。
Host_admin_task()主站管理任務(wù)的具體執(zhí)行過程如圖5所示。主站管理任務(wù)得優(yōu)先級(jí)比所有請(qǐng)求主站服務(wù)任務(wù)都要低,以便最后接收到所有的請(qǐng)求并依次處理。調(diào)用OSQPend()等待消息隊(duì)列Buffaddress_Queue中的具體消息,一旦得到消息內(nèi)容,就將該內(nèi)容作為緩沖區(qū)首地址,并預(yù)先處理該緩沖區(qū)的后4字節(jié)內(nèi)容,將handle初始化為0,將Rx和Tx導(dǎo)入底層函數(shù)。隨后調(diào)用底層函數(shù)完成具體發(fā)送和接收。然后調(diào)用OSMboxPend()等待接收郵箱Rev_Msg,等待時(shí)間設(shè)置為1s,由于轉(zhuǎn)換延時(shí)時(shí)間小于響應(yīng)超時(shí),這里統(tǒng)一設(shè)為一種超時(shí)計(jì)時(shí)方式。最后,如果正常接收Rx個(gè)字節(jié),對(duì)應(yīng)修改緩沖區(qū)中的handle標(biāo)志為1(已接收),若出現(xiàn)超時(shí)或者發(fā)送命令錯(cuò)誤則統(tǒng)一修改緩沖區(qū)中的標(biāo)志為2(超時(shí))。
圖5 主站管理任務(wù)流程圖Fig.5 Flow chart of the host_admin_task()
Service_call()主站服務(wù)請(qǐng)求函數(shù)的具體執(zhí)行過程如圖6所示。首先調(diào)用OSMemGet()申請(qǐng)一個(gè)緩沖區(qū)作為任務(wù)的數(shù)據(jù)幀空間。若申請(qǐng)成功則填充數(shù)據(jù)幀,填充數(shù)據(jù)幀不要超過256字節(jié)大小。最后發(fā)送緩沖區(qū)地址給消息隊(duì)列Buffaddress_Queue。若填充溢出或者發(fā)送隊(duì)列失敗則需要及時(shí)調(diào)用OSMemPut()釋放掉申請(qǐng)的緩沖區(qū)。
圖6 主站服務(wù)請(qǐng)求函數(shù)流程圖Fig.6 Flow chart of the service_call()
Host_apply()主站調(diào)用函數(shù)具體執(zhí)行過程如圖7所示。主站調(diào)用函數(shù)是基于state請(qǐng)求狀態(tài)的處理。state請(qǐng)求狀態(tài)作為任務(wù)里的靜態(tài)變量,與任務(wù)里的每一個(gè)請(qǐng)求任都相對(duì)應(yīng),表示當(dāng)前請(qǐng)求任務(wù)在主站系統(tǒng)中的狀態(tài)信息,state有4種狀態(tài):0空閑可用;1已回復(fù);2回復(fù)超時(shí);3已請(qǐng)求。主站調(diào)用函數(shù)根據(jù)state狀態(tài)完成具體的請(qǐng)求和處理工作。當(dāng)state為1時(shí),進(jìn)行數(shù)據(jù)幀校驗(yàn)和上層應(yīng)用處理。當(dāng)state為2時(shí),進(jìn)行釋放緩沖區(qū),準(zhǔn)備重新請(qǐng)求。當(dāng)state為0時(shí),請(qǐng)求主站服務(wù)Service_call()。當(dāng)state為3時(shí),讀取緩沖區(qū)處理標(biāo)志handle,檢測是否接收或者超時(shí)。
圖7 主站調(diào)用函數(shù)流程圖Fig.7 Flow chart of the host_apply()
4)Modbus主站底層驅(qū)動(dòng)設(shè)計(jì)
串口底層驅(qū)動(dòng)是由STM32中的usart外設(shè)中斷服務(wù)函
數(shù)完成。Usart外設(shè)的中斷處理服務(wù)函數(shù)完成對(duì)
usart_low_output()底層發(fā)送函數(shù)和usart_low_input()底層接收
函數(shù)的調(diào)用。在底層接收函數(shù)usart_low_input()中,判斷了是
否正確接收規(guī)定的字節(jié)數(shù),若接收字節(jié)小于或者未接收都認(rèn)
為超時(shí)錯(cuò)誤。
底層接收函數(shù)的部分代碼:
Void usart_low_output(uint8_t*Datas)//參數(shù)為將要發(fā)送的數(shù)據(jù)
{
if(TxBytes!=0)
{
USART_SendData(USART,*Datas);//STM32串口驅(qū)動(dòng)發(fā)送函數(shù)
Datas++;
TxBytes--;//全局變量TxBytes當(dāng)前主站需發(fā)送的字節(jié)數(shù)
}
else
{
USART_ITConfig(USART,USART_IT_RXNE,ENABLE);//啟動(dòng)接收中斷
RxBytes=Datas[257];//當(dāng)前主站需接收的字節(jié)數(shù)
}
}
底層發(fā)送函數(shù)的部分代碼:
Void usart_low_input(uint8_t*Buff)//參數(shù)為將要接收數(shù)據(jù)的緩沖區(qū)地址
{
if(RxBytes!=0)
{
Buff++;
RxBytes--;
}
else//接收完畢
{
USART_ITConfig(USART,USART_IT_RXNE,DISABLE);//關(guān)閉接收中斷
OSMboxPost(Rev_Msg,&RxBytes);
}
}
系統(tǒng)測試通過將單片機(jī)通過RS485轉(zhuǎn)串口與電腦串口連接并使用modbus slave軟件作為通信的從設(shè)備。建立了5個(gè)從設(shè)備連接到主站系統(tǒng)中,從設(shè)備ID號(hào)為1~5,每個(gè)從設(shè)備都帶有10個(gè)寄存器,測試主站的0x03讀取輸入寄存器功能。同時(shí),在主站系統(tǒng)中建立了5個(gè)請(qǐng)求主站任務(wù),每個(gè)任務(wù)都周期性500 ms調(diào)度一次,按照任務(wù)自身優(yōu)先級(jí)順序進(jìn)行主站請(qǐng)求發(fā)送,發(fā)送命令為03,寄存器個(gè)數(shù)為10。測試結(jié)果表明slave中每個(gè)從設(shè)備都周期性的獲取到主站服務(wù)并成功完成了接收和發(fā)送。
簡易式主站系統(tǒng)通過使用μC/OS-Ⅱ?qū)崟r(shí)操作系統(tǒng)內(nèi)核帶來的一些系統(tǒng)服務(wù)功能使得整個(gè)主站系統(tǒng)變得穩(wěn)定和具有實(shí)時(shí)性。該主站系統(tǒng)能夠完成一些主要的命令單播的發(fā)送與接收,并能簡單的處理從設(shè)備超時(shí)重發(fā)和廣播轉(zhuǎn)換延時(shí)等問題,保證了整體系統(tǒng)實(shí)時(shí)性和穩(wěn)定性,并能與上位機(jī)軟件進(jìn)行正常通信,達(dá)到了主站系統(tǒng)的設(shè)計(jì)要求,同時(shí)簡易式主站系統(tǒng)也提供了移植到其他嵌入式環(huán)境的可能。
[1]方羽,梁廣瑞,羅覃東.基于uCOS_Ⅱ的MODBUS協(xié)議的實(shí)現(xiàn)[J].裝備制造技術(shù),2009(1):83-84.FANG Yu,LIANG Guang-rui,LUO Qin-dong.The Implementation of Modbus Protocol Based on uCOS_II[J].Equipment Manufacturing Technology,2009(1):83-84.
[2]李振東.Modbus協(xié)議的工業(yè)PLC監(jiān)控儀表設(shè)計(jì)[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2012(4):5-8.LI Zhen -dong.Modbus Protocol Monitoring Instrument for Industrial PLC [J].Microcontrollers&Embedded Systems.2012(4):5-8.
[3]余杰,李鐵輝.基于MODBUS協(xié)議的串口控件的實(shí)現(xiàn)[J].微計(jì)算機(jī)信息,2008(21):79-81.YU Jie,LI Tie -h(huán)ui.The Realization of Serial Port ActiveX Control Based on Modbus Protocol[J].Microcomputer Information,2008(21):79-81.
[4]邵貝貝.嵌入式實(shí)時(shí)操作系統(tǒng)μC/OS-II[M].2版.北京:北京航空航天大學(xué)出版社,2003.
[5]任哲.嵌入式實(shí)時(shí)操作系統(tǒng)μC/OS-II原理及應(yīng)用[M].北京:北京航空航天大學(xué)出版社,2005.
[6]華镕.從Modbus到透明就緒[M].北京:機(jī)械工業(yè)出版社,2009.
[7]張利平,劉寧,董樹泉.基于Modbus協(xié)議CP341與BENTLY3500之間的通訊[J].工業(yè)儀表與自動(dòng)化裝置,2011(2):86-87.ZHANG Li-ping,LIU Ning,DONG Shu-quan.The communication between CP341 and BENTLY3500 based on Modbus protocol [J].Industrial Instrumentation&Automation,2011(2):86-87.