楊志杰,石驥碩,徐 寧,王財進
(中國鐵道科學研究院通信信號研究所,北京100081;2.北京交通大學理學院,北京100044)
工業現場設備通常都會長時間運行,為了對設備的運行狀況進行更好的監控,可以利用信號采集系統對這些設備運行狀況以及產生的數據進行采集,并發送給監控計算機,運行在監控計算機上的分析軟件通過對這些數據的分析處理,可以得出設備當前的運行狀況,從而可以針對當前的運行狀況采取相應的措施。目前,常用的信號采集裝置,在其系統軟件設計中多采用單片機、DSP或基于嵌入式計算機的架構。然而基于DSP的數據采集系統, 雖然處理速度快,但成本較高,實現通信接口較困難,過多的中斷會降低CPU 的效率,系統響應速度變差。而單片機的系統則由于單片機本身的局限性,運行速度低,無法執行多任務操作。基于嵌入式Linux的數據采集系統則很好地完成相應功能,彌補了上面兩種系統的缺陷。
嵌入式Linux操作系統作為整個系統的核心部分,完成對任務進行控制和調度,并且實現任務間通信與同步、對系統資源以及存儲的管理。
本文以嵌入式Linux操作系統為平臺,以基于ARMv5te、XScale架構的PXA270為處理器,設計和實現一種通用的高性能數據采集系統。
數據采集系統采用分布式設計,可以使用以太網、485/422串口、CAN總線等多種通信接口實現系統上位機與現場檢測下位機之間的通信。正常運行時,數據采集系統可以用來完成數據采集、數據簡單處理、數據在文件中的存儲、數據傳輸等多種任務。系統有一定的自動檢測、自動校正能力,可以將檢測出的異常情況發送給上位機,方便對系統進行維護。為了適應各種自動檢測的需求,采用模塊化結構對整個檢測系統進行設計,這樣可以方便地對模塊進行不同的組合,從而構造出不同功能的應用系統。
數據采集系統選用PXA270處理器作為整個系統的核心,其系統硬件組成如圖1。從傳感器等信號源接收的模擬信號經過調理電路處理后,由模數轉換器(ADC)轉換為數字信號,輸入到PXA270中。根據不同的應用,在ARM中進行數字濾波和其它相應處理,通過通信接口將數據傳輸到上位機,從而進行進一步的分析和處理。圖形界面利用QT技術,利用液晶屏顯示軟件界面以及調試信息,可以方便地通過圖形界面的提示,利用鼠標和鍵盤進行控制。

圖1 基于PXA270的數據采集系統框圖
信號調理電路主要是為了將信號分量調整到適當的幅度,并抑制干擾信號。采取的主要措施有:增加衰減器以調整較大信號電壓到合適ADC輸入的范圍,并增加與前端的傳感器或接收天線的匹配程度。調理電路中包括LC低通濾波器,濾去干擾信號。
模數轉換器采用12 bit雙通道、采樣速率為65 Msp/s的AD9238。該芯片采用3.3 V供電,與單通道A/D轉換器相比,AD9238具有與A/D轉換器同樣優異的動態性能,但是與兩個單通道A/D轉換器相比,AD9238可以實現比A/D轉換器更好的抗串擾性能。
根據系統需求,外部可擴展相應大小的FLASH,供緩存數據和存貯程序。PXA270處理器集成了存儲單元控制器,其外部的存儲總線接口支持為:SDRAM、FLASH、ROM、SRAM、PC卡等。SDRAM具有單位空間存儲容量大和價格便宜的優點,主要被用作程序的運行空間以及數據集堆棧區。系統上電啟動時,CPU首先會讀取地址0x0處的代碼,在這段代碼完成相應硬件初始化后,會將其他相應的程序代碼傳送到SDRAM中運行。系統設計中,使用4片HY57V561620FTP-H芯片構成128 Mbit的大容量存儲空間。HY57V-561620是4 Mbit×4 banks×16 bit的SDRAM,單片容量為32 Mbit,這里,使用位擴展的方式擴展成32 bit的接口。
與上位機通信接口包括:以太網,帶光電隔離的3路422/485串口,CAN總線。
針對該系統的特點,將軟件平臺在嵌入式Linux上實現。

圖2 嵌入式Linux的分層體系結構
如圖2,嵌入式Linux具有分層的體系結構,每一層都屏蔽了它以下各層具體的實現細節,為上層提供相應的功能接口,上層模塊不需要知道下面各層的具體實現細節,只需要利用下層提供的接口來完成相應功能。正因分層的體系結構,提高了嵌入式Linux的安全性、穩定性以及便利性。
由于基于PXA270的系統資源受限,真正標準的Linux操作系統是面向PC的,這就需要裁減Linux內核,只保留所需要的功能使之適應受限的系統資源。對于一些可獨立加載或者可以卸載的功能塊,可以在配置內核時僅保留嵌入式系統功能真正實現所需要的模塊,卸載那些不需要的功能模塊。系統對數據采集的實時性有一定要求,而內核中的虛擬內存管理機制對實時性有所影響,可以將其屏蔽從而增強Linux的實時性。
數據采集系統中,PXA270屬于X86體系結構,與一般PC使用的Linux操作系統兼容。因此,可以使用X86體系下Linux系統的gcc編譯器,對裁剪過的Linux 內核源代碼進行編譯。本系統增加了對文件系統和GUI的支持,其中所實現的文件系統包括:基本文件的系統體系結構,基本可執行程序,配置文件,設備/dev/hd* 和/dev/tty*,程序運行所需的庫文件。GUI是實現軟件可視化設計需求所必需的,用其所實現的圖形界面也為將來的現場檢修維護提供便于操作的圖形界面。
BootLoader是一段小程序,用于引導操作系統或者用戶應用程序。BootLoader用于對必要的硬件設備進行初始化、建立內存映射,為最終內核或用戶應用程序的啟用準備好正確的軟硬件環境。
為了完成系統的功能,實現應用程序對硬件的控制,需要對串口以及I/O口編寫相應的設備驅動程序。設備驅動程序運行在內核空間,是內核的一部分,用于完成內核與硬件之間的交互。設備驅動程序的主要功能包含:對設備初始化、設備使用完成后對設備以及其使用相關資源的釋放、驅動程序與硬件之間數據的交互、應用程序與驅動程序之間的數據交流、對設備出現的異常情況的監測和處理。
設備驅動程序的功能主要通過對中斷處理實現。為了使系統更好地工作,完成中斷的功能,一般把中斷處理程序分為上半部和下半部。上半部也就是在關中斷方式先被硬件中斷觸發的一般意義上的中斷服務程序,所以要求運行時間應當盡可能短,處理盡可能快,否則影響系統性能;下半部適合處理占用時間較長,甚至有休眠的任務,可以在開中斷以及任務串行化的環境下運行。實時性很強的任務被驅動程序上半部處理完成后會調用queue_task函數,這樣就會把下半部處理函數掛入到立即隊列中,并激活立即隊列,再通過調用mark_bh函數,下半部就可以以最高最優級被先執行。
由于中斷信號線數目極其有限,當數據采集系統面對多個數據源,如果對每個信號源都獨占一根中斷信號線時,顯然中斷信號線的數目無法滿足要求。為了解決上面的問題,使系統具有更好的靈活性,則應使用數據源共享某根中斷信號線的方式來實現中斷。中斷信號線共享的實現只需要在申請中斷信號線時把request_irq函數的flags參數設置為SA_SHIRQ即可。此時的中斷處理例程需要通過inb函數查看AD9238相應的寄存器來判斷中斷是否是這個芯片發出,如果不是則繼續查找中斷源。如果找到中斷源,則讀取相應的數據寄存器中的相關數據,放到驅動程序的緩存區AD_Data中,等待進程通過調用read函數來調用驅動程序中實現的read函數,并通過copy_to_user將數據拷貝到用戶空間中。
在接收中斷的過程中,為了防止由于丟失中斷導致驅動程序沒有讀取AD9238中的數據并對其進行設置,使其不能發送中斷導致整個驅動卡死的這種情況發生,這里需要使用內核定時器,如果在100個時鐘滴答內沒有收到中斷,會自行調動中斷處理例程,檢測是否芯片已經發出了中斷卻沒有收到。
用戶進程是通過/dev目錄下的相關設備文件來與硬件打交道的,通過調用對設備文件相關操作的系統調用從而對設備或接口進行操作。需要使用file_operations結構來實現設備驅動程序要實現的系統調用,file_operations結構中每一個成員都對應著一個系統調用。用戶進程通過對/dev下設備文件的操作找到相應設備驅動程序的相關調用,通過讀取這個設備對應file_operations結構中的函數指針,最終把控制權交給該函數。對設備驅動程序的編寫主要是要實現與該設備相關的系統調用,也就是填充file_operations的各個域并編寫相對應的函數。
設備驅動程序可以以模塊的方式加入內核。init_module函數首先要檢測設備是否存在;然后對系統中未使用的空閑中斷進行申請;設備驅動申請輸入輸出緩存隊列空間對提高系統的性能有很大幫助,可以通過調用kmalloc函數進行申請;以上工作完成后,對 register_chrdev函數進行調用就可以完成系統對設備驅動程序的加載。在clearup_module時,先通過調用free_irq函數釋放掉申請到的中斷資源,然后調用kfree函數釋放初始化時申請到的內存空間,最后通過調用unregister_chrdev函數來完成對這個已經注冊的字符設備驅動程序的釋放。
系統的應用程序由多個功能模塊構成,包括數據采集、數據處理和數據通信等模塊。
(1)數據采集模塊通過對I/O接口的操作,實現對數據的采集,系統中利用inb、inb_p、outb、outb_p這4個函數實現設備中數據的讀取和寫入。inb_p、outb_p相對于inb、outb,需要在存取I/O時有等待(pause),可適應響應較慢的I/O設備。Linux內核提供對端口使用狀況的控制及查詢功能,合理利用這些功能就可以防止I/O讀寫時發生沖突。端口使用之前,檢查相應的I/O端口是否正在被使用,如果當前狀態為空閑,就把相應端口標記為正在使用,在使用完后進行釋放。
(2)數據處理模塊完成數據的數字濾波以及其它處理功能,并將數據導出存到相應文件中。最終要將處理后的數據經過適當接口傳到上位機。
(3)數據通信模塊負責從緩沖區讀取數據,并發送給上位機。
應用程序的工作流程如圖3。

圖3 應用程序工作流程圖
從圖3可以看出,應用程序完成了以下工作:(1)初始化操作,開辟一塊共享緩沖區,并為該緩沖區加一個互斥鎖。(2)創建3個線程,分別對應3種數據通信方式:socket網絡通信,485串口通信,CAN總線通信。這3種數據通信方式負責把數據傳送給上位機。
在主線程中,打開驅動程序設備文件,并從這個設備中讀取數據。由于設備read()函數是阻塞函數,所以使用了select()函數設置了一個等待時間,使得讀取操作為非阻塞操作。當有數據可讀時,就調用read()函數,把驅動程序處于內核區的數據傳遞給用戶區的數據緩存,也就是主線程把數據寫入了共享緩沖區中。
在socket網絡通信線程中,先要創建一個用于通信的socket文件描述符,并使用bind()函數綁定本地的網絡地址(IP)、端口號(Port);然后循環檢測緩沖區是否有數據可讀,如果有,就讀取出來并調用sendTo()函數把數據發送給對方。
在485通信線程中,先要打開串口設備,并設置串口的相關數據,如波特率,數據位,停止位等,然后也是到共享緩沖區讀取數據,并通過write函數將數據發送給上位機。
在CAN總線通信線程中,首先打開CAN總線設備文件,進行一系列的初始化操作,然后判斷共享緩沖區的數據是否可以讀取,如果可以就讀取下來,通過CAN總線給上位機傳輸數據。
本文設計了一種通用的高性能信號采集系統,可以通過加載不同的應用程序使用在不同的應用場合,具有集成度高、低成本、高性能、多用途的特點。數據采集系統調試非常方便,可靠性高,擴展方便,組合容易,可以根據現場提供的通信條件如422/485串口、以太網,或者CAN總線與上位機通信,便于將現場采集到的數據可靠地上傳。本系統現在已經應用于400 km/h高速綜合檢測列車上應答器的數據采集,高速列車上多處現場監控和數據采集設備也采用了本系統。
[1] 孫天澤,袁文菊,張海峰. 嵌入式設計及Linux驅動開發指南[M] . 北京:電子工業出版社,2005.
[2] 石秀民,魏洪興. 嵌入式系統原理與應用—基于Xscale與Linux[M] . 北京:北京航空航天大學出版社,2007.
[3] 朱利利,陳斌,何運桃. 基于PXA270的電源管理[J] . 電腦知識與技術,2009(17).
[4] Marvell Technology Group Ltd. Marvell PXA27x Processor Family Design Guide[Z] . 2007.