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