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

📄 101priapp.c

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