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

📄 dnpsec.c

📁 详细介绍了arm7-at91r40008,的开发全过程
💻 C
📖 第 1 页 / 共 4 页
字号:

#include    "includes.h"



//OS_FLAG_GRP *DnpFlag;
OS_FLAGS value;
extern struct DBConfig		*DBCfgs;
extern struct SysPort 	*pp1;
extern struct SysPort 	*pp2;


UCHAR  cur_frame[PORTNUM];			/*发送帧队列当前帧和帧总数,考虑长包发送*/
UCHAR  max_frame[PORTNUM];     		
UCHAR  mFCB[PORTNUM];	    		/*避免副方接收重复帧(链路层)*/
UCHAR  sFCB[PORTNUM];
BOOL   DL_reset[PORTNUM];			/*本机复位标志*/
UCHAR  THcount[PORTNUM];
UCHAR  Sequence[PORTNUM];			/*应用层段号*/
USHORT m_wIIN[PORTNUM];
//USHORT iinMask[PORTNUM];				/*IIN屏蔽字*/
UCHAR  bsending[PORTNUM];			/*正传送的数据类型, 用于应用层确认*/


struct DnpPadPara* DnpSecPadPara[PORTNUM];

struct DBInfo	DnpSoeinfo[PORTNUM],DnpCosinfo[PORTNUM];

stIFrame *DnpCom1,*DnpCom2;
stIFrame *dliCom1[9],*dliCom2[9];
stOFrame *dloCom1[9],*dloCom2[9];
stOFrame *ploCom1,*ploCom2;
stIPacket *aliCom1,*aliCom2;
stOPacket *aloCom1,*aloCom2;
SoeReadPoint *SoeReadCom1,*SoeReadCom2;
VarYcValue	*VarYcValueStruct[PORTNUM];

INT16U *YCDValue[PORTNUM];
BOOL	ValueFlag[PORTNUM];

INT8U	*YC_Value[PORTNUM];
INT8U   *YX_Value[PORTNUM];
extern INT8U	SwitchCounter, SwitchCounter2;

BOOL	TimeFlag = FALSE;			//非广播对钟

BOOL InitDnpSecLink(INT8U Port, struct PortAppInfo* PortCfg)
{
	INT8U	i;
	INT16U	tmp;
	struct PSecDnpPad *pPad;
	
	i = Port - 1;



	pPad = (struct PSecDnpPad*)(PortCfg->pPad);
	if (pPad != NULL)
	{
		tmp = pPad->PBase.CmdControl;
		if(tmp&DnpSecEnableYk)
			DnpSecPadPara[i]->EnYk = TRUE;
		else
			DnpSecPadPara[i]->EnYk = FALSE;
			
		if(tmp&DnpSecEnableClock)
			DnpSecPadPara[i]->EnClock = TRUE;
		else
			DnpSecPadPara[i]->EnClock = FALSE;
			
		if(tmp&DnpSecEnableAllData)
			DnpSecPadPara[i]->EnAllData = TRUE;
		else
			DnpSecPadPara[i]->EnAllData = FALSE;
			
		if(tmp&DnpSecEnableDD)
			DnpSecPadPara[i]->EnDD = TRUE;
		else
			DnpSecPadPara[i]->EnDD = FALSE;
			
		DnpSecPadPara[i]->AIDeadValue = pPad->PBase.AIDeadValue;
		DnpSecPadPara[i]->AllData = pPad->PBase.Timer.AllData;
		DnpSecPadPara[i]->DdTime = pPad->PBase.Timer.Counter;
		DnpSecPadPara[i]->DlDelay = pPad->PBase.Timer.CtrlTimeOut;
		DnpSecPadPara[i]->ScanData2 = pPad->PBase.Timer.ScanData2;
		DnpSecPadPara[i]->AlDelay = pPad->PBase.Timer.TimeoutValue1;
		DnpSecPadPara[i]->Class1Data = pPad->Class1Data;
		DnpSecPadPara[i]->Class2Data = pPad->Class2Data;
		DnpSecPadPara[i]->Class3Data = pPad->Class3Data;
	}
	else
	{
		DnpSecPadPara[i]->EnYk = DnpYkEn;
		DnpSecPadPara[i]->EnClock = DnpClockEn;
		DnpSecPadPara[i]->EnAllData = DnpAllDataEn;
		DnpSecPadPara[i]->EnDD = DnpDdEn;
		DnpSecPadPara[i]->AIDeadValue = DnpAIDeadValue;
		DnpSecPadPara[i]->AllData = DnpAllData;
		DnpSecPadPara[i]->DdTime = DnpDdTime;
		DnpSecPadPara[i]->DlDelay = DnpDlDelay;
		DnpSecPadPara[i]->ScanData2 = DnpScanData2;
		DnpSecPadPara[i]->AlDelay = DnpAlDelay;
		DnpSecPadPara[i]->Class1Data = DnpClass1Data;
		DnpSecPadPara[i]->Class2Data = DnpClass2Data;
		DnpSecPadPara[i]->Class3Data = DnpClass3Data;
	}
	
	return TRUE;
}
void DnpSecTask(struct SysPort *info, struct PortAppInfo* PortCfg)
{
	INT8U	 i,err, tick;
	INT16U	events,j;
	BOOL	flag;
	void	*msg;
	struct DBInfo	Rinfo,YCDinfo;
	INT16U *YCFullValue[PORTNUM];
	
	tick = 0;
	
	if(info->PortID == PORT1)
	{
		pp1 = info;
		DnpCom1	= malloc(sizeof(stIFrame));
		dliCom1[0] = malloc(sizeof(stIFrame)*9);
		dloCom1[0] = malloc(sizeof(stOFrame)*9);
		ploCom1 = malloc(sizeof(stOFrame));
		aliCom1 = malloc(sizeof(stIFrame));
		aloCom1 = malloc(sizeof(stIFrame));
		SoeReadCom1 = malloc(sizeof(stIFrame));
		
		Rinfo.Num = pp1->DBCfgs->YCNum;						//用于变化遥测
		VarYcValueStruct[0] = (VarYcValue*)malloc(sizeof(VarYcValue)*Rinfo.Num);
		memset((char*)VarYcValueStruct[0],0,sizeof(VarYcValue)*Rinfo.Num);
		
		YCFullValue[0] = malloc(Rinfo.Num*sizeof(INT16U));
		memset((INT8U*)YCFullValue[0],0,sizeof(INT16U)*Rinfo.Num);
		
		YCDValue[0] = malloc(Rinfo.Num*sizeof(INT16U));
		memset((INT8U*)YCDValue[0],0,sizeof(INT16U)*Rinfo.Num);

		
		YCDinfo.Type = YCFULLVAULE;
		YCDinfo.Start = 0;	
		YCDinfo.SuperID = pp1->DBCfgs->DevID;
		YCDinfo.DevID = pp1->DBCfgs->DevID;
		YCDinfo.Num = pp1->DBCfgs->YCNum;
		
		YC_Value[0] = malloc(sizeof(INT16U)*YCDinfo.Num);
		memset((INT8U*)YC_Value[0],0,sizeof(INT16U)*YCDinfo.Num);
		
		YX_Value[0] = malloc(pp1->DBCfgs->YXNum);
		memset((INT8U*)YX_Value[0],0,pp1->DBCfgs->YXNum);
		
		DBRead((INT8U*)YCFullValue[0], &YCDinfo);
	}
	
	else if(info->PortID == PORT2)
	{
		pp2 = info;
		DnpCom2	= malloc(sizeof(stIFrame));
		dliCom2[0] = malloc(sizeof(stIFrame)*9);
		dloCom2[0] = malloc(sizeof(stOFrame)*9);
		ploCom2 = malloc(sizeof(stOFrame));
		aliCom2 = malloc(sizeof(stIFrame));
		aloCom2 = malloc(sizeof(stIFrame));
		SoeReadCom2 = malloc(sizeof(stIFrame));
		
		Rinfo.Num = pp2->DBCfgs->YCNum;						//用于变化遥测
		VarYcValueStruct[1] = (VarYcValue*)malloc(sizeof(VarYcValue)*Rinfo.Num);
		memset((char*)VarYcValueStruct[1],0,sizeof(VarYcValue)*Rinfo.Num);
		
		YCFullValue[1] = malloc(Rinfo.Num*sizeof(INT16U));
		memset((INT8U*)YCFullValue[1],0,sizeof(INT16U)*Rinfo.Num);
		
		YCDValue[1] = malloc(Rinfo.Num*sizeof(INT16U));
		memset((INT8U*)YCDValue[1],0,sizeof(INT16U)*Rinfo.Num);
				
		YCDinfo.Type = YCFULLVAULE;
		YCDinfo.Start = 0;	
		YCDinfo.SuperID = pp2->DBCfgs->DevID;
		YCDinfo.DevID = pp2->DBCfgs->DevID;
		YCDinfo.Num = pp2->DBCfgs->YCNum;
		
		YC_Value[1] = malloc(sizeof(INT16U)*YCDinfo.Num);
		memset((INT8U*)YC_Value[1],0,sizeof(INT16U)*YCDinfo.Num);
		
		YX_Value[1] = malloc(pp2->DBCfgs->YXNum);
		memset((INT8U*)YX_Value[1],0,pp2->DBCfgs->YXNum);
		
		DBRead((INT8U*)YCFullValue[1], &YCDinfo);
	}

	i = info->PortID;
	if (i > PORT2)
		return ;
	else
		i -= 1;
		
	DnpSecPadPara[i] = (void*) malloc (sizeof (struct DnpPadPara));		
	
	if(DnpSecPadPara[i] == NULL)
		return ;
		
	flag = InitDnpSecLink(i+1, PortCfg);

	if(info->PortID == PORT1)
	{
		for(j=0;j<Rinfo.Num;j++)
		{
			*(YCDValue[0]+j) = *(YCFullValue[0]+j)*DnpSecPadPara[0]->AIDeadValue/1000;
		}
		free (YCFullValue[0]);
	}
	else if(info->PortID == PORT2)
	{
		for(j=0;j<Rinfo.Num;j++)
		{
			*(YCDValue[1]+j) = *(YCFullValue[1]+j)*DnpSecPadPara[1]->AIDeadValue/1000;
		}
		free (YCFullValue[1]);
	}
	
	
	for(j = 0;j < PORTNUM; j++)
	{
		cur_frame[j] = 0;			/*发送帧队列当前帧和帧总数,考虑长包发送*/
		max_frame[j] = 0;     		
		mFCB[j] = 0;	    		/*避免副方接收重复帧(链路层)*/
		sFCB[j] = 0;
		DL_reset[j] = 0;			/*本机复位标志*/
		THcount[j] = 0;
		Sequence[j] = 0;			/*应用层段号*/
		m_wIIN[j] = 0;
		bsending[j] = 0;			/*正传送的数据类型, 用于应用层确认*/
	}


	while(1)
	{
		events = OSFlagPend(info->Event,RxdFrame+Dnp_Al_Ready+Dnp_Dl_Ready+FBOOP+FCOS+FSOE,OS_FLAG_WAIT_SET_ANY+OS_FLAG_CONSUME,0,&err);
		if(events&FBOOP)
		{
			msg = OSQPend(info->CommQ, 0, &err);
			if (err == OS_NO_ERR)
			{
				//AppSend(m_wIIN[i], AL_OG_YK, 22, (INT8U)info->PortID);
				YkRespond(info, (struct DBBOOPInfo*)msg, (INT8U)info->PortID);
			}
		}
		if(events&FSOE)
		{
			m_wIIN[i] |= AL_IIN_CLASS2;
		}
		if(events&FCOS)
		{
			m_wIIN[i] |= AL_IIN_CLASS1;
		}

		if(events&RxdFrame)
		{
			//规约切换
			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);
				}
			}
				
			DnpOnRx((INT8U)info->PortID);
		
			tick++;
			if (tick >= 10)
			{
				tick = 0;
				OnTick1s((INT8U)info->PortID);
			}
		}	
		if(events&Dnp_Al_Ready)
		{
			Send((INT8U)info->PortID);
		}
		if(events&Dnp_Dl_Ready)
		{
			ComFrame(info->PortID);
			OnApp((INT8U)info->PortID);
		}
		
	}
}
/*------------------------------------------------------------------------
 Procedure:     DnpOnRx()
 Purpose:       处理物理层准备好的数据,
 Input:
 Output:
 Errors:
------------------------------------------------------------------------*/
int DnpOnRx(INT8U port)
{
	stIFrame *p=NULL;
	stIFrame *dli = NULL;
	stOFrame *dlo = NULL;
	stOFrame *plo = NULL;
	stIPacket *ali = NULL;
	stOPacket *alo = NULL;	
	
	if(port == COM1)
	{
		p= DnpCom1;
		dli = dliCom1[0];
		dlo = dloCom1[0];
		plo = ploCom1;
		ali = aliCom1;
		alo = aloCom1;
	}
	else if(port == COM2)
	{
		p= DnpCom2;
		dli = dliCom2[0];
		dlo = dloCom2[0];
		plo = ploCom2;
		ali = aliCom2;
		alo = aloCom2;
	}	
	if(DnpFrame(port) < 0) return -1;
	
	if (DlCheckSum(port) == 0) {
		if ( (p->buf[3]&PRM_YES) == PRM_YES)
			DL_Slave(port);		     	/*作为副方站接收原方站报文*/
		else
			DL_Master(port);		 	/*作为原方站接收副方站回答*/
		return 0;	
	}
	else return -2;
}
/*------------------------------------------------------------------------
 Procedure:     ComFrame
 Purpose:       把接收的帧序列组合成数据包供应用层使用.
 Input:
 Output:
 Errors:
------------------------------------------------------------------------*/
int ComFrame(INT8U port)
{
	UCHAR k, j, i, block, rem16;
	
	stIFrame *p=NULL;
	stIFrame *dli = NULL;
	stOFrame *dlo = NULL;
	stOFrame *plo = NULL;
	stIPacket *ali = NULL;
	stOPacket *alo = NULL;	
	
	if(port == COM1)
	{
		p= DnpCom1;
		dli = dliCom1[0];
		dlo = dloCom1[0];
		plo = ploCom1;
		ali = aliCom1;
		alo = aloCom1;
	}
	else if(port == COM2)
	{
		p= DnpCom2;
		dli = dliCom2[0];
		dlo = dloCom2[0];
		plo = ploCom2;
		ali = aliCom2;
		alo = aloCom2;
	}	
	
	ali->count = 0;
	ali->source = MERGE(dli[0].buf[7], dli[0].buf[6]);
	ali->rec_time = dli[0].rec_time;
	for(k=0; k<9; k++)
		if(dli[k].ready) {
			block = (dli[k].buf[2]-5)/16; rem16 = (dli[k].buf[2]-5)%16;
			if(block == 0) {
				for (i=0; i<rem16-1; i++)
					ali->buf[ali->count+i] = dli[k].buf[11+i];
				ali->count += rem16-1;
			}
			else {
				for (i=0; i<15; i++)
					ali->buf[ali->count+i] = dli[k].buf[11+i];
				ali->count += 15;
				for (j=1; j<block; j++) {
					for (i=0; i<16; i++)
						ali->buf[ali->count+i] = dli[k].buf[10+j*18+i];
					ali->count += 16;
				}
				for(i=0; i<rem16; i++)
					ali->buf[ali->count+i] = dli[k].buf[10+block*18+i];
				ali->count +=rem16;
			}
		}
		else break;
	for(k=0; k<9; k++) dli[k].ready = FALSE;
	ali->ready = TRUE;
	return 0;
}
/*------------------------------------------------------------------------
 Procedure:     Send
 Purpose:       发送应用层准备好的数据,
 Input:
 Output:
 Errors:
------------------------------------------------------------------------*/
int Send(INT8U port)
{
	stIFrame *p=NULL;
	stIFrame *dli = NULL;
	stOFrame *dlo = NULL;
	stOFrame *plo = NULL;
	stIPacket *ali = NULL;
	stOPacket *alo = NULL;	
	
	if(port == COM1)
	{
		p = DnpCom1;
		dli = dliCom1[0];
		dlo = dloCom1[0];
		plo = ploCom1;
		ali = aliCom1;
		alo = aloCom1;
	}
	else if(port == COM2)
	{
		p = DnpCom2;
		dli = dliCom2[0];
		dlo = dloCom2[0];
		plo = ploCom2;
		ali = aliCom2;
		alo = aloCom2;
	}	
	SplitPacket(port);					/*OutPacket分割为OutFrame*/
	cur_frame[port-1] = 0;
	FillBuffer(Dnp_Al_Ready,port);

	WriteX((INT8U*)plo->buf, plo->count,port);	/*DlStartSend();*/
	return 0;
}
/*------------------------------------------------------------------------
 Procedure:     CDNP::SplitPacket ID:1
 Purpose:       将应用层的数据包分割为FT3帧序列.
 Input:
 Output:
 Errors:
------------------------------------------------------------------------*/
void SplitPacket(INT8U port)
{
	UCHAR k, i, j; USHORT CRC16;
	UCHAR rem249, frame, TH[9], block, rem16, count[9],tempFCB;
	stIFrame *p=NULL;
	stIFrame *dli = NULL;
	stOFrame *dlo = NULL;
	stOFrame *plo = NULL;
	stIPacket *ali = NULL;
	stOPacket *alo = NULL;	
	
	if(port == COM1)
	{
		p = DnpCom1;
		dli = dliCom1[0];
		dlo = dloCom1[0];
		plo = ploCom1;
		ali = aliCom1;
		alo = aloCom1;
	}
	else if(port == COM2)
	{
		p = DnpCom2;
		dli = dliCom2[0];
		dlo = dloCom2[0];
		plo = ploCom2;
		ali = aliCom2;
		alo = aloCom2;
	}	
	rem249 = ((alo->count)%249);
	if(rem249 == 0)	frame = alo->count/249;
	else			frame = alo->count/249 +1;
	if(frame > 9) return;

	if (frame == 1) TH[0]=0xC0;				/*伪传输层控制字节(TH)*/
	else {
		TH[0]=0x40;
		for(i=1; i<frame-1; i++) TH[i]=i;
		TH[frame-1]=0x80+frame-1; }

	/*记录每帧长度, 以便循环处理*/
	if(rem249 != 0){						/*added on 2001.03.01*/
		for(k=0; k<frame-1; k++) count[k] = 250;
		count[frame-1] = rem249 + 1;
	}
	else {
		for(k=0; k<frame; k++) count[k] = 250;
	}

	tempFCB = 0x20;
	for(k=0; k<frame; k++){					/*实现链路层功能, 为每一帧构造FT3头和CRC校验*/
											/*检查dlo[k]是否空闲???*/
		dlo[k].buf[0] = 0x05;	dlo[k].buf[1] = 0x64;
		dlo[k].buf[2] = 5 + count[k];
		switch (alo->service) {				/*根据服务要求确定帧类型*/
			case DL_SEND_CF:
				dlo[k].buf[3] = DIR_OUT + PRM_YES + tempFCB+ FCV_YES + FUNC_DATA_ACK;
				if(tempFCB==0x20) tempFCB=0;/*循环翻转FCB*/
				else              tempFCB=0x20;
				break;
			case DL_SEND_NOCF:
				dlo[k].buf[3] = DIR_OUT + PRM_YES + FUNC_DATA_NACK;
				break;
			case DL_FAST_CF:	break;
			case DL_FAST_NOCF:	break;
			default:			break;
		}
		dlo[k].buf[4] = LOW(alo->dest);	dlo[k].buf[5] = HIGH(alo->dest);
		if(port == PORT1)
		{
			dlo[k].buf[6] = LOW(pp1->DBCfgs->Address);
			dlo[k].buf[7] = HIGH(pp1->DBCfgs->Address);
		}
		else
		{
			dlo[k].buf[6] = LOW(pp2->DBCfgs->Address);
			dlo[k].buf[7] = HIGH(pp2->DBCfgs->Address);
		}
		CRC16 = dnpcrc((INT8U*)&dlo[k].buf[0], 8);
		dlo[k].buf[8] = LOW(CRC16);		dlo[k].buf[9] = HIGH(CRC16);	
		/*FT3头构造完成*/
		block = count[k]/16;			rem16 = count[k]%16;
		dlo[k].buf[10] = TH[k];			/*伪传输层头*//*open on 2001.03.01*/
		if(block == 0/*&& rem16>1*/) {
			//dlo[k].buf[10] = TH[k];			/*2000.09.26*/
			for(j=0; j<rem16-1; j++)		/*-1:伪传输字节*/
				dlo[k].buf[11+j] = alo->buf[j+249*k];
			CRC16 = dnpcrc((INT8U*)&dlo[k].buf[10], rem16);
			dlo[k].buf[10+rem16] = LOW(CRC16);
			dlo[k].buf[10+rem16+1] = HIGH(CRC16);
		}
		else {
			for(j=0; j<15; j++)	dlo[k].buf[11+j] = alo->buf[j+249*k];
			CRC16 = dnpcrc((INT8U*)&dlo[k].buf[10], 16);
			dlo[k].buf[10+16] =  LOW(CRC16);
			dlo[k].buf[10+17] = HIGH(CRC16);
			for(i=0; i<block-1; i++) {
				for(j=0; j<16; j++)
					dlo[k].buf[28+i*18+j] = alo->buf[15+i*16+j+249*k];
				CRC16 = dnpcrc((INT8U*)&dlo[k].buf[28+i*18], 16);
				dlo[k].buf[28+i*18+16] =  LOW(CRC16);
				dlo[k].buf[28+i*18+17] = HIGH(CRC16);
			}
			if(rem16>0){					/*2000.09.26*/	
			for(j=0; j<rem16; j++)
				dlo[k].buf[10+block*18+j] = alo->buf[15+(block-1)*16+j+249*k];
			CRC16 = dnpcrc((INT8U*)&(dlo[k].buf[10+block*18]), rem16);
			dlo[k].buf[10+block*18+rem16]   =  LOW(CRC16);
			dlo[k].buf[10+block*18+rem16+1] = HIGH(CRC16);
			}
		}									/*CRC校验完成*/
		/*2000.09.26*/
		if(rem16>0) dlo[k].count = 10+block*18+rem16+2;
		else        dlo[k].count = 10+block*18;
		dlo[k].ready = TRUE;
	} /*for(k=0; k<=frame; k++)*/
	max_frame[port-1] = frame;		alo->ready = FALSE;
}
/*------------------------------------------------------------------------
 Procedure:     FillBuffer
 Purpose:       dli[]->p->???
 Input:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -