淺談遠程診斷技術(shù)在電控發(fā)動機方面的應(yīng)用
具體地講,GPRS DTU通過數(shù)據(jù)中心的IP地址(如果是采用中心域名的話,先通過中心域名解析出中心IP地址)以及端口號等參數(shù),向數(shù)據(jù)中心發(fā)起TCP或UDP通信請求。在得到中心的響應(yīng)后,GPRS DTU即認為與中心握手成功,然后就保持這個通信連接一直存在,如果通信連接中斷,GPRS DTU將立即重新與中心握手。
對于DTU來說,只要建立了與數(shù)據(jù)中心的雙向通信,完成用戶串口數(shù)據(jù)與GPRS網(wǎng)絡(luò)數(shù)據(jù)包的轉(zhuǎn)換就相對簡單了。一旦接收到用戶的串口數(shù)據(jù),DTU就立即把串口數(shù)據(jù)封裝在一個TCP/UDP包里,發(fā)送給數(shù)據(jù)中心。反之,當(dāng)DTU收到數(shù)據(jù)中心發(fā)來的TCP/UDP包時,從中取出數(shù)據(jù)內(nèi)容,立即通過串口發(fā)送給用戶設(shè)備。
2.3軟件
在前端,DTU和電控單元(ECU)通過RS232接口相連。DTU上電運行后先注冊到移動的GPRS網(wǎng)絡(luò),然后去和設(shè)置在DTU中的后臺中心建立SOCKET連接。后臺中心作為SOCKET的服務(wù)端,DTU是SOCKET連接的客戶端。因此只有DTU是不能完成數(shù)據(jù)的無線傳輸?shù)?,還需要有后臺軟件的配合一起使用。在建立連接后,前端的設(shè)備和后臺的中心就可以通過DTU進行無線數(shù)據(jù)傳輸了,而且是雙向的傳輸。
軟件設(shè)計實質(zhì)上是改變現(xiàn)有基于本地串口通信的故障診斷軟件的通信方式,將串口上的數(shù)據(jù)傳輸改變?yōu)門CP/IP協(xié)議的網(wǎng)絡(luò)傳輸數(shù)據(jù),及SOCKET網(wǎng)絡(luò)編程。通過SOCKET編程,將電控單元(ECU)的通信協(xié)議命令移植到TCP/UDP數(shù)據(jù)包中,通過TCP/UDP數(shù)據(jù)傳輸實現(xiàn)發(fā)動機的故障診斷命令收發(fā)。本文基于VC++程序,將原有程序設(shè)計的通信模塊進行重新設(shè)計,從而實現(xiàn)了不改變原有故障診斷軟件的基本框架,快速實現(xiàn)基于DTU數(shù)據(jù)交互的診斷軟件。
在vc中進行winsock的api編程開發(fā)的時候,需要在項目中使用以下三個文件。
(1)winsock.h: winsock api的頭文件,需要包含在項目中??稍趕tdafx.h中加入#Include "winsock2.h"?! ?P> (2)wsock32.lib: winsock api連接庫文件。在使用中,一定要把它作為項目的非缺省的連接庫包含到項目文件中去。打開選擇菜單project->setting (alt+f7),進入project setting 對話框,在link下的 ob-ject/library modules 輸入ws2_32.lib,然后點ok,或者在頭文件中添加:#pragma comment(lib, "ws2_32.lib")。
(3)winsock.dll: winsock的動態(tài)連接庫,位于windows的安裝目錄
基本的SOCKET編程大致可分為以下幾個步驟,如圖1所示:
圖1 SOCKET編程步驟
由于DTU上電后主動向服務(wù)器端發(fā)送連接請求,所以故障診斷軟件主要基于服務(wù)器端SOCKET編程,具體服務(wù)器端操作如下。
服務(wù)器端操作 socket(套接字)
(1)在初始化階段調(diào)用wsastartup()
此函數(shù)在應(yīng)用程序中初始化windows sockets dll ,只有此函數(shù)調(diào)用成功后,應(yīng)用程序才可以再調(diào)用其他windows sockets dll中的api函數(shù)。在程式中調(diào)用該函數(shù)的形式如下:wsastartup(0x0202,(lpwsadata)&wsadata),其中0x0202表示我們用的是winsocket2.0版本,wsaata用來存儲系統(tǒng)傳回的關(guān)于winsocket的資料。
(2)建立socket
初始化winsock的動態(tài)連接庫后,需要在服務(wù)器端建立一個監(jiān)聽的socket,為此可以調(diào)用socket()函數(shù)用來建立這個監(jiān)聽的socket,并定義此socket所使用的通信協(xié)議。此函數(shù)調(diào)用成功返回socket對象,失敗則返回invalid_socket(調(diào)用wsagetlasterror()可得知原因,所有winsocket 的函數(shù)都可以使用這個函數(shù)來獲取失敗的原因)。
socket pascal far socket( int af, int type, int protocol )
參數(shù): af:目前只提供 pf_inet(af_inet);
type:socket 的類型 (sock_stream、sock_dgram);
protocol:通訊協(xié)定(如果使用者不指定則設(shè)為0);
如果要建立的是遵從tcp/ip協(xié)議的socket,第二個參數(shù)type應(yīng)為sock_stream,如為udp(數(shù)據(jù)報)的socket,應(yīng)為sock_dgram。
(3)綁定端口
接下來要為服務(wù)器端定義的這個監(jiān)聽的socket指定一個地址及端口(port),這樣客戶端才知道待會要連接哪一個地址的哪個端口,為此我們要調(diào)用bind()函數(shù),該函數(shù)調(diào)用成功返回0,否則返回socket_error。
int pascal far bind( socket s, const struct sockaddr far *name,int namelen );
參 數(shù): s:socket對象名,即通過socket函數(shù)創(chuàng)建的socket對象;
name:socket的地址值,這個地址必須是執(zhí)行這個程式所在機器的ip地址,這個地址為地址結(jié)構(gòu),其中包含了本機的ip地址和監(jiān)聽端口號;
namelen:name的長度,即地址結(jié)構(gòu)的長度;
如果使用者不在意地址或端口的值,那么可以設(shè)定地址為inaddr_any,及port為0,windows sockets 會自動將其設(shè)定適當(dāng)之地址及port (1024 到 5000之間的值)。此后可以調(diào)用getsockname()函數(shù)來獲知其被設(shè)定的值。
(4)監(jiān)聽
當(dāng)服務(wù)器端的socket對象綁定完成之后,服務(wù)器端必須建立一個監(jiān)聽的隊列來接收客戶端的連接請求。listen()函數(shù)使服務(wù)器端的socket 進入監(jiān)聽狀態(tài),并設(shè)定可以建立的最大連接數(shù)(目前最大值限制為 5, 最小值為1)。該函數(shù)調(diào)用成功返回0,否則返回socket_error。
評論