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