軟件無線電(Software Defined Radio)以前往往以高(zhuang)大(bi)上(fan)的面目示人,是大公司或學校實驗室的高級玩具,一套系統(tǒng)動輒幾萬甚至幾十萬,從來都是一個2B(2B = to business)的模式。自從一個芬蘭黑客(考證癖出來考證一下)破解了rtl2832芯片的電視棒之后(
http://sdr.osmocom.org/trac/wiki /rtl-sdr),SDR終于像樹莓派一樣普及了。你可以淘寶一個50或60RMB的電視棒,然后給妹子show off跟蹤飛機,偷聽空管說話,掃描GSM信號,再然后在妹子崇拜的眼神里嚴辭拒絕出去吃飯的提議,潛心鉆研下一個可玩的無線電信號–LTE。
言歸正轉。
一、背景介紹
世界各地的SDR玩家們肯定不會放過前面提到的LTE。比如這個LTE小區(qū)搜索和跟蹤程序(
https://github.com/Evrytania/LTE-Cell-Scanner),它可以用前述的廉價電視棒掃描并解調LTE基站下行PBCH(物理廣播信道)信號,獲取一些基本的小區(qū)信息。
后來中國也宣布上4G了,我想那就git clone下來試一下吧,從而一發(fā)而不可收了。先后為這個程序加入了TD-LTE支持(原來只支持FDD模式,居然無視我泱泱大國自主知識產權4G標準!),外部LNB/變頻器算法支持,OpenCL加速(單頻點掃描速度提高約20倍,縮減到半秒左右)等。以上改進的整個歷程和程序在此:
https://github.com/JiaoXianjun/LTE-Cell-Scanner 。折騰歷程參見“HackRF 掃描LTE基站 支持中國的TDD-LTE”。
電視棒便宜又好玩,但局限性也很明顯:
1.頻率覆蓋范圍有限。E4K版本覆蓋到約2.2GHz(但高端頻率接收性能已嚴重下降),820t版本覆蓋到約1.76GHz。國內目前開通的LTE信號最 低也在1.8GHz以上,超出820t版的覆蓋范圍。雖然部分在E4K電視棒覆蓋范圍內,但E4K版的電視棒早已停產,奇貨可居,手里有E4K電視棒的各 位且用且珍惜吧!顯然,電視棒也玩不了最熱鬧的2.4GHz頻段,除非外接MMDS-LNB或者其他變頻器進行頻率擴展。
2.帶寬和采樣率有限,也就最高2、3M的樣子,只能玩玩1、2M帶寬以下的信號,對LTE和WiFi的信號帶寬就望塵莫及了。所幸按照LTE標準,PBCH 信號(基站廣播的最基本信息)固定在中心1MHz左右?guī)拑龋瑒偤眠在電視棒的能力之內。但是對于LTE基站廣播的更多信息(比如SIB)就無能為力了, 因為更多信息就可能分布在超出中心1MHz帶寬范圍了。
3. 只能收不能發(fā)。
4. RF指標一般。畢竟太廉價,以及接收目標是很強的電視廣播信號。
雖然電視棒有種種缺點,但它實在太便宜,便宜到價格都快要忽略不計了。世界各地的人們玩的不亦樂乎。各種“打磨”“改裝”“提升”方案層出不窮。與 此同時,各路大神悉數登場,要為世人打造更強大的開源SDR硬件,同時還要把以往的2B價格(比如USRP)降到2C范圍。這其中的明星產品就是 BladeRF和HackRF了,兩者都在kickstarter上成功募集到資金,前者已開始交付用戶。后者HackRF據說生產上遇到一些問題,一再 跳票,還未開始大規(guī)模交付kickstarter上交了錢的用戶。NB的是 hackrf.net 居然按照HackRF圖紙先造了出來并開始銷售!于是就有了我將HackRF的支持加入LTE小區(qū)搜索程序的事情:
中華人民共和國二零一四年三月十五日,就是HFD硬件自由日清華站活動在清華大學五教5102召開講座的那一天,我獨自前往5102聆聽大神們布 道,遇見王康,前來問我道,“先生可曾用過HackRF沒有?”我說“沒有”。他就正告我,“先生還是用一用罷;HackRF就是為先生這樣的人設計的!
二、對HackRF的初步試用感受
介紹具體細節(jié)之前,先給出一些直觀的試用感受。
先說優(yōu)點:
1. 覆蓋頻率范圍、支持的帶寬和采樣率自然是比電視棒高太多了,可玩的信號種類更多,更重要的是比電視棒多了發(fā)射(友情提示,國家有法規(guī),發(fā)射需謹慎)。HackRF的配置和功能從電視棒的玩票性質已經進入高大上的專業(yè)選手圈子。
2. 靈敏度比我珍藏的絕版E4K電視棒明顯的要好,在家里E4K電視棒搜到LTE信號要憑運氣,但是用HackRF基本就每次都能搜到了。
3.功耗(或者是啟動電流?)居然比E4K電視棒要低,這個有些出乎我的意料,畢竟HackRF的板子看起來比電視棒還是大不少,上面的芯片也多不 少。電視棒在ThinkpadT410筆記本上用的時候,如果不用筆記本底座(220V電源供電)上的USB口而直接用筆記本自帶的USB口,則經常會驅 動報錯甚至導致筆記本死機(這個問題困擾我好久,最后發(fā)現(xiàn)是供電不足),HackRF則直接用筆記本本身USB口,無需外接電源,就已經運行的很穩(wěn)定,這 樣我筆記本就不用插電源,可以到處跑了。
如果非要說缺點,HackRF價格比起電視棒當然高了n倍。但對比專業(yè)設備和業(yè)余設備的價格本身就是沒意義的。我感覺HackRF應該是專業(yè)選手里價格最低的了。
另一個美中不足(或者說也是價格所限)是僅支持單天線和半雙工。單天線的話就玩不了MIMO和測向之類的了。如果能像BladeRF那樣支持雙天線,那么就不但可以提高解調信號的質量,并且有可能找出信號的方向從而可能定位目標的物理位置,豈不更有趣。
(按: HackRF有10MHz同步時鐘的輸入和輸出,理論上可以進行多個HackRF的級聯(lián),從而完成上述的MIMO和測向應用。詳見HackRF10MHz時鐘)
三、使用純C語言操作HackRF
羅嗦半天,終于要進入正題了。
GNURadio,開源SDR領域最大的生態(tài)系統(tǒng)。圖形界面,腳本語言,支持各種硬件(USRP,BladeRF,rtl- sdr,HackRF,etc),軟件資源極為豐富,上手快,深得愛好者、學校、研究人員的喜愛。幾句命令,幾下鼠標,搭個框圖便能玩弄空中的信號于掌股 之中。
但,今天我們不說GNURadio。
說說如何用純C/C++程序直接調用HackRF(或者rtl-sdr電視棒以及其他基于USB的SDR硬件,都應該是類似的)。這樣你就可以在別 人用鼠標搭框圖對各種采樣率變換焦頭爛額的時候,飛快的敲鍵盤用VI編寫C/C++程序來使用HackRF,不經意流露鄙視的眼神,深藏功與名。逼格頓時 提升幾個檔次。好(dan)牛(teng)!
以下介紹的都是在Linux下的一些工作。這里假設你對Linux比較熟悉(不太熟悉的,可以看這篇blog中的一些基礎操作介紹:
http://blog.sina.com.cn/s/blog_67cdafe201014odm.html)。
(前方“野程序員”預警!本人不是計算機專業(yè)科班出身,本文關于程序方面的內容都是照貓畫虎或者頻繁試錯的結果,未必最優(yōu)或者最正確,僅供參考,歡迎指正。大言不慚的說本人其實是通信專業(yè)科班出身,咳咳。)
1)環(huán)境的建立
hackrf的程序包是一個典型的cmake包,可以從github上自由下載、編譯和安裝。以我在Ubuntu12.04系統(tǒng)下的操作為例。
祈禱你的系統(tǒng)已經安裝了HackRF所需的其他程序包,以上過程會非常順暢和快速。否則cmake步驟和make步驟可能會給一些錯誤提示,按照提示安裝所需的包即可。libusb是必須的,USB接口的SDR設備驅動一般都是基于libusb構建。
最后一步的安裝操作( sudo make install )會把其他程序進行API調用所需的頭文件以及編譯好的二進制庫文件放在一些預定義的位置:
頭文件: /usr/local/include/libhackrf/hackrf.h
庫文件:/usr/local/lib/libhackrf.a,libhackrf.so
其實HackRF源代碼包里已經包含了一些有益的參考和例子:
host/libhackrf/src/下面是庫文件的源代碼:hackrf.h; hackrf.c,我們要調用的API的具體實現(xiàn)都在這里。
host/hackrf-tools/src/ 下面是附帶的一些小測試程序,比如我主要是通過 hackrf_transfer.c 學習的如何通過C/C++使用HackRF。
你可以先玩玩這些小工具。至此,無需龐大的GNURadio,HackRF已經可以玩起來了,是不是很簡單?
2)如何使你的代碼編譯時找到HackRF庫
接下來你想讓自己的C/C++信號處理程序用上HackRF,那么首先就是如何讓你的代碼找到HackRF庫。
直接包含HackRF頭文件,并且鏈接HackRF庫當然可以,對于Linuxer怎么弄都成。
如果你的代碼工程也是基于cmake構建,也很容易寫cmake腳本來使你的代碼編譯時自動找到HackRF庫。以LTE小區(qū)搜索程序為例(可以從
https://github.com/JiaoXianjun/LTE-Cell-Scanner 下載),在 cmake/Modules/ 目錄下,寫了一個 FindHACKRF.cmake 的腳本,該腳本會搜索一些預定義的頭文件和庫文件位置來檢測HackRF庫的存在。如果你編譯時提示找不到 HackRF的庫,可以看看你的HackRF庫是否沒有安裝在 FindHACKRF.cmake 搜索的幾個位置中,以下摘自 FindHACKRF.cmake :
在代碼cmake過程中,頂層腳本 CMakeLists.txt 會調用 FindHACKRF.cmake 并且執(zhí)行相應的操作,比如告訴 src/CMakeLists.txt 去鏈接HackRF庫。
3)調用HackRF的API以及編寫回調函數
好了,下面講解具體的,如何在你的C/C++信號處理代碼中調用HackRF,獲取空中的信號樣本。
首先介紹一下一般性的流程。
在你的程序中,需要先調用一些初始化API完成最初的設備open、初始化操作。之后調用LNA增益、VGA增益、射頻頻率、采樣率等API按照你的需要進行相關的設置。(按: 這些增益可以參考這篇文章的解釋)
而后調用接收/發(fā)射API(也會把你寫的回調函數作為參數告知該API)開始接收/發(fā)射。以接收為例,當HackRF驅動接收到USB接口傳來的 I&Q采樣數據時,會自動調用你寫的回調函數,你的回調函數中會看到驅動程序傳過來的一些信息(通過傳入回調函數的參數),比如本次接收到數據的 長度、buffer的起始地址之類的信息,根據這些信息,你可以進行相應的處理,比如告訴告訴前臺程序:數據來了,拿去處理!
仍舊以LTE小區(qū)搜索程序為例進行介紹。
在 src/CellSearch.cpp 中,函數 config_hackrf() 完成初始化和初次信號接收的測試。依次調用的HackRF API有(這些API都定義在hackrf.h中,實現(xiàn)在hackrf.c中):
然后調用信號接收子函數 capture_data() ,進行初次接收測試。信號接收子函數 capture_data() 實現(xiàn)在 src/capbuf.cpp 中。具體代碼:
本次接收至此完成,接收的 CAPLENGTH*2 數據存在全局數組 hackrf_rx_buf 中了。程序可以進一步處理接收到的數據了。數據格式很簡單,就是I和Q交替存儲,均為有符號8bit整數(因為HackRF目前最新的CPLD程序已經做了
無符號有符號變換,因此我們在host程序里看到的已經是處理完的有符號數,信號處理可以直接用了。當然其中可能有一些RF的非理想因素,比如DC offset, IQ imbalance之類的,這些都是信號處理可以用算法去搞的了)
下面介紹回調函數;卣{函數除了把接收數據總長度更新到全局變量 hackrf_rx_count 中外,還會把接收數據存儲到全局數組
中;卣{函數 capbuf_hackrf_callback(hackrf_transfer* transfer) 也實現(xiàn)在 src/capbuf.cpp 中。當回調函數被驅動自動調用時,驅動本次接收數據的長度會在 transfer->valid_length 中,而數據內容會在 transfer->buffer 中。注意,回調函數不是驅動的一部分,而是用戶自己根據需要寫的用戶程序,然后通過 hackrf_start_rx() 這個API告知驅動,每當驅動收到數據時就會自動調用回調函數(你可以類比中斷服務程序)。
回調函數介紹。
以上就是使用C/C++直接操作HackRF的方法。
當然不能算是我完全原創(chuàng),只是照著之前的LTE小區(qū)搜索程序作者James Peroulas對rtl-sdr驅動的調用方法,依葫蘆畫瓢做的。
和JamesPeroulas有過幾次交流,得知他居然還在深圳的中興工作過很長時間,后來去了硅谷那邊的Intel,現(xiàn)在在那邊專門做SDR系統(tǒng)的range
network公司工作(據說是做OpenBTS的人創(chuàng)建的,有興趣的可以考證一下)。在無線通信信號處理和編程方面都有非常非常豐富的經驗。通過學習和改進他的代碼,真的學到了很多很多東西。所以,想深挖的,強烈推薦讀代碼并且寫代碼做實驗。
源自:FreebuF.COM