OpenEdv-开源电子网

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

F407开发板ETH_Rx_Packet()函数让我困惑了

[复制链接]

2

主题

4

帖子

0

精华

新手入门

积分
32
金钱
32
注册时间
2015-2-3
在线时间
0 小时
发表于 2015-2-3 20:43:16 | 显示全部楼层 |阅读模式
5金钱
先贴上原子407开发板  的 LAN8720.c 里的一个函数代码:(请注意加初涂红的部分)
//===========================================
//接收一个网卡数据包
//返回值:网络数据包帧结构体
FrameTypeDef ETH_Rx_Packet(void)

u32 framelength=0;
FrameTypeDef frame={0,0};   
//检查当前描述符,是否属于ETHERNET DMA(设置的时候)/CPU(复位的时候)
if((DMARxDescToGet->Status&ETH_DMARxDesc_OWN)!=(u32)RESET)
{
frame.length=ETH_ERROR; 
if ((ETH->DMASR&ETH_DMASR_RBUS)!=(u32)RESET)  

ETH->DMASR = ETH_DMASR_RBUS;//清除ETH DMA的RBUS位 
ETH->DMARPDR=0;//恢复DMA接收
}
return frame;//错误,OWN位被设置了
}  
if(((DMARxDescToGet->Status&ETH_DMARxDesc_ES)==(u32)RESET)&& 
((DMARxDescToGet->Status & ETH_DMARxDesc_LS)!=(u32)RESET)&&  
((DMARxDescToGet->Status & ETH_DMARxDesc_FS)!=(u32)RESET))  
{       
framelength=((DMARxDescToGet->Status&ETH_DMARxDesc_FL)>>ETH_DMARxDesc_FrameLengthShift)-4;//得到接收包帧长度(不包含4字节CRC)
  frame.buffer = DMARxDescToGet->Buffer1Addr;//得到包数据所在的位置
}else framelength=ETH_ERROR;//错误  
frame.length=framelength; 
frame.descriptor=DMARxDescToGet;  
//更新ETH DMA全局Rx描述符为下一个Rx描述符
//为下一次buffer读取设置下一个DMA Rx描述符
DMARxDescToGet=(ETH_DMADESCTypeDef*)(DMARxDescToGet->Buffer2NextDescAddr);   
return frame;  
}
//===========================================
让我困惑的是,得到帧长度为什么是Status 里取的,按照参考手册应该是从ControlBufferSize里取啊。

附上描述符结构体:
typedef struct  {
  __IO uint32_t   Status;                /*!< Status */
  uint32_t   ControlBufferSize;     /*!< Control and Buffer1, Buffer2 lengths */
  uint32_t   Buffer1Addr;           /*!< Buffer1 address pointer */
  uint32_t   Buffer2NextDescAddr;   /*!< Buffer2 or next descriptor address pointer */
/* Enhanced ETHERNET DMA PTP Descriptors */
#ifdef USE_ENHANCED_DMA_DESCRIPTORS
  uint32_t   ExtendedStatus;        /* Extended status for PTP receive descriptor */
  uint32_t   Reserved1;             /* Reserved */
  uint32_t   TimeStampLow;          /* Time Stamp Low value for transmit and receive */
  uint32_t   TimeStampHigh;         /* Time Stamp High value for transmit and receive */
#endif /* USE_ENHANCED_DMA_DESCRIPTORS */
} ETH_DMADESCTypeDef;
//====================================================
另外我查了ST官方的库函数,也是类似,请大侠们告诉我,为什么呀?
ST的:
/* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
      framelength = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4;

最佳答案

查看完整内容[请看2#楼]

可以结贴了,看书不仔细啊, DMA当接收到最后一帧后,将帧长写入status, 而ControlBufferSize是用户程序给DMA的,指的是用于保存接受数据的缓存大小。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

4

帖子

0

精华

新手入门

积分
32
金钱
32
注册时间
2015-2-3
在线时间
0 小时
 楼主| 发表于 2015-2-3 20:43:17 | 显示全部楼层
可以结贴了,看书不仔细啊,
DMA当接收到最后一帧后,将帧长写入status,
而ControlBufferSize是用户程序给DMA的,指的是用于保存接受数据的缓存大小。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-23 16:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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