OpenEdv-开源电子网

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

UDP遇到的问题?

[复制链接]

28

主题

91

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2132
金钱
2132
注册时间
2014-11-18
在线时间
215 小时
发表于 2015-1-5 23:25:57 | 显示全部楼层 |阅读模式
5金钱
[mw_shl_code=c,true] uip_len = tapdev_read(); //从网络设备读取一个IP包,返回数据长度 if(uip_len > 0) //收到数据 { /* 处理IP数据包(只有校验通过的IP包才会被接收) */ if(BUF->type == htons(UIP_ETHTYPE_IP)) //是IP包吗? { uip_arp_ipin(); //去除以太网头结构,更新ARP表 uip_input(); //IP包处理 /* 当上面的函数执行后,如果需要发送数据,则全局变量 uip_len > 0 需要发送的数据在uip_buf, 长度是uip_len (这是2个全局变量) */ if (uip_len > 0) //有带外回应数据 { uip_arp_out(); //加以太网头结构,在主动连接时可能要构造ARP请求 tapdev_send(); //发送数据到以太网(设备驱动程序) } } /* 处理arp报文 */ else if (BUF->type == htons(UIP_ETHTYPE_ARP)) //是ARP请求包 { uip_arp_arpin(); //如是是ARP回应,更新ARP表;如果是请求,构造回应数据包 /* 当上面的函数执行后,如果需要发送数据,则全局变量 uip_len > 0 需要发送的数据在uip_buf, 长度是uip_len (这是2个全局变量) */ if (uip_len > 0) //是ARP请求,要发送回应 { tapdev_send(); //发ARP回应到以太网上 } } } }[/mw_shl_code]
1 . uip_len = tapdev_read(); //从网络设备读取一个IP包,返回数据长度
     这里到底指的是从以太网读数据到stm32,还是指的是从程序里面给定数据读到ENC28j6上面?
     如果是把数据读到ENC28J60端口上面,然后在调用后面的?那么我从PC端发送的数据又是从哪里接收的?
2.  回调函数最终是在uip_input()里面被调用的吗?是不是也可以不要回调函数?
3.  如果仅仅用到UDP可以吗?
4.  若UDP配置成功后,是不是两者(电脑和板子)可以相互发数据,接数据?
    谢谢!
  (新手,莫怪!)


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

使用道具 举报

14

主题

97

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
204
金钱
204
注册时间
2014-12-16
在线时间
10 小时
发表于 2015-1-6 08:46:01 | 显示全部楼层
作为一个入门不到半个月的新手,近来做的实验中的一个功能也是UDP,我尝试回答一下,作为一次考试,让大神们评改
1.调用关系:
tapdev_read调用ENC28J60_Packet_Receive,ENC28J60_Packet_Receive又调用了ENC28J60_Read_op,enc28j60_Read_op调用了spi_Read.
由此判断,tapdev_read是控制enc28j60从以太网中读取数据到stm32中。你PC端发送的数据会经过uip_input(实际是uip_process)处理接收。
2.回调函数最终是在uip_process中调用,定义的宏是UIP_APPCALL()和UIP_UDP_APPCALL().如果不用回调函数,需直接在uip_process中处理,不方便。
3.所有的数据包,都会被接收,但是你可以只处理UDP,系统要维护arp列表,所以这些arp包默认处理。
4.udp配置后,可以接收数据,如果想主动发送数据的话,要自己构建包(我看了uip_process中有建包功能,但不知道怎样调用)
主动发包我用的是这个:
void make_udp_send(unsigned  int srcport, unsigned  int dstport, char* data, unsigned char datalen)
{
  unsigned char i = 0;
  unsigned  int ck;
 
//OS_EVENT *Mutex_TEST; // 定义互斥型事件
//static u8 buf[BUFFER_SIZE + 1];
//u8 buf[BUFFER_SIZE + 1];

  //u8 err;

//u8    udpbuf[100];
//u8    stateSend=0;
//u8    stateReceive=0;
//u8    stateStop=0;
   //make_eth(buf);
  //if((stateSend==0)||(stateStop==0))return;
   
   //if(stateSend==0)return;
//printf("in make_udp_send\r\n");
  while (i < 6)
  {
     sendbuf[ETH_DST_MAC + i] = mac_dstaddr;
     sendbuf[ETH_SRC_MAC + i] = mac_addr;
     i++;
  }
  i=0;
  


  if (datalen > 220)
  {
     datalen = 220;
  }
   // total length field in the IP header must be set:
  sendbuf[IP_TOTLEN_H_P] = 0;
  sendbuf[IP_TOTLEN_L_P] = IP_HEADER_LEN + UDP_HEADER_LEN + datalen;
   //make_dstip(buf);

  sendbuf[12] = 0x08;
  sendbuf[13] = 0x00;
  sendbuf[14] = 0x45;
  sendbuf[15] = 0x00;


  sendbuf[20] = 0x00;
  sendbuf[21] = 0x00;
  sendbuf[22] = 0x40;
  sendbuf[23] = 0x11;

  i = 0;
  while (i < 4)
  {
     sendbuf[IP_DST_P + i] = dstip;
     sendbuf[IP_SRC_P + i] = myip;
     i++;
  }
  i = 0;
  fill_ip_hdr_checksum(sendbuf);

  sendbuf[UDP_SRC_PORT_H_P] = srcport >> 8;
  sendbuf[UDP_SRC_PORT_L_P] = srcport & 0xff;
  sendbuf[UDP_DST_PORT_H_P] = dstport >> 8;
  sendbuf[UDP_DST_PORT_L_P] = dstport & 0xff;
   // source port does not matter and is what the sender used.
   // calculte the udp length:
  sendbuf[UDP_LEN_H_P] = 0;
  sendbuf[UDP_LEN_L_P] = UDP_HEADER_LEN + datalen;
   // zero the checksum
  sendbuf[UDP_CHECKSUM_H_P] = 0;
  sendbuf[UDP_CHECKSUM_L_P] = 0;
  // copy the data:

  while (i < datalen)
  {
     sendbuf[UDP_DATA_P + i] = data;
     i++;
  }
  ck = checksum(&sendbuf[IP_SRC_P], 16 + datalen, 1);
  sendbuf[UDP_CHECKSUM_H_P] = ck >> 8;
  sendbuf[UDP_CHECKSUM_L_P] = ck & 0xff;
  //OSMutexPend(Mutex_TEST, 0, &err);  // 等待信号量

  ENC28J60_Packet_Send(UDP_HEADER_LEN + IP_HEADER_LEN + ETH_HEADER_LEN + datalen,sendbuf);

  //OSMutexPost(Mutex_TEST);  // 释放信号量 
}
回复

使用道具 举报

28

主题

91

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2132
金钱
2132
注册时间
2014-11-18
在线时间
215 小时
 楼主| 发表于 2015-1-6 13:06:41 | 显示全部楼层
回复【2楼】prettywolf:
---------------------------------
 1.程序中,tapdev_read()读取数据,如果有的数据的话,返回值应该大于0(即len>0),那么则会进入if语句后,又有一个tapdev_send()函数;这个函数又好像是发送到以太网上面的?
 2.你说的都是从PC端发送到stm32板子上的,那如果要从板子给电脑发送呢,又是怎么一个过程?
回复

使用道具 举报

14

主题

97

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
204
金钱
204
注册时间
2014-12-16
在线时间
10 小时
发表于 2015-1-6 14:49:39 | 显示全部楼层
回复【3楼】freeelectron:
---------------------------------
是发送到以太网
4的那个函数就是说stm32板子发送数据到PC的。主动发就是这样。
如果是回调中收到PC发来的数据,立即发回去的,可以直接用uip_udp_send发送
void myudp_send(char *str,short n) 


   char   *nptr;   
   nptr = (char *)uip_appdata;       
   memcpy(nptr, str, n); 
   uip_udp_send(n); 
}
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-27 06:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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