LAN8720配置:
IP: 192.168.192.30
Gateway: 192.168.192.1
检测到高频率的ARP包
包的内容在询问192.168.192.1的mac地址,并要求应答者发往192.168.192.30。
可以判断为LAN8720可能要夸网段发包,但是找不到网管。
于是把LAN8720的网关改为192.168.192.15, 即PC机的IP。
然后使用wireshark抓包。
能够看到高频的错误包信息。
从抓到的包可以看到,IP地址和端口都不是想要的。
查到在sendto函数的IP地址赋值,原子的例程,赋值方式如下:
upcb->remote_ip=*addr;1
而pcb中remote_ip的类型和addr的类型相同,都为:struct ip_addr *
/* This is the aligned version of ip_addr_t, used as local variable, on the stack, etc. */ struct ip_addr { u32_t addr; };12345
于是把自己的代码改成:
pcb->remote_ip.addr = 0x0FC0A8C0;1
于是发出去了。
发送内容是数组时会死在发送函数里。
发送前的call stack:
调用完sendto后的call stack:
那么在后边弹栈的时候就会崩。
用原子的例程去试,代码也会掉进Hardfault。
原子的例程:
//UDP服务器发送数据
void udp_demo_senddata(struct udp_pcb *upcb)
{
struct pbuf *ptr;
ptr=pbuf_alloc(PBUF_TRANSPORT,strlen((char*)tcp_demo_sendbuf),PBUF_POOL); //申请内存
if(ptr)
{
ptr->payload=(void*)tcp_demo_sendbuf;
udp_send(upcb,ptr); //udp发送数据
pbuf_free(ptr);//释放内存
}
}
奇怪的地方在于
ptr->payload = (void*)tcp_demo_sendbuf;
payload没用使用memcpy而是直接被一个指针赋值。
按网上的例子把这里改成:
memset(ptr->payload, 0 , ptr->len);
memcpy(ptr->payload, dataptr, sendsize);
然后就不报错了。不知道为啥原子的能跑通。
调recvfrom函数崩掉了
int len;
len = recvfrom(socket_n, _commandBuffer, len, MSG_DONTWAIT, (sockaddr *)&remoteaddr, &remoteaddrlen);
问题在于传入的第三个参数len 是缓冲区长度。
而申请到的len误作为值传入。
在recvfrom函数中调用了memset 对缓冲区清零。然后代码就崩了。
上一篇:STM32F407和LAN8720调试记录 (1)
下一篇:STM32移植LWIP网线热插入网络不通的解决办法
推荐阅读最新更新时间:2024-03-16 16:00