STM32F4 LAN8720以及LWIP的移植调试记录 (3)

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抓包。
能够看到高频的错误包信息。
STM32F4 LAN8720以及LWIP的移植调试记录 (3)_第1张图片
从抓到的包可以看到,IP地址和端口都不是想要的。
查到在sendto函数的IP地址赋值,原子的例程,赋值方式如下:

upcb->remote_ip=*addr;

而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;
};

于是把自己的代码改成:

pcb->remote_ip.addr = 0x0FC0A8C0;

于是发出去了。


call stack中的东西会莫名其妙消失。

发送内容是数组时会死在发送函数里。

发送前的call stack:
STM32F4 LAN8720以及LWIP的移植调试记录 (3)_第2张图片

调用完sendto后的call stack:
STM32F4 LAN8720以及LWIP的移植调试记录 (3)_第3张图片
那么在后边弹栈的时候就会崩。

用原子的例程去试,代码也会掉进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 对缓冲区清零。然后代码就崩了。

你可能感兴趣的:(单片机,移动机器人)