1. 程式人生 > >HackRF 程式碼講解 (一)

HackRF 程式碼講解 (一)

本文包括驅動、韌體、CPLD程式碼講解(也包括gr-osmosdr中的相關部分)。

HackRF是比較早期的一款SDR裝置,憑藉其相對低廉的價格加上半雙工收發能力,在國內的SDR市場中佔比很高。這款裝置的優點是軟硬體全部開源,加上晶片也比較常見,因此出現了不少國產版本,降低了使用門檻。雖然,目前出現了各種各樣效能更高的SDR裝置,如LimeSDR、BladeRF、FreeSRP等,但是這些裝置的結構和工作原理都與HackRF類似,板子上一般都帶有射頻晶片(HackRF分為變頻晶片和AD/DA晶片,其它裝置合併在一個晶片中)、FPGA(HackRF裡用的是CPLD)、ARM核心的微控制器。

雖然,HackRF經過多次修改,配套程式碼越來越完善,但是根據本人的習慣,還是喜歡從較早期的版本開始,雖然可能有bug,但是冗餘功能比較少,可以更好地抓住重點。目前打算從hackrf-2013.06.1這個版本開始看,這個版本應該是對應於jawbreaker(HackRF的早期測試版),但是程式碼結構基本跟最新的一樣,以後可能會再看對應於HackRF One的早期程式碼。所有這些版本的程式碼都能在原作Michael Ossmann的github repository裡找到。只有gr-osmosdr是單獨的,但是也能從github上找到。

這些程式名字各種各樣,有的叫介面,有的叫驅動、韌體。但是其實說到底都是c/c++的程式碼,只要大概看得懂c/c++語法就能看懂,只有CPLD的程式碼是VHDL語言,但是HackRF的CPLD的功能比較簡單,因此vhd程式碼量也很少,早期版本才160多行,其中大多數也只是一些格式上必須有的東西。

在看這篇文章前,建議先看一下hackrf的硬體原理( http://www.hackrf.net/硬體/)

先說一下比較重要的幾個檔案,順序基本上是自頂向下的呼叫關係。

gr-osmosdr是使gnuradio支援hackrf的介面包。gr-osmosdr/sink_impl.cc和gr-osmosdr/source_impl.cc,這兩個檔案用來匹配特定的裝置,比如此文關注的hackrf。另外還有gr-osmosdr/lib/hackrf/hackrf_sink_c.cc和gr-osmosdr/lib/hackrf/hackrf_source_c.cc,這兩個檔案呼叫了hackrf驅動中的函式,使得這個gnuradio中的輸入輸出能夠與hackrf裝置聯絡起來。

然後是hackrf/host/hackrf-tools/src裡的幾個程式,hackrf_transfer.c和hackrf_info.c。他們的層級應該和前面說的gr-osmosdr裡的程式相同,都是在呼叫hackrf驅動裡的函式。hackrf_transfer.c主要是在命令列中實現收發,hackrf_info.c用於顯示板子的資訊。

接下來要說的是hackrf/host/libhackrf/src/hackrf.c,這個程式就是前面說的hackrf驅動了,它經過編譯後會變成libhackrf.so檔案供前面其它程式呼叫,這個程式中主要是通過呼叫libusb的函式來與hackrf板子上的韌體實現互動的。

再往下就是hackrf這個塊板子上跑的程式了,比較重要的是hackrf/firmware/hackrf_usb/hackrf_usb.c。這個程式在板子上的微控制器裡執行。電腦通過libusb發出一些設定上的指令,然後這個hackrf_usb.c就會接收這些指令,並呼叫其它幾個晶片對應的驅動程式碼(注意這裡說的驅動是晶片的驅動,下面會講)對晶片進行設定。另外這個程式也實現了與主機間的USB資料的傳輸。

同樣執行在板子的微控制器裡的,還有hackrf/firmware/common/裡的幾個對應於晶片名字的.c檔案,這些檔案被前面說的hackrf_usb.c呼叫,用來對板子上的射頻晶片、AD/DA晶片等晶片的工作模式及引數進行控制。一般來說都是通過讀寫晶片的暫存器來控制的,根據晶片datasheet裡的要求來完成,這些程式碼也可以寫在hackrf_usb.c裡,只不過為了結構清晰才分開寫。

最後講一下CPLD裡上的程式碼。說是程式碼,但是它與c/c++不一樣,它更接近於對一個結構的描述,早期只是硬體工程師用來描述數位電路用來交流的格式化的語言,根據語言的定義來安排數位電路的連線,只是後期可以自動綜合出實際的電路直接寫入晶片來執行。主要功能在hackrf/firmware/cpld/sgpio_if/top.vhd裡。其實也沒多少複雜的功能,這個CPLD只做了資料中轉,某些狀態下可能要取個反之類的。根據使用者要求的接收還是發射狀態來控制CPLD中流過的資料,有時從電腦傳給AD/DA晶片,有時從AD/DA晶片傳給電腦。另外也可以看一下hackrf/firmware/cpld/sgpio_if/top_tb.vhd,這個程式是一個測試用的程式,用於自動化測試前面說的那個vhd檔案,給予一定輸入後看看輸出是否符合預期的想法。HackRF上的CPLD功能比較簡單,其實根據Michael Ossmann本人的說法這個晶片是可以去除的,現在留著只是因為這樣佈線比較簡單,但是在其它SDR中,對應的FPGA晶片實現的功能可能就會高階不少,LimeSDR的愛好者還有用那塊FPGA實現RISC-V晶片的。

本文講的各種程式碼還比較粗略,實際上這些檔案編譯或者綜合後生成的檔案是不一樣的,寫入板子也需要其它的程式(這些程式也是開源的,也在HackRF的這個repository裡,它們還需要電腦上跑的程式和微控制器裡跑的程式兩部分來配合,一般名字裡帶cpldjtag和spiflash)。另外,幾個程式互相的呼叫也值得深入研究一下,尤其是libusb和微控制器程式的通訊。

這些內容以後都會講到。

(本文將與http://club.digiic.com/Forum/PostDetail/p-1793.html同步更新,後續內容敬請期待!)