📄 101priapp.c
字号:
/*------------------------------------------------------------------*/
/*模块名称:101priapp.c */
/*模块功能:DL/T 634-1997 101主站方规约应用层 */
/*编写日期:2005年4月 */
/*编写者: dingding */
/*------------------------------------------------------------------*/
#include "includes.h"
#include "101def.h"
#include "101prilink.h"
#include "101priapp.h"
extern struct DBConfig *DBCfgs;
extern struct LinkInfo* ComLink[PORTNUM];
extern struct AppInfo* ComApp[PORTNUM];
extern struct SysPort* ComDb[PORTNUM];
/*------------------------------------------------------------------*/
/*函数名称:P101_97SecTask() */
/*函数功能:101规约从站方任务 */
/*------------------------------------------------------------------*/
void P101_97PriTask(struct SysPort *Info, struct PortAppInfo* PortCfg)
{
BOOL flag;
INT8U i, err;
INT16U events;
i = Info->PortID - 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 = InitPriLink(i+1, PortCfg);
if (!flag)
{
free (ComLink[i]);
ComDb[i] = NULL;
return ;
}
flag = InitPriApp(i+1, PortCfg);
if (!flag)
{
free (ComApp[i]);
ComDb[i] = NULL;
return ;
}
//启动任务调度
ComApp[i]->AppCommand = APP_REQSTATUS;
OSFlagPost(ComDb[i]->Event, FTXNEXT, OS_FLAG_SET, &err);
//进入事项循环
while (1)
{
events = OSFlagPend(Info->Event, TIME100MS+FBOOP+FTXAVAIL+FTXNEXT,
OS_FLAG_WAIT_SET_ANY+OS_FLAG_CONSUME, 0, &err);
//处理遥控
if(events & FBOOP)
{
ComApp[i]->AppTaskFlag |= DBREQYK;
}
//定时处理区(100MS)
if(events & TIME100MS)
{
//链路层定时器
P101LinkOnTimer(Info->PortID);
//应用层定时器
P101AppOnTimer(Info->PortID);
//查询MISI接收缓冲区
P101RecMISIData(Info->PortID, TRUE);
}
//发送数据
if (events & FTXAVAIL)
{
P101SendDataToMISI(Info->PortID);
}
if (events & FTXNEXT) //继续处理
{
P101DLSendProc(Info->PortID);
}
}
}
/*------------------------------------------------------------------*/
/*函数名称:InitSecApp() */
/*函数功能:应用层初始化 */
/*------------------------------------------------------------------*/
BOOL InitPriApp(INT8U Port, struct PortAppInfo* PortCfg)
{
INT8U i, j;
struct PPri101Pad *pPad;
i = Port - 1;
pPad = (struct PPri101Pad*)(PortCfg->pPad);
if (pPad != NULL)
{
ComApp[i]->BaseControl = pPad->PBase.CmdControl;
ComApp[i]->Control = pPad->Control;
ComApp[i]->MaxErrCount = pPad->PBase.MaxErrCount;
ComApp[i]->AllData = pPad->PBase.Timer.AllData * 600;
ComApp[i]->SetClock = pPad->PBase.Timer.SetClock * 600;
ComApp[i]->Counter = pPad->PBase.Timer.Counter * 600;
}
else //默认参数
{
ComApp[i]->Control = 0x10;
ComApp[i]->BaseControl = 0x1F;
ComApp[i]->MaxErrCount = 3;
ComApp[i]->AllData = 30 * 600;
ComApp[i]->SetClock = 5 * 600;
ComApp[i]->Counter = 60 * 600;
}
ComApp[i]->DevNum = ComDb[i]->DevNum;
ComApp[i]->AppDevs = (struct PDevInfo*)malloc (ComDb[i]->DevNum * sizeof (struct PDevInfo));
if (ComApp[i]->AppDevs == NULL)
return (FALSE);
for (j=0; j<ComApp[i]->DevNum; j++)
{
ComApp[i]->AppDevs[j].DevID = ComDb[i]->DBCfgs[j].DevID;
ComApp[i]->AppDevs[j].TaskFlag = 0;
ComApp[i]->AppDevs[j].ErrorNum = 0;
ComApp[i]->AppDevs[j].Status = NOUSE;
ComApp[i]->AppDevs[j].CommStatus = FALSE;
}
//初始化
ComApp[i]->AllDataCount = 0;
ComApp[i]->ClockCount = 0;
ComApp[i]->CounterCount = 0;
ComApp[i]->AppTaskFlag = 0;
ComApp[i]->ActIndex = 0;
ComApp[i]->ActDevIndex = ComDb[i]->DBCfgs->DevID;
return TRUE;
}
/*------------------------------------------------------------------*/
/*函数名称:P101AppOnTimer() */
/*函数功能:应用层定时器 */
/*------------------------------------------------------------------*/
void P101AppOnTimer(INT8U Port)
{
INT8U i, j;
i = Port - 1;
//广播对钟
if (ComApp[i]->BaseControl & SETSECTIME)
{
ComApp[i]->ClockCount++;
if (ComApp[i]->ClockCount >= ComApp[i]->SetClock)
{
for (j=0; j<ComApp[i]->DevNum; j++)
{
if (ComApp[i]->AppDevs[j].Status != NOUSE)
{
ComApp[i]->AppTaskFlag |= TIMERCLOCK;
break;
}
}
ComApp[i]->ClockCount = 0;
}
}
//全数据
if (ComApp[i]->BaseControl & ALLDATAPROC)
{
ComApp[i]->AllDataCount++;
if (ComApp[i]->AllDataCount >= ComApp[i]->AllData)
{
for (j=0; j<ComApp[i]->DevNum; j++)
{
if (ComApp[i]->AppDevs[j].Status != NOUSE)
ComApp[i]->AppDevs[j].TaskFlag |= TIMERALLDATA;
}
ComApp[i]->AllDataCount = 0;
}
}
//电度
if (ComApp[i]->BaseControl & COUNTERPROC)
{
ComApp[i]->CounterCount++;
if (ComApp[i]->CounterCount >= ComApp[i]->Counter)
{
for (j=0; j<ComApp[i]->DevNum; j++)
{
if ((ComApp[i]->AppDevs[j].Status != NOUSE) &&
(ComDb[i]->DBCfgs[j].DDNum != 0))
ComApp[i]->AppDevs[j].TaskFlag |= TIMERCOUNTER;
}
ComApp[i]->CounterCount = 0;
}
}
}
/*------------------------------------------------------------------*/
/*函数名称:SecAppProc() */
/*函数功能:链路接口函数,处理链路层送来的命令和数据 */
/*输入说明:DLCmd--链路层命令;pBuf--应用层数据区指针;Len--pBuf长度*/
/*------------------------------------------------------------------*/
void PriAppProc(INT8U Port, INT16U DLCmd, INT8U* pBuf, INT16U Len)
{
INT8U i;
i = Port - 1;
ComApp[i]->RxMsg = (struct PASDU*)pBuf;
ComApp[i]->AppCommand = APP_NOJOB;
ComApp[i]->TxLen = 0;
//更新当前设备,防止答非所问
if (ComLink[i]->ActIndex != ComApp[i]->ActIndex)
{
ComApp[i]->ActIndex = ComLink[i]->ActIndex;
ComApp[i]->ActDevIndex = P101GetDevIndexByAddr(Port, ComApp[i]->ActDevIndex);
}
if (Len != 0) //数据处理
{
switch(ComApp[i]->RxMsg->Head.TypeID) //具体类型标识处理
{
case C_SC_NA: //单点遥控命令
case C_DC_NA: //双点遥控命令
case C_RC_NA: //升降命令
P101ProcControl(Port);
break;
case C_IC_NA: //总召唤或分组召唤确认或结束帧
if (ComApp[i]->RxMsg->Head.COT == ACTTERM)
ComApp[i]->AppDevs[ComApp[i]->ActIndex].Status = INUSE;
else
ComApp[i]->AppDevs[ComApp[i]->ActIndex].Status = USING;
break;
case C_CI_NA: //电度总召唤或分组召唤确认或结束帧
if (ComApp[i]->RxMsg->Head.COT == ACTTERM)
ComApp[i]->AppDevs[ComApp[i]->ActIndex].Status = INUSE;
else
ComApp[i]->AppDevs[ComApp[i]->ActIndex].Status = USING;
break;
case M_SP_NA: //处理遥信数据
P101ProcYX(Port, M_SP_NA);
break;
case M_PS_NA:
P101ProcYX(Port, M_PS_NA);
break;
case M_ME_NA: //处理遥测数据
P101ProcYC(Port, M_ME_NA);
break;
case M_ME_ND:
P101ProcYC(Port ,M_ME_ND);
break;
case M_SP_TA: //处理SOE
P101ProcSOE(Port);
break;
case M_IT_NA: //处理电度
P101ProcDD(Port);
break;
case C_SE_NA: //设定命令,只支持归一化,为了测试
P101ProcSetNVA(Port);
break;
case C_CD_NA: //延时获得命令
P101ProcTimeDelay(Port);
break;
case C_CS_NA: //对钟确认命令
P101ProcClock(Port);
break;
case C_RP_NA: //复位进程命令
P101ProcReset(Port);
break;
case C_RD_NA://读数据命令
P101ProcReadData(Port);
break;
case C_TS_NA: //测试命令
P101ProcTest(Port);
break;
case P_ME_NA: //装载参数命令,规一化值
case P_ME_NB: //装载参数命令,标度化值
case P_ME_NC: //装载参数命令,短浮点数
P101ProcParaSet(Port);
break;
default: //类型标识有错误或不支持
P101ProcAppErr(Port);
break;
}
}
//命令处理
if (DLCmd & DL_REC_ACD)
ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag |= DLDATA1;
switch (DLCmd & 0xFF)
{
case DL_SENDCON:
break;
case DL_LINKDISABLE:
ComApp[i]->AppDevs[ComApp[i]->ActIndex].Status = NOUSE;
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag & TIMERCLOCK)
{
ComApp[i]->AppTaskFlag &= (~TIMERCLOCK);
}
ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag = 0;
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].CommStatus)
ComApp[i]->AppDevs[ComApp[i]->ActIndex].ErrorNum++;
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].ErrorNum >= ComApp[i]->MaxErrCount)
{
ComApp[i]->AppDevs[ComApp[i]->ActIndex].ErrorNum = 0;
ComApp[i]->AppDevs[ComApp[i]->ActIndex].CommStatus = FALSE;
P101EnCodeCommStatus(Port, FALSE);
}
break;
case DL_LINKENABLE:
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].Status == NOUSE)
{
ComApp[i]->AppDevs[ComApp[i]->ActIndex].Status = INUSE;
ComApp[i]->AppDevs[ComApp[i]->ActIndex].CommStatus = TRUE;
P101EnCodeCommStatus(Port, TRUE);
}
ComApp[i]->AppTaskFlag |= TIMERCLOCK;
ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag |= TIMERCLOCK;
ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag |= TIMERALLDATA;
break;
case DL_NODATA:
ComApp[i]->AppDevs[ComApp[i]->ActIndex].Status = INUSE;
break;
}
//处理后续命令
if ((ComApp[i]->AppDevs[ComApp[i]->ActIndex].Status == INUSE) ||
(ComApp[i]->AppDevs[ComApp[i]->ActIndex].Status == NOUSE))
P101ProcNextCmd(Port);
}
/*------------------------------------------------------------------*/
/*函数名称:P101ProcNextCmd() */
/*函数功能:处理后续命令 */
/*------------------------------------------------------------------*/
void P101ProcNextCmd(INT8U Port)
{
INT8U i, j, err;
void *msg;
i = Port - 1;
//处理当前设备的命令
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag)
{
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag & DLDATA1)
{
ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag &= (~DLDATA1);
ComApp[i]->AppCommand = APP_CALLDATA1;
return ;
}
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag & TIMERALLDATA)
{
ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag &= (~TIMERALLDATA);
P101EnCodeAllData(Port);
return ;
}
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag & TIMERCOUNTER)
{
ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag &= (~TIMERCOUNTER);
P101EnCodeCounter(Port);
return ;
}
}
//处理遥控插帧命令
if (ComApp[i]->AppTaskFlag & DBREQYK)
{
msg = OSQPend(ComDb[i]->CommQ, 0, &err);
if (err == OS_NO_ERR)
{
ComApp[i]->ActDevIndex = ((struct DBBOOPInfo*)msg)->DevID;
for (j=0; j<ComApp[i]->DevNum; j++)
{
if (ComApp[i]->AppDevs[j].DevID == ComApp[i]->ActDevIndex)
{
ComApp[i]->ActIndex = j;
break;
}
}
P101EnCodeControl(Port, (struct DBBOOPInfo*)msg);
ComApp[i]->AppTaskFlag &= (~DBREQYK);
}
return ;
}
//对钟
if (ComApp[i]->AppTaskFlag & TIMERCLOCK)
{
ComApp[i]->AppTaskFlag &= (~TIMERCLOCK);
ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag &= (~TIMERCLOCK);
P101EnCodeClock(Port);
return ;
}
//跳转到下一台设备
ComApp[i]->ActIndex = (ComApp[i]->ActIndex + 1) % ComApp[i]->DevNum;
ComApp[i]->ActDevIndex = ComDb[i]->DBCfgs[ComApp[i]->ActIndex].DevID;
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].Status != NOUSE)
{
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag)
{
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag & DLDATA1)
{
ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag &= (~DLDATA1);
ComApp[i]->AppCommand = APP_CALLDATA1;
return ;
}
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag & TIMERALLDATA)
{
P101EnCodeAllData(Port);
return ;
}
if (ComApp[i]->AppDevs[ComApp[i]->ActIndex].TaskFlag & TIMERCOUNTER)
{
P101EnCodeCounter(Port);
return ;
}
}
else
{
ComApp[i]->AppCommand = APP_CALLDATA2;
}
}
else
{
ComApp[i]->AppCommand = APP_REQSTATUS;
}
}
/*------------------------------------------------------------------*/
/*函数名称:P101ProcControl() */
/*函数功能:处理控制命令 */
/*------------------------------------------------------------------*/
void P101ProcControl(INT8U Port)
{
INT8U i, dco;
struct BOCode code;
struct DBInfo info;
i = Port - 1;
memset (&code, 0, sizeof (struct BOCode));
switch (ComApp[i]->RxMsg->Head.TypeID)
{
case C_DC_NA: //遥控操作
info.SuperID = ComApp[i]->YKDevID;
info.DevID = ComApp[i]->ActDevIndex;
info.Type = BORESP;
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 & P101_REASON) == ACTCON)
code.Control &= (~BODEL);
else
code.Control |= BODEL;
if (ComApp[i]->RxMsg->Head.COT & P101_PN)
info.Num |= BOOPFAIL;
DBOperate((INT8U*)&code, &info);
if (code.Status != BORCOK)
{
ErrorInfo(OSPrioCur, "数据库操作失败");
}
break;
case C_RC_NA:
break;
case C_SE_NA:
break;
}
}
/*------------------------------------------------------------------*/
/*函数名称:P101ProcSetNVA() */
/*函数功能:设定命令 */
/*------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -