版主
- 积分
- 11922
- 金钱
- 11922
- 注册时间
- 2015-11-5
- 在线时间
- 2086 小时
|
发表于 2017-12-11 13:36:14
|
显示全部楼层
很抱歉我这段时间都比较忙没法及时处理你们的问题,非常抱歉!
对于你说的FreeRTOS+LWIP出现的问题,我本人用LWIP时没有跑OS,所以观点可能比较片面
你的附件下载不了,根据你的截图只能判断你用的是战舰板,网卡是DM9000
很抱歉我不了解DM9000的驱动,目前只能大概给你讲下LWIP的接收处理过程
看了下战舰版的例程,都是调用以下两行代码来执行数据接收处理的:
[mw_shl_code=applescript,true]lwip_periodic_handle();
lwip_pkt_handle();[/mw_shl_code]
以UDP为例,上面的函数调用最终会调用底层的回调函数:
[mw_shl_code=applescript,true]void udp_demo_recv(void *arg,struct udp_pcb *upcb,struct pbuf *p,struct ip_addr *addr,u16_t port)
{
u32 data_len = 0;
struct pbuf *q;
if(p!=NULL) //接收到不为空的数据时
{
memset(udp_demo_recvbuf,0,UDP_DEMO_RX_BUFSIZE); //数据接收缓冲区清零
for(q=p;q!=NULL;q=q->next) //遍历完整个pbuf链表
{
//判断要拷贝到UDP_DEMO_RX_BUFSIZE中的数据是否大于UDP_DEMO_RX_BUFSIZE的剩余空间,如果大于
//的话就只拷贝UDP_DEMO_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据
if(q->len > (UDP_DEMO_RX_BUFSIZE-data_len)) memcpy(udp_demo_recvbuf+data_len,q->payload,(UDP_DEMO_RX_BUFSIZE-data_len));//拷贝数据
else memcpy(udp_demo_recvbuf+data_len,q->payload,q->len);
data_len += q->len;
if(data_len > UDP_DEMO_RX_BUFSIZE) break; //超出TCP客户端接收数组,跳出
}
upcb->remote_ip=*addr; //记录远程主机的IP地址
upcb->remote_port=port; //记录远程主机的端口号
lwipdev.remoteip[0]=upcb->remote_ip.addr&0xff; //IADDR4
lwipdev.remoteip[1]=(upcb->remote_ip.addr>>8)&0xff; //IADDR3
lwipdev.remoteip[2]=(upcb->remote_ip.addr>>16)&0xff;//IADDR2
lwipdev.remoteip[3]=(upcb->remote_ip.addr>>24)&0xff;//IADDR1
udp_demo_flag|=1<<6; //标记接收到数据了
pbuf_free(p);//释放内存
}else
{
udp_disconnect(upcb);
LCD_Clear(WHITE); //清屏
POINT_COLOR = RED;
LCD_ShowString(30,30,200,16,16,"WarShip STM32");
LCD_ShowString(30,50,200,16,16,"UDP Test");
LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
POINT_COLOR=BLUE;
LCD_ShowString(30,90,200,16,16,"Connect break!");
LCD_ShowString(30,110,200,16,16,"KEY1:Connect");
udp_demo_flag &= ~(1<<5); //标记连接断开
}
} [/mw_shl_code]
由于LWIP采用pbuf链表形式存储接收数据,因此接收时是先分配pbuf,用完后立刻释放,这部分原子的代码都处理了,不应该有问题
更具体的内容请参照另一篇文章:http://www.openedv.com/forum.php ... d=106344&extra=
值得注意的是,LWIP的函数嵌套比较多,栈深度不太好估计,所以你任务开辟的堆栈一定要足够大
最后建议你在上面的回调函数里设断点,看函数返回之前会不会进入硬件错误
|
|