关于以太网(Ethernet II)这个网络的个人理解以及应用(2)

来源:互联网 发布:sql union order by 编辑:程序博客网 时间:2024/05/01 13:36

惩戒上篇文章,这里说下实际的开发应用,
在stm32f107环境下实现如下功能:
- 以太网接口用作串口使用(区别于C/S模型);
- 以太网接口接收全部的网内数据;
- 对网内数据包过滤,仅接收本机相关数据包及广播包;

工具:

anysend.exe:Anysend是基于Winpcap驱动开发的,实现以太网接口发送任意自组数据包的工具,各位请自行查找下载;
wireshark.exe:网络抓包工具
如果你是一个嵌入式开发人员,
MDK:嵌入式集成开发环境;
开发板:板载stm32f107处理器+PHY的开发板;

简要说下以太网外设:

以太网外设框图:

这里写图片描述

使用SMI接口(MDC、MDIO)读写PHY寄存器,参见下图的指引:

这里写图片描述

DMA发送描述符(接收描述符–略):

这里写图片描述

相关寄存器的配置,主要关注MAC寄存器和DMA寄存器:

这里写图片描述

可能用到的MAC、DMA相关寄存器如下:

这里写图片描述

源码流程图如下:

这里写图片描述

部分源码:

接收数据处理程序:

/**  * @brief  Called when a frame is received  * @param  None  * @retval None  */void ETH_RxPkt_Handle(void){    u8 *buffer;    u16 len;  FrameTypeDef frame;    frame = ETH_RxPkt_ChainMode();    /* Obtain the size of the packet and put it into the "len"     variable. */  len = frame.length;    buffer= (u8*)frame.buffer;    memcpy(buff_rx,(u8*)&buffer[0], len);    /* Set Own bit of the Rx descriptor Status: gives the buffer back to ETHERNET DMA    设置Rx描述符Status的 OWN位*/  frame.descriptor->Status = ETH_DMARxDesc_OWN;    /* When Rx Buffer unavailable flag is set: clear it and resume reception     Rx缓冲区不可用时,清除ETH_DMASR_RBUS并且恢复接收*/  if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)    {    /* Clear RBUS ETHERNET DMA flag */    ETH->DMASR = ETH_DMASR_RBUS;    /* Resume DMA reception */    ETH->DMARPDR = 0;  }    //ETH_DMA_test();}

获取接收到的数据信息(DMA描述符)

/******************************************************************************** Function Name  : ETH_RxPkt_ChainMode* Description    : 获取接收到的数据信息(DMA描述符)* Input          : None* Output         : None* Return         : frame: farme size and location*******************************************************************************/FrameTypeDef ETH_RxPkt_ChainMode(void){  u32 framelength = 0;  FrameTypeDef frame = {0,0};   /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset)    检查这个描述符在被谁占用,DMA? CPU?*/  if((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) != (u32)RESET)  { //不等于0,表示DMA正在使用描述符对应的缓冲区, 0==CPU占有,1==DMA占有,      frame.length = ETH_ERROR;    if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)      {      /* Clear RBUS ETHERNET DMA flag */      ETH->DMASR = ETH_DMASR_RBUS;      /* Resume DMA reception */      ETH->DMARPDR = 0;    }    /* Return error: OWN bit set */    return frame;   }  if(((DMARxDescToGet->Status & ETH_DMARxDesc_ES) == (u32)RESET) && //无相关错误     ((DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (u32)RESET) &&  //这个描述符指向的缓冲区是帧的最后一个缓冲区     ((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (u32)RESET))  //这个描述符包含帧的第一个缓冲区  {          /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC         获取接收数据包的长度,需要减掉4字节的CRC*/    framelength = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4;    /* Get the addrees of the actual buffer */    frame.buffer = DMARxDescToGet->Buffer1Addr;   }  else  {    /* Return ERROR */    framelength = ETH_ERROR;  }  frame.length = framelength;  frame.descriptor = DMARxDescToGet;  /* Update the ETHERNET DMA global Rx descriptor with next Rx decriptor     更新DMA全局Rx描述符成为下一个Rx描述符*/        /* Chained Mode ==链表模式*/      /* Selects the next DMA Rx descriptor list for next buffer to read     选择下一个DMA Rx描述符链表为下一个缓冲区去读*/   DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);      /* Return Frame */  return (frame);  }

发送数据包的处理程序:

err_t ETH_TxPkt_Handle(u8* buff,u16 len){  int l = 0;  u8 *buffer =  (u8 *)ETH_GetCurrentTxBuffer();//获取当前的发送缓冲区地址  memcpy((u8*)&buffer[l], buff, len);  while(ETH_ERROR== ETH_TxPkt_ChainMode(len));  return 0;}

更新DMA发送描述符:

/******************************************************************************** Function Name  : ETH_TxPkt_ChainMode* Description    : Transmits a packet, from application buffer, pointed by ppkt.* Input          : - FrameLength: Tx Packet size.* Output         : None* Return         : ETH_ERROR: in case of Tx desc owned by DMA*                  ETH_SUCCESS: for correct transmission*******************************************************************************/u32 ETH_TxPkt_ChainMode(u16 FrameLength){  /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */  if((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (u32)RESET)  {  //被DMA占用    /* Return ERROR: OWN bit set */    return ETH_ERROR;  }  /* Setting the Frame Length: bits[12:0]     设置帧长*/  DMATxDescToSet->ControlBufferSize = (FrameLength & ETH_DMATxDesc_TBS1);  /* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */      DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS;  /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */  DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;  /* When Tx Buffer unavailable flag is set: clear it and resume transmission */  if ((ETH->DMASR & ETH_DMASR_TBUS) != (u32)RESET)  {    /* Clear TBUS ETHERNET DMA flag */    ETH->DMASR = ETH_DMASR_TBUS;    /* Resume DMA transmission*/    ETH->DMATPDR = 0;  }  /* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */    /* Chained Mode */  /* Selects the next DMA Tx descriptor list for next buffer to send */   DMATxDescToSet = (ETH_DMADESCTypeDef*) (DMATxDescToSet->Buffer2NextDescAddr);      /* Return SUCCESS */  return ETH_SUCCESS;   }

应用:

以太网接口用作串口使用(区别于C/S模型):

在MAC帧过滤寄存器上做文章:

ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Enable;//

关于发送数据环节,只能发送Ethernet II协议侦,不能发送IEEE802.3帧,问题查找中;

以太网接口接收全部的网内数据:

同上…

对网内数据包过滤,仅接收本机相关数据包及广播包;

ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;//关闭接收所有的帧,来实现过滤掉 非本机为目的地址的数据  ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;//允许接收所有广播帧  ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;  //关闭混合模式的地址过滤    ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;//对于组播地址使用完美地址过滤     ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;//对单播地址使用完美地址过滤 

源码参考:

对网内数据包过滤,仅接收本机相关数据包及广播包”应用源码见网盘:
链接: http://pan.baidu.com/s/1qXFVzze 密码: gkka

这块说的比较笼统,毕竟以太网很庞大,本人理解有限,想说出来更加费劲,,,,大伙有情况再一块儿分析,,,,

0 0
原创粉丝点击