📄 101secapp.c
字号:
/*------------------------------------------------------------------*/
/*模块名称:101-97sec.c */
/*模块功能:DL/T 634-1997 101从站方规约 */
/*编写日期:2005年3月 */
/*编写者: dingding */
/*------------------------------------------------------------------*/
#include "includes.h"
#include "101def.h"
#include "101seclink.h"
#include "101secapp.h"
extern struct DBConfig *DBCfgs;
extern struct LinkInfo* ComLink[PORTNUM];
extern struct AppInfo* ComApp[PORTNUM];
extern struct SysPort* ComDb[PORTNUM];
extern INT8U SwitchCounter, SwitchCounter2;
/*------------------------------------------------------------------*/
/*函数名称:P101_97SecTask() */
/*函数功能:101规约从站方任务 */
/*------------------------------------------------------------------*/
void P101_97SecTask(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 = InitSecLink(i+1, PortCfg);
if (!flag)
{
free (ComLink[i]);
ComDb[i] = NULL;
return ;
}
flag = InitSecApp(i+1, PortCfg);
if (!flag)
{
free (ComApp[i]);
ComDb[i] = NULL;
return ;
}
//进入事项循环
while (1)
{
events = OSFlagPend(Info->Event, TIME100MS+FBOOP+FCOS+FSOE+FTXAVAIL+FTXNEXT,
OS_FLAG_WAIT_SET_ANY+OS_FLAG_CONSUME, 0, &err);
//发送数据
if (events & FTXAVAIL)
{
SendDataToMISI(Info->PortID);
}
//处理遥控
if(events & FBOOP)
{
ComApp[i]->AppNextFlag |= FNextYK;
}
//处理变化遥信
if(events & FCOS)
{
ComApp[i]->Data1Flag |= HaveCOS;
}
//处理SOE
if(events & FSOE)
{
ComApp[i]->Data2Flag |= HaveSOE;
}
//续发数据
// if (events & FTXNEXT)
if (ComApp[i]->AppNextFlag)
{
SendNextData(Info->PortID);
if (ComApp[i]->AppNextFlag)
flag = FALSE;
else
{
flag = TRUE;
RecMISIData(Info->PortID, TRUE);
}
}
//定时处理区(100MS)
if(events & TIME100MS)
{
//链路层定时器
LinkOnTimer(Info->PortID);
//应用层定时器
AppOnTimer(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接收缓冲区
if (flag)
RecMISIData(Info->PortID, TRUE);
}
}
}
/*------------------------------------------------------------------*/
/*函数名称:InitSecApp() */
/*函数功能:应用层初始化 */
/*------------------------------------------------------------------*/
BOOL InitSecApp(INT8U Port, struct PortAppInfo* PortCfg)
{
INT8U i, j;
INT16U num, tmp;
struct PSec101Pad *pPad;
i = Port - 1;
pPad = (struct PSec101Pad*)(PortCfg->pPad);
for (j=0, num=0; j<ComDb[i]->DBCfgs->Info.Logic.DevNum; j++)
{
num += ComDb[i]->DBCfgs[j].YCNum;
}
if (num)
{
ComApp[i]->YCValue = malloc (num * 2);
ComApp[i]->YCDVal = 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++)
{
num += ComDb[i]->DBCfgs[j].DDNum;
}
if (num)
{
ComApp[i]->DDValue = malloc (num * 4);
if (ComApp[i]->DDValue == NULL)
return (FALSE);
}
if (pPad != NULL)
{
tmp = pPad->PBase.AIDeadValue;
ComApp[i]->ScanData2 = pPad->PBase.Timer.ScanData2 * 10;
ComApp[i]->BaseControl = pPad->PBase.CmdControl;
ComApp[i]->Control = pPad->Control;
ComApp[i]->PubAddrBase = pPad->PubAddrBase;
ComApp[i]->YXTypeID = pPad->Type.TSP;
if (!((ComApp[i]->YXTypeID == M_SP_NA) || (ComApp[i]->YXTypeID == M_PS_NA)))
ComApp[i]->YXTypeID = M_SP_NA;
ComApp[i]->YCTypeID = pPad->Type.TAI;
if (!((ComApp[i]->YCTypeID == M_ME_ND) || (ComApp[i]->YCTypeID == M_ME_NA)))
ComApp[i]->YCTypeID = M_ME_ND;
if (ComApp[i]->YCTypeID == M_ME_NA)
ComApp[i]->MaxYCNum = pPad->PBase.MaxALLen / 4 - 1;
else
ComApp[i]->MaxYCNum = pPad->PBase.MaxALLen / 5 - 1;
}
else //默认参数
{
tmp = 5;
ComApp[i]->ScanData2 = 30;
ComApp[i]->Control = 0x14;
ComApp[i]->BaseControl = 0x03;
ComApp[i]->MaxYCNum = 60;
ComApp[i]->YXTypeID = M_SP_NA;
ComApp[i]->YCTypeID = M_ME_ND;
}
GetYcDeadValue (Port, num, tmp);
InitReset(Port);
return TRUE;
}
/*------------------------------------------------------------------*/
/*函数名称:InitReset() */
/*函数功能:应用层数据初始化 */
/*------------------------------------------------------------------*/
void InitReset(INT8U Port)
{
INT8U i, j;
struct DBInfo info;
i = Port - 1;
ComApp[i]->ActDevIndex = ComDb[i]->DBCfgs[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]->Data2Flag |= HaveSOE;
info.Type = COSDATA;
if (DBCheck(&info))
ComApp[i]->Data1Flag |= HaveCOS;
if (!GetNextActDevIndex(Port, ComApp[i]->ActDevIndex, ACTDEVINDEX))
break;
}
ComApp[i]->Data2Count = 0;
ComApp[i]->AllDataFlag = FALSE;
ComApp[i]->AppNextFlag = FALSE;
ComApp[i]->ActDevIndex = ComDb[i]->DBCfgs[0].DevID;
ComApp[i]->NvaActDev = ComDb[i]->DBCfgs[0].DevID;
ComApp[i]->NvaActDevCur = 0;
ComApp[i]->LastDevIndex = 0xFFFF;
ComApp[i]->LastDevType = 0;
ComApp[i]->LastDevNum = 0;
}
/*------------------------------------------------------------------*/
/*函数名称:AppOnTimer() */
/*函数功能:应用层定时器 */
/*------------------------------------------------------------------*/
void AppOnTimer(INT8U Port)
{
INT8U i;
i = Port - 1;
//扫描二级数据
ComApp[i]->Data2Count++;
if (ComApp[i]->Data2Count > ComApp[i]->ScanData2)
{
ComApp[i]->Data2Count = 0;
if (CheckNVA(Port))
ComApp[i]->Data2Flag |= HaveNVA;
}
}
/*------------------------------------------------------------------*/
/*函数名称:SecAppProcNext() */
/*函数功能:链路接口函数,处理应用层需要后续的命令和数据 */
/*------------------------------------------------------------------*/
void SecAppProcNext(INT8U Port)
{
INT8U i, err;
void *msg;
i = Port - 1;
if (ComApp[i]->AppNextFlag & FNextYK)
{
msg = OSQPend(ComDb[i]->CommQ, 0, &err);
if (err == OS_NO_ERR)
{
EnCodeControl(Port, (struct DBBOOPInfo*)msg);
}
ComApp[i]->AppNextFlag &= (~FNextYK);
OSFlagPost(ComDb[i]->Event, FTXNEXT, OS_FLAG_SET, &err);
return ;
}
if (ComApp[i]->AppNextFlag & FNextALLDATA)
{
ProcAllDataCall(Port);
return ;
}
if (ComApp[i]->AppNextFlag & FNextCounter)
{
ProcCounterCall(Port);
return ;
}
}
/*------------------------------------------------------------------*/
/*函数名称:SecAppProc() */
/*函数功能:链路接口函数,处理链路层送来的命令和数据 */
/*输入说明:DLCmd--链路层命令;pBuf--应用层数据区指针;Len--pBuf长度*/
/*------------------------------------------------------------------*/
void SecAppProc(INT8U Port, INT16U DLCmd, INT8U* pBuf, INT16U Len)
{
INT8U i;
struct DBInfo info;
i = Port - 1;
ComApp[i]->RxMsg = (struct PASDU*)pBuf;
ComApp[i]->AppCommand = 0;
ComApp[i]->TxLen = 0;
if (ComApp[i]->LastDevIndex != 0xFFFF)
{
info.SuperID = ComDb[i]->DBCfgs->DevID;
info.DevID = ComApp[i]->LastDevIndex;
info.Type = ComApp[i]->LastDevType;
info.Num = ComApp[i]->LastDevNum;
if (DBClear(&info))
ComApp[i]->LastDevIndex = 0xFFFF;
if (DBCheck(&info))
{
if (ComApp[i]->LastDevType == SOEDATA)
ComApp[i]->Data2Flag |= HaveSOE;
if (ComApp[i]->LastDevType == COSDATA)
ComApp[i]->Data1Flag |= HaveCOS;
}
}
if (Len == 0) //命令处理
{
switch (DLCmd)
{
case DLREQDATA1:
ProcData1(Port);
break;
case DLREQDATA2:
ProcData2(Port);
break;
case DL_RESETDL:
InitReset(Port);
break;
default: //类型标识有错误或不支持
ProcAppErr(Port);
break;
}
}
else //数据处理
{
if ((ComApp[i]->RxMsg->Head.COT & P101_REASON) > 41 ) //传送原因未明
{
ProcAppErr(Port);
}
if (!GetActDevIndexByAddr(Port, ComApp[i]->RxMsg->Head.PubAddr)) //设备不存在
{
if ( ComApp[i]->RxMsg->Head.PubAddr != BROADCASTADDR) //也不是广播地址
ProcAppErr(Port);
}
switch(ComApp[i]->RxMsg->Head.TypeID) //具体类型标识处理
{
case C_SC_NA: //单点遥控命令
case C_DC_NA: //双点遥控命令
case C_RC_NA: //升降命令
ProcControl(Port);
break;
case C_SE_NA: //设定命令,只支持归一化,为了测试
ProcSetNVA(Port);
break;
case C_IC_NA: //总召唤或分组召唤
ProcAllDataCall(Port);
break;
case C_CI_NA: //电度总召唤或分组召唤
ProcCounterCall(Port);
break;
case C_CD_NA: //延时获得命令
ProcTimeDelay(Port);
break;
case C_CS_NA: //对钟命令
if (DLCmd == DL_SENDNOCON) //广播对钟
ProcClock(Port, FALSE);
else
ProcClock(Port, TRUE);
break;
case C_RP_NA: //复位进程命令
ProcReset(Port);
break;
case C_RD_NA://读数据命令
ProcReadData(Port);
break;
case C_TS_NA: //测试命令
ProcTest(Port);
break;
case P_ME_NA: //装载参数命令,规一化值
case P_ME_NB: //装载参数命令,标度化值
case P_ME_NC: //装载参数命令,短浮点数
ProcParaSet(Port);
break;
default: //类型标识有错误或不支持
ProcAppErr(Port);
break;
}
}
if ((ComApp[i]->RxMsg->Head.TypeID == C_IC_NA) || (ComApp[i]->RxMsg->Head.TypeID == C_CI_NA))
return ; //发完再插帧?
if (ComApp[i]->Data1Flag)
ComApp[i]->AppCommand |= APP_HAVEDATA1;
}
/*------------------------------------------------------------------*/
/*函数名称:ProcData1() */
/*函数功能:处理一级数据 */
/*------------------------------------------------------------------*/
void ProcData1(INT8U Port)
{
INT8U i;
i = Port - 1;
if (ComApp[i]->Data1Flag & HaveCOS)
{
EnCodeCOS(Port);
ComApp[i]->Data1Flag &= (~HaveCOS);
return ;
}
if (ComApp[i]->Data1Flag & CallReadData)
{
EnCodeReadData(Port);
ComApp[i]->Data1Flag &= (~CallReadData);
return ;
}
ComApp[i]->Data1Flag = 0;
ComApp[i]->AppCommand = APP_NODATA;
}
/*------------------------------------------------------------------*/
/*函数名称:ProcData2() */
/*函数功能:处理二级数据 */
/*------------------------------------------------------------------*/
void ProcData2(INT8U Port)
{
INT8U i;
i = Port - 1;
if (ComApp[i]->Data2Flag & HaveSOE)
{
EnCodeSOE(Port);
ComApp[i]->Data2Flag &= (~HaveSOE);
return ;
}
if (ComApp[i]->Data2Flag & HaveFA)
{
EnCodeFA(Port);
ComApp[i]->Data2Flag &= (~HaveFA);
return ;
}
if (ComApp[i]->Data2Flag & HaveNVA)
{
EnCodeNVA(Port);
ComApp[i]->Data2Flag &= (~HaveNVA);
return ;
}
ComApp[i]->AppCommand = APP_NODATA;
}
/*------------------------------------------------------------------*/
/*函数名称:ProcControl() */
/*函数功能:处理控制命令 */
/*------------------------------------------------------------------*/
void ProcControl(INT8U Port)
{
INT8U i, dco;
struct BOCode code;
struct DBInfo info;
struct DBBOOPInfo result;
i = Port - 1;
memset (&code, 0, sizeof (struct BOCode));
switch (ComApp[i]->RxMsg->Head.TypeID)
{
case C_DC_NA: //遥控操作
info.SuperID = ComDb[i]->DBCfgs->DevID;
info.DevID = ComApp[i]->ActDevIndex;
info.Type = BORESQ;
info.Start = ComApp[i]->RxMsg->Head.InfoAddr - LBO + 1;
dco = ComApp[i]->RxMsg->Data[0];
if (dco & DCO_SE)
info.Num = BOSELECT;
else
info.Num = BOOPERATE;
if ((dco & DCO_DCS) == 0x01)
code.Control |= BOOPEN;
else if ((dco & DCO_DCS) == 0x02)
code.Control |= BOCLOSE;
if (ComApp[i]->RxMsg->Head.COT == ACT)
code.Control &= (~BODEL);
else
code.Control |= BODEL;
code.Status = BORCNONSUPPORT;
if (ComApp[i]->BaseControl & YKPERMIT) //遥控允许
DBOperate((INT8U*)&code, &info);
if (code.Status != BORCOK)
{
result.SuperID = info.SuperID;
result.DevID = info.DevID;
result.ID = info.Start;
result.Status = code.Control;
if (dco & DCO_SE)
result.Flag = BOOPSELECT;
else
result.Flag = BOOPOPERATE;
if (ComApp[i]->RxMsg->Head.COT != ACT)
result.Flag |= BOOPDEL;
result.Flag |= BOOPERROR;
EnCodeControl(Port, &result);
}
break;
case C_RC_NA:
break;
case C_SE_NA:
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -