⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 104sa.c

📁 详细介绍了arm7-at91r40008,的开发全过程
💻 C
📖 第 1 页 / 共 4 页
字号:
/*------------------------------------------------------------------*/
/*模块名称: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 + -