陳 鵬,師奕兵,張 偉
(電子科技大學自動化工程學院,四川 成都 611731)
隨鉆聲波測井的數據量非常大,受到隨鉆測井傳輸速率的限制,大量的測井數據不能實時傳輸到地面系統,必須存儲在井下儀器的存儲電路中,待儀器工作起鉆后,再由上位機讀取[1]。井下儀器工作環境異常惡劣,對井下電路必須進行橡膠封裝以增強其抗震性能,這導致儀器的拆卸比較困難。為了便于測井數據的讀取以及對井下電路程序的在線升級更新,設計了隨鉆聲波測井儀維護系統。該系統通過串口和井下儀器進行通信,并通過USB或者網線和上位機進行通信,同時上位機能夠對井下儀器進行維護和程序更新。USB具有速度高、成本低、功耗低、使用方便、支持即插即用等優點;以太網又可以做到遠程快速故障分析與處理、設備的遠程維護和數據的遠程傳輸,可以提高工作效率并降低整體成本。
維護系統與上位機和井下裝置的連接示意圖如圖1所示。
隨鉆聲波測井儀維護系統的應用程序主要采用Qt進行開發,應用程序主要實現兩部分功能:

圖1 系統連接示意圖
(1)實現與井下儀器的數據通信;
(2)實現與上位機數據通信并響應上位機命令。
系統軟件采用Qt Creator進行開發,Qt Creator是用于Qt開發的輕量級跨平臺集成開發環境,它提供一個專為支持跨平臺開發而設計的集成開發環境(IDE)。
Qt最獨特之處在于它的“信號與槽”機制[2],簡言之,“信號與槽”機制就是將一個窗體里面發生的某一個事件所產生的信號與工程中任何一個窗體里面的任何一個預定義的或者程序員自定義的槽函數進行關聯,關聯方法為:
QObject::connect(signalemitter,SIGNAL(),signalreceiver,SLOT());
編譯應用程序時應使用配置好的Qt-Embeded-Linux交叉編譯環境進行編譯,生成一個二進制可執行程序文件,用NFS加載文件系統的方法啟動開發板,然后將Qt的庫文件復制到維護裝置的/lib/文件系統目錄下,再拷貝二進制可執行程序文件到NFS共享目錄的文件系統中,即可使用命令形式啟動程序。
USB(通用串行總線)的結構等在很多文獻中已有提及,該文主要涉及到USB從設備驅動程序的開發。
系統是建立在Linux操作系統上的USB從設備,一方面需要遵循Linux設備驅動程序模型,另一方面需要配合USB Gadget設備規范。
USB從設備驅動程序分為3個層次,USB從設備驅動程序體系圖如圖2所示,從底層向上分別是設備控制器(UDC)驅動程序層、Gadget API和Gadget驅動程序層[3]。
設備控制器驅動程序層直接和硬件通信,不同的設備控制器硬件有不同的設備控制器驅動程序。Gadget API是對硬件控制的抽象層,是Gadget驅動程序的編程接口,它將Gadget驅動程序的控制傳遞給具體的設備控制器硬件驅動程序。

圖2 USB從設備驅動程序層次圖
系統采用三星公司的s3c2440芯片,其中集成了USB從設備控制器,通過對Gadget驅動程序進行編寫并通過USB從設備控制器與USB主機連接,實現設備功能。
在驅動程序激活之前需要對各個端點進行配置[4],在用戶空間端點初始化的方法為:
fd=open(“/dev/gadget/$ENDPOINT”,0_RDWR);
status=write(fd,descriptors,sizeof(descriptors));
此處的write函數通過調用文件操作函數集ep_config_operations中的ep_config函數建立端點配置。函數主要功能是使控制器端點有合適的最大包尺寸等配置,以分別適應批量、中斷、同步傳輸的傳輸包要求。
端點配置完成后,即可通過端點文件的文件操作函數集file_operations來對端點進行控制實現數據的傳輸操作,其中主要用到的重點函數有read、write、ioctl、release等,在實現時將這些函數分別實例化為ep_read、ep_write等。
其中ep_read和ep_write函數實現端點數據與用戶空間數據之間的傳輸,ioctl函數實現端點的各種控制操作。
在USB的傳輸方式中,批量傳輸可以保證數據的可靠性,當出現錯誤時,會要求發送方重發[5]。因而為了保證測井數據傳輸的準確性,采用批量傳輸方式。
端點寫操作函數ep_write的主體是USB從設備,將USB從設備的用戶空間的數據通過端點傳給USB主設備,ep_write用于處理一個bulk批量傳輸,函數聲明如下:
static ssize_t ep_write(struct file*fd,const char_user*buf,size_t len,loff_t*ptr)
函數實現中主要涉及參數的初始化以及內核空間的分配等工作,在write函數中調用ep_io()函數。此處的ep_io調用Gadget API函數usb_ep_queue()將讀寫請求放到端點上進行排隊,在端點上進行數據的發送和接收。
s3c2440芯片包含了5個終端,其中包括一個控制端點即端點0和4個數據端點,控制端點的FIFO最大為16Byte,數據端點的FIFO最大為64Byte。端點進行寫操作時,大于64Byte的數據都分包發送,發送時先將發送寄存器設為只發狀態,向端點對應的FIFO中不斷寫入64 Byte的數據包,發送完成后即將發送寄存器恢復為可用狀態。
端點讀操作函數ep_read和ep_write有類似的操作,只是數據操作方向相反。在端點進行讀操作時,先通過ep_read函數中傳入的用戶空間接收數據的地址,一直等待數據接收,接收完成后便喚醒等待,重新進入可用狀態。
測井儀維護系統與PC通過網絡連接時,使用socket套接字編程,系統將作為服務器端,PC將作為客戶端進行通信。
系統中要求測井數據的傳輸準確無誤,所以選用TCP/IP協議族傳輸層上的TCP協議。相對于UDP協議,TCP為應用程序提供可靠的通信連接,通過各種機制來減少錯誤發生的概率[6],可靠性比較高。使用基于TCP協議的流式socket(SOCK_STREAM)進行網絡編程,保證了測井數據傳輸的正確性和順序性。
網絡通信的程序流程圖如圖3所示。
首先,建立自己的套接口:
s=socket(AF_INET,SOCK_STREAM,0)
該函數建立指定地址格式、數據類型和協議下的套接口。
bind(s,(struct sockaddr*)&server,sizeof(server))
該函數將建立服務器本地的半相關,其中,server是sockaddr_in結構,其成員描述了本地端口號和本地主機地址,經過bind()將服務器進程在網絡上標識出來。
然后建立連接。首先調用listen()函數表示開始監聽,再通過accept()調用等待接收連接。
ns=accept(s,(struct sockaddr*)&client,&namelen))

圖3 網絡通信服務器端流程圖
accept()阻塞等待請求隊列中的請求,一旦有連接請求,該函數就建立一個和s有相同屬性的新的套接口。
接下來,就可以按照以下格式接收和發送數據了。
recv(ns,buf,1024,0)
send(ns,buf,pktlen,0)
recv從ns(建立連接的套接口)接收數據放入buf中,send則將buf中的數據發送給ns。
最后,調用close()關閉套接口。
在該設計中,UART口與井下儀器電路板的SCI口相連,讀取井下儀器的測井數據,將數據讀入緩存。在Linux系統中,串口屬于字符型設備,位于“/dev”目錄下,設備名分別為“/dev/ttyS0”,“/dev/ttyS1”,“/dev/ttyS2”。在Linux下對設備的操作方法與對文件的操作方法是一樣的,對串口的讀寫可以使用簡單的 open()、read()和 write()函數來完成,但是對串口的其他參數需要另作配置[7]。對struct termios結構體的各成員值進行設置,波特率設置為115.2kb/s,傳輸協議為:1個起始位+8個數據位+1個停止位,無奇偶校驗位。
應用程序工作流程圖如圖4所示。維護系統接收上位機傳送過來的命令并將命令傳給井下儀器。
命令分為以下兩種:
(1)讀取數據;
(2)井下儀器在線升級。
井下儀器在接收到維護系統通過串口發送的數據傳輸命令后,就開始將存儲在存儲器中的測井數據通過SCI上傳。維護系統用串口讀取到數據后,經過串口接收單元把串口幀還原出數據,存儲到數據緩沖區,然后讀取數據緩沖區的數據,經過USB口或網口發送至上位機。
PC可以通過維護系統直接對井下儀器進行必要的維護,實現對CPLD的快速在線配置,并使用串口模擬JTAG口燒寫DSP程序。
6.2.1 配置CPLD
基于ARM的嵌入式Linux中對CPLD進行JTAG配置,必須使用.jam或者.jbc格式的配置文件和標準測試與編程語言(Standard Test And Programming Language,STAPL)標準。由于用 Altera 公司的QuartusⅡ集成開發環境生成配置文件,默認產生.sol和.pof格式的配置文件,必須進行必要的轉換。
Jam STAPI是Altera公司提供的支持STAPL的套件。使Jam STAPI進行配置包含兩部分,Jam Player(Jam解釋器或者稱為Jam虛擬機)和Jam配置文件。Jam Player運行在微處理器中,讀取Jam文件并解析Jam文件表達的內容,在JTAG接口上產生用于配置的二進制數據流并讀取反饋數據。
Altera公司提供的Jam Player源程序文件包含了DOS、Windows和Unix 3種平臺的代碼。在類似Unix的Linux平臺中使用,必須進行定制和移植。
將Jam Player移植到嵌入式Linux中,主要進行下列的定制:
(1)更改平臺預定義環境,添加預處理語句,去除不必要的源代碼;
(2)將JTAG信號映射到具體硬件引腳;
(3)定制錯誤信息輸出方式;
(4)根據具體微處理器的處理能力,定制延時函數。
6.2.2 燒寫DSP
井下儀器電路部分的DSP采用的是TI公司的TMS320F28335,傳統方式是基于JTAG的燒寫技術,但在隨鉆聲波測井儀中,欲使用JTAG接口則需對測井儀進行拆卸,難以實現在線燒寫。所以在此處利用該系統通過串口燒寫技術來實現DSP的程序更新[8-9]。
DSP程序更新示意圖如圖5所示。

圖4 應用程序流程圖

圖5 DSP程序更新示意圖
遠程燒寫的過程分為以下3個步驟:
(1)上位機軟件端將CCS開發環境中的通用目標文件(COFF文件)轉化為測井儀升級系統特定格式的二進制文件(BIN文件)。
(2)測井儀維護系統將二進制文件下發至測井儀,這個過程等同于維護系統向測井儀發送采集命令和采集參數。
(3)測井儀中由CPLD實現的中控模塊對傳輸來的二進制文件進行變壓耦合、解碼并緩存到FIFO中,DSP讀取FIFO中的數據并存到外部RAM內,底層軟件負責控制Flash的燒寫,完成更新。
隨鉆聲波測井儀在井下采集的測井數據數據量大,數據結構復雜,通過USB或者網線進行數據傳輸將大大提高傳輸速度以及傳輸的準確性,確保井下數據的不失真回顯。隨鉆測井儀的維護問題一直是困擾測井相關項目的難題,該文提出采用維護系統利用單一的串口線對井下儀器進行數據傳輸和在線升級,避免了對井下儀器的拆卸,直接在上位機端進行必要的操作就可以完成數據的傳輸以及系統的在線升級等維護工作,極大地提高了測井儀維護人員的工作效率,在實際應用中具有較高的現實意義和應用前景。
[1]肖紅兵,鞠曉東,楊錦舟.隨鉆聲波測井數據存儲技術研究[J].科學技術工程,2009,6(9):3065-3068.
[2] 成潔,盧紫毅.Linux窗口程序設計-Qt4精彩實例分析[M].北京:清華大學出版社,2008.
[3] 閆婷婷,龍卓群.基于Linux的USB從設備驅動研究[J].電子元器件應用,2009,11(10):55-57.
[4] Linux內核USB從設備驅動程序-shangshuwu[DB/OL].[2010-11-20].http://www.shangshuwu.cn/index.php/.
[5] 李俊.嵌入式Linux設備驅動開發詳解[M].北京:人民郵電出版社,2008.
[6] Donahoo M J,Calvert K L,陳宗斌,等.TCP/IP Sockets編程:C語言實現[M].2版.北京:清華大學出版社,2009.
[7] 華清遠見嵌入式培訓中心.嵌入式Linux應用程序開發標準教程[M].北京:人民郵電出版社,2009.
[8] 韓紅霞,耿愛輝.DSP外部Flash燒寫的兩種方法[J].微計算機信息,2009,23(2):170-171.
[9] 孫秋生,陳尚峰.基于CCS的DSP片外Flash直接燒寫設計[J].電子設計工程,2009,17(1):93-95.