W5500接收丢数据
以前测试从来没有发现这个问题,今天测试WEB服务器时,发现·W5500丢失数据:
> Receive_Len=536
POST /example.cgi HTTP/1.1
Host: 192.168.1.199
Connection: keep-alive
Content-Length: 71
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.1.199
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.1.199/
Accept-
这种现象是偶然出现的,但很难捕捉到。既然发现了,就要去跟踪解决。
正确的应该是这样的,如下:
> Receive_Len=667
POST /example.cgi HTTP/1.1
Host: 192.168.1.199
Connection: keep-alive
Content-Length: 71
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.1.199
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.1.199/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Relay1=1&Relay2=1&Relay3=0&Relay4=0&Relay5=0&Relay6=0&Relay7=0&Relay8=0
经过检查,发现W5500的库函数有问题,源程序如下:
//函数功能:在“TCP模式”中,读“Socket n的接收缓冲区的接收量大小寄存器”,直到W5500接收完成
uint16_t getSn_RX_RSR(uint8_t sn)
{uint16_t val=0,val1=0;do{val1 = WIZCHIP_READ(Sn_RX_RSR(sn));/*从W5500读取一个字节Sn_RX_RSRsn)是“W5500帧的第1个字节,第2个字节,第3个字节的高5位值,且第3个字节的低3位为0”*/val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));/*从W5500读取一个字节WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)实现“偏移地址加1”Sn_RX_RSR(sn)是“W5500帧的第1个字节,第2个字节,第3个字节的高5位值,且第3个字节的低3位为0”Sn_RX_RSR(sn)为3个字节,最高两个字节是偏移地址,所以加(1<<8),就表示“W5500帧的第1个字节和第2个字节”加1,实现“偏移地址加1”*/if (val1 != 0){val = WIZCHIP_READ(Sn_RX_RSR(sn));/*从W5500读取一个字节Sn_RX_RSRsn)是“W5500帧的第1个字节,第2个字节,第3个字节的高5位值,且第3个字节的低3位为0”*/val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));/*从W5500读取一个字节WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)实现“偏移地址加1”Sn_RX_RSR(sn)是“W5500帧的第1个字节,第2个字节,第3个字节的高5位值,且第3个字节的低3位为0”Sn_RX_RSR(sn)为3个字节,最高两个字节是偏移地址,所以加(1<<8),就表示“W5500帧的第1个字节和第2个字节”加1,实现“偏移地址加1”*/}}while (val != val1);//若前后所读“Socket n的接收缓冲区的接收量大小寄存器”不等,则表示W5500正在接收数据return val;
}
我以前都过这段代码,当时觉得有点问题,认为是厂家提供的,应该可以,总觉得厂家应该反复测试过了。后来测试也行,但是在做WEB服务器时,问题就暴露出来了。我做了修改,如下:
//函数功能:在“TCP模式”中,读“Socket n的接收缓冲区的接收量大小寄存器”,直到W5500接收完成
uint16_t getSn_RX_RSR(uint8_t sn)
{uint16_t val=0,val1=0;do{val1 = WIZCHIP_READ(Sn_RX_RSR(sn));/*从W5500读取一个字节Sn_RX_RSRsn)是“W5500帧的第1个字节,第2个字节,第3个字节的高5位值,且第3个字节的低3位为0”*/val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));/*从W5500读取一个字节WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)实现“偏移地址加1”Sn_RX_RSR(sn)是“W5500帧的第1个字节,第2个字节,第3个字节的高5位值,且第3个字节的低3位为0”Sn_RX_RSR(sn)为3个字节,最高两个字节是偏移地址,所以加(1<<8),就表示“W5500帧的第1个字节和第2个字节”加1,实现“偏移地址加1”*/if (val1 != 0){delay_ms(1);//延时1msval = WIZCHIP_READ(Sn_RX_RSR(sn));/*从W5500读取一个字节Sn_RX_RSRsn)是“W5500帧的第1个字节,第2个字节,第3个字节的高5位值,且第3个字节的低3位为0”*/val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));/*从W5500读取一个字节WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)实现“偏移地址加1”Sn_RX_RSR(sn)是“W5500帧的第1个字节,第2个字节,第3个字节的高5位值,且第3个字节的低3位为0”Sn_RX_RSR(sn)为3个字节,最高两个字节是偏移地址,所以加(1<<8),就表示“W5500帧的第1个字节和第2个字节”加1,实现“偏移地址加1”*/}}while (val != val1);//若前后所读“Socket n的接收缓冲区的接收量大小寄存器”不等,则表示W5500正在接收数据return val;
}
其实就是在代码之间,插入一条延时语句delay_ms(1);
再测试,就正常了。
我又想起了“uint16_t getSn_TX_FSR(uint8_t sn)”,应该也有问题,干脆一起修改了。它们的问题是一样,也要插入插入一条延时语句delay_ms(1);正确代码如下:
//函数功能:读“Socket n的发送缓冲区剩余量大小寄存器”,直到W5500发送完成
uint16_t getSn_TX_FSR(uint8_t sn)
{uint16_t val=0,val1=0;do{val1 = WIZCHIP_READ(Sn_TX_FSR(sn));/*从W5500读取一个字节Sn_TX_FSR(sn)是“W5500帧的第1个字节,第2个字节,第3个字节的高5位值,且第3个字节的低3位为0”*/val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));/*从W5500读取一个字节WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)实现“偏移地址加1”Sn_TX_FSR(sn)是“W5500帧的第1个字节,第2个字节,第3个字节的高5位值,且第3个字节的低3位为0”所以加(1<<8),就表示“W5500帧的第1个字节和第2个字节”加1,实现“偏移地址加1”*/if (val1 != 0){delay_ms(1);//延时1msval = WIZCHIP_READ(Sn_TX_FSR(sn));/*从W5500读取一个字节Sn_TX_FSR(sn)是“W5500帧的第1个字节,第2个字节,第3个字节的高5位值,且第3个字节的低3位为0”*/val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));/*从W5500读取一个字节WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)实现“偏移地址加1”Sn_TX_FSR(sn)是“W5500帧的第1个字节,第2个字节,第3个字节的高5位值,且第3个字节的低3位为0”所以加(1<<8),就表示“W5500帧的第1个字节和第2个字节”加1,实现“偏移地址加1”*/}}while (val != val1);//若前后所读“Socket n的发送缓冲区剩余量大小”不等,则表示W5500正在发送数据return val;
}
如果我没有读过厂家的驱动程序,就永远都搞不好了。
我多余的ioLibrary中多余的文件删除,文件更加简洁: