📄 epa_csme.c
字号:
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 + -