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

📄 secapp.c

📁 详细介绍了arm7-at91r40008,的开发全过程
💻 C
📖 第 1 页 / 共 5 页
字号:
#include "includes.h"
#include "iec101def.h"
#include "iec101wh.h"
#include "secapp.h"
#include "secdlink.h"

extern struct DBConfig	*DBCfgs;
extern struct LinkInfo* ComLink[PORTNUM];
extern struct AppInfo* ComApp[PORTNUM];
extern struct SysPort*	ComDb[PORTNUM];
extern INT8U SwitchCounter, SwitchCounter2;


void P101_2002SecTask(struct SysPort *Info, struct PortAppInfo* PortCfg)
{
    BOOL	flag;
    INT8U	i, err;
    INT16U	events;
	
    i = Info->PortID;
    if (i > PORT2)
	return ;
    else
	i -= 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 = Init101SecDLink(i+1, PortCfg);
	if (!flag)
	{
		free (ComLink[i]);
		ComDb[i] = NULL;
		return ;
	}
	flag = InitSec101App(i+1, PortCfg);
	if (!flag)
	{
		free (ComApp[i]);
		ComDb[i] = NULL;
		return ;
	}
	
     //整点存电度事项
    	flag=InitHisDataBuf(Info->PortID);
    	if (!flag)
    	{
		free (ComApp[i]);
		ComDb[i] = NULL;
		return ;
    	}
	
    //判断通讯模式
    if(ComLink[i]->BalanMode)
        OSFlagPost(ComDb[i]->Event, SCHEDULE, OS_FLAG_SET, &err);
    
   
    //进入事项处理循环
    for(;;)
    {
        events = OSFlagPend(Info->Event, TIME100MS+FBOOP+FCOS+FSOE+FTXAVAIL+FTXNEXT+SCHEDULE,
			OS_FLAG_WAIT_SET_ANY+OS_FLAG_CONSUME, 0, &err);	


        if(events & NEXTFRAME)
        {
            S101_2002SearchFrame(Info->PortID);
        }

        if(events&FTXAVAIL)//发送数据
        {
            S101_2002SendDataToMISI(Info->PortID);
        }

        if(events&SENDOVER)//发送数据
        {
            if(ComApp[i]->BalanMode)
                SendDataEnd(Info->PortID);
        }

        if (events & FBOOP)//YK消息处理(调用应用层服务)
        {
            SetUMsgFlag(Info->PortID);

            if(ComLink[i]->BalanMode&&DLStatusCheck(Info->PortID))
                CallUMsg(Info->PortID);
        }

        if(events&(FCOS|FSOE))//数据库事项处理(COS、SOE事项设置标志)
        {
            if(events&FCOS)
            	ComApp[i]->Data1.Flag|=HaveCOS;
	    if(events&FSOE)
	    	ComApp[i]->Data1.Flag|=HaveSOE;

            if(ComLink[i]->BalanMode&&DLStatusCheck(Info->PortID))
                CallUData(Info->PortID);
        }

        //定时处理区(100MS)
	if(events & TIME100MS)
	{
		ComApp[i]->TimerCounter++;
		if(ComApp[i]->TimerCounter >= 10)
		{
			ComApp[i]->TimerCounter=0;
			//链路层定时器
			TimeOut(Info->PortID);
			
			//应用层定时器
			OnTimer(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);
				}
			}
						
			//查询MISI接收缓冲区
			S101RecMISIData(Info->PortID, TRUE);
	}	
		
	if (events & SCHEDULE)//启动链路过程
        {
            CallDLStatus(Info->PortID);
        }
    }
}


BOOL  InitSec101App(INT8U Port, struct PortAppInfo* PortCfg)
{
//    int i;
    INT8U	i, j;
    INT16U	num, tmp;
    struct PSec101_2002Pad *pPad;
    
    i = Port - 1;
    pPad = (struct PSec101_2002Pad*)(PortCfg->pPad);
    
    if (ComDb[i]->DBCfgs->Info.Logic.DevNum==0)
    {
         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);
		ComApp[i]->AIMaxVal = malloc (num * 2);
		if ((ComApp[i]->YCDVal == NULL) || (ComApp[i]->YCValue == 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].DDNum;
	}
	if (num)
	{
		ComApp[i]->CounterData = malloc (num * sizeof(struct Counter));
		if (ComApp[i]->CounterData == NULL)
			return (FALSE);
			
		ComApp[i]->LastCounterData = malloc (num * 4);
		if (ComApp[i]->LastCounterData == NULL)
			return (FALSE);
			
	}
    
        
        if (pPad != NULL)
        {
            memcpy((void *)&ComApp[i]->Sec101Pad,PortCfg->pPad,sizeof(struct PSec101_2002Pad));
            if (ComApp[i]->Sec101Pad.PBase.MaxALLen>ASDULEN)//应用层最大报文长度超限
	        ComApp[i]->Sec101Pad.PBase.MaxALLen=ASDULEN;
	    else if(ComApp[i]->Sec101Pad.PBase.MaxALLen<16)
	        ComApp[i]->Sec101Pad.PBase.MaxALLen=ASDULEN;
	
	    if ((ComApp[i]->Sec101Pad.PBase.Timer.ScanData2>3600))//二级数据扫描间隔
	        ComApp[i]->NvaInterval=SCANDATA2TIMER;
	    else
	        ComApp[i]->NvaInterval=ComApp[i]->Sec101Pad.PBase.Timer.ScanData2;
	
	    ComApp[i]->BackScanTime=ComApp[i]->Sec101Pad.BackScanTime*60;//分,背景数据扫描间隔
	    ComApp[i]->CycScanTime=ComApp[i]->Sec101Pad.CycScanTime;//秒,周期循环数据扫描间隔
	
	    if (ComApp[i]->Sec101Pad.PBase.ProtocolControl&BALANCE)
	        ComApp[i]->BalanMode=TRUE;
	    else
	        ComApp[i]->BalanMode=FALSE;
	   
	   //历史电度
           if(ComApp[i]->Sec101Pad.Control&USEHISTORYDD)
           {
                ComApp[i]->HisDDCycle=ComApp[i]->Sec101Pad.HistoryDDTime;
           }

	    ComApp[i]->LinkAddrSize=ComApp[i]->Sec101Pad.LINKAddrSize;
	    ComApp[i]->CotSize=ComApp[i]->Sec101Pad.COTSize;
	    ComApp[i]->PubAddrSize=ComApp[i]->Sec101Pad.PUBAddrSize;
	    ComApp[i]->InfoAddrSize=ComApp[i]->Sec101Pad.INFOAddrSize;
	
	    if(ComApp[i]->LinkAddrSize!=1)
	        ComApp[i]->LinkAddrSize=2;//zzw
	    if(ComApp[i]->CotSize!=2)
	        ComApp[i]->CotSize=1;//zzw
	    if(ComApp[i]->PubAddrSize!=1)
	        ComApp[i]->PubAddrSize=2;//zzw
	    if(ComApp[i]->InfoAddrSize!=3)
	        ComApp[i]->InfoAddrSize=2;//zzw
	
	    if(ComApp[i]->Sec101Pad.TypeID[16]!=M_IT_TA)
	        ComApp[i]->Sec101Pad.TypeID[16]=M_IT_NA;
	    tmp = ComApp[i]->Sec101Pad.PBase.AIDeadValue;
        }
        else
        {
            ComApp[i]->Sec101Pad.PBase.CmdControl=0;
	    ComApp[i]->Sec101Pad.PBase.CmdControl|=YKPERMIT;
	    ComApp[i]->Sec101Pad.PBase.CmdControl|=SETSECTIME;
	
	    ComApp[i]->Sec101Pad.PBase.MaxALLen=ASDULEN;
	    ComApp[i]->Sec101Pad.PBase.AIDeadValue=3;
	    ComApp[i]->Sec101Pad.PBase.Timer.ScanData2=SCANDATA2TIMER;//3,二级数据扫描间隔
	
	    ComApp[i]->Sec101Pad.Control=0;
	    ComApp[i]->Sec101Pad.Control|=USESTANDARDCLOCKFORMAT;  //0x10,使用标准时钟格式
	    ComApp[i]->Sec101Pad.Control|=USECP56TIME2A;
	
	    ComApp[i]->BackScanTime=20*60;//分,背景数据扫描间隔
	    ComApp[i]->CycScanTime=20;//秒,周期循环数据扫描间隔
	    ComApp[i]->HisDDCycle=TIMETOSAVEDATA;
	   
	    ComApp[i]->BalanMode=FALSE;
	
	    for(j=0;j<8;j++)
	        ComApp[i]->Sec101Pad.TypeID[j]=M_PS_NA;//20;//具有状态变位检出的成组单点信息
	    for(j=8;j<12;j++)
	        ComApp[i]->Sec101Pad.TypeID[j]=M_ME_NB;//11;////测量值,标度化值
	    ComApp[i]->Sec101Pad.TypeID[12]=0;//该组为空
	    ComApp[i]->Sec101Pad.TypeID[13]=M_ME_NB;//11;//该组为参数
	    ComApp[i]->Sec101Pad.TypeID[14]=M_ST_NA;//5;//该组为步位置信息
	    for(j=0;j<16;j++)
	        ComApp[i]->Sec101Pad.GroupNum[j]=512;
	
	    ComApp[i]->Sec101Pad.TypeID[16]=M_IT_NA;
	
	    ComApp[i]->LinkAddrSize=2;
	    ComApp[i]->CotSize=1;
	    ComApp[i]->PubAddrSize=2;
	    ComApp[i]->InfoAddrSize=2;
	    tmp = 5;
        }    
	
	S101_2002GetYcDeadValue(Port, tmp);

        InitPara(Port);
   
    return TRUE;
}



void InitPara(INT8U Port)
{
    INT8U i, j;
    struct DBInfo info;
	
    i = Port - 1;
    	
    ComApp[i]->ActDevIndex = ComDb[i]->DBCfgs->Info.Logic.pOld[0].DevID;
    ComApp[i]->NvaActDevNo=ComDb[i]->DBCfgs->Info.Logic.pOld[0].DevID;
    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]->Data1.Flag |= HaveSOE;
		
	info.Type = COSDATA;
	if (DBCheck(&info))
		ComApp[i]->Data1.Flag |= HaveCOS;

	if (!S101GetNextActDevIndex(Port, ComApp[i]->ActDevIndex, ACTDEVINDEX))
		break;
    }
		
    ComApp[i]->Data1.Flag=0;
    ComApp[i]->AllDataCount=0;
    ComApp[i]->CounterCount=0;
    ComApp[i]->WatchDogCount=0;
    ComApp[i]->NvaActDevCur = 0;
   
    ComApp[i]->Status=Polling;
    ComApp[i]->LastStatus=Polling;
    ComApp[i]->LastFrame=Polling;
    ComApp[i]->BIFrame=0;
    ComApp[i]->LastDevIndex=0xFFFF;

    ComApp[i]->MasterStatus=NOUSE;

    ComApp[i]->ScanData2Count=0;

    ComApp[i]->EditAllDataCon=0;

    ComApp[i]->SDTTime=0;
    ComApp[i]->TrTime=0;
    ComApp[i]->SendTime=0;
    ComApp[i]->TimeDelay=0;

    ComApp[i]->ResetFlag=0;
    ComApp[i]->ResetCount=0;

    ComApp[i]->Data2Flag=0;
    ComApp[i]->BackScanCount=0;
    ComApp[i]->CycScanCount=0;
    ComApp[i]->FirstHisDDSaveCount=0xFF;
    //ComApp[i]->HisDDSaveCount=0;

    ComApp[i]->InitFlag=0xFF;
    ComApp[i]->HaveWrongData=FALSE;
    ComApp[i]->WrongDataLength=0;

    ComApp[i]->TimerCounter=0;

    ComApp[i]->CotLocation=2;//COT在ASDU中的位置
    ComApp[i]->PubAddrLocation=ComApp[i]->CotLocation+ComApp[i]->CotSize;//PUBADDR在ASDU中的位置
    ComApp[i]->InfoAddrLocation=ComApp[i]->PubAddrLocation+ComApp[i]->PubAddrSize;//INFOADDR在ASDU中的位置
    ComApp[i]->AsduHeadLength=ComApp[i]->InfoAddrLocation+ComApp[i]->InfoAddrSize;//ASDU头的长度

    if(ComApp[i]->PubAddrSize==1)
        ComApp[i]->BroadCastAddr=0xff;
    else
        ComApp[i]->BroadCastAddr=0xffff;
        
}

void OnTimer(INT8U Port)
{
    INT8U i;
    struct AbsTime_t absTime;
    
    i=Port-1;
    if(ComApp[i]->BalanMode&&(ComApp[i]->MasterStatus==NOUSE))//平衡模式链路无效时不启动定时器
        return;
    if((!ComApp[i]->BalanMode)&&(ComApp[i]->InitFlag==0xFF))
        return;
    if(ComApp[i]->ResetFlag==0xff)//收到复位命令后设置标志,发出命令两秒钟后复位
    {
        ComApp[i]->ResetCount++;
        if(ComApp[i]->ResetCount>=10)
        {
            ComApp[i]->ResetCount=0;
            ComApp[i]->ResetFlag=0;
            //热复位函数或标志
	    KillProg(RESET_RETAIN, RESET_DD, TRUE);
            //SystemReset(COLDRESET);
        }
    }
    //背景数据标志(全数据以BACK原因发送)
    ComApp[i]->BackScanCount++;
    if(ComApp[i]->BackScanCount>=ComApp[i]->BackScanTime)
    {
        if(ComApp[i]->Data1.Flag&CallAllData)//避免冲突
        {
            ComApp[i]->BackScanCount=0;
            return;
        }
       

        ComApp[i]->BackScanCount=0;
        ComApp[i]->Data2Flag|=BackData;
        ComApp[i]->GroupTrn.COT=BACK;
        ComApp[i]->GroupTrn.DevIndex=ComDb[i]->DBCfgs->Info.Logic.pOld[0].DevID;
        ComApp[i]->AllDataNum = 0;
        ComApp[i]->GroupTrn.GroupNo=1;//组号从1开始
        ComApp[i]->GroupTrn.InfoAddr=LBI;//信息体地址从0x1开始
    }

    ComApp[i]->ScanData2Count++;
    if((ComApp[i]->ScanData2Count)>=(ComApp[i]->NvaInterval))
    {
        ComApp[i]->ScanData2Count=0;

⌨️ 快捷键说明

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