📄 secapp.c
字号:
#include "includes.h"
#include "iec101def.h"
#include "iec101wh.h"
#include "secapp.h"
#include "secdlink.h"
extern struct DBConfig *DBCfgs;
extern struct LinkInfo* ComLink[PORTNUM];
extern struct AppInfo* ComApp[PORTNUM];
extern struct SysPort* ComDb[PORTNUM];
extern INT8U SwitchCounter, SwitchCounter2;
void P101_2002SecTask(struct SysPort *Info, struct PortAppInfo* PortCfg)
{
BOOL flag;
INT8U i, err;
INT16U events;
i = Info->PortID;
if (i > PORT2)
return ;
else
i -= 1;
//初始化
ComLink[i] = (void*) malloc (sizeof (struct LinkInfo));
ComApp[i] = (void*) malloc (sizeof (struct AppInfo));
if ((ComLink[i] == NULL) || (ComApp[i] == NULL))
return ;
else
{
memset (ComLink[i], 0, sizeof (struct LinkInfo));
memset (ComApp[i], 0, sizeof (struct AppInfo));
}
ComDb[i] = Info;
flag = Init101SecDLink(i+1, PortCfg);
if (!flag)
{
free (ComLink[i]);
ComDb[i] = NULL;
return ;
}
flag = InitSec101App(i+1, PortCfg);
if (!flag)
{
free (ComApp[i]);
ComDb[i] = NULL;
return ;
}
//整点存电度事项
flag=InitHisDataBuf(Info->PortID);
if (!flag)
{
free (ComApp[i]);
ComDb[i] = NULL;
return ;
}
//判断通讯模式
if(ComLink[i]->BalanMode)
OSFlagPost(ComDb[i]->Event, SCHEDULE, OS_FLAG_SET, &err);
//进入事项处理循环
for(;;)
{
events = OSFlagPend(Info->Event, TIME100MS+FBOOP+FCOS+FSOE+FTXAVAIL+FTXNEXT+SCHEDULE,
OS_FLAG_WAIT_SET_ANY+OS_FLAG_CONSUME, 0, &err);
if(events & NEXTFRAME)
{
S101_2002SearchFrame(Info->PortID);
}
if(events&FTXAVAIL)//发送数据
{
S101_2002SendDataToMISI(Info->PortID);
}
if(events&SENDOVER)//发送数据
{
if(ComApp[i]->BalanMode)
SendDataEnd(Info->PortID);
}
if (events & FBOOP)//YK消息处理(调用应用层服务)
{
SetUMsgFlag(Info->PortID);
if(ComLink[i]->BalanMode&&DLStatusCheck(Info->PortID))
CallUMsg(Info->PortID);
}
if(events&(FCOS|FSOE))//数据库事项处理(COS、SOE事项设置标志)
{
if(events&FCOS)
ComApp[i]->Data1.Flag|=HaveCOS;
if(events&FSOE)
ComApp[i]->Data1.Flag|=HaveSOE;
if(ComLink[i]->BalanMode&&DLStatusCheck(Info->PortID))
CallUData(Info->PortID);
}
//定时处理区(100MS)
if(events & TIME100MS)
{
ComApp[i]->TimerCounter++;
if(ComApp[i]->TimerCounter >= 10)
{
ComApp[i]->TimerCounter=0;
//链路层定时器
TimeOut(Info->PortID);
//应用层定时器
OnTimer(Info->PortID);
}
//规约切换
if (RReadx(Info->DBCfgs->Address, Info->PortID))
{
SwitchCounter++;
if (SwitchCounter >= 2)
{
SwitchCounter = 0;
SwitchCounter2 = 1;
}
}
if (SwitchCounter2)
{
if (SwitchCounter2++ > 10)
{
SwitchCounter2 = 0;
KillProg(RESET_DD, RESET_CLR, TRUE);
}
}
//查询MISI接收缓冲区
S101RecMISIData(Info->PortID, TRUE);
}
if (events & SCHEDULE)//启动链路过程
{
CallDLStatus(Info->PortID);
}
}
}
BOOL InitSec101App(INT8U Port, struct PortAppInfo* PortCfg)
{
// int i;
INT8U i, j;
INT16U num, tmp;
struct PSec101_2002Pad *pPad;
i = Port - 1;
pPad = (struct PSec101_2002Pad*)(PortCfg->pPad);
if (ComDb[i]->DBCfgs->Info.Logic.DevNum==0)
{
return FALSE;
}
for (j=0, num=0; j<ComDb[i]->DBCfgs->Info.Logic.DevNum; j++)
{
tmp = ComDb[i]->DBCfgs->Info.Logic.pOld[j].DevID;
num += DBCfgs[tmp].YCNum;
}
if (num)
{
ComApp[i]->YCValue = malloc (num * 2);
ComApp[i]->YCDVal = malloc (num * 2);
ComApp[i]->AIMaxVal = malloc (num * 2);
if ((ComApp[i]->YCDVal == NULL) || (ComApp[i]->YCValue == NULL))
return (FALSE);
}
for (j=0, num=0; j<ComDb[i]->DBCfgs->Info.Logic.DevNum; j++)
{
tmp = ComDb[i]->DBCfgs->Info.Logic.pOld[j].DevID;
num += DBCfgs[tmp].DDNum;
}
if (num)
{
ComApp[i]->CounterData = malloc (num * sizeof(struct Counter));
if (ComApp[i]->CounterData == NULL)
return (FALSE);
ComApp[i]->LastCounterData = malloc (num * 4);
if (ComApp[i]->LastCounterData == NULL)
return (FALSE);
}
if (pPad != NULL)
{
memcpy((void *)&ComApp[i]->Sec101Pad,PortCfg->pPad,sizeof(struct PSec101_2002Pad));
if (ComApp[i]->Sec101Pad.PBase.MaxALLen>ASDULEN)//应用层最大报文长度超限
ComApp[i]->Sec101Pad.PBase.MaxALLen=ASDULEN;
else if(ComApp[i]->Sec101Pad.PBase.MaxALLen<16)
ComApp[i]->Sec101Pad.PBase.MaxALLen=ASDULEN;
if ((ComApp[i]->Sec101Pad.PBase.Timer.ScanData2>3600))//二级数据扫描间隔
ComApp[i]->NvaInterval=SCANDATA2TIMER;
else
ComApp[i]->NvaInterval=ComApp[i]->Sec101Pad.PBase.Timer.ScanData2;
ComApp[i]->BackScanTime=ComApp[i]->Sec101Pad.BackScanTime*60;//分,背景数据扫描间隔
ComApp[i]->CycScanTime=ComApp[i]->Sec101Pad.CycScanTime;//秒,周期循环数据扫描间隔
if (ComApp[i]->Sec101Pad.PBase.ProtocolControl&BALANCE)
ComApp[i]->BalanMode=TRUE;
else
ComApp[i]->BalanMode=FALSE;
//历史电度
if(ComApp[i]->Sec101Pad.Control&USEHISTORYDD)
{
ComApp[i]->HisDDCycle=ComApp[i]->Sec101Pad.HistoryDDTime;
}
ComApp[i]->LinkAddrSize=ComApp[i]->Sec101Pad.LINKAddrSize;
ComApp[i]->CotSize=ComApp[i]->Sec101Pad.COTSize;
ComApp[i]->PubAddrSize=ComApp[i]->Sec101Pad.PUBAddrSize;
ComApp[i]->InfoAddrSize=ComApp[i]->Sec101Pad.INFOAddrSize;
if(ComApp[i]->LinkAddrSize!=1)
ComApp[i]->LinkAddrSize=2;//zzw
if(ComApp[i]->CotSize!=2)
ComApp[i]->CotSize=1;//zzw
if(ComApp[i]->PubAddrSize!=1)
ComApp[i]->PubAddrSize=2;//zzw
if(ComApp[i]->InfoAddrSize!=3)
ComApp[i]->InfoAddrSize=2;//zzw
if(ComApp[i]->Sec101Pad.TypeID[16]!=M_IT_TA)
ComApp[i]->Sec101Pad.TypeID[16]=M_IT_NA;
tmp = ComApp[i]->Sec101Pad.PBase.AIDeadValue;
}
else
{
ComApp[i]->Sec101Pad.PBase.CmdControl=0;
ComApp[i]->Sec101Pad.PBase.CmdControl|=YKPERMIT;
ComApp[i]->Sec101Pad.PBase.CmdControl|=SETSECTIME;
ComApp[i]->Sec101Pad.PBase.MaxALLen=ASDULEN;
ComApp[i]->Sec101Pad.PBase.AIDeadValue=3;
ComApp[i]->Sec101Pad.PBase.Timer.ScanData2=SCANDATA2TIMER;//3,二级数据扫描间隔
ComApp[i]->Sec101Pad.Control=0;
ComApp[i]->Sec101Pad.Control|=USESTANDARDCLOCKFORMAT; //0x10,使用标准时钟格式
ComApp[i]->Sec101Pad.Control|=USECP56TIME2A;
ComApp[i]->BackScanTime=20*60;//分,背景数据扫描间隔
ComApp[i]->CycScanTime=20;//秒,周期循环数据扫描间隔
ComApp[i]->HisDDCycle=TIMETOSAVEDATA;
ComApp[i]->BalanMode=FALSE;
for(j=0;j<8;j++)
ComApp[i]->Sec101Pad.TypeID[j]=M_PS_NA;//20;//具有状态变位检出的成组单点信息
for(j=8;j<12;j++)
ComApp[i]->Sec101Pad.TypeID[j]=M_ME_NB;//11;////测量值,标度化值
ComApp[i]->Sec101Pad.TypeID[12]=0;//该组为空
ComApp[i]->Sec101Pad.TypeID[13]=M_ME_NB;//11;//该组为参数
ComApp[i]->Sec101Pad.TypeID[14]=M_ST_NA;//5;//该组为步位置信息
for(j=0;j<16;j++)
ComApp[i]->Sec101Pad.GroupNum[j]=512;
ComApp[i]->Sec101Pad.TypeID[16]=M_IT_NA;
ComApp[i]->LinkAddrSize=2;
ComApp[i]->CotSize=1;
ComApp[i]->PubAddrSize=2;
ComApp[i]->InfoAddrSize=2;
tmp = 5;
}
S101_2002GetYcDeadValue(Port, tmp);
InitPara(Port);
return TRUE;
}
void InitPara(INT8U Port)
{
INT8U i, j;
struct DBInfo info;
i = Port - 1;
ComApp[i]->ActDevIndex = ComDb[i]->DBCfgs->Info.Logic.pOld[0].DevID;
ComApp[i]->NvaActDevNo=ComDb[i]->DBCfgs->Info.Logic.pOld[0].DevID;
for (j=0; j<ComDb[i]->DBCfgs->Info.Logic.DevNum; j++)
{
info.SuperID = ComDb[i]->DBCfgs->DevID;
info.DevID = ComApp[i]->ActDevIndex;
info.Type = SOEDATA;
if (DBCheck(&info))
ComApp[i]->Data1.Flag |= HaveSOE;
info.Type = COSDATA;
if (DBCheck(&info))
ComApp[i]->Data1.Flag |= HaveCOS;
if (!S101GetNextActDevIndex(Port, ComApp[i]->ActDevIndex, ACTDEVINDEX))
break;
}
ComApp[i]->Data1.Flag=0;
ComApp[i]->AllDataCount=0;
ComApp[i]->CounterCount=0;
ComApp[i]->WatchDogCount=0;
ComApp[i]->NvaActDevCur = 0;
ComApp[i]->Status=Polling;
ComApp[i]->LastStatus=Polling;
ComApp[i]->LastFrame=Polling;
ComApp[i]->BIFrame=0;
ComApp[i]->LastDevIndex=0xFFFF;
ComApp[i]->MasterStatus=NOUSE;
ComApp[i]->ScanData2Count=0;
ComApp[i]->EditAllDataCon=0;
ComApp[i]->SDTTime=0;
ComApp[i]->TrTime=0;
ComApp[i]->SendTime=0;
ComApp[i]->TimeDelay=0;
ComApp[i]->ResetFlag=0;
ComApp[i]->ResetCount=0;
ComApp[i]->Data2Flag=0;
ComApp[i]->BackScanCount=0;
ComApp[i]->CycScanCount=0;
ComApp[i]->FirstHisDDSaveCount=0xFF;
//ComApp[i]->HisDDSaveCount=0;
ComApp[i]->InitFlag=0xFF;
ComApp[i]->HaveWrongData=FALSE;
ComApp[i]->WrongDataLength=0;
ComApp[i]->TimerCounter=0;
ComApp[i]->CotLocation=2;//COT在ASDU中的位置
ComApp[i]->PubAddrLocation=ComApp[i]->CotLocation+ComApp[i]->CotSize;//PUBADDR在ASDU中的位置
ComApp[i]->InfoAddrLocation=ComApp[i]->PubAddrLocation+ComApp[i]->PubAddrSize;//INFOADDR在ASDU中的位置
ComApp[i]->AsduHeadLength=ComApp[i]->InfoAddrLocation+ComApp[i]->InfoAddrSize;//ASDU头的长度
if(ComApp[i]->PubAddrSize==1)
ComApp[i]->BroadCastAddr=0xff;
else
ComApp[i]->BroadCastAddr=0xffff;
}
void OnTimer(INT8U Port)
{
INT8U i;
struct AbsTime_t absTime;
i=Port-1;
if(ComApp[i]->BalanMode&&(ComApp[i]->MasterStatus==NOUSE))//平衡模式链路无效时不启动定时器
return;
if((!ComApp[i]->BalanMode)&&(ComApp[i]->InitFlag==0xFF))
return;
if(ComApp[i]->ResetFlag==0xff)//收到复位命令后设置标志,发出命令两秒钟后复位
{
ComApp[i]->ResetCount++;
if(ComApp[i]->ResetCount>=10)
{
ComApp[i]->ResetCount=0;
ComApp[i]->ResetFlag=0;
//热复位函数或标志
KillProg(RESET_RETAIN, RESET_DD, TRUE);
//SystemReset(COLDRESET);
}
}
//背景数据标志(全数据以BACK原因发送)
ComApp[i]->BackScanCount++;
if(ComApp[i]->BackScanCount>=ComApp[i]->BackScanTime)
{
if(ComApp[i]->Data1.Flag&CallAllData)//避免冲突
{
ComApp[i]->BackScanCount=0;
return;
}
ComApp[i]->BackScanCount=0;
ComApp[i]->Data2Flag|=BackData;
ComApp[i]->GroupTrn.COT=BACK;
ComApp[i]->GroupTrn.DevIndex=ComDb[i]->DBCfgs->Info.Logic.pOld[0].DevID;
ComApp[i]->AllDataNum = 0;
ComApp[i]->GroupTrn.GroupNo=1;//组号从1开始
ComApp[i]->GroupTrn.InfoAddr=LBI;//信息体地址从0x1开始
}
ComApp[i]->ScanData2Count++;
if((ComApp[i]->ScanData2Count)>=(ComApp[i]->NvaInterval))
{
ComApp[i]->ScanData2Count=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -