📄 104sl.c
字号:
/*------------------------------------------------------------------*/
/*模块名称:104SL.c */
/*模块功能:IEC870-5-104:2000从站 */
/*编写日期:2005年6月 */
/*编写者: dingding */
/*------------------------------------------------------------------*/
#include "includes.h"
#include "104Def.h"
#include "104SL.h"
#include "104SA.h"
extern struct LinkInfo* ComLink[PORTNUM];
extern struct AppInfo* ComApp[PORTNUM];
extern struct SysPort* ComDb[PORTNUM];
/*------------------------------------------------------------------*/
/*函数名称:S104InitLink() */
/*函数功能:链路层初始化 */
/*------------------------------------------------------------------*/
BOOL S104InitLink(INT8U Port, struct PortAppInfo* PortCfg)
{
INT8U i;
struct PSec104Pad *pPad;
i = Port - NET1;
pPad = (struct PSec104Pad*)(PortCfg->pPad);
memset (ComLink[i], 0, sizeof (struct LinkInfo));
if (pPad != NULL)
{
ComLink[i]->Tick0 = pPad->TickValue[0] * 10;
ComLink[i]->Tick1 = pPad->TickValue[1] * 10;
ComLink[i]->Tick2 = pPad->TickValue[2] * 10;
ComLink[i]->Tick3 = pPad->TickValue[3] * 10 + 10;
}
else //默认规约面板
{
ComLink[i]->Tick0 = T0 * 10;
ComLink[i]->Tick1 = T1 * 10;
ComLink[i]->Tick2 = T2 * 10;
ComLink[i]->Tick3 = T3 * 10 + 10;
}
return (TRUE);
}
/*------------------------------------------------------------------*/
/*函数名称:S104LinkOnTimer() */
/*函数功能:链路层定时器 */
/*------------------------------------------------------------------*/
void S104LinkOnTimer(INT8U Port)
{
INT8U i, j;
i = Port - NET1;
if (ComLink[i]->Tick.Flag & TICKT0USE)
{
ComLink[i]->Tick.TValue0++;
if (ComLink[i]->Tick.TValue0 > ComLink[i]->Tick0)
{
S104StopTick(Port, 0);
S104StopDT(Port);
}
}
if (ComLink[i]->Tick.Flag & TICKT1USE)
{
for (j=0; j<ComLink[i]->PeerNoAckNum; j++)
{
ComLink[i]->Tick.TValue1[j]++;
if (ComLink[i]->Tick.TValue1[j] > ComLink[i]->Tick1)
{
/* //ceshi
ErrorInfo(OSPrioCur, "Tick1帧确认错误");
*/
S104StopTick(Port, 1);
S104StopDT(Port);
}
}
}
if (ComLink[i]->Tick.Flag & TICKT2USE)
{
ComLink[i]->Tick.TValue2++;
if (ComLink[i]->Tick.TValue2 > ComLink[i]->Tick2)
{
S104StopTick(Port, 2);
S104SendCtrlFrame(Port, S_FRAME);
}
}
if (ComLink[i]->Tick.Flag & TICKT3USE)
{
ComLink[i]->Tick.TValue3++;
if (ComLink[i]->Tick.TValue3 > ComLink[i]->Tick3)
{
S104StopTick(Port, 3);
if (ComLink[i]->PeerNoAckNum)
{
S104SendCtrlFrame(Port, U_TESTFRACT);
}
else if (!(ComLink[i]->Tick.Flag & TICKT1USE))
{
S104BeginTick(Port, 1);
}
}
}
}
/*------------------------------------------------------------------*/
/*函数名称:S014SearchFrame() */
/*函数功能:寻找正确帧 */
/*------------------------------------------------------------------*/
void S104SearchFrame(INT8U Port)
{
BOOL stop = FALSE;
INT8U i, err;
struct PAPCI *pAPCI;
i = Port - NET1;
while ((ComLink[i]->RxdHead < ComLink[i]->RxdTail) && (!stop))
{
if (ComLink[i]->RxdStatus == RXDSTART)
{
if (ComLink[i]->RxdBuf[ComLink[i]->RxdHead] != STARTCODE)
{
ComLink[i]->RxdHead++;
continue;
}
//找到后,清除无用的缓冲区报文
if (ComLink[i]->RxdTail > ComLink[i]->RxdHead)
{
ComLink[i]->RxdLength = ComLink[i]->RxdTail - ComLink[i]->RxdHead;
memcpy (ComLink[i]->RxdBuf, &ComLink[i]->RxdBuf[ComLink[i]->RxdHead], ComLink[i]->RxdLength);
ComLink[i]->RxdHead = 0;
ComLink[i]->RxdTail = ComLink[i]->RxdLength;
}
ComLink[i]->RxdStatus = RXDHEAD;
}
if (ComLink[i]->RxdStatus == RXDHEAD)
{
pAPCI = (struct PAPCI*)ComLink[i]->RxdBuf;
if (ComLink[i]->RxdLength >= sizeof (struct PAPCI))
{
switch (pAPCI->NS & U_FRAME)
{
case S_FRAME:
S104StopTick(Port, 1);
S104BeginTick(Port, 3);
S104ProcSFrame(Port);
break;
case U_FRAME:
S104StopTick(Port, 1);
S104BeginTick(Port, 3);
S104ProcUFrame(Port);
break;
default:
if ((ComLink[i]->RxdLength >= (pAPCI->Length + 2)))
{
S104ProcIFrame(Port);
}
else
{
stop = TRUE;
}
break;
}
}
else
stop = TRUE;
if (!stop)
ComLink[i]->RxdStatus = RXDCONTINUE;
}
if (ComLink[i]->RxdStatus == RXDCONTINUE)
{
ComLink[i]->RxdLength = ComLink[i]->RxdTail - (pAPCI->Length + 2);
memcpy (ComLink[i]->RxdBuf, &ComLink[i]->RxdBuf[pAPCI->Length + 2], ComLink[i]->RxdLength);
ComLink[i]->RxdHead = 0;
ComLink[i]->RxdTail = ComLink[i]->RxdLength;
ComLink[i]->RxdStatus = RXDSTART;
if (ComLink[i]->RxdTail > ComLink[i]->RxdHead)
{
OSFlagPost(ComDb[i]->Event, NEXTFRAME, OS_FLAG_SET, &err);
stop = TRUE;
}
}
}
}
/*------------------------------------------------------------------*/
/*函数名称:S104ProcIFrame() */
/*函数功能:处理I格式帧数据 */
/*------------------------------------------------------------------*/
void S104ProcIFrame(INT8U Port)
{
INT8U i;
INT16U tmp;
struct AppMsg msg;
struct PAPCI *pAPCI;
i = Port - NET1;
pAPCI = (struct PAPCI*)ComLink[i]->RxdBuf;
if (!ComLink[i]->Connect)
return;
tmp = ComLink[i]->PeerNoAckNum;
if (!S104ProcPeerNoAckNum(Port, pAPCI->NR>>1))
{
S104StopDT(Port);
return;
}
if (ComLink[i]->NR == 32767)
ComLink[i]->NR = 0;
else
ComLink[i]->NR++;
S104StopTick(Port, 1);
S104BeginTick(Port, 2);
S104BeginTick(Port, 3);
msg.Cmd = DL_CALLDATA;
msg.ConNum = tmp - ComLink[i]->PeerNoAckNum;
msg.pData = &ComLink[i]->RxdBuf[6];
msg.Len = pAPCI->Length - 4;
S104AppProc(Port, &msg);
}
/*------------------------------------------------------------------*/
/*函数名称:S104ProcSFrame() */
/*函数功能:处理S格式帧数据 */
/*------------------------------------------------------------------*/
void S104ProcSFrame(INT8U Port)
{
INT8U i;
INT16U tmp;
struct PAPCI *pAPCI;
struct AppMsg msg;
i = Port - NET1;
pAPCI = (struct PAPCI*)ComLink[i]->RxdBuf;
if (!ComLink[i]->Connect)
return;
tmp = ComLink[i]->PeerNoAckNum;
if (!S104ProcPeerNoAckNum(Port, pAPCI->NR>>1))
{
S104StopDT(Port);
return;
}
msg.Cmd = DL_APPCON;
msg.ConNum = tmp - ComLink[i]->PeerNoAckNum;
msg.pData = NULL;
msg.Len = 0;
S104AppProc(Port, &msg);
}
/*------------------------------------------------------------------*/
/*函数名称:S104ProcUFrame() */
/*函数功能:处理U格式帧数据 */
/*------------------------------------------------------------------*/
void S104ProcUFrame(INT8U Port)
{
INT8U i;
struct PAPCI *pAPCI;
struct AppMsg msg;
i = Port - NET1;
pAPCI = (struct PAPCI*)ComLink[i]->RxdBuf;
switch (pAPCI->NS & 0xFF)
{
case U_STARTDTACT:
//是否初始化
ComLink[i]->Tick.Flag = ComLink[i]->Tick.FlagBak;
ComLink[i]->Connect = TRUE;
msg.Cmd = DL_WORK;
msg.ConNum = 0;
msg.pData = NULL;
msg.Len = 0;
S104AppProc(Port, &msg);
S104SendCtrlFrame(Port, U_STARTDTCON);
break;
case U_STARTDTCON:
break;
case U_STOPDTACT:
ComLink[i]->Tick.FlagBak = ComLink[i]->Tick.Flag;
ComLink[i]->Tick.Flag = 0;
S104SendCtrlFrame(Port, U_STOPDTCON);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -