802.11AX(WIFI6)无线协商速率计算
从2019年末的iphone11系列开始,到后来的三星S10,在手机参数中总会有WIFI6这么一条参数,这里的WIFI6就是802.11的一个比较新的协议规范:802.11AX。因为笔者软件出生,对射频了解的不多,基本上也是靠查查找到,学习到了无线速率的计算方法,因为手头上的相关WIFI6的资料有限,网上也查不到比较全的无线速率对照表,所以干脆学习了一下,写了一段代码来计算无线各个参数下的WIFI6协商速率。能查到这里来的应该都是对802.11有一定了解的,所以一些细节东西就不展开去讲。
下面要讲的东西基本上是从华为学习过来的,原文链接如下:
https://support.huawei.com/enterprise/zh/doc/EDOC1100102758
公式如下:
*WiFi理论协商速率 =(符号位长×码率×子载波数量×空间流)÷ 传输时间*
符号位长:不同调制方式的大小不同,某种调制方式下为一定值
码率:不同调制方式的大小不同,某种调制方式下为一定制
子载波数量:这里只计算有效子载波数量,即携带有效数据的载波数量
空间流:就是我们常说的几发几收,1T1R,2T2R这种东西
传输时间:不同协议时间不同,为一定值,注意我们计算时这里的时间要加上GI(帧间间隙)这个值在协议规范也是有一系列固定值的
讲到这里就要列出来这些变量的主要取值了,首先是不同协议和不同频宽下的有效子载波数量
有效子载波数量:
传输时间
符号位长,码率以及调制方式
有了以上的东西,再加上空间流即可完成计算,如计算11AX最大理论速率,8T8R:
11ax理论最大速率 =(10bit × 5/6 × (2*980) * 8) ÷ (12.8 + 0.8) = 9607.86Mbps
如果遇到查不到表的情况,并且有时候表不全的时候怎么办呢,笔者抽空写了段代码,可以计算并输出11ax的速率,附上代码:
/*
* =====================================================================================
*
* Filename: ax_rate.c
*
* Description: cal 802.11AX wireless rate
*
* Version: 1.0
* Created: 2020年03月06日 21时23分14秒
* Revision: none
* Compiler: gcc
*
* Author: lyx
* Company: xxx
*
* =====================================================================================
*/
#include <stdio.h>
#define TRANS_TIME_AX 12.8 //11ax基本传输耗时
#define BAND_WIDTH_20 20 //20M频宽
#define BAND_WIDTH_40 40 //40M频宽
#define BAND_WIDTH_80 80 //80M频宽
#define BAND_WIDTH_160 160 //160M频宽
float bit_symbol[12] = {1,2,3,4,4,5,5,5,8,8,10,10}; //不同解调方式/mcs对应的符号位长
float mcs_bit_rate[12] = {(float)1/2, (float)1/2, (float)3/4, (float)1/2, (float)3/4,\
(float)1/2, (float)3/4, (float)5/6, (float)3/4, (float)5/6, (float)3/4, (float)5/6}; //mcs index对应的码率
float num_word_carr[4] = {234, 468, 980, 1960}; //不同频宽的子载波数量20/40/80/160
float cal_rate(int bandwidth, float GI, int mcs_index, float space_flow)
{
float rate = 0;
int bandwidth_index = -1;
switch (bandwidth)
{
case BAND_WIDTH_20:
bandwidth_index = 0;
break;
case BAND_WIDTH_40:
bandwidth_index = 1;
break;
case BAND_WIDTH_80:
bandwidth_index = 2;
break;
case BAND_WIDTH_160:
bandwidth_index = 3;
break;
default:
break;
}
rate = ( bit_symbol[mcs_index] * mcs_bit_rate[mcs_index] * num_word_carr[bandwidth_index] * space_flow ) / (TRANS_TIME_AX + GI);
return rate;
}
int main(int argc, char **argv)
{
// float rate1 = cal_rate(40,0.8,9,2);
int mcs_idx = 0, band = 0;
for (band = BAND_WIDTH_20; band <=BAND_WIDTH_80; band*=2)
{
for (mcs_idx = 0; mcs_idx < 12; mcs_idx++)
{
printf("%.1f\t", cal_rate(band,3.2,mcs_idx,2));
}
printf("\n");
for (mcs_idx = 0; mcs_idx < 12; mcs_idx++)
{
printf("%.1f\t", cal_rate(band,1.6,mcs_idx,2));
}
printf("\n");
for (mcs_idx = 0; mcs_idx < 12; mcs_idx++)
{
printf("%.1f\t", cal_rate(band,0.8,mcs_idx,2));
}
printf("\n");
}
return 0;
}
编译
运行
因为图省事,就没用argv参数,调用全是写死了,只写了20M 40M 80M 和分别对应的GI, 2GI, 4GI 对应的速率。需要修改的自己修改吧,a,b,g,n,ac,ax的计算方式一样,注意GI,调制方式以及空间流合法就好了。