📄 104sa.c
字号:
/*------------------------------------------------------------------*/
/*模块名称:104SA.c */
/*模块功能:IEC870-5-104:2000从站 */
/*编写日期:2005年6月 */
/*编写者: dingding */
/*------------------------------------------------------------------*/
#include "includes.h"
#include "104Def.h"
#include "104SL.h"
#include "104SA.h"
extern struct DBConfig *DBCfgs;
extern struct LinkInfo* ComLink[PORTNUM];
extern struct AppInfo* ComApp[PORTNUM];
extern struct SysPort* ComDb[PORTNUM];
extern INT8U SwitchCounter, SwitchCounter2;
/*------------------------------------------------------------------*/
/*函数名称:S104_2000Task() */
/*函数功能:104规约从站方任务 */
/*------------------------------------------------------------------*/
void S104_2000Task(struct SysPort *Info, struct PortAppInfo* PortCfg)
{
BOOL flag;
INT8U i, err;
INT16U events;
i = Info->PortID;
if (i == NET1)
i = 0;
else if (i == NET2)
i = 1;
else
return ;
//初始化
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 = S104InitLink(Info->PortID, PortCfg);
if (!flag)
{
free (ComLink[i]);
return ;
}
flag = S104InitApp(Info->PortID, PortCfg);
if (!flag)
{
free (ComApp[i]);
return ;
}
OSTimeDlyHMSM(0, 0, 5, 0);
flag = TRUE;
//进入事项循环
while (1)
{
events = OSFlagPend(Info->Event, TIME100MS+FBOOP+FCOS+FSOE+FTXAVAIL+FTXNEXT,
OS_FLAG_WAIT_SET_ANY+OS_FLAG_CONSUME, 0, &err);
if (!ComApp[i]->Connect)
{
S104NetTest(Info->PortID);
S104RecMISIData(Info->PortID, TRUE);
OSTimeDlyHMSM(0, 0, 0, 100);
continue;
}
//发送数据
if (events & FTXAVAIL)
{
S104SendDataToMISI(Info->PortID);
}
//处理遥控
if(events & FBOOP)
{
ComApp[i]->AppNextFlag |= FNextYK;
}
//处理变化遥信
if(events & FCOS)
{
ComApp[i]->AppNextFlag |= HaveCOS;
}
//处理SOE
if(events & FSOE)
{
ComApp[i]->AppNextFlag |= HaveSOE;
}
//续发数据
// if (events & FTXNEXT)
if (ComApp[i]->AppNextFlag)
{
S104AppProcNext(Info->PortID);
if (ComApp[i]->AppNextFlag)
flag = FALSE;
else
{
flag = TRUE;
S104RecMISIData(Info->PortID, TRUE);
}
}
//定时处理区(100MS)
if(events & TIME100MS)
{
//查询MISI接收缓冲区
if (flag)
S104RecMISIData(Info->PortID, TRUE);
//链路层定时器
S104LinkOnTimer(Info->PortID);
//应用层定时器
S104AppOnTimer(Info->PortID);
//网络判断
S104NetTest(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);
}
}
}
}
}
/*------------------------------------------------------------------*/
/*函数名称:S104InitApp() */
/*函数功能:应用层初始化 */
/*------------------------------------------------------------------*/
BOOL S104InitApp(INT8U Port, struct PortAppInfo* PortCfg)
{
INT8U i, j;
INT16U num, tmp;
struct PSec101Pad *pPad;
i = Port - NET1;
pPad = (struct PSec101Pad*)(PortCfg->pPad);
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]->DDValue = malloc (num * 4);
if (ComApp[i]->DDValue == 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].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);
}
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]->TAllData = pPad->PBase.Timer.AllData * 600;
ComApp[i]->TCounter = pPad->PBase.Timer.Counter * 600;
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_NB)))
ComApp[i]->YCTypeID = M_ME_NB;
}
else //默认参数
{
tmp = 5;
ComApp[i]->ScanData2 = 30;
ComApp[i]->Control = 0x14;
ComApp[i]->BaseControl = 0x03;
ComApp[i]->YXTypeID = M_SP_NA;
ComApp[i]->YCTypeID = M_ME_NB;
}
S104GetYcDeadValue (Port, num, tmp);
S104InitReset(Port);
return TRUE;
}
/*------------------------------------------------------------------*/
/*函数名称:S104InitReset() */
/*函数功能:应用层数据初始化 */
/*------------------------------------------------------------------*/
void S104InitReset(INT8U Port)
{
INT8U i, j;
struct DBInfo info;
i = Port - NET1;
ComApp[i]->CurSData = 0;
ComApp[i]->Data2Count = 0;
ComApp[i]->AllDataFlag = FALSE;
ComApp[i]->AppNextFlag = FALSE;
ComApp[i]->ActDevIndex = ComDb[i]->DBCfgs->Info.Logic.pOld[0].DevID;
ComApp[i]->NvaActDev = ComDb[i]->DBCfgs->Info.Logic.pOld[0].DevID;
ComApp[i]->NvaActDevCur = 0;
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]->AppNextFlag |= HaveSOE;
info.Type = COSDATA;
if (DBCheck(&info))
ComApp[i]->AppNextFlag |= HaveCOS;
if (!S104GetNextActDevIndex(Port, ComApp[i]->ActDevIndex, ACTDEVINDEX))
break;
}
//Link
ComLink[i]->Connect = FALSE;
ComLink[i]->NR = 0;
ComLink[i]->NS = 0;
ComLink[i]->PeerNoAckNum = 0;
ComLink[i]->RxFrmNum = 0;
ComLink[i]->IdleTimeCount = 0;
ComLink[i]->FrameHead = 0;
ComLink[i]->TxdHead = 0;
ComLink[i]->TxdTail = 0;
}
/*------------------------------------------------------------------*/
/*函数名称:S104AppOnTimer() */
/*函数功能:应用层定时器 */
/*------------------------------------------------------------------*/
void S104AppOnTimer(INT8U Port)
{
INT8U i, err;
i = Port - NET1;
//扫描二级数据
ComApp[i]->Data2Count++;
if (ComApp[i]->Data2Count > ComApp[i]->ScanData2)
{
ComApp[i]->Data2Count = 0;
if (S104CheckNVA(Port))
{
ComApp[i]->AppNextFlag |= HaveNVA;
}
}
if (ComApp[i]->AppNextFlag)
OSFlagPost(ComDb[i]->Event, FTXNEXT, OS_FLAG_SET, &err);
}
/*------------------------------------------------------------------*/
/*函数名称:S104AppProc() */
/*函数功能:应用层数据处理 */
/*------------------------------------------------------------------*/
void S104AppProc(INT8U Port, struct AppMsg* Msg)
{
INT8U i;
//ceshi
char errbuf[60];
struct SysTime_t SystemTime;
i = Port - NET1;
ComApp[i]->TxLen = 0;
ComApp[i]->RxMsg = (struct PASDU*)Msg->pData;
if (Msg->ConNum)
{
S104ProcDB(Port, Msg->ConNum);
}
if ((ComApp[i]->RxMsg->Head.COT & P101_REASON) > 41 ) //传送原因未明
{
S104ProcAppErr(Port);
}
if (!S104GetActDevIndexByAddr(Port, ComApp[i]->RxMsg->Head.PubAddr)) //设备不存在
{
S104ProcAppErr(Port);
}
switch (Msg->Cmd)
{
case DL_CALLDATA:
switch (ComApp[i]->RxMsg->Head.TypeID) //具体类型标识处理
{
case C_SC_NA: //单点遥控命令
case C_DC_NA: //双点遥控命令
case C_RC_NA: //升降命令
S104ProcControl(Port);
break;
case C_SE_NA: //设定命令,只支持归一化,为了测试
S104ProcSetNVA(Port);
break;
case C_IC_NA: //总召唤或分组召唤
S104ProcAllDataCall(Port);
break;
case C_CI_NA: //电度总召唤或分组召唤
S104ProcCounterCall(Port);
break;
case C_CD_NA: //延时获得命令
// S104ProcTimeDelay(Port);
break;
case C_CS_NA: //对钟命令
S104ProcClock(Port);
break;
case C_RP_NA: //复位进程命令
S104ProcReset(Port);
break;
case C_RD_NA://读数据命令
S104ProcReadData(Port);
break;
case C_TS_NA: //测试命令
S104ProcTest(Port);
break;
case P_ME_NA: //装载参数命令,规一化值
case P_ME_NB: //装载参数命令,标度化值
case P_ME_NC: //装载参数命令,短浮点数
S104ProcParaSet(Port);
break;
default: //类型标识有错误或不支持
break;
}
break;
case DL_APPCON:
break;
case DL_WORK:
ComApp[i]->Connect = TRUE;
//ceshi
GetTime((void *)&SystemTime, SYSTIME);
sprintf(errbuf, "%04d-%02d-%02d %02d:%02d:%02d:%03d 链路工作", SystemTime.Year, SystemTime.Month, SystemTime.Day, SystemTime.Hour,SystemTime.Minute, SystemTime.Second, SystemTime.MSecond);
ErrorInfo(OSPrioCur, errbuf);
break;
case DL_NOWORK:
S104InitReset(Port);
ComApp[i]->Connect = FALSE;
//ceshi
GetTime((void *)&SystemTime, SYSTIME);
sprintf(errbuf, "%04d-%02d-%02d %02d:%02d:%02d:%03d 链路中止", SystemTime.Year, SystemTime.Month, SystemTime.Day, SystemTime.Hour,SystemTime.Minute, SystemTime.Second, SystemTime.MSecond);
ErrorInfo(OSPrioCur, errbuf);
break;
default:
break;
}
if (ComApp[i]->TxLen)
S104DLSendProc(Port, (INT8U*)&ComApp[i]->TxMsg, ComApp[i]->TxLen);
}
/*------------------------------------------------------------------*/
/*函数名称:S104AppProcNext() */
/*函数功能:链路接口函数,处理应用层需要后续的命令和数据 */
/*------------------------------------------------------------------*/
void S104AppProcNext(INT8U Port)
{
INT8U i, err;
void *msg;
i = Port - NET1;
ComApp[i]->TxLen = 0;
if (ComApp[i]->AppNextFlag & FNextYK)
{
msg = OSQPend(ComDb[i]->CommQ, 0, &err);
if (err == OS_NO_ERR)
{
S104EnCodeControl(Port, (struct DBBOOPInfo*)msg);
}
ComApp[i]->AppNextFlag &= (~FNextYK);
OSFlagPost(ComDb[i]->Event, FTXNEXT, OS_FLAG_SET, &err);
}
else if (ComApp[i]->AppNextFlag & FNextALLDATA)
{
S104ProcAllDataCall(Port);
}
else if (ComApp[i]->AppNextFlag & FNextCounter)
{
S104ProcCounterCall(Port);
}
else if (ComApp[i]->AppNextFlag & HaveCOS)
{
S104EnCodeCOS(Port);
}
else if (ComApp[i]->AppNextFlag & HaveSOE)
{
S104EnCodeSOE(Port);
}
else if (ComApp[i]->AppNextFlag & HaveNVA)
{
S104EnCodeNVA(Port);
}
else
ComApp[i]->AppNextFlag = 0;
if (ComApp[i]->AppNextFlag)
OSFlagPost(ComDb[i]->Event, FTXNEXT, OS_FLAG_SET, &err);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -