[SDR] GNU Radio 系列教程 —— GNU Radio TX PDU (發(fā)送數(shù)據(jù)包操作)的基礎(chǔ)知識(shí)(超全)
1 PDU 概述
在電信領(lǐng)域,協(xié)議數(shù)據(jù)單元(PDU)[1] 是指在計(jì)算機(jī)網(wǎng)絡(luò)的對(duì)等實(shí)體之間傳輸?shù)膯蝹€(gè)信息單元。它由協(xié)議特定的 控制信息 和 用戶數(shù)據(jù) 組成。在通信協(xié)議棧的分層架構(gòu)中,每一層都實(shí)現(xiàn)針對(duì)特定類型或數(shù)據(jù)交換模式定制的協(xié)議。
例如,傳輸控制協(xié)議(TCP)實(shí)現(xiàn)了面向連接的傳輸模式,該協(xié)議的 PDU 被稱為段,而用戶數(shù)據(jù)協(xié)議(UDP)則使用數(shù)據(jù)包作為 PDU 進(jìn)行無(wú)連接通信。在互聯(lián)網(wǎng)協(xié)議族的較底層,即互聯(lián)網(wǎng)層,PDU 被稱為數(shù)據(jù)包,而不考慮其有效載荷類型。
本文將以一些列的例子來(lái)了解 GNU Radio 的 PDU 相關(guān)操作。為我們使用數(shù)字調(diào)制傳輸文件、音頻、視頻等數(shù)據(jù)打好基礎(chǔ)。
2 Demo 詳解
2.1 Random PDU Generator
該塊在啟動(dòng)時(shí)發(fā)送一次隨機(jī) PDU,然后每次收到消息時(shí)發(fā)送,第一個(gè) demo 如下 pdu_simple_demo1_random.grc:[2]

運(yùn)行后,每隔 2S 產(chǎn)生一個(gè) PDU:
message_debug :info: The `print_pdu` port is deprecated and will be removed; forwarding to `print`.
***** VERBOSE PDU DEBUG PRINT ******
()
pdu length = 110 bytes
pdu vector contents =
0000: 69 e4 6c f5 94 8c 28 23 c3 26 3a 41 cf d7 fd 41
0010: 55 d0 4c 3e 03 ed 37 59 e8 32 d9 40 f4 9d c7 79
0020: fc 5a 11 d4 cb 95 98 8c bb ea b1 49 ae c1 64 c0
0030: 8f 61 35 91 87 13 67 0d 5a 87 97 c7 5b ef f7 21
0040: 27 91 65 78 63 03 ba 56 63 29 ed cb 6f 4f dc 87
0050: 9e 2a 1e 9a 78 43 57 a7 87 b0 b7 bf fd 73 b8 15
0060: e9 3a 81 e9 8e 27 80 d3 76 89 8b ff 72 14
************************************
其四個(gè)參數(shù)分別影響:PDU 長(zhǎng)度范圍最少為 15,最大為 150 字節(jié),mask 與 pdu 每一字節(jié)做 AND 操作,總長(zhǎng)度必須是 Length Modulo 的倍數(shù)。
2.2 Async CRC32
在 3.10 版本該塊已經(jīng)被 CRC_Append 和 CRC_Check 替換。[4]
該塊用于處理異步消息的字節(jié)流,可以選擇 create 模式和 check 模式:
- create:在 pdu 數(shù)據(jù)后面多加 4 字節(jié),即輸入數(shù)據(jù)的 CRC32
- check:計(jì)算輸入數(shù)據(jù)的 LEN(PDU)-4 的 CRC32 和 PDU 最后 4 字節(jié)是否相等,相等輸出去除 CRC32 的數(shù)據(jù),不相等沒(méi)有輸出。
例子如下 tx_stage1.grc:

輸出 LOG:
Press Enter to quit: ***** VERBOSE PDU DEBUG PRINT ******
()
pdu length = 44 bytes
pdu vector contents =
0000: 22 e7 d5 20 f8 e9 38 a1 4e 18 8c 47 30 8c fe f5
0010: ff f7 f7 28 b9 f8 fb f5 1c 7c cc cc 4c 24 01 6b
0020: 1c ea a3 ca e0 f5 80 a7 cc 09 5c d9
************************************
***** VERBOSE PDU DEBUG PRINT ******
()
pdu length = 48 bytes
pdu vector contents =
0000: 22 e7 d5 20 f8 e9 38 a1 4e 18 8c 47 30 8c fe f5
0010: ff f7 f7 28 b9 f8 fb f5 1c 7c cc cc 4c 24 01 6b
0020: 1c ea a3 ca e0 f5 80 a7 cc 09 5c d9 db 73 02 76
************************************
2.3 Protocol Formatter (Async)
一個(gè)數(shù)據(jù)幀一般由 幀頭 + 內(nèi)容 + 校驗(yàn)(幀尾) 構(gòu)成,這個(gè)例子介紹如何添加幀頭 tx_stage3.grc:

1)Default Header Format Obj
Default Header Format Obj [14] 用于 PDU 格式化的默認(rèn)標(biāo)頭格式化程序。用于處理默認(rèn)的數(shù)據(jù)包頭。默認(rèn)標(biāo)頭由訪問(wèn)代碼和數(shù)據(jù)包長(zhǎng)度組成。長(zhǎng)度被編碼為重復(fù)兩次的 16 位值:
| access code | hdr | payload |
當(dāng) access code <= 64 bits 時(shí) hdr 為:
| 0 -- 15 | 16 -- 31 |
| pkt len | pkt len |
訪問(wèn)代碼和標(biāo)頭按照網(wǎng)絡(luò)字節(jié)順序進(jìn)行格式化。
該標(biāo)頭生成器不會(huì)計(jì)算 CRC 或?qū)?CRC 附加到數(shù)據(jù)包中。在添加標(biāo)頭之前,請(qǐng)使用 CRC32 異步塊。
因此: 流程圖中的設(shè)置意義如下:
- Access Code:'10101010111101010101',最長(zhǎng)為 64 bits,用于其他塊去查找包的起始位置(測(cè)試發(fā)現(xiàn),最終輸出的 Aceesss Code 總是 8bits 倍數(shù),從右向左數(shù) 8 倍數(shù)個(gè) bits)
- Threshold:(臨界點(diǎn))訪問(wèn)代碼中有多少位可能是錯(cuò)誤的,但仍然算作正確
- Payload Bits per Symbol:有效負(fù)載調(diào)制器中使用的每個(gè)符號(hào)的位數(shù)
2)Protocol Formatter (Async)
Protocol Formatter (Async) [15] 塊可以將一個(gè) a header format object 附加到 PDU 上。然后標(biāo)頭的長(zhǎng)度將測(cè)量有效負(fù)載加上 CRC 長(zhǎng)度(CRC32 為 4 個(gè)字節(jié))。
該塊接收 PDU 并創(chuàng)建 header,通常用于 MAC 級(jí)處理。每個(gè)收到的 PDU 被認(rèn)為是它自己的 frame,因此任何 fragmentation 要在上游或之前的流程圖中處理完畢。
該塊的 'header' message port 會(huì)輸出在該塊中創(chuàng)建的 header。標(biāo)頭完全基于對(duì)象,該對(duì)象是從 header_format_base 類派生的對(duì)象。所有這些 packet header format objects 都是相同的:他們接收 payload 數(shù)據(jù)以及有關(guān) PDU 可能的 metadata 信息。
對(duì)于不同的數(shù)據(jù)包頭格式化需求,我們可以定義繼承自 header_format_base 塊并重載 header_format_base::format 函數(shù)的新類。
因此,運(yùn)行后輸出結(jié)果為:
***** VERBOSE PDU DEBUG PRINT ******
()
pdu length = 6 bytes
pdu vector contents =
0000: af 55 00 30 00 30
************************************
***** VERBOSE PDU DEBUG PRINT ******
()
pdu length = 48 bytes
pdu vector contents =
0000: 22 e7 d5 20 f8 e9 38 a1 4e 18 8c 47 30 8c fe f5
0010: ff f7 f7 28 b9 f8 fb f5 1c 7c cc cc 4c 24 01 6b
0020: 1c ea a3 ca e0 f5 80 a7 cc 09 5c d9 db 73 02 76
************************************
2.4 將 header 和 payload 合并輸出
上面三個(gè)例子終于合成了一個(gè)完整數(shù)據(jù)幀,接下來(lái)我們嘗試將其 header 和 payload 部分合并輸出:tx_stage4.grc

上面例子基于 2.3 中的合成信息,分別對(duì) header 和 payload PDU 轉(zhuǎn)換為 Stream,然后每 1 bit 輸出 1bytes 數(shù)據(jù)(其實(shí)就是 bit 0 -> byte 0; bit 1 -> byte 1),接著 Map 其實(shí)就是執(zhí)行 output[i] = map[input[i]],然后借助 Chunks to Symbols[21][22] 將 bytes 轉(zhuǎn)變?yōu)閺?fù)數(shù)(采用星座圖轉(zhuǎn)換),最后使用 Tagged Steam Mux 將兩股輸入合并輸出。運(yùn)行后看 time sink 圖能看出 header (0xaf 0x55 ... -> 10101111 01010101 ...) 對(duì)應(yīng):1 -1 1 -1 1 1 1 1 -1 1 ....
備注: 該流程圖中涉及星座圖的知識(shí),可以參考 [16] [17] [18] [19] [20] [21] [22]
2.5 對(duì) PDU 實(shí)施突發(fā)填充和漸變
burst shaper block 用于應(yīng)用突發(fā)填充和斜坡的突發(fā)整形器塊,通過(guò)在每個(gè)脈沖的前后添加一些補(bǔ)償,使得脈沖更加穩(wěn)定和清晰。它有兩種補(bǔ)償方式:
- 一種是在脈沖的前后添加一些零值,也就是沒(méi)有信號(hào)的空白,這樣可以避免脈沖之間的干擾,也可以調(diào)節(jié)脈沖的間隔。
- 另一種是在脈沖的前后添加一些相位符號(hào),也就是交替的+1/-1的信號(hào),這樣可以使得脈沖的上升和下降更加平滑,也可以調(diào)節(jié)脈沖的形狀。
如果使用定相符號(hào),則在每個(gè)突發(fā)之前和之后將插入長(zhǎng)度為ceil(N/2)的+1/-1個(gè)符號(hào)的交替模式,其中 N 是抽頭矢量的長(zhǎng)度。斜上/斜下形狀將應(yīng)用于這些相位符號(hào)。
如果不使用相位符號(hào),則漸變將直接應(yīng)用于每個(gè)突發(fā)的頭部和尾部。
burst shaper block 的參數(shù)有以下幾個(gè):
-
窗口系數(shù)(Window Taps):這是一組用來(lái)控制脈沖的上升和下降的系數(shù),它可以用來(lái)改變脈沖的波形,例如將方波變?yōu)檎也ǎ驅(qū)⒛M信號(hào)變?yōu)閿?shù)字信號(hào) [23] [24]。
-
前補(bǔ)償長(zhǎng)度(Pre-padding Length):這是在每個(gè)脈沖前面添加的零值的個(gè)數(shù),它可以用來(lái)調(diào)節(jié)脈沖的間隔,也可以用來(lái)避免脈沖之間的干擾。
-
后補(bǔ)償長(zhǎng)度(Post-padding Length):這是在每個(gè)脈沖后面添加的零值的個(gè)數(shù),它可以用來(lái)調(diào)節(jié)脈沖的間隔,也可以用來(lái)避免脈沖之間的干擾。
-
插入相位符號(hào)(Insert Phasing Symbols):這是一個(gè)布爾值,表示是否在每個(gè)脈沖的前后添加相位符號(hào),如果為真,那么會(huì)在每個(gè)脈沖的前后添加交替的+1/-1的信號(hào)(ceil(N/2) 用于上翼側(cè),ceil(N/2) 用于下翼側(cè),如果 taps.size 為奇數(shù),中間的 tag 將用作上翼側(cè)的最后一個(gè),和下翼側(cè)的第一個(gè)),如果為假,那么不會(huì)添加相位符號(hào),而是直接對(duì)脈沖的頭尾進(jìn)行補(bǔ)償。
-
長(zhǎng)度標(biāo)簽名稱(Length Tag Name):這是用來(lái)標(biāo)記每個(gè)脈沖的長(zhǎng)度的標(biāo)簽的名稱,它可以用來(lái)控制脈沖的發(fā)送和接收,也可以用來(lái)分析脈沖的性能。
burst shaper block 的輸出是一個(gè)經(jīng)過(guò)整形和補(bǔ)償?shù)拿}沖序列,它的長(zhǎng)度標(biāo)簽會(huì)更新為包含補(bǔ)償?shù)拈L(zhǎng)度,而且會(huì)放在輸出的開頭。其他的標(biāo)簽會(huì)根據(jù)它們的位置,放在相應(yīng)的輸出上,以保持與脈沖的關(guān)聯(lián)。
備注:窗函數(shù)(英語(yǔ):window function)在信號(hào)處理中是指一種除在給定區(qū)間之外取值均為0的實(shí)函數(shù)。譬如:在給定區(qū)間內(nèi)為常數(shù)而在區(qū)間外為0的窗函數(shù)被形象地稱為矩形窗。任何函數(shù)與窗函數(shù)之積仍為窗函數(shù),所以相乘的結(jié)果就像透過(guò)窗口“看”其他函數(shù)一樣。窗函數(shù)在頻譜分析、濾波器設(shè)計(jì)、波束形成、以及音頻數(shù)據(jù)壓縮(如在Ogg Vorbis音頻格式中)等方面有廣泛的應(yīng)用。[23] [24]
一個(gè)簡(jiǎn)單的例子如下:burst_tagger.grc

運(yùn)行后效果如下:

其中 Vector Source 是 8 個(gè) 1,8 個(gè) -1,在 Stream to Tagged Stream 中將 160 個(gè)采樣打包加長(zhǎng)度標(biāo)簽(即 10 組向量),然后將數(shù)據(jù)送到兩個(gè)配置不同的 Burst shaper 塊中(一個(gè)使能定向符號(hào),一個(gè)不使能,兩個(gè)都使用海寧窗,N=50):
-
因此第一個(gè)輸出的數(shù)據(jù)為:上翼 25 個(gè)1,-1交替信號(hào)(作用海寧窗),然后 160 個(gè)采樣數(shù)據(jù),然后 25 個(gè)下翼 1,-1交替信號(hào),最后 padding 20 個(gè) 0 信號(hào)。因此最終數(shù)據(jù)總長(zhǎng)度為:25+160+25+20 = 230
-
因此第二個(gè)輸出的數(shù)據(jù)為:海寧窗直接作用 160 個(gè)采樣數(shù)據(jù)的前 25 個(gè)形成上翼,作用后 25 個(gè)形成下翼,中間 110 個(gè)不實(shí)施作用,最后 padding 20 個(gè) 0 信號(hào)。因此最終數(shù)據(jù)總長(zhǎng)度為:160+20=180
進(jìn)一步,我們可以在 2.4 的完整數(shù)據(jù)幀基礎(chǔ)上,加入 burst shaper(前后各填充 10 個(gè) 0,采用海寧窗,使能定向符號(hào))-> tx_stage5.grc:

2.6 RRC 濾波與多相任意重采樣
2.6.1 FIR 濾波器例子
首先來(lái)看幾個(gè)常見(jiàn)的濾波器的效果filter_taps.grc:

效果如下:

其中:
1)低通濾波器:截止頻率為 14K,帶寬為 1K,看圖就能直接 get 到
2)高通濾波器:截止頻率為 2K,帶寬為 1K,看圖也能 get
3)帶通濾波器:設(shè)置 6K 到 10K,也是能看圖 get
4)帶阻濾波器:設(shè)置 6K 到 10K,也是能看圖 get
5)RRC 根(平方根)升余弦濾波器需要單獨(dú)介紹下
2.6.2 濾波器基礎(chǔ)及 RRC 知識(shí)
要想理解 RRC 需要補(bǔ)充幾個(gè)基礎(chǔ)知識(shí)點(diǎn):
1)什么時(shí)候用 RRC?
數(shù)字通信系統(tǒng)中,基帶信號(hào)進(jìn)入調(diào)制器前,波形是矩形脈沖,突變的上升沿和下降沿包含高頻成分豐富,信號(hào)的頻譜一般比較寬,通過(guò)帶限信道時(shí),單個(gè)符號(hào)的脈沖將延伸到相鄰符號(hào)的碼元內(nèi),產(chǎn)生碼間串?dāng)_。因此在信道帶寬有限的情況下,要降低誤碼率,需在信號(hào)傳遞前,通過(guò)發(fā)送濾波器(脈沖成型濾波器)對(duì)其進(jìn)行脈沖成型處理,改善其頻譜特性,產(chǎn)生合適信道傳輸?shù)牟ㄐ巍?shù)字系統(tǒng)中常用的波形成形濾波器有升余玄脈沖濾波器、平方根升余玄濾波器、高斯濾波器等 [32]。
2)什么是 RRC?
升余弦濾波器: 升余弦濾波器(Raised-cosine filter)是一種經(jīng)常作脈沖成型濾波器,它能夠最大限度地減少碼間干擾(ISI)。之所以會(huì)如此命名是因?yàn)椋摓V波器的最簡(jiǎn)形式頻譜 (\(\beta = 1\)) 的非零部分為余弦函數(shù)且被抬升至水平軸的上方 [33] [34]。
數(shù)學(xué)描述為:
升余弦濾波器是低通奈奎斯特濾波器的一種實(shí)現(xiàn),即具有對(duì)稱性的濾波器。這意味著它的頻譜在 f=± 1/(2T) 表現(xiàn)出奇對(duì)稱性(Ts 是符號(hào)速率),如下:

引出根升余玄濾波:
當(dāng)用于過(guò)濾符元流時(shí),奈奎斯特濾波器具有消除 ISI 的特性,因?yàn)槌?\(n = 0\) 的情形之外,所有 \(nT\)(n 是整數(shù))的脈沖響應(yīng)都是零。
因此,如果傳輸?shù)牟ㄐ卧诮邮斩吮徽_采樣,原本的符元值就可以完全恢復(fù)。
然而,在許多實(shí)際的通訊系統(tǒng),由于受白噪聲之影響,會(huì)在接收器中使用匹配濾波器。對(duì)于零 ISI,發(fā)射和接收濾波器的凈響應(yīng)必須等于 \(H(f)\):
因此:
集中重要參數(shù):
滾降系數(shù):滾降系數(shù) \(\beta\) 是對(duì)濾波器帶寬過(guò)量(excess bandwidth)的度量,即所占帶寬超過(guò)奈奎斯特帶寬 \(\frac {1}{2T}\) 的部分,有些作者會(huì)使用 \({\displaystyle \alpha }\) 表示.
若我們將多余的帶寬表示為 \({\displaystyle \Delta f}\),則:
\({\displaystyle R_{S}={\frac {1}{T}}}\) 是符元率。
上面的圖顯示為 \({\displaystyle \beta }\) 在 0 和 1 之間變化的振幅響應(yīng),以及對(duì)脈沖響應(yīng)的相應(yīng)作用。可以看出,時(shí)域的漣波準(zhǔn)位會(huì)隨著 \({\displaystyle \beta }\) 減少而增加,這可以減少濾波器的頻寛過(guò)量,但只能以伸長(zhǎng)脈沖響應(yīng)為代價(jià)。
寬帶:升余弦濾波器的帶寬通常定義為其頻譜的非零正頻率部分的寬度,即:
3)高斯濾波和升余玄濾波的區(qū)別
問(wèn):為什么GMSK要加高斯濾波器,而QPSK加升余弦濾波器?這么加這兩種濾波器的主要區(qū)別是什么?有什么好處 [30]?
答:GMSK 加高斯濾波器主要是為了減少帶外輻射,讓信號(hào)帶寬更窄,從而增加信道容量,加入高斯后,反而會(huì)增加 ISI。而 QPSK 加升余弦濾波器主要是為了減少 ISI,對(duì)信號(hào)帶寬有一定的減小,但減小程度沒(méi)有高斯厲害。
4)濾波基礎(chǔ)知識(shí)
為了更好地理解 RRC,我們需要再補(bǔ)充些濾波器的基礎(chǔ)知識(shí):
數(shù)字濾波器的作用通常可以概括為兩方面:
- 信號(hào)恢復(fù)(signal restoration): 信號(hào)恢復(fù)指濾波器能對(duì)失真信號(hào)進(jìn)行恢復(fù)
- 信號(hào)分離(signal separation):信號(hào)分離 則指濾波器可以從沖突、干擾、或噪聲中分離目標(biāo)信號(hào)
數(shù)字濾波的兩方面作用恰好對(duì)應(yīng)了信號(hào)攜帶信息的兩種不同模式:
- 時(shí)域調(diào)制: 時(shí)域調(diào)制 指使用信號(hào)的振幅、相位等波形特征表示要攜帶的信息內(nèi)容,在這種情況下時(shí)域的采樣結(jié)果可直接用于信息內(nèi)容的提取;
- 頻域調(diào)制:頻域調(diào)制是利用周期信號(hào)的頻率特征區(qū)別和表示不同的信息;
濾波器分類:

時(shí)域參數(shù):
通常使用 階躍響應(yīng)(Step Response) 描述濾波器的時(shí)域特征 [40] 。階躍響應(yīng)指輸入信號(hào)為單位準(zhǔn)階躍信號(hào)時(shí),濾波器的響應(yīng)輸出(階躍信號(hào)的形式如下圖所示)。由于階躍信號(hào)本質(zhì)上是單位脈沖信號(hào)在時(shí)間上的積分,所以對(duì)于線性系統(tǒng)而言,階躍響應(yīng)就是單位脈沖響應(yīng)在時(shí)間上的積分。
給定一個(gè)濾波器階躍響應(yīng),階躍響應(yīng)的哪些參數(shù)可以用于描述該濾波器的性能?
- 過(guò)渡速度(transition speed):規(guī)定階躍響應(yīng)中輸出振幅從10%變化到90%振幅所經(jīng)歷的樣本數(shù)為過(guò)渡速度。
- 過(guò)沖幅度(overshoot):過(guò)沖指信號(hào)通過(guò)濾波器后其時(shí)域振幅發(fā)生波動(dòng)的現(xiàn)象,這是時(shí)域中包含的信息的基本失真。
- 線性相位(linear phase):希望階躍響應(yīng)的上半部分與下半部分對(duì)稱。這種對(duì)稱是為了使上升邊與下降邊看起來(lái)相同。這種對(duì)稱性被稱為線性相位,因?yàn)楫?dāng)階躍響應(yīng)上下對(duì)稱時(shí),頻率響應(yīng)的相位是一條直線。
注:本節(jié)基本上復(fù)制于《物聯(lián)網(wǎng)前沿實(shí)踐》,詳細(xì)細(xì)請(qǐng)參考 [40]。
頻域參數(shù):
從頻域上看,濾波器的作用是允許某些頻率的信號(hào)無(wú)失真地通過(guò),而完全阻塞另一些頻率的信號(hào)。有:低通、高通、帶通、帶阻。
上述四種濾波器的共同特征是能夠在頻域分離不同頻率的信號(hào)分量,在設(shè)計(jì)和選擇濾波器時(shí),我們需要考慮以下三個(gè)重要參數(shù):
- 滾降速度:為了分離間隔很近的頻率,濾波器必須具有快速滾降
- 通帶波紋:為了使通帶頻率不改變地通過(guò)濾波器,必須盡可能抑制通帶紋波
- 阻帶衰減:為了充分阻擋阻帶頻率,必須具有良好的阻帶衰減

注:本節(jié)基本上復(fù)制于《物聯(lián)網(wǎng)前沿實(shí)踐》,詳細(xì)細(xì)請(qǐng)參考 [40]。
2.6.3 回來(lái)理解 RRC

RRC Filter Taps 有以下參數(shù)[41]:
- Gain: Overall gain of filter (default 1.0)
- Sample Rate: Sample rate in samples per second.
- Symbol Rate: Symbol rate, must be a factor of sample rate. Typically ((samples/second) / (samples/symbol)).
- Excess BW: Excess bandwidth factor, also known as alpha. (default: 0.35)
- Num Taps: Number of taps (default: 11*samp_rate). Note that the number of generated filter coefficients will be num_taps + 1.
由于 2.2 介紹升余弦濾波器的帶寬通常定義為其頻譜的非零正頻率部分的寬度,即:
因此流程圖中的 RRC 濾波器相當(dāng)于低通濾波器,濾波的帶寬為 16K/2(1+0.35) = 10.8
2.6.4 理解重采樣
對(duì)于數(shù)字調(diào)制:

采樣率變換,是軟件無(wú)線電中的一個(gè)重要概念。一般來(lái)說(shuō),接收端射頻器件以較高的采樣率進(jìn)行采樣,可以使被采樣帶寬增加,而且有利于降低量化噪聲,但高采樣率會(huì)使采樣后的數(shù)據(jù)速率很高,例如,接收衛(wèi)星信號(hào)的采樣率可達(dá)500MSPS,每秒采500M個(gè)樣點(diǎn),數(shù)據(jù)規(guī)模龐大,容易導(dǎo)致后續(xù)信號(hào)處理的負(fù)擔(dān)加重,因此,非常有必要在ADC后進(jìn)行降速處理,自然也就涉及到采樣率的變換問(wèn)題。
采樣率的變換,通常分為內(nèi)插(也稱上采樣)和抽取(也稱下采樣)。內(nèi)插是指提高采樣率以增加數(shù)據(jù)樣點(diǎn)的過(guò)程;抽取是指降低采樣率以去除多余數(shù)據(jù)樣點(diǎn)的過(guò)程。

這里直接上結(jié)論,插值后信號(hào)的頻譜為原始信號(hào)頻譜經(jīng)過(guò)I倍“壓縮”得到,抽取后的信號(hào)頻譜以原始信號(hào)頻譜的D倍進(jìn)行“展寬”。
—— 復(fù)制自知乎-楚友馬-gnuradio 入門開發(fā)
GNU Radio 提供以下幾種重采樣塊:Fractional Resampler、Rational Resampler Base、Rational Resampler、Polyphase Arbitrary Resampler。我們這個(gè)例子中使用了 Polyphase Arbitrary Resampler,因此只對(duì)其進(jìn)行簡(jiǎn)單介紹(其他的后面出一期專門介紹):
多相任意重采樣器是一種用于對(duì)信號(hào)流進(jìn)行任意比例的重采樣的技術(shù),它可以根據(jù)不同的需求,調(diào)節(jié)信號(hào)的采樣率和波形。它的原理是,將一個(gè)長(zhǎng)的濾波器分解為多個(gè)短的濾波器,形成一個(gè)多相濾波器組,然后對(duì)輸入信號(hào)進(jìn)行多相分解,使得每個(gè)分支的信號(hào)只需要經(jīng)過(guò)一個(gè)短的濾波器,從而降低運(yùn)算量和延遲。接著,根據(jù)目標(biāo)的重采樣比例,從多相濾波器組中循環(huán)地取出一定數(shù)量的輸出信號(hào),并在相鄰的輸出信號(hào)之間進(jìn)行插值,得到一個(gè)近似的重采樣結(jié)果 [26] [28]。
多相任意重采樣器的優(yōu)點(diǎn)是,它可以實(shí)現(xiàn)任意的重采樣比例,無(wú)論是有理數(shù)還是無(wú)理數(shù),而不需要進(jìn)行復(fù)雜的內(nèi)插或抽取操作。它也可以有效地減少濾波器的長(zhǎng)度和運(yùn)算量,提高重采樣的效率和精度。它的缺點(diǎn)是,它需要對(duì)濾波器和信號(hào)進(jìn)行多相分解,這會(huì)增加一些存儲(chǔ)和計(jì)算的開銷。它也會(huì)引入一些量化誤差,因?yàn)樗峭ㄟ^(guò)插值來(lái)實(shí)現(xiàn)任意比例的重采樣,而不是精確的重采樣。因此,它需要根據(jù)具體的應(yīng)用場(chǎng)景和性能要求,來(lái)選擇合適的濾波器個(gè)數(shù)和插值方法 [27] [29]。
3 發(fā)送相關(guān)的小 DEMO
3.1 前向糾錯(cuò)編碼
編碼需要用到 FEC Async Encoder 塊[5]:
將在 message port 上接收到的幀(作為 async messages 或 PDU)進(jìn)行編碼。該 encoder 將完整消息作為一個(gè)幀或塊進(jìn)行編碼。消息的長(zhǎng)度會(huì)被用于幀的長(zhǎng)度,特別的該塊的 MTU 參數(shù)用于設(shè)置最大傳輸單元的大小,這意味傳輸幀長(zhǎng)度不能大于這個(gè)值。
此部署處理的消息是 messages full of unpacked bits 或 PDU messages,這意味著協(xié)議的更高層需要完成幀頭、幀尾、CRC 校驗(yàn)等組裝。為了處理 PDU,需要將 packed 選項(xiàng)設(shè)置為 True,然后該塊將使用 FEC API 來(lái)正確地對(duì) PDU 中的 bits 進(jìn)行解包,再通過(guò) encoder,并將它們重新打包輸出新的 PDU 用于下一階段。
該塊還提供對(duì)解包和打包順序設(shè)置:LSB 和 MSB。默認(rèn) rev_unpack 和 rev_pack 設(shè)置為 True,也就是說(shuō)拆包 bits 反轉(zhuǎn)、打包 bits 反轉(zhuǎn)。

因此,流程圖(tx_stage2.grc)中的 Encoder 模塊的 MTU 設(shè)置為 1.5K,packed 設(shè)置為 True,F(xiàn)EC 打包對(duì)象可選三個(gè):
| EFC 對(duì)象塊 | 參數(shù) | 功能介紹 |
|---|---|---|
| Repetition Encoder Definition[6] | - 維度:? - Frame Bits:幀最大 bits - 重復(fù):每 1 bit 重復(fù)多少次 |
按 bits 重復(fù)多少個(gè) |
| Dummy Encoder Definitio | - 維度:? - Frame Bits |
透?jìng)?/td> |
| CC Encoder Definition[7] | - 維度:? - Frame Bits - Constraint Length (K):[2, 31] - Rate Inverse(1/R) - Polynomials(多項(xiàng)式) - Start State:移位寄存器初始值 [0, 2^(K-1)-1],大多數(shù)文獻(xiàn)和書籍都使用從左向右移位的移位寄存器,而這里是從右向左,這意味著該值必須反轉(zhuǎn)。- Streaming behavior:指定卷積編碼器的行為方式 - Byte Padding(字節(jié)填充):編碼的幀是否應(yīng)該填充到最近的字節(jié) |
對(duì)恒定長(zhǎng)的幀實(shí)施卷積編碼,允許指定約束長(zhǎng)度(K)、編碼率、多項(xiàng)式。編碼對(duì)象維護(hù)一個(gè)移位寄存器,該移位寄存器從輸入流中取每個(gè) bit,然后與與移位寄存器做 AND 運(yùn)算, Voyager 多項(xiàng)式常見(jiàn)二進(jìn)制表示為 1011011和1111001,八進(jìn)制為 133 和 171。對(duì)于這個(gè)塊二進(jìn)制需要顛倒:1101101和1001111;八進(jìn)制這是155和117;十進(jìn)制是109和79。一些標(biāo)準(zhǔn)(例如CCSDS 131.0-B-3)要求對(duì)某些輸出進(jìn)行反轉(zhuǎn)。這是通過(guò)提供多項(xiàng)式的負(fù)值來(lái)支持的,例如-109。 NASA 的 Voyager code 使用 K=7, Rate=1/2: 1 + x^2 + x^3 + x^5 + x^6 1 + x + x^2 + x^3 + x^6 卷積編碼行為有: - Streaming:這種模式期望不間斷的樣本流進(jìn)入編碼器,并且輸出流被連續(xù)編碼。 - Terminated:為基于分組的系統(tǒng)設(shè)計(jì)的模式。此模式刷入 K-1 bits 進(jìn)入編碼器,將 rate*(K-1) bits 添加到輸出,這提高了對(duì)塊的最后比特的保護(hù),并有助于解碼器。 - Tailbiting(咬尾):另一種基于分組的方法。此模式將用數(shù)據(jù)包的最后(k-1)位預(yù)初始化編碼器的狀態(tài),而不是在數(shù)據(jù)包的末尾添加位(如“CC_TERMINATED”)。 - Truncated(截?cái)嗟模嚎偸窃趲g將寄存器重置為起始狀態(tài)。 |
| CCSDS Encoder Definition[13] | 參數(shù)和 CC Encoder Definition 類似 | 是一種特殊的卷積碼:CCSDS Encoding class for convolutional encoding with rate 1/2, K=7, and polynomials [109, 79]. |
采用 3 重復(fù)編碼輸出 log :
***** VERBOSE PDU DEBUG PRINT ******
()
pdu length = 48 bytes
pdu vector contents =
0000: 22 e7 d5 20 f8 e9 38 a1 4e 18 8c 47 30 8c fe f5
0010: ff f7 f7 28 b9 f8 fb f5 1c 7c cc cc 4c 24 01 6b
0020: 1c ea a3 ca e0 f5 80 a7 cc 09 5c d9 db 73 02 76
************************************
***** VERBOSE PDU DEBUG PRINT ******
()
pdu length = 144 bytes
pdu vector contents =
0000: 03 80 38 ff 81 ff fc 71 c7 03 80 00 ff fe 00 ff
0010: 8e 07 03 fe 00 e3 80 07 1c 0f f8 00 7e 00 e0 0f
0020: c0 1c 01 ff 03 f0 00 e0 0f c0 ff ff f8 ff f1 c7
0030: ff ff ff ff f1 ff ff f1 ff 03 8e 00 e3 fe 07 ff
0040: fe 00 ff fe 3f ff f1 c7 00 7f c0 1f ff c0 fc 0f
0050: c0 fc 0f c0 1c 0f c0 03 81 c0 00 00 07 1f 8e 3f
0060: 00 7f c0 ff 8e 38 e3 80 3f fc 0e 38 ff 80 00 ff
0070: f1 c7 e0 00 00 e3 81 ff fc 0f c0 00 0e 07 1c 7f
0080: c0 fc 7e 07 fc 7e 3f 1f f0 3f 00 00 38 1f f1 f8
************************************
運(yùn)算過(guò)程:
22 e7 -> 0010 0010 1110 0111 -> [000 000 111 000] [000 000 111 000] [111 111 111 000] [000 111 111 111]
-> 0000 0011 1000 0000 0011 1000 1111 1111 1000 0001 1111 1111
-> 0 3 8 0 3 8 f f 8 1 f f
-> 03 80 38 ff 81 ff
采用 CC Encoder 編碼:K=7, Rate=1/2(rate = 1/Rate = 2),多項(xiàng)式使用 [109,79]
***** VERBOSE PDU DEBUG PRINT ******
()
pdu length = 48 bytes
pdu vector contents =
0000: 22 e7 d5 20 f8 e9 38 a1 4e 18 8c 47 30 8c fe f5
0010: ff f7 f7 28 b9 f8 fb f5 1c 7c cc cc 4c 24 01 6b
0020: 1c ea a3 ca e0 f5 80 a7 cc 09 5c d9 db 73 02 76
************************************
***** VERBOSE PDU DEBUG PRINT ******
()
pdu length = 97 bytes
pdu vector contents =
0000: 0d ff d7 ec 6e df 0a 42 26 b6 b9 c9 9e e1 8e dd
0010: 8b 9e 16 63 43 c4 d0 f2 4b fe af c4 01 8c 83 9d
0020: 21 3f ff 20 d3 20 38 5d 3d 7e c6 06 ba b8 34 2d
0030: c4 24 6e ad 7f 0f 0f 0f d0 23 ea c5 0b 03 46 58
0040: 61 e4 b2 c7 cc 10 a6 45 3b d5 26 5d 18 9c d2 e7
0050: 6d 7f e7 dc 64 ef bc 47 0b fa 2b 3b fe 7d cb bf
0060: 49
************************************
運(yùn)算過(guò)程[8][9][10][11][12]:
22 e7 d5 20 -> 0010 0010 1110 0111 1101 0101 0010 0000 -> [001000] [101110] [011111] [010101] [001000] 00
001000 001000
1011011 1111001
------- -------
001000 001000
000000 001000 -> 0 0 1 0 1 1 -> 000011011111 -> 0D F
001000 001000 -> 0 0 1 1 1 1
001000 001000
000000 000000
001000 000000
001000 001000
------ ------
001011 001111
更標(biāo)準(zhǔn)與生動(dòng)的計(jì)算過(guò)程:

- 將多項(xiàng)式轉(zhuǎn)為寄存器流程圖
2)初始每個(gè)寄存器為 0,然后將 00100010 按照從左到右順序一個(gè)字節(jié)一個(gè)字節(jié)送入這個(gè)寄存器圖
3)每送入 1 個(gè) bit 出來(lái) 2 個(gè) bits
4)最后將每次輸出的 bit 對(duì)按順序連接
3.2 Chat App
這個(gè)例子比較簡(jiǎn)單,就是個(gè)輸入框內(nèi)輸入啥,Message Debug 輸出啥 pdu_simple_demo2_chat.grc:

3.3 PDU 操作集合演示
這個(gè)例子展示了關(guān)于 PDU 操作的各種塊 pdu_simple_demo3_pdu_tools.grc:

其中幾個(gè)新塊的功能如下:
- PDU Set:此塊將向 PDU 元數(shù)據(jù)字典添加一個(gè) key-value 數(shù)據(jù)對(duì)。
- Add System Time:此塊將把系統(tǒng)時(shí)間作為雙精度浮點(diǎn)值添加到 PDU 元數(shù)據(jù)中。時(shí)間鍵可以由用戶設(shè)置。
- Note:通常,一些 PDU 處理將在這里進(jìn)行,以便應(yīng)用時(shí)間基準(zhǔn)。
- Time Delta:此塊計(jì)算從添加時(shí)間鍵到現(xiàn)在所經(jīng)過(guò)的毫秒數(shù),并當(dāng)流程圖停止時(shí)打印統(tǒng)計(jì)信息。
- PDU Split:PDU 將會(huì)被拆分成數(shù)據(jù)字典 metadata dictionary 和 統(tǒng)一向量 uniform vector , 然后分別作為 dict/uvec PMT 消息發(fā)出。
因此整個(gè)流程圖每隔 400ms 輸出一個(gè)大 PDU,然后增加一個(gè) KEY1 鍵值對(duì),再增加一個(gè) SYS_TIME 鍵值對(duì),然后做一個(gè)小處理(主要是演示耗費(fèi)時(shí)間統(tǒng)計(jì)),然后增加一個(gè) time_delta_ms 鍵值對(duì),最后將信息分拆為字典和向量。
字典的打印結(jié)果為:
time_delta :debug: time_delta_ms PDU received at 1706628911.598694 with time delta 0.045776 milliseconds
******* MESSAGE DEBUG PRINT ********
((time_delta_ms . 0.0457764) (SYS_TIME . 1.70663e+09) (KEY1 . 123.4))
************************************
參考鏈接
[1].維基百科 —— PDU
[2].GNU Radio —— Random PDU Generator
[3].GNU Radio —— PDU Set
[4].GNU Radio —— Async CRC32
[5].GNU Radio —— FEC Async Encoder
[6].GNU Radio —— Repetition Encoder Definition
[7].GNU Radio —— CC Encoder Definition
[8].周武旸 —— 中國(guó)科學(xué)技術(shù)大學(xué) 個(gè)人通信與擴(kuò)頻實(shí)驗(yàn)室《編碼論第四章》(超詳細(xì)介紹卷積編碼)
[9].知乎 —— 卷積碼(有些錯(cuò)誤,對(duì)于理解 8 有幫助)
[10].國(guó)外問(wèn)答論壇 —— 旅行者號(hào)上面如何實(shí)現(xiàn)卷積碼的提問(wèn)
[11].美國(guó)國(guó)防信息安全中心
[12].維基百科 —— 卷積碼
[13].GNU Radio —— CCSDS Encoder Definition
[14].GNU Radio —— Default Header Format Obj
[15].GNU Radio —— Protocol Formatter (Async)
[16].清華大學(xué)學(xué)報(bào) —— OFDM星座旋轉(zhuǎn)調(diào)制自適應(yīng)交織器設(shè)計(jì)
[17].知乎 —— 星座圖通信原理(相比 18 更多例子和圖)
[18].CSDN —— 詳解IQ調(diào)制以及星座圖原理(相比 20 更詳細(xì))
[19].中國(guó)科技核心期刊 —— 基于星座圖的數(shù)字信號(hào)調(diào)制方法綜述
[20].CSDN —— 星座圖的原理和應(yīng)用(簡(jiǎn)單介紹 IQ 調(diào)制和星座圖)
[21].GNU Radio —— Chunks to Symbols
[22].GNU Radio —— Constellation Object
[23].CSDN —— 一文讀懂FFT,海寧窗(hann)和漢明窗(hamming)的區(qū)別,如何選擇窗函數(shù)
[24].維基百科 —— 窗函數(shù) Window function
[25].GNU Radio —— Burst Shaper
[26].知乎 —— 楚友馬-gnuradio 入門開發(fā)
[27].北理工學(xué)報(bào) —— 基于抽取濾波器多相分解的多速率采樣模塊設(shè)計(jì)
[28].CSDN —— 多相抽取器實(shí)現(xiàn)及matlab示例
[29].Matlab —— 對(duì)非均勻采樣信號(hào)進(jìn)行重采樣
[30].通信技術(shù)互動(dòng)問(wèn)答 —— 為什么GMSK要加高斯濾波器,而QPSK加升余弦濾波器?
[31].CSDN —— 濾波器之升余弦(很簡(jiǎn)單形象介紹了清楚)
[32].清華大學(xué)出版社 —— MATLAB/System View 通信原理實(shí)驗(yàn)與系統(tǒng)仿真,3.3.1 升余弦濾波器
[33].CSDN —— 升余弦和根升余弦濾波器(SRRC,RRC)的單位脈沖響應(yīng)(詳細(xì))
[34].維基百科 —— 升余弦濾波器
[35].維基百科 —— 沖激響應(yīng)
[36].維基百科 —— 濾波器
[37].維基百科 —— 低通濾波器
[38].IC 先生 —— 升余玄濾波器工作原理_滾降系數(shù)_沖激響應(yīng)表達(dá)式
[39].知乎 —— 信號(hào)發(fā)送端用根升余弦濾波器進(jìn)行成形濾波,那么接收端用什么濾波器來(lái)匹配呢?
[40].清華大學(xué) —— 《物聯(lián)網(wǎng)前沿實(shí)踐》第 5 章信號(hào)濾波(超好)
[41].GNU Radio —— Root Raised Cosine Filter
[42].NASA —— Root Raised Cosine (RRC) Filters and Pulse Shaping in Communication Systems
[43].Matlab —— raised-cosine-filtering
[44].文獻(xiàn) —— The care and feeding of digital,pulse-shaping filters
[45].華強(qiáng)電子 —— 什么是FIR濾波器?FIR濾波器工作原理、組成、優(yōu)缺點(diǎn)及應(yīng)用詳解
[46].Stack Exchange —— RRC 濾波器的正確增益是多少?
[47]. NI —— RFmx 波形創(chuàng)建器用戶手冊(cè)
[48]. 博客 —— C 中的根升余弦濾波器
[49]. 歐洲航天局 —— 平方根升余弦信號(hào)
[50]. BOOK —— Intuitive guide to topics in communications and digital signal processing(很直觀看信號(hào)與系統(tǒng))
教程列表
基礎(chǔ)教程:
- [1]. GNU Radio 系列教程(一) —— 什么是 GNU Radio
- [2]. GNU Radio 系列教程(二) —— 繪制第一個(gè)信號(hào)分析流程圖
- [3]. GNU Radio 系列教程(三) —— 變量的使用
- [4]. GNU Radio 系列教程(四) —— 比特的打包與解包
- [5]. GNU Radio 系列教程(五) —— 流和向量
- [6]. GNU Radio 系列教程(六) —— 基于層創(chuàng)建自己的塊
- [7]. GNU Radio 系列教程(七)—— 創(chuàng)建第一個(gè)塊
- [8]. GNU Radio 系列教程(八)—— 創(chuàng)建能處理向量的 Python 塊
- [9]. GNU Radio 系列教程(九)—— Python 塊的消息傳遞
- [10]. GNU Radio 系列教程(十)—— Python 塊的 Tags
- [11]. GNU Radio 系列教程(十一)—— 低通濾波器
- [12]. GNU Radio 系列教程(十二)—— 窄帶 FM 收發(fā)系統(tǒng)(基于ZMQ模擬射頻發(fā)送)
- [13]. GNU Radio 系列教程(十三)—— 用兩個(gè) HackRF 實(shí)現(xiàn) FM 收發(fā)
- [14]. GNU Radio 系列教程(十四)—— GNU Radio 低階到高階用法的分水嶺 ZMQ 的使用詳解
- [15]. GNU Radio 系列教程(十五)—— GNU Radio GFSK 模塊
- [16]. GNU Radio 系列教程(十六)—— GNU Radio 的調(diào)試?yán)?Message Strobe
- [17]. GNU Radio 系列教程(十七)—— GNU Radio PDU TX 利用三個(gè)塊實(shí)現(xiàn)最小的數(shù)據(jù)包(幀頭+數(shù)據(jù)+校驗(yàn))
- [18]. GNU Radio 系列教程(十八)—— GNU Radio PDU TX 將幀頭和 payload 消息合并為數(shù)據(jù)幀
- [19]. GNU Radio 系列教程(十九)—— GNU Radio PDU TX 將最小數(shù)據(jù)幀實(shí)施脈沖突發(fā)整形填充 --> 讓幀更穩(wěn)定
- [20]. GNU Radio 系列教程(二十)—— GNU Radio PDU TX 根升余弦深度介紹&發(fā)送數(shù)據(jù)幀的收尾之作
- [21]. GNU Radio 系列教程(二一)—— GNU Radio PDU RX 利用相關(guān)性估計(jì)器尋找數(shù)據(jù)幀的起始位置
- [22]. GNU Radio 系列教程(二二)—— GNU Radio PDU RX 利用多相時(shí)鐘同步塊實(shí)現(xiàn)消除時(shí)鐘偏移
- [23]. GNU Radio 系列教程(二三)—— GNU Radio PDU RX 利用自適應(yīng)線性均衡器消除 ISI
- [24]. GNU Radio 系列教程(二四)—— GNU Radio PDU RX 利用 Costas Loop 校正相位和頻率偏移
- [25]. GNU Radio 系列教程(二五)—— 硬核,基于通信原理設(shè)計(jì)一個(gè)文件傳輸系統(tǒng)
- [26]. GNU Radio 系列教程(二六)—— 開胃菜,hackrf 發(fā)送 ble 廣播包的簡(jiǎn)單 DEMO
綜合教程:
- [1]. SDR 教程實(shí)戰(zhàn)(一) —— 利用 GNU Radio + HackRF 做 FM 收音機(jī)
- [2]. SDR 教程實(shí)戰(zhàn)(二) —— 利用 GNU Radio + HackRF 做藍(lán)牙定頻測(cè)試工具(超低成本)
- [3]. SDR 教程實(shí)戰(zhàn)(三) —— 利用 GNU Radio + HackRF + WireShark 做藍(lán)牙抓包器(超低成本)
- [4]. SDR 教程實(shí)戰(zhàn)(四) —— 利用 GNU Radio + HackRF 手把手深入了解藍(lán)牙協(xié)議棧(從電磁波 -> 01數(shù)據(jù)流 -> 藍(lán)牙數(shù)據(jù)包)
- [5]. SDR 教程實(shí)戰(zhàn)(五) —— 利用 GNU Radio + LimeSDR+ WireShark 做藍(lán)牙抓包器(上上個(gè)視頻使用 HackRF)
- [6]. SDR 教程實(shí)戰(zhàn)(五) —— 利用兩個(gè) hackrf 實(shí)現(xiàn)大文件(視頻)高速傳輸
SDR 小工具教程:
基礎(chǔ)塊教程:
視頻和博客
: 如果覺(jué)得不錯(cuò),幫忙點(diǎn)個(gè)支持哈~




浙公網(wǎng)安備 33010602011771號(hào)