GNU  Radio 中OFDM  Tunnel 詳解
(在gnuradio3.4中確實有文中的例子,而且也在相應的目錄下,在gnuradio3.7.1中,基於GMSK的是在/usr/local/share/gnuradio/examples/digital/narrowband目錄下,基於OFDM的是在/usr/local/share/gnuradio/examples/digital/ofdm目錄下,本文講的應該是在3.4下的,但看了3.7的感覺大同小異)
OFDM Tunnel是GNU Radio中很經典的例子。Tunnel有兩個,一個是基於GMSK 調 製 的 (gnuradio-examples\python\digital) , 另 一 個 基 於 OFDM 調 製 的 (gnuradio-examples\python\ofdm)。它們都由物理層和MAC層構成,提供一個虛 擬的Ethernet接口,使得基於IP的各種應用程序都可以加載在這個tunnel 上麵, 它的主要作用是負責數據的傳輸。我們主要研究後者。因為MIMO/OFDM 在當前最 新一代的通信係統中,幾乎是必選的兩個關鍵技術,因此很多做物理層研發的GNU Radio用戶都會從這兩個例子開始著手。
係統框圖和MAC幀的構成
下圖是Tunnel的係統框圖。Tunnel的物理層由發射機,接收機和一個載波偵 聽(sensing probe)三部分構成,完成由信息比特到基帶波形之間的轉換,以 及通過能量檢測判斷當前信道是否空閑。MAC 層是一個基於CSMA的簡單的MAC。 MAC 層與PHY 層之間傳遞的是一個在IP包的基礎上加了一些包頭和包尾的數據 包。

了解了Tunnel的係統框圖,我們來看一下MAC幀的結構和數據打包過程。圖2 說明了一個IP數據包是如何打包成MAC數據包的。
首先,IP包被加上了4字節的校驗比特,算法是CRC32。然後數據部分,加上 CRC比特和尾比特(X55),都被白化處理,使得數據具有隨機均勻分布的特性。 最後,加上一個4字節的包頭。包頭包含兩個信息:白化參數4 比特和數據包長 度12比特。包頭采用了重複發送的方法,以增加可靠性。到此,一個完整的MAC 數據包就包裝完成了。

OFDM Tunnel 發射部分解讀
下麵以ofdm tunnel為例來解讀一下物理層。Ofdm tunnel的代碼除了在 gnuradio-examples\python\ofdm 目 錄 下 以 外 , 還 有 一 些 在 gnuradiocore\src\python\gnuradio\blks2impl目錄下。

先來看發射機,如圖3所示。在transmit_path.py中,語句 self.connect(self.ofdm_tx,self.amp,self)
說明其中包含兩個模塊,ofdm_tx是一個ofdm_mod類,amp是一個乘法器。 進入ofdm_mod類看一下,其代碼在文件ofdm.py中。Ofdm_mod中,數據包首
先經過一個send_pkt函數,完成MAC包的打包過程。 send_pkt(self,payload='',eof=False)
然後MAC包被放進一個隊列 self._pkt_input.msgq().insert_tail(msg)
後麵的ofdm_mapper_bcv模塊從隊列中取出數據包,根據OFDM調製的參數映 射成一個個OFDM symbol,再送到後續模塊,添加preamble,IFFT變換,添加cyclic prefix,最後調整一下幅度,發送出去。這裏想特別提一下的是,在ofdm_mapper 之後是流圖的形式,在這之前是通過一個message queue與MAC層聯係在一起。這 種連接方式使得“異步的”MAC層數據(而且數據包長不定),跟與係統時鍾“同 步的”物理層連接在一起。這種連接方式是一個很好的例子,值得參考。
OFDM Tunnel 接收部分解讀
接收機部分如圖4所示。receive_path.py包含了ofdm_demod和probe兩個模 塊。Ofdm_demod顯然就是ofdm接收機部分。而probe是一個信號檢測模塊,當usrp 收到的信號幅度大於門限時,就認為無線信道已經被其他用戶占用。Ofdm_demod類的代碼在文件ofdm.py中,主要分成同步模塊(ofdm_receiver),解調模塊 (ofdm_frame_sink),和MAC幀拆包部分。與發射部分類似,物理層與MAC層也是 通過一個隊列self._rcvd_pktq連接在一起的。Ofdm_receiver部分比較複雜,是 用python寫的,完成了幀同步,頻偏估計,頻偏糾正,FFT的功能。ofdm_frame_sink是一個C寫成的模塊,完成了從調製符號到比特的解映射過程。

下麵就詳細介紹一下接收解調框圖中各個模塊的具體作用。
1)OFDM Receiver 部分。Filter(gr_fft_filter_ccc.cc)模塊完成對 USRP 接收信號的匹配濾波功能;sync(gr_ofdm_sync_pn.py)模塊的主要功能是完成 接收符號的窗口匹配,匹配成功時發送匹配成功標誌給 sampler 模塊;Nco (gr_frequency_modulator_fc.cc)模塊完成細頻偏糾正功能,相當於鎖相環 PLL;Sig_mix(gr_multiply_cc.cc)模塊對接收到的 OFDM 符號進行處理(將輸 入符號相乘後輸出),然後送給 sampler 模塊;sampler(gr_ofdm_sampler.cc)
模塊根據 sync 模塊的匹配標誌信號尋找 preamble,將 preamble 和 data 分離, 並給出二者的邊界標誌,然後把每個幀前麵的循環前綴(Cycle Prefix)去除, 最後將 OFDM 符號送給 fft 模塊,同時發送幀時序信號(Frame timing signal) 給 Frame acquisition 模塊;fft(gr_fft_vcc.cc)模塊對接收到的數據進行 fft 變換後輸出給 Frame acquisition 模塊(當查看 gr_fft_vcc.cc 時,你會發 現 該 模 塊 並 沒 有 做 實 際 的 fft 變 換 , 而 真 正 的 fft 和 ifft 變 換 在 gr_fft_vcc_fftw.cc 中進行);Frame acquisition(gr_ofdm_frame_acquisition)模塊接收來自 FFT 的星座映射點向量,使用已知的 pn 碼和接收到的 pn 碼序列進 行比較得到信道增益,然後使用的到的增益修正其後的數據幀,進行相關和均衡。
2)ofdm_frame_sink(解調)模塊。該模塊接收 OFDM 符號,把他們接映射 成 0、1 比特流數據,再將這些比特流打包發送到接收消息序列,完成從調製的 OFDM 信號到實際發送比特數據的解映射過程。
3)MAC 幀拆包部分。主要功能是對解映射後的數據(還是幀結構的)進行幀 拆包,最終獲得實際的有用數據信息。
開發和調試方法
整個ofdm tunnel 的物理層還是比較簡單的。它模仿了802.11 的物理層, 在不定長的burst 前麵添加一個定長的preamble,依靠這個preamble 完成時間 同步和頻率同步。但它沒有信道編碼,因此抗噪聲性能較差。
gnuradio-examples\python\ofdm 目錄下,除了tunnel 調用的函數外,還
有許多其他的函數。這些函數都是程序的開發過程中需要用到的,它們教會了我 們如何一步步的進行程序開發。特別是對於利用GNU Radio 做物理層研發的人來 說,是很好的參考。下麵簡單說明一下。
ofdm_mod_demod_test.py——用於物理層收發模塊的仿真測試。
benchmark_ofdm.py——加上MAC 層以後,做收發的仿真測試。
benchmark_ofdm_tx.py,benchmark_ofdm_rx.py——加上USRP 之後,做單 向收發的測試。分別測試了連續的數據包傳輸,和不連續的突發數據包傳輸。
當單向傳輸沒有問題之後,就可以實驗雙向的傳輸了:tunnel.py。
另外,還有一些matlab程序,幫助調試程序。當我們把log標誌設為True時, 就會產生很多.dat文件。這些文件把各個block的輸出都記錄下來:同步之前, 頻率同步之後,FFT之後,解映射之後等等。然後用Matlab程序一一檢查,就可 以發現究竟哪一步出了問題。
總結這個例子的開發方法,要創建一個自定義的無線連接程序,
第一步:用Matlab寫一個物理層收發程序,設計各個功能模塊,確定參數等。
第二步:用GNU Radio寫一個不包括USRP 的收發程序,與Matlab程序一致, 方便把GNU Radio中的數據導入Matlab 中調試。
第三步:當物理層沒有問題之後,再添加MAC層。
第四步:加入USRP。先調試單向通信,再調試雙向的。
最後更新:2017-04-03 12:53:58