Wiznet W5500 MAC RAW和UDP

使用MAC RAW功能对于W5500来说有点浪费,不过如果想要在W5500基础上移植LwIP之类的协议栈的话就需要MAC RAW功能了,这就使得W5500和一片ENC28J60网卡芯片的功能一样了,屏蔽掉了内部的硬件TCP/IP协议栈。但是我使用MAC RAW的功能不是为了移植LwIP协议栈,而是作为一种局域组网的高速数据传输的验证,场景如下:

现在有一个设备需要8个控制器控制,8个控制器由一个主控器统一协调控制,主控器会向控制器发送数据,并且数据量很大,每个控制器需要33.75KBps的带宽(1152Bytes * 30,每秒30帧数据,一帧数据1152个字节),8个控制器需要的总带宽为270KBps,如果使用115200bps的RS485总线传输数据的话只能实现1.25FPS的效果,是不够的。使用500Kbps的CAN总线的话,虽然速率提高的了,但是CAN总线中一帧数据中的有效数据(Payload)占比太小,导致实际数据传输速率可能还低于RS485总线。最后想到的是网络了,但是每个控制器有自己活要干,分配太多的资源给网络LwIP类的协议栈的话会导致控制效果不好,当然直接使用W5500的硬件TCP/IP协议栈也是没有问题的,不过这里还是验证一下基于MAC RAW的数据传输。W5500拥有10/100M 以太网数据链路层(MAC)及物理层(PHY),SPI接口的最高速率为80Mhz,实际使用速率为36Mhz,实现270KBps的带宽是绰绰有余的。

下面可以开始进行试验,由于W5500的MAC RAW模式只能在socket 0上使用,所以我们将socket 0设置为MACRAW模式,开启MAC地址过滤、IPV6帧过滤,源端口、目的IP、目的端口等参数无需设置,初始化完成之后执行CR_OPEN命令打开socket(可不执行CR_CONNECT命令),等待socket的状态变为SOCK_MACRAW即表示初始化完成:

    struct Common_InitStruct Common_InitStructure = 
	{
		.gateway = {192,168,2,1},
		.subnet_mask = {255,255,255,0},
		.hardware_addr = {0x12,0x12,0x12,0x12,0x12,0x12},
		.ipaddr = {192,168,2,66},
		.int_mask = 0xFF,
		.sock_int_mask = 0xFF,
		.phy_config = 0xF8,
	};
	struct Socket_InitStruct Socket_InitStructure = 
	{
		.Sn = 0,
		.SnMR = Sn_MR_MFEN | Sn_MR_MIP6N | Sn_MR_MACRAW,
		.SnSrcPort = 8888,
		.SnDIP = {192,168,2,1},
		.SnDstPort = 6666,
	};
	
	w5500_init();
	common_init(&Common_InitStructure);
	socket_init(&Socket_InitStructure);
	
	u8 sock_sr;
	printf("%.2X ",sock_sr = getSnSR(0));
	setSnCR(0,Sn_CR_OPEN);
	setSnCR(0,Sn_CR_CONNECT);
	while(1)
	{
		printf("%.2X ",sock_sr = getSnSR(0));
		if(sock_sr == SOCK_MACRAW)
		{
			printf("Socket 0 MACRAW mdoe established\r\n");
			break;
		}
		vTaskDelay(500);
	}
	
	printf("%s\r\n",__FUNCTION__);
	u8 temp[] = "0123456789\r\n";
	static u8 temp2[2048];
	while(1)
	{
// 		writeSnTxBuff(0,temp,strlen(temp));
		int len = readSnRxBuff(0,temp2);
		int i;
		if(len)
		{
			printf("%.4X--",len);
			for(i=0;i<len;i++)
				printf("%.2X ",temp2[i]);
			printf("\r\n\r\n");
		}
		vTaskDelay(1);
	}

程序中把数据发送部分注释了,先进行接收试验,结果如下:

结果发现收到的MAC帧和我们记忆中的MAC帧格式不大一样:https://blog.csdn.net/tq384998430/article/details/53391818。仔细查看这里的MAC帧前面多了两个字节的数据,如果把这两个字节去掉,后面的数据的结构和MAC帧格式是一样的,54 E1 AD 4F 78 5E是我电脑的MAC地址,我使用网线直接将W5500和电脑的网口连接,所以收到的帧中的源MAC地址应该是我的电脑的MAC地址,没有错,但是目的地址却不是W5500的MAC地址或者是广播地址,不知道为什么没有过滤MAC帧,这个问题先放这。看看前两个字节的数据是什么。仔细观察发现有的帧中前面两个字节和帧长度是一样的,说明这两个字节可能是帧长度,但是有帧的前两个字节又和帧长度不一样,再用心一点就发现了其实我们从W5500中读取的数据可能是多帧数据,也就是在我们读取的时候W5500中已经有多帧数据了,这时候我们读取的数据长度是多帧数据长度的总和,所以出现了实际帧长度和前两个字节不一样的现象,例如:

第一张图画红圈的地方是我电脑的MAC地址,那么说明读出来的额数据中有两个完整的帧,两个帧的长度都为0x0070,长度总和就是0x00E0,正好是我读取的数据的长度,注意这里读取的数据的长度包含了前两个字节,并且前两个字节表示的长度又包含了自己,也就是实际的MAC帧是0x6E个字节,加上2个字节的长度之后变成了0x70了。为什么W5500要加两个字节的数据作为帧长度呢?因为MAC帧是没有帧界定的,虽然数据链路层的MAC帧是有前导域和和校验的,但是存放在内存中的是不包含前导域和和校验的(校验是硬件计算并发送以及校验和剥离的),所以两帧数据如果同时放在缓存区中的话会导致无法确定帧的分界线,这才导致了两个字节的MAC帧长度数据的出现。

现在我们可以读取原始的MAC帧数据了,但是MAC地址的过滤没有有效,不知道是哪个细节没有注意到,不过使用软件进行MAC地址过滤不会占用很多CPU。下面进行MAC RAW的数据发送测试,直接取消上面代码的发送部分的注释,然后将循环延时调整到1000,打开网络抓包工具进行抓包,我们需要指定网卡,不然会导致WIFI网络的数据都会被抓取到,数据量非常大不方便分析,下面是实际的抓包结果(发送的数据是12字节的字符串“0123456789\r\n”):

发送了12个字节的数据,但是接收到了60个字节,这可能是电脑上MAC帧的最小长度,或者是抓包工具每个帧都分配了至少60字节的长度,如果收到的帧没有达到60个字节也会将60个字节全部输出,如果使用两个W5500进行数据互发我猜测应该没有这种情况。

MAC RAW的试验没有问题,我们的方案可以使用一个拥有9端口以上的交换机然后将8台控制器和主控器连接到交换机上,控制器和主控器分配不同的MAC地址,以构成一个局域网,主控器可以向控制器定点发送数据或者广播发送数据。为了让交换机内部可以正常地建立MAC地址表,控制器和主控器需要发送一帧数据出去,不管目的地址,这样交换机在收到数据的时候就能知道端口号对应的设备的MAC地址了。

接下来就可以使用MAC RAW进行自定义协议并通讯了。

 

续。

 

前面发现W5500的MAC RAW模式下无法过滤MAC非本机MAC地址或广播MAC地址的帧,后面我做了一些实验,将Sn_MR_MFEN位去掉,也就是屏蔽MAC过滤功能,发送相比打开MAC过滤功能时多接受了很多帧,这说明MAC过滤功能时有作用的,那么为什么还有会接收到非本机MAC地址的帧呢?然后又做了一个实验,将MR寄存器中的Sn_MR_MMB位置位,他可以屏蔽多播MAC 地址的包传输,然后发现就没有再收到非本机MAC或者广播地址的帧了,由于没人知道我的MAC地址,所有收到的都是广播地址FF FF FF FF FF FF,那么这个多播MAC 地址的包是什么呢?参考文章:http://blog.chinaunix.net/uid-30343738-id-5748915.html,下图是打开MAC多播时接收到的多播帧:

就不深入探讨这个问题了,我们这里屏蔽掉多播地址即可,然后就能收到只属于我们的帧数据了。

另外再说一下,使用UDP进行数据传输也可以实现上诉场景,我也进行了UDP传输的测试,发现和MAC RAW一样,在原始数据的前面会有数据长度,而且还有源IP地址和源端口号,这样我们就能知道发送过来数据的人是谁了,使用UDP的优点是可以和现成的网络设备例如PC电脑、Linux主板等直接通讯,因为这些设备进行MAC RAW传输不方便,而使用UDP是非常方便的。全速发送UDP数据测试了一下W5500的UDP数据传输速率:

	while(1)
	{
		writeSnTxBuff(0,temp,strlen(temp));
	}

writeSnTxBuff函数中会判断缓冲区是否有空闲,没有的话会直接返回。电脑上打开一个网络调试助手,本地端口6666,对方端口8888,运行程序打开任务管理器查看网络调试助手的网速:

可以看到网络调试助手的网速为10.5Mbps,已经满足我们的需求了。

 

续。

 

前面的测试程序中有BUG。进行UDP数据发送时,当UDP帧数据长度为512时,查看接受到的数据时发现数据有错误,测试了帧数据长度为128、150、256时的结果,发现256也有问题,仔细查看底层的函数:void spi_write_frame(u32 addr,u8 *buff,u8 len);中的len参数的类型为u8,这样如果传参256或者512的话,实际接收到的是0(其他大于255的数值取余255就是实际的值),但是在写入数据到W5500的缓冲区之后又会更新发送缓冲区写指针,告诉W5500我写了256或者512个数据,也就是说我实际SPI写了0个数据,但是W5500要发送256或者512个字节的数据,那么这样就“节省”了SPI写入大量数据的时间,大大提高网速了,实际测得UDP数据发送速度在11MBps,大约在100Mbps的带宽,和W5500的介绍是一样的“10/100M 以太网数据链路层(MAC)及物理层(PHY)”。但是实际上肯定达不到这个速度,因为我们没有发送数据到缓冲区就发送出去了,将函数spi_write_frame的len参数类型改成int之后再测试,这时候帧长度为256或者512时接收到的数据没有错误,此时网速约为808KBps:

可以看到360和任务管理器显示的网速大致是一样的,但是为什么和前面测试的结果不一样?前面是在我的笔记本电脑上测试的,而且那时候函数BUG没有修改,但是UDP帧数据只有12个字节,BUG对此没有影响,但是任务管理器显示的网速是10.5Mbps,为什么如此之高?12个字节数据的帧的有效数据占比如此之低还能达到10Mbps,512个字节数据的帧却只有6.8Mbps?继续测试,将数据帧长度改成12个字节:

281KBps的网速对应的是10.8Mbps?

然后再改成128字节测试:


怎么任务管理器显示的网速还下降了?再将帧数据长度改成1字节:

为什么360显示的网速越高,任务管理器显示的网速越低,根据计算,帧有效数据长度越长,有效数据的占比越大,网速应该越快,这点和360显示结果是一样的。我还能不能相信你,我的任务管理器。

W5500是一款基于SPI接口的以太网控制器,支持TCP/IP协议栈,并且支持MACRAW模式。在MACRAW模式下,可以实现对以太网帧的直接发送和接收,不需要使用TCP/IP协议栈,因此可以实现更高的灵活性和更高的吞吐量。 以下是使用W5500实现MACRAW模式的基本步骤: 1. 初始化W5500控制器,包括设置SPI接口、复位W5500寄存器、配置网络参数等。 2. 配置W5500控制器进入MACRAW模式,包括设置MACRAW模式寄存器、开启MACRAW模式。 3. 发送和接收以太网帧,包括设置DMA传输、配置发送和接收缓冲区、设置以太网帧头信息等。 在这个过程中,需要使用W5500所提供的寄存器和API接口来实现。以下是使用WIZnet官方提供的W5500库实现MACRAW模式的代码示例: ```c #include <Ethernet/W5500/w5500.h> // 初始化W5500控制器 w5500.init(); w5500.setIPAddress(ip); w5500.setGatewayIP(gateway); w5500.setSubnetMask(subnet); // 配置W5500控制器进入MACRAW模式 w5500.setMACRAWMode(); // 设置MACRAW模式 w5500.execOPCMD(); // 开启MACRAW模式 // 发送以太网帧 uint8_t buffer[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x08, 0x00, 0x45, ...}; // 以太网帧数据 w5500.sendRaw(buffer, sizeof(buffer)); // 接收以太网帧 int size = w5500.getRXReceivedSize(); uint8_t buffer[size]; w5500.recvRaw(buffer, size); ``` 需要注意的是,MACRAW模式下需要手动实现以太网帧头信息,包括目的MAC地址、源MAC地址、以太网帧类型等,具体信息可以参考以太网协议。同时,W5500的发送和接收缓冲区大小有限,需要根据实际情况进行调整。 值得一提的是,使用W5500实现MACRAW模式需要一定的网络编程基础,并且需要了解硬件电路和SPI通信协议相关的知识。因此,如果初学者想要使用W5500实现MACRAW模式,需要进行深入学习和实践。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值