資源描述:
《freemodbus代碼解讀及移植筆記》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在學術(shù)論文-天天文庫。
1、....1.FreeModbus協(xié)議分析協(xié)議必須首先調(diào)用初始化功能eMBinit()函數(shù)。后調(diào)用eMBEnable(),最后,在循環(huán)體或者單獨一個任務(wù)中調(diào)用eMBPoll()函數(shù)。2.應(yīng)用層協(xié)議2.1.系統(tǒng)的啟動2.1.1.eMBInit()函數(shù)的源碼分析以RTU方式為例,首先,檢查調(diào)用的地址是否合法。如不合法,返回錯誤。如果合法則繼續(xù)執(zhí)行,首先,針對RTU方式還是ASCII方式,選擇不同的編譯模塊。對需要調(diào)用的函數(shù)指針進行復(fù)制。如果移植需要改變其他用途,則要修改相應(yīng)的指針,包括如下賦值:pvMBFrameStartCur=eMBRTUStart;pvMBFrameStop
2、Cur=eMBRTUStop;peMBFrameSendCur=eMBRTUSend;peMBFrameReceiveCur=eMBRTUReceive;pvMBFrameCloseCur=MB_PORT_HAS_CLOSE?vMBPortClose:NULL;pxMBFrameCBByteReceived=xMBRTUReceiveFSM;pxMBFrameCBTransmitterEmpty=xMBRTUTransmitFSM;pxMBPortCBTimerExpired=xMBRTUTimerT35Expired;然后調(diào)用eStatus=eMBRTUInit(ucMB
3、Address,ucPort,ulBaudRate,eParity);具體初始化通訊端口。2.1.2.eMBRTUIniteMBRTUInit這個函數(shù)主要干兩件事:第一,初始化串口:if(xMBPortSerialInit(ucPort,ulBaudRate,8,eParity)!=TRUE){eStatus=MB_EPORTERR;}這個函數(shù)在portserial.c中,需要用戶在移植的時候根據(jù)自己的處理器編寫。第二,初始化計時器:首先要根據(jù)波特率計算一下是3.5~5.0個字節(jié)周期的時間,然后再調(diào)用xMBPortTimersInit((USHORT)usTimerT35_
4、50us),初始化計時器。這個函數(shù)在porttimer.c中,需要用戶在移植的時候根據(jù)自己的處理器編寫。........2.1.3.eMBEnable源碼分析首先,看看Modbus功能是否是被關(guān)閉的,如果不是被關(guān)閉(可能是沒有被初始化或者已經(jīng)打開),就返回錯誤。如果是disable狀態(tài),就干下面兩件事:l調(diào)用pvMBFrameStartCur()。由于這是個函數(shù)指針,在模塊eMBInit中,指向了eMBRTUStart函數(shù)n在源代碼中有這樣一段注釋:,意思是,首先設(shè)置成STATE_RX_INIT,然后打開計時器,等待t3.5以后,進入STATE_RX_IDLE狀態(tài)。n看源代
5、碼中,首先有設(shè)置Receiver的狀態(tài),后調(diào)用vMBPortSerialEnable,設(shè)置接收狀態(tài),然后打開定時器。n當定時器中斷后,自動調(diào)用中斷服務(wù)程序,在中斷服務(wù)程序中,只調(diào)用了pxMBPortCBTimerExpired,而這是一個函數(shù)指針,在RTU方式初始化時,被指向了xMBRTUTimerT35Expired()函數(shù)。nxMBRTUTimerT35Expired函數(shù)在mbrtu.c中,在這里,我們只看第一種方式,就是進入初始化狀態(tài),在t35時間以后,只調(diào)用了一個xNeedPoll=xMBPortEventPost(EV_READY);nxMBPortEventPo
6、st函數(shù)就是在事件隊列里加了一個EV_RDY事件。l然后,將eMB狀態(tài)改為使能狀態(tài),l初始化結(jié)束。2.2.總線偵聽eMBPoll()首先,判斷系統(tǒng)是否被使能,如果沒有,則返回錯誤值。然后,檢查是否有事件發(fā)生,如果有,則根據(jù)不同類型的事件響應(yīng):l如果是EV_RDY,表示系統(tǒng)剛剛進入偵聽狀態(tài),則什么都不做;l如果狀態(tài)為EV_FRAME_RECEIVED,也就是接收到完整的幀,做下面兩件事情:n調(diào)用eStatus=peMBFrameReceiveCur(&ucRcvAddress,&ucMBFrame,&usLength)。這是一個函數(shù)指針,在eMBInit中,被初始化指向eMB
7、RTUReceive。neMBRTUReceive這個函數(shù)首先校驗幀的長度和CRC,然后從協(xié)議中解析出地址、數(shù)據(jù)和長度。n然后檢查地址,如果是廣播地址或者是本機地址,就調(diào)用xMBPortEventPost(EV-EXECUTE),將接收器的狀態(tài)更改為EV_EXECUTE。l如果狀態(tài)為EV_EXECUTE,就在函數(shù)列表中檢查,有沒有與命令字段相符合的函數(shù)來解析相應(yīng)則執(zhí)行該函數(shù),否則返回非法功能代碼。2.3.數(shù)據(jù)發(fā)送........發(fā)送數(shù)據(jù)通過指針eMBRTUSend,調(diào)用eMBRTUSend函數(shù)。2.3.1.eMBR