⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 epa_csme.c

📁 AVR单片机基础上的以太网协议编程
💻 C
📖 第 1 页 / 共 2 页
字号:
   AnnListHead=tempnode->pNext;
}

/**************************************************************************
**
**    函数: void Send_NonPeriodDataAnnunciation(void)
**    描述: 该函数完成非周期数据声明的发送
**
**************************************************************************/   
void Send_NonPeriodDataAnnunciation(void)
{
    uchar i;
 
    S_Nda->NPMA_TAG=NonPeriodDataAnnunciation_ID;
    if(NonPeriodicListHead!=NULL)
    S_Nda->PRI=NonPeriodicListHead->pri;
    else
	S_Nda->PRI=0xff;
    for(i=0;i<44;i++)
	S_Nda->PAD[i]=' ';
 
    Send_UDP(Bro_MAC,Bro_IP,EPA_Port,EPA_Port,sizeof(struct NonPeriodDataAnnunciation)); //向UDP层传递
}  

/**************************************************************************
**
**    函数: void Send_PeriodData(void)
**    描述: 该函数完成周期报文的发送
**
**************************************************************************/
void Send_PeriodData(void)
{
    while(1)
    {
        if(PeriodicListHead!=NULL)
        {
            Send_Packet(PeriodicListHead->pkt,PeriodicListHead->lenth); //发送周期队列中的周期报文
            EpaPeriodicListDelHead();//删除周期队列首节点
        }
        else break;                  //周期队列中所有周期报文都已经发送结束
    }
	Send_NonPeriodDataAnnunciation();//发送非周期数据声明
}

/**************************************************************************
**
**    函数: void Send_EndofNonPeriodDataSending(void)
**    描述: 该函数完成非周期数据结束声明的发送
**
**************************************************************************/
void Send_EndofNonPeriodDataSending(void)
{
    uchar i; 
   
    S_End->ENPMTA_TAG=EndofNonPeriodDataSending_ID;
    if(NonPeriodicListHead!=NULL)
    S_End->PRI=NonPeriodicListHead->pri;
    else
	S_End->PRI=0xff;
    for(i=0;i<44;i++)
	S_End->PAD[i]=' ';
	
    Send_UDP(Bro_MAC,Bro_IP,EPA_Port,EPA_Port,sizeof(struct EndofNonPeriodDataSending)); //向UDP层传递
}

/**************************************************************************
**
**    函数: void Send_NonPeriodData(void)
**    描述: 该函数完成非周期报文的发送
**
**************************************************************************/ 
void Send_NonPeriodData(void)
{
    if((NonPeriodicListHead!=NULL)&&((AnnListHead==NULL)||((AnnListHead!=NULL)\
	   &&((NonPeriodicListHead->pri<AnnListHead->pri)||((NonPeriodicListHead->pri==AnnListHead->pri)\
	   &&(memcmp(My_IP,AnnListHead->u_ip,4)<0))))))                       //满足本地本周期报文发送条件
    {
        Send_Packet(NonPeriodicListHead->pkt,NonPeriodicListHead->lenth); //发送非周期队列中的非周期报文
        EpaNonPeriodicListDelHead();                  //删除非周期队列首节点
        Send_EndofNonPeriodDataSending();        //发送非周期数据结束声明报文
    }
}

/**************************************************************************
**
**    函数: void EPA_CSME(uchar *,uint)
**    描述: 该函数对接收到本地报文进行调度管理,入口参数为待发送报文长度,首地址确定为Send_Buf
**
**************************************************************************/
void EPA_CSME(uint len)
{
    uchar type;                 //以太网头的帧类型
    uchar id;                   //应用层服务标识
     
    if(Macro_Cycle_Ed==FALSE)   //通信宏周期尚未启动,直接发送
	Send_Packet(Send_Buf,len);
	else
	{
	type=ntohs(S_Ehe->Ether_Type);
    if(type==Ether_Type_ARP)    //本地要发送的报文是优先级为1的ARP报文(ARP请求或ARP应答)
    {
	    memcpy(NonPeriodic_Ring+NonPeriodic_ID*Max_Size,Send_Buf,len);
		EpaNonPeriodicListAddNode(NonPeriodic_Ring+NonPeriodic_ID*Max_Size,len,1); //插入非周期队列
        NonPeriodic_ID++;
        if(NonPeriodic_ID==Node_Number)//非周期报文缓冲环尾咬头
		NonPeriodic_ID=0;        
    }
    else if(type==Ether_Type_IP)//本地要发送的报文是优先级为4的Ping报文或声明报文或优先级与服务标识有关的UDP报文
    {
	    if(S_Pip->IP_Protocol==IP_ICMP)    //本地要发送的报文是优先级为4的Ping报文(Ping请求或Ping应答)
        {
		    memcpy(NonPeriodic_Ring+NonPeriodic_ID*Max_Size,Send_Buf,len);
			EpaNonPeriodicListAddNode(NonPeriodic_Ring+NonPeriodic_ID*Max_Size,len,4); //插入非周期队列
            NonPeriodic_ID++;
            if(NonPeriodic_ID==Node_Number)//非周期报文缓冲环尾咬头
			NonPeriodic_ID=0;            
		}
        else if(S_Pip->IP_Protocol==IP_UDP)//本地要发送的报文是声明报文或优先级与服务标识有关的UDP报文
        {
            if((S_Pdp->UDP_Data[0]==NonPeriodDataAnnunciation_ID)\
			   ||(S_Pdp->UDP_Data[0]==EndofNonPeriodDataSending_ID)) //本地要发送的报文是声明报文
            Send_Packet(Send_Buf,len);     //直接发送
            else
            {
                if((S_She->ServiceID&0x3f)==Distribute_ID)//本地要发送的报文是优先级为0的周期报文
                {
				    memcpy(Periodic_Ring+Periodic_ID*Max_Size,Send_Buf,len);
					EpaPeriodicListAddTail(Periodic_Ring+Periodic_ID*Max_Size,len);//插入周期队列
                    Periodic_ID++;
                    if(Periodic_ID==Node_Number) //周期报文缓冲环尾咬头
					Periodic_ID=0;                    
                }
                else                                      //本地要发送的报文是优先级与服务标识有关的非周期报文
                {
				    memcpy(NonPeriodic_Ring+NonPeriodic_ID*Max_Size,Send_Buf,len);
                    id=S_She->ServiceID&0x3f;
					if(id==EM_FindTagQuery_ID||id==EM_FindTagReply_ID||id==EM_GetDeviceAttribute_ID\
                       ||id==EM_DeviceAnnunciation_ID||id==EM_SetDeviceAttribute_ID\
					   ||id==EM_ClearDeviceAttribute_ID||id==DomainDownload_ID||id==DomainUpload_ID\
					   ||id==Read_ID||id==Write_ID)                                            //优先级为2
	                EpaNonPeriodicListAddNode(NonPeriodic_Ring+NonPeriodic_ID*Max_Size,len,2); //插入非周期队列
	                else if(id==EventNotification_ID||id==AcknowledgeEventNotification_ID\
					        ||id==AlterEventCondition_ID)                                      //优先级为1
                    EpaNonPeriodicListAddNode(NonPeriodic_Ring+NonPeriodic_ID*Max_Size,len,1); //插入非周期队列
					NonPeriodic_ID++;
                    if(NonPeriodic_ID==Node_Number)//非周期报文缓冲环尾咬头
					NonPeriodic_ID=0;
	            }
            }
        }
    }
	}
}

/**************************************************************************
**
**    函数: void Receive_Annunciation_Data(uchar)
**    描述: 该函数处理从其他EPA设备接收的声明报文,入口参数为声明报文的标识
**
**************************************************************************/
void Receive_Annunciation_Data(uchar id)
{
    if(Ready_Ed==TRUE && Macro_Cycle_Ed==FALSE && memcmp(R_Pip->IP_Sour_IP,Dest_IP,4)==0\
	   && id==NonPeriodDataAnnunciation_ID)
    //本地设备已组态,如果收到上位机的非周期数据声明报文并且通信宏周期未启动,则启动定时器1和3
    {
        Timer3_Init(MIB_Csm->Communication_Macro_Cycle);
        T1_Flag=T1_Period;
        Timer1_Init(MIB_Lo->Send_Time_Offset);
        Macro_Cycle_Ed=TRUE;
		if(R_Nda->PRI!=0xff)
        EpaAnnAddNode(R_Nda->PRI,R_Ehe->Ether_Sour_MAC,R_Pip->IP_Sour_IP);//上位机的非周期声明插入声明队列
    } 
	else if(Macro_Cycle_Ed==TRUE) //通信宏周期已经启动,则将接收到的声明报文插入声明队列
	{
	    if(id==NonPeriodDataAnnunciation_ID)     //收到的EPA报文是非周期数据声明报文
        {
            if(R_Nda->PRI!=0xff)
            EpaAnnAddNode(R_Nda->PRI,R_Ehe->Ether_Sour_MAC,R_Pip->IP_Sour_IP);//插入声明队列
        
        }
        else if(id==EndofNonPeriodDataSending_ID) //收到的EPA报文是非周期数据结束声明报文
        {
            EpaAnnListDelHead();  //删除声明队列首节点
            if(R_End->PRI != 0xff)
            EpaAnnAddNode(R_End->PRI,R_Ehe->Ether_Sour_MAC,R_Pip->IP_Sour_IP);//插入声明队列
            Send_NonPeriodData(); //发送非周期报文
        }
	}
}

/******************* End Of File **********************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -