OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2680|回复: 1

关于原子哥ENC28J60网络通信模块接收数据代码的一点疑惑

[复制链接]

2

主题

2

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2015-9-3
在线时间
5 小时
发表于 2016-8-17 07:14:12 | 显示全部楼层 |阅读模式
本帖最后由 yangfengwu 于 2016-8-17 09:51 编辑

这几天做STM32的ENC28J60网络通信模块,自己在原子哥的代码上进行修改测试,,发现一个问题,电脑和板子进行通信的时候总隔一段时间板子就死机了.
使用自己的就不会死机,,不知道原因.....
直接源码
[mw_shl_code=applescript,true]struct netbuf *recvbuf;//接收buf
struct pbuf *q;   

err_t recv_err;//接收数据返回信息

u32 data_len = 0; //客户端接收数组的长度

u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE]; //TCP客户端接收数据缓冲区
memset(tcp_server_recvbuf,0,TCP_SERVER_RX_BUFSIZE);  //数据接收缓冲区清零
if((recv_err = netconn_recv(newconn,&recvbuf)) == ERR_OK) //接收到数据
{

for(q=recvbuf->p;q!=NULL;q=q->next)  //遍历完整个pbuf链表
            {
                //判断要拷贝到TCP_SERVER_RX_BUFSIZE中的数据是否大于TCP_SERVER_RX_BUFSIZE的剩余空间,如果大于
                //的话就只拷贝TCP_SERVER_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据
                if(q->len > (TCP_SERVER_RX_BUFSIZE-data_len))
                    memcpy(tcp_server_recvbuf+data_len,q->payload,(TCP_SERVER_RX_BUFSIZE-data_len));//拷贝数据
                else
                    memcpy(tcp_server_recvbuf+data_len,q->payload,q->len);
               
                data_len = data_len + q->len;  
               
                if(data_len > TCP_SERVER_RX_BUFSIZE) break; //超出TCP客户端接收数组,跳出   
            }
复制代码[/mw_shl_code]
自己修改后的,,其实还没优化好,,先这样吧!不影响下面的叙述
[mw_shl_code=applescript,true]struct netbuf *recvbuf;//接收buf
struct pbuf *q;   

err_t recv_err;//接收数据返回信息

u32 data_len = 0; //客户端接收数组的长度

u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE]; //TCP客户端接收数据缓冲区
memset(tcp_server_recvbuf,0,TCP_SERVER_RX_BUFSIZE);  //数据接收缓冲区清零
if((recv_err = netconn_recv(newconn,&recvbuf)) == ERR_OK) //接收到数据
{

for(q=recvbuf->p;q!=NULL;q=q->next)  //遍历完整个pbuf链表
            {
                if(q->tot_len > TCP_SERVER_RX_BUFSIZE)//接收的数据大于了接收数组
                {
                    printf("接收的数据大于了接收数组");
                }
                else
                {
                    memcpy(tcp_server_recvbuf+data_len,q->payload,q->len);
                    data_len = data_len + q->len;
                }
            }[/mw_shl_code]
首先介绍一下存数据的这个链表----如果不会链表,,,,那就百度一下吧!或者接着看看也行,,,,,改天我写个关于链表的博客,,,,,
[mw_shl_code=applescript,true]struct pbuf {
  /** next pbuf in singly linked pbuf chain */
  struct pbuf *next;指向下一个链表

  /** pointer to the actual data in the buffer */
  void *payload;指向下一个链表的数据区

  /**
   * total length of this buffer and all next buffers in chain
   * belonging to the same packet.
   *
   * For non-queue packet chains this is the invariant:
   * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
   */
  u16_t tot_len;当前pbuf的数据长度与后面所有的pbuf数据之和

  /** length of this buffer */
  u16_t len;//当前pbuf数据长度
  下面的就不说了,,和我们说的无关,,,,
  /** pbuf_type as u8_t instead of enum to save space */
  u8_t /*pbuf_type*/ type;

  /** misc flags */
  u8_t flags;

  /**
   * the reference count always equals the number of pointers
   * that refer to this pbuf. This can be pointers from an application,
   * the stack itself, or pbuf->next pointers from a chain.
   */
  u16_t ref;
};[/mw_shl_code]

假设数据来了,因为数据的个数不一定,而每一个链表存数据的个数都是有限的,所以呢就出现了上图,把数据分割依次存入几个链表中

我们要把数据存入

TCP_SERVER_RX_BUFSIZE  自己定义的1000u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE]; //TCP客户端接收数据缓冲区
这个数组

是不是应该

先看一眼这个,

[mw_shl_code=applescript,true]struct netbuf {
  struct pbuf *p, *ptr;[/mw_shl_code]

[mw_shl_code=applescript,true]struct netbuf *recvbuf;//接收buf
struct pbuf *q;//定义了一个q 也是用它指向下一个链表同next功能一样   

err_t recv_err;//接收数据返回信息

u32 data_len = 0; //客户端接收数组的长度

u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE]; //TCP客户端接收数据缓冲区
memset(tcp_server_recvbuf,0,TCP_SERVER_RX_BUFSIZE);  //数据接收缓冲区清零
if((recv_err = netconn_recv(newconn,&recvbuf)) == ERR_OK) //接收到数据,,现在recvbuf->p就是第一个链表的地址了
{

for(q=recvbuf->p;q!=NULL;q=q->next)  //遍历完整个pbuf链表       for(把第一个链表的地址给q, q是空的吗, 指向下一个链表)
            {
                 其实只需要判断第一个q->tot_len,它记录的是本链表的数据长度(len记录本链表的数据长度)加后面所有的数据长度,,也就是总数据长度
                if(q->tot_len > TCP_SERVER_RX_BUFSIZE)//接收的数据大于了接收数组
                {
                    printf("接收的数据大于了接收数组");
                }
                else
                {
                 memcpy(tcp_server_recvbuf+data_len,q->payload,q->len);memcpy(数组的首地址+每一个链表的数据长度累加和, 有效的数据首地址, 对应链表的数据长度)
                 data_len = data_len + q->len; //每一的链表的数据累加和,,
                }
            }[/mw_shl_code]

迷茫
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

0

帖子

0

精华

新手入门

积分
1
金钱
1
注册时间
2024-1-5
在线时间
0 小时
发表于 2016-8-24 12:54:19 | 显示全部楼层
我也遇到了这样的问题,只能正常通信50s左右
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 21:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表