網址:https://github.com/open-sdr/openwifi
Openwifi:openwifi與linux的驅動部分原始碼和linux系統。
Openwifi-hw:openwifi的FPGA部分原始碼,是硬體部分,也是lowmac部分。
Openofdm:openwifi的基帶部分原始碼,也是執行在FPGA中,最終整合到openwif-hw專案中,也算是openwif-hw的一部分(ip),在這裡單獨作為一個工程更便於大家理解和學習。
openwifi-hw-img:放置了一些關於openwifi FPGA img的硬體git資訊
上面這是openwifi的整體框架,兩個藍色adi-linux什麼的是專用linux系統(先不管,看內容是公司專門出的)
driver裡面
從上到下,分別對應下面那個框圖中ARM這邊的驅動程式碼部分。ad9361的驅動少了,應該是放別的地方了,而且有別的晶片比如ad9364,我手頭的就是7020+9363
基本上就是.c檔案+一個makefile,很標準的linux驅動程式
openwifi-hw裡面放的是FPGA工程,其中
adi-hdl @ f61d970裡面放著暫時不知道,但是確實有很多AD晶片的驅動的感覺。
boards裡面放著各種支援板子的工程路徑
ip裡面是 openwifi的verilog程式碼這個side_ch沒有在框圖裡面顯示(翻譯是新增集中式DBG交換機,暫時不懂)
這是其document裡面的一張很完整的結構框架圖。後面的學習會對照這個圖,把每個模組都弄懂(爭取,畢竟是要做畢設的)。
我準備先從硬體這邊入手,畢竟Linux驅動那邊都較為完善,而且大機率用別人寫好的修改,FPGA這邊就需要下點功夫,堆工作量的任務就在這。
這是手冊裡面的一張示意圖,也就是上面的簡化。下面這個就是AD9361和FPGA之間具體的一些介面以及模組配置
從OpenOFDM開始,這個工程是openwifi-hw的一個ip,都屬於fpga這邊的硬體部分。
這個包含802.11 OFDM PHY解碼器的Verilog實現。(OFDM和802.11n都會單獨學習)
OpenOFDM的模組的學習網站:https://openofdm.readthedocs.io/en/latest/
一旦RF訊號被捕獲並且下變頻到基帶,解碼流水線(步驟統一)就開始了,包括:
- Packet detection(資料包檢測)
- Center frequency offset correction(中心頻率偏移校正)
- FFT(快速傅立葉轉換)
- Channel gain estimation(通道增益估計)
- Demodulation(檢波)
- Deinterleaving(去交織)
- Convolutional decoding(卷積編碼)
- Descrambling(解擾)
在此之前,已經學會了如何編譯openwifi-hw檔案、透過vivado生成bit流檔案和vitis生成boot.bin檔案,匯入sd卡,燒錄等
在sdr硬體上也學會了如何使用使用者空間指令配置相關引數和獲取,透過寫指令碼和配置啟動檔案能讓sdr啟動就能ad-hoc組網等。
2024-8-12
已經燒錄好官方映象,測試了一些命令,以及透過ad-hoc組網並ping通(但是ad-hoc是無線自組網協議,無法透過乙太網口傳輸,而且是5G訊號)
在文件裡發現了這個,但是好像沒什麼用,並沒有真正把頻率改變(再研究。。。)
2024-8-13
2024-8-14
透過閱讀官方手冊繼續學習
sdrctrl檔案裡的.c .h檔案就是解釋./sdrctrl後面的引數命令的地方,沒仔細研究,大致摸了一遍
2024-8-15
2024-8-16
測試了8-12號的改變頻率問題,買的SMA轉BNC介面還沒到(而且不確定示波器的頻寬夠不夠測試最低的頻率,因為是9363不是9361)
所以先將兩個裝置進入ad-hoc模式,這個時候按照iwconfig命令顯示,sdr0裝置是5.22Ghz,這是命令選擇通道時候44決定的(在802.11學習文章裡面提到過,如果是通道6就是2.4G範疇了)
先配置的原因就是需要預先設計一個wifi正常工作的環境,首先ping通,然後在裝置頻率
先給其中一個sdr設定頻率1.4G,也就是1400(收發都要)
再ping發現ping不通了,然後給另一個也設定收發1400,又可以ping通了,而且通訊距離變遠了(雖然本來就距離很短)
透過iperf3工具測試頻寬看起來還可以。(上下行都可以,還能經過UDP TCP等測速)
就收發距離上來看的話,增加通訊距離的手段有很多
1、增加 TX發射增益,也可以增加發射距離,放大嗓門說話
2、接收靈敏度,其實是可接受的觸發最低電平基準,相當於提高聽力
3、天線增益,包括髮送天線增益和接收天線增益。相當於擴音器和助聽器
發射增益透過rf的0暫存器值可以改變
接受靈敏度應該是rx裡面的2,power trigger and dc detection threshold。這個接收靈敏度在sdr.c檔案裡面找到
一開始get是32位,00000000
/*這個函式的目的是將接收強度指示 RSSI的值從半分貝(half-db)單位轉換為分貝毫瓦(dBm)單位
並應用一個校正因子,需要從RSSI值中減去的校正因子,以分貝為單位
*/
inline int rssi_half_db_to_rssi_dbm(int rssi_half_db, int rssi_correction)
{
int rssi_db, rssi_dbm;
//首先右移1位將半分貝改分貝,因為2個半分貝=1分貝
rssi_db = (rssi_half_db>>1);
//減去校正因子得到RSSI值
rssi_dbm = rssi_db - rssi_correction;
//由於RSSI值(在分貝單位下)可能變得非常低(即非常負),因此將rssi_dbm的值限制在-128以上。
rssi_dbm = (rssi_dbm < (-128)? (-128) : rssi_dbm);
return rssi_dbm;
}
inline int rssi_dbm_to_rssi_half_db(int rssi_dbm, int rssi_correction)
{
//分貝轉半分貝,因為1分貝等於兩個半分貝
return ((rssi_correction+rssi_dbm)<<1);
}
2024-8-17
sdrctrl的使用者設定set get 程式碼在openwifi/user_space/sdrctrl_src/cmd.c裡面的42行的這個函式,後面還有get
cmd.c
static int handle_set_reg(struct nl80211_state *state,
struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv,
enum id_input id)
{
struct nlattr *tmdata;
char *end;
unsigned int reg_cat, reg_addr, reg_val;
tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA);
if (!tmdata) {
return 1;
}
if (strcasecmp(argv[0],"rf")==0)
reg_cat=1;
else if (strcasecmp(argv[0],"rx_intf")==0)
reg_cat = 2;
else if (strcasecmp(argv[0],"tx_intf")==0)
reg_cat = 3;
else if (strcasecmp(argv[0],"rx")==0)
reg_cat = 4;
else if (strcasecmp(argv[0],"tx")==0)
reg_cat = 5;
else if (strcasecmp(argv[0],"xpu")==0)
reg_cat = 6;
else if (strcasecmp(argv[0],"drv_rx")==0)
reg_cat = 7;
else if (strcasecmp(argv[0],"drv_tx")==0)
reg_cat = 8;
else if (strcasecmp(argv[0],"drv_xpu")==0)
reg_cat = 9;
else {
printf("Wrong the 1st argument. Should be rf/rx_intf/tx_intf/rx/tx/xpu/drv_rx/drv_tx/drv_xpu\n");
return 1;
}
reg_addr = strtoul(argv[1], &end, 10);
if (*end) {
return 1;
}
reg_addr = reg_addr<<2;//from idx to addr
reg_addr = ((reg_cat<<16)|reg_addr);
reg_val = strtoul(argv[2], &end, 10);
if (*end) {
return 1;
}
//這個應該就是將你設定的地址和值寫入暫存器的程式碼
NLA_PUT_U32(msg, OPENWIFI_ATTR_CMD, REG_CMD_SET);
NLA_PUT_U32(msg, REG_ATTR_ADDR, reg_addr);
NLA_PUT_U32(msg, REG_ATTR_VAL, reg_val);
nla_nest_end(msg, tmdata);
printf("reg cat: %d\n", reg_cat);
printf("reg addr: %08x\n", reg_addr);
printf("reg val: %08x\n", reg_val);
return 0;
nla_put_failure:
return -ENOBUFS;
}
COMMAND(set, reg, "<rf/rx_intf/tx_intf/rx/tx/xpu/drv_rx/drv_tx/drv_xpu reg_idx value>", NL80211_CMD_TESTMODE, 0, CIB_NETDEV, handle_set_reg, "set reg");
今天用示波器試了一下,在配置了發射頻率為325Mhz(9363的調諧範圍325M~3.8G)
按道理週期波長應該是1/325M*10^9=3.0769ns,看了示波器,差不多,說明確實可以透過使用者空間控制功率。
昨天的增加發射功率和提高接收靈敏度的問題,在設定一些值的時候,有一些error(發射的頻率和接收頻率雖然可以隨便設定,但是硬體有限制,暫且不管)
但是設定發射功率的時候,超過80db(反正不到90db)就會報錯
注意:這個rf 模組的0不是發射功率是發射衰減,等於0的時候,才是發射功率最大的時候(一直搞錯了,調越大越不能通,md)
查到的報錯程式碼是sdrctrl.c裡面的
if (err == 1) {
if (cmd)
usage_cmd(cmd);
else
usage(0, NULL);
} else if (err < 0)
fprintf(stderr, "command failed: %s (%d)\n", strerror(-err), err);
2024-8-18
天線增益先不管,硬體的事後面再說
發射增益可以調節
接下來就是接收靈敏度的調節了
在看一下這個,rx模組的配置,用命令檢視一下
在openofdm_rx.c裡面97行
openofdm_rx_api->OPENOFDM_RX_REG_POWER_THRES_write((OPENOFDM_RX_DC_RUNNING_SUM_TH_INIT<<16)|OPENOFDM_RX_POWER_THRES_INIT); // turn on signal watchdog by default
#define OPENOFDM_RX_POWER_THRES_INIT 124
// Above 118 is based on these test result (2022-03-09)
// FMCOMMS3
// 2437M
// 11a/g BPSK 6M, Rx sensitivity level dmesg report -85dBm
// priv->rssi_correction = 153; rssi_half_db/2 = 153-85=68; rssi_half_db = 136
// 5180M
// 11a/g BPSK 6m, Rx sensitivity level dmesg report -84dBm
// priv->rssi_correction = 145; rssi_half_db/2 = 145-84=61; rssi_half_db = 122
// 5320M
// 11a/g BPSK 6m, Rx sensitivity level dmesg report -86dBm
// priv->rssi_correction = 148; rssi_half_db/2 = 148-86=62; rssi_half_db = 124
// FMCOMMS2
// 2437M
// 11a/g BPSK 6M, Rx sensitivity level dmesg report -80dBm
// priv->rssi_correction = 153; rssi_half_db/2 = 153-80=73; rssi_half_db = 146
// 5180M
// 11a/g BPSK 6m, Rx sensitivity level dmesg report -83dBm
// priv->rssi_correction = 145; rssi_half_db/2 = 145-83=62; rssi_half_db = 124
// 5320M
// 11a/g BPSK 6m, Rx sensitivity level dmesg report -86dBm
// priv->rssi_correction = 148; rssi_half_db/2 = 148-86=62; rssi_half_db = 124
#define OPENOFDM_RX_RSSI_DBM_TH_DEFAULT (-85) //-85 will remove lots of false alarm. the best openwifi reported sensitivity is like -90/-92 (set it manually if conductive test with wifi tester)
#define OPENOFDM_RX_DC_RUNNING_SUM_TH_INIT 64
#define OPENOFDM_RX_MIN_PLATEAU_INIT 100
#define OPENOFDM_RX_FFT_WIN_SHIFT_INIT 1
#define OPENOFDM_RX_SMALL_EQ_OUT_COUNTER_TH 48
#define OPENWIFI_MAX_SIGNAL_LEN_TH 1700 //Packet longer than this threshold will result in receiver early termination. It goes to openofdm_rx/xpu/rx_intf
#define OPENWIFI_MIN_SIGNAL_LEN_TH 14 //Packet shorter than this threshold will result in receiver early termination. It goes to openofdm_rx/xpu/rx_intf
//due to CRC32, at least 4 bytes needed to push out expected CRC result
上面這個註釋裡面,應該是每個頻率的標準或者說規定,比如FMCOMMS2的5320Mhz的下面,rssi_correction訊號強度修正148,其他頻段就不一樣。
所以我們要在別的頻段這樣做,不一定用一樣的,驗證一下
當我改變發射和接收頻率,再獲得接收電平訊號閾值的時候就變了,十進位制從120變136(暫時沒找到怎麼根據頻率變化修改的)
2024-8-19
發現了rf模組下的0是發射衰減,不是發射功率,0的時候發射功率才能最大(哎,仔細點)
後面開始試試MIMO能不能增加距離和頻寬
2024-8-21
ad-hoc組網不能接入有線,網橋手段也不行,另尋他路(~~)
板子的源換成別的需要改時間,改成現在的日期(卡了一天)
2024-8-27
這幾天嘗試了一些手段,想改wifi發射功率的問題,包括改US美國地址,以及用crda和wireless工具等修改。(都因為一些問題暫時擱置,python的版本問題以及安裝好後的環境缺失)
以及使用了飛睿智慧的遠距離wifi產品在做測試,如果能用的話,想一些辦法把兩個東西合起來做一下。
9月份之後重點放一部分在硬體設計上。(抄板)
2024-9-24
這一個月,參考一些電路,將自己的硬體設計SDR板子設計完並走線結束了,檢查一段時間再打板測試(全機器貼片的話,很貴,大機率貼DDR,ZYNQ,AD三個,其他的自己貼(估計總價要2k~~~,還不一定能用~~))
透過對微相科技的E310的發射TX增加一個射頻功率放大器,5V供電,估計增加20dbm不到(估計15db左右)
經過測試,確實增加了通訊距離(從1m多增加到10m不到),頻寬先不考慮,對接收靈敏度這邊研究一下。
單獨寫一章:在802.11學習裡面寫了一點。
觀察sdr.c的裡面的一些函式,低於2412Mhz的的rssi_correction修正值,我們也在這個範圍也就是153
inline int rssi_correction_lookup_table(u32 freq_MHz)
{
int rssi_correction;
if (freq_MHz<2412) {
rssi_correction = 153;
} else if (freq_MHz<=2484) {
rssi_correction = 153;
} else if (freq_MHz<5160) {
rssi_correction = 153;
} else if (freq_MHz<=5240) {
rssi_correction = 145;
} else if (freq_MHz<=5320) {
rssi_correction = 145;
} else {
rssi_correction = 145;
}
return rssi_correction;
}
在hw_def.h檔案裡面,看第一個2437M的FMCOMMS3,rssi修正153,接收靈敏度-85dbm
rssi半db值=153+
#define OPENOFDM_RX_POWER_THRES_INIT 124
// Above 118 is based on these test result (2022-03-09)
// FMCOMMS3
// 2437M
// 11a/g BPSK 6M, Rx sensitivity level dmesg report -85dBm
// priv->rssi_correction = 153; rssi_half_db/2 = 153-85=68; rssi_half_db = 136
// 5180M
// 11a/g BPSK 6m, Rx sensitivity level dmesg report -84dBm
// priv->rssi_correction = 145; rssi_half_db/2 = 145-84=61; rssi_half_db = 122
// 5320M
// 11a/g BPSK 6m, Rx sensitivity level dmesg report -86dBm
// priv->rssi_correction = 148; rssi_half_db/2 = 148-86=62; rssi_half_db = 124
// FMCOMMS2
// 2437M
// 11a/g BPSK 6M, Rx sensitivity level dmesg report -80dBm
// priv->rssi_correction = 153; rssi_half_db/2 = 153-80=73; rssi_half_db = 146
// 5180M
// 11a/g BPSK 6m, Rx sensitivity level dmesg report -83dBm
// priv->rssi_correction = 145; rssi_half_db/2 = 145-83=62; rssi_half_db = 124
// 5320M
// 11a/g BPSK 6m, Rx sensitivity level dmesg report -86dBm
// priv->rssi_correction = 148; rssi_half_db/2 = 148-86=62; rssi_half_db = 124
#define OPENOFDM_RX_RSSI_DBM_TH_DEFAULT (-85) //-85 will remove lots of false alarm. the best openwifi reported sensitivity is like -90/-92 (set it manually if conductive test with wifi tester)
#define OPENOFDM_RX_DC_RUNNING_SUM_TH_INIT 64
#define OPENOFDM_RX_MIN_PLATEAU_INIT 100
#define OPENOFDM_RX_FFT_WIN_SHIFT_INIT 1
#define OPENOFDM_RX_SMALL_EQ_OUT_COUNTER_TH 48
#define OPENWIFI_MAX_SIGNAL_LEN_TH 1700 //Packet longer than this threshold will result in receiver early termination. It goes to openofdm_rx/xpu/rx_intf
#define OPENWIFI_MIN_SIGNAL_LEN_TH 14 //Packet shorter than this threshold will result in receiver early termination. It goes to openofdm_rx/xpu/rx_intf
//due to CRC32, at least 4 bytes needed to push out expected CRC result
看一下板子上得到的值,也就是00400088,bit0-10位,就是十進位制136,低於這個值的都不會觸發解調。
跟上面的註釋對應,就是接收靈敏度-85dbm
嘗試:修改接收靈敏度-85dbm的值,改到-96dbm左右,不知道能不能成功。
結果,改了-95dbm,然後沒什麼效果,還更差了(透過重新編譯然後傳ko檔案到板子)