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

📄 secdlink.c

📁 详细介绍了arm7-at91r40008,的开发全过程
💻 C
📖 第 1 页 / 共 3 页
字号:
    i = Port - 1;
    p=(ComLink[i]->RxdBuf+ComLink[i]->RxdHead);
    if(p[2+ComLink[i]->LinkAddrSize]!=CheckSum(Port, p))
        return(FALSE);
    if(p[3+ComLink[i]->LinkAddrSize]!=ENDCODE)
        return(FALSE);
    if(ComLink[i]->LinkAddrSize==1)
        addr=p[2];
    else
        addr=(p[2]+(p[3]<<8));
    if(addr!=ComLink[i]->SourceNo)
        return(FALSE);
    return(TRUE);
}

//判断68帧头。
BOOL S101_2002ExeDLFun68(INT8U Port)
{
    INT8U i;
    INT8U *p;
    
    i = Port - 1;
    p=(ComLink[i]->RxdBuf+ComLink[i]->RxdHead);
    if((p[0]!=p[3])||(p[1]!=p[2]))
        return(FALSE);
    if(ComLink[i]->LinkAddrSize==1)
    {
        if((p[5]!=ComLink[i]->SourceNo)&&(p[5]!=0xff))
            return(FALSE);
    }
    else
    {
        if(((p[5]+(p[6]<<8))!=ComLink[i]->SourceNo)&&((p[5]+(p[6]<<8))!=0xffff))
            return(FALSE);
    }
    return(TRUE);
}

void S101_2002ExeDLFunCode10(INT8U Port)
{
    INT8U Stop=0;
    INT8U Control, i;

    i = Port-1;
    Control=ComLink[i]->RxdBuf[1];
    ComLink[i]->IdleTimeCount=0;
    ComLink[i]->TimeOutTick_Pri=0;//链路有数据就可以不重发??
    if(Control&P101_PRM)//子站作为从动站接收主站的命令
    {
        if ((!(Control&P101_FCV)) || ((Control&P101_FCB) !=((ComLink[i]->RlaConCode) & 0x20)))
        {
            if (Control&P101_FCV)//FCV有效,FCB翻转。
            {
                ComLink[i]->RlaConCode=ComLink[i]->RxdBuf[1];
                ComLink[i]->FCBNoTurnNum=MAXRETRYNUM;
            }
            switch(Control&P101_FUNCODE)
            {
                case DLREQSTATUS://召唤链路状态
                    S101_2002RecReqDLStatus(Port);
                    while(((ComLink[i]->RxdTail-ComLink[i]->RxdHead)>=ComLink[i]->FixFrmLength)&&(Stop==0))//收到召唤链路状态命令时,清掉后续相同命令。
                    {//可以避免答非所问的过程,尽快建立链路。
                        if(memcmp(ComLink[i]->RxdBuf,ComLink[i]->RxdBuf+ComLink[i]->RxdHead,ComLink[i]->FixFrmLength)==0)
                            ComLink[i]->RxdHead+=ComLink[i]->FixFrmLength;
                        else
                            Stop=1;
                    }
                    break;
                case DLRESETRDL://复位链路
                    S101_2002RecResetDL(Port);
                    break;
                case DLREQDATA1://10
                    //应用层调用
                    ComApp[i]->DLCommand=DL_CALLDATA1;
                    if((!ComLink[i]->BalanMode)&&(Control&P101_FCV))
                        ComApp[i]->DLCommand|=DL_FCBOK; 
                    ComApp[i]->LengthIn=0;
                    Sec101_2002AppProc(Port, (ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize),ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                                        (ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize),(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);

                    S101_2002DLSendProc(Port);
                    break;
                case DLREQDATA2://11
                    //应用层调用
                    if(ComApp[i]->InitFlag==0xFF)
       					return;
   
                    ComApp[i]->DLCommand=DL_CALLDATA2;
                    if((!ComLink[i]->BalanMode)&&(Control&P101_FCV))
                        ComApp[i]->DLCommand|=DL_FCBOK;   
                    ComApp[i]->LengthIn=0;
                    Sec101_2002AppProc(Port, ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                                        ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
                    S101_2002DLSendProc(Port);
                    break;
                default:
                    ComLink[i]->ComStatus.OtherError++;
                    break;
            }
            return;
        }
        else //FCB未翻转
        {
            //ComStatus.OtherError++;
            //if (FCBNoTurnNum)
            {
                ComLink[i]->FCBNoTurnNum--;
                //if (FCBNoTurnNum)
                SendSec101_2002DataToMISI(Port);
            }
        }
    }
    else//Prm=0 平衡模式子站作为启动站接收到主站的命令。
    {
        ComLink[i]->TimeOutTick_Pri=0;
        switch(Control&P101_FUNCODE)
        {
            case DLCON:	//确认
                RecConf10(Port);
                break;
            case DLSTATUSOK://应答链路
                RecDLSta(Port);
                break;
            default:
                CallDLStatus(Port);
                ComLink[i]->ComStatus.OtherError++;
                break;
        }
    }
}

void S101_2002ExeDLFunCode68(INT8U Port)
{
    INT8U i;
    INT8U Control;
    
    i = Port - 1;
    Control=ComLink[i]->RxdBuf[4];

    ComLink[i]->IdleTimeCount=0;
    ComLink[i]->TimeOutTick_Pri=0;//链路有数据就可以不重发??
    if(Control&P101_PRM)//子站作为从动站接收主站链路报文。
    {
        if ((!(Control&P101_FCV)) || ((Control&P101_FCB) !=((ComLink[i]->RlaConCode) & 0x20)))
        {
            if (Control&P101_FCV)//FCV有效而且FCB变位
            {
                ComLink[i]->RlaConCode=ComLink[i]->RxdBuf[4]; //保存最新的功能码,这里只用到FCB
                ComLink[i]->FCBNoTurnNum=MAXRETRYNUM;//设置重发次数,指下次收到主站报文FCB未翻转时重发缓冲区内的报文。
            }
            switch(Control&P101_FUNCODE)
            {
                case DLRESETUSE://1,启动站复位从动站用户过程
                    //应用层调用
                    ComApp[i]->LengthIn=ComLink[i]->RxdBuf[1]-1-ComLink[i]->LinkAddrSize;
                    ComApp[i]->DLCommand=DL_RESETUSE;
                    if((!ComLink[i]->BalanMode)&&(Control&P101_FCV))
                        ComApp[i]->DLCommand|=DL_FCBOK;  
                    Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                                        ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
                    S101_2002DLSendProc(Port);
                    break;
                case DLTESTDL://2,测试链路
                    ComApp[i]->LengthIn=ComLink[i]->RxdBuf[1]-1-ComLink[i]->LinkAddrSize;
                    ComApp[i]->DLCommand=DL_TESTDLINK;
                    if((!ComLink[i]->BalanMode)&&(Control&P101_FCV))
                        ComApp[i]->DLCommand|=DL_FCBOK;   
                    Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                                        ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
                    S101_2002DLSendProc(Port);
                    break;
                case DLSENDCON://3,发送/确认 命令
                    ComApp[i]->DLCommand=DL_SENDCON;//
                    ComApp[i]->LengthIn=ComLink[i]->RxdBuf[1]-1-ComLink[i]->LinkAddrSize;
                    if((!ComLink[i]->BalanMode)&&(Control&P101_FCV))
                        ComApp[i]->DLCommand|=DL_FCBOK;  
                    Sec101_2002AppProc(Port, ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                                        ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
                    S101_2002DLSendProc(Port);
                    break;
                case DLSENDNOCON://4,发送/无回答 命令
                    ComApp[i]->DLCommand=DL_SENDNOCON;//
                    ComApp[i]->LengthIn=ComLink[i]->RxdBuf[1]-1-ComLink[i]->LinkAddrSize;
                    if((!ComLink[i]->BalanMode)&&(Control&P101_FCV))
                        ComApp[i]->DLCommand|=DL_FCBOK;   
                    Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                                        ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
                    S101_2002DLSendProc(Port);
                    break;
            }
        }
        else  //FCB 未翻转  //change by wyj
        {
            //ComStatus.OtherError++;
            //if (FCBNoTurnNum)
            {
                ComLink[i]->FCBNoTurnNum--;
                //	if (FCBNoTurnNum) //重发缓冲区的报文(上次的)
                    SendSec101_2002DataToMISI(Port);
            }
            return;
        }
    }
    else  //Prm=0;子站作为启动站接收主站链路报文
    {
    }
}

INT8U CheckSum(INT8U Port, INT8U *RxdBuf)
{
    INT8U sum, i, j;
    
    sum = 0;
    i = Port - 1;
    if(*(RxdBuf)==STARTCODE10)
    {
        for(j=0;j<ComLink[i]->LinkAddrSize+1;j++)
            sum+=*(RxdBuf+1+j);
    }
    else
    {
        INT8U *p;
        BYTE i;
        p=RxdBuf+4;
        i=*(RxdBuf+1);

        while(i--)
            sum += *p++ & 0xFF;
    }
    return(sum);
}

INT32U TimeDelay(INT8U Port, INT16U j)
{
    INT8U i;
    i = Port - 1;
    ComLink[i]->TimeOutTickCopy=j*10/ComLink[i]->Baudrate+ComLink[i]->TimeOutValue/100+1;
    return(ComLink[i]->TimeOutTickCopy);
}

void RecDLSta(INT8U Port)
{
    INT8U i;
    
    i=Port-1;
    switch(ComLink[i]->DLPriStatus)
    {
        case PRIWAITSTATUS:
        case PRIWAITRSCON://链路过程未完成,为解决报文错位情况。即发送复位链路收到链路状态的情况,这时继续复位链路。
            EditFra10(Port, DLRESETRDL);
            S101_2002SendDataToMISI(Port);
            ComLink[i]->TlaConCode&=0xDF;  //change by wyj
            ComLink[i]->DLPriStatus=PRIWAITRSCON;
            ComLink[i]->TimeOutTick_Pri=TimeDelay(Port, 2* ComLink[i]->FixFrmLength);
            ComLink[i]->RetryCount=MAXRETRYNUM;
            break;
        default://出现状态错位情况,怎么处理
            ComLink[i]->DLPriStatus=PRIENABLE;
    }
}

void RecConf10(INT8U Port)
{
    INT8U i;
    
    i=Port-1;
    if (ComLink[i]->DLPriStatus==PRIWAITRSCON)//非平衡模式不可能到这里
    {
        if (ComLink[i]->BalanMode)//平衡模式
        {
            ComLink[i]->DLPriStatus=PRIENABLE;
            ComLink[i]->RemoteDLOK=0xff;//远方链路(主站)已经被复位
            if(ComLink[i]->LocalDLOK==0xff)//如果这之前,本地链路已经被复位(主站复位过子站)则进行应用层调用。
            {
                if(ComLink[i]->StartDL==0xFF)
                {
                    ComLink[i]->StartDL=0;//链路过程结束

                    ComApp[i]->DLCommand=DL_LINKENABLE;
                    ComApp[i]->LengthIn=0;
                    Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                                        ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
                    S101_2002DLSendProc(Port);//发送初始化结束帧
                }
                else//防止运行过程中召唤链路却未设置StartDL标志,这个判断好象没有必要。
                {
                    ComLink[i]->StartDL=0xFF;
                    ComLink[i]->LocalDLOK=0;
                }
            }
        }
    }
    else if (ComLink[i]->DLPriStatus==PRISENDCON)//平衡模式
    {
        ComLink[i]->DLPriStatus=PRIENABLE;
        //应用层调用
        ComApp[i]->DLCommand=DL_APPCON;
        ComApp[i]->LengthIn=0;
        Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                            ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
        S101_2002DLSendProc(Port);
    }
    else
        ComLink[i]->DLPriStatus=PRIENABLE;
}

void S101_2002RecResetDL(INT8U Port)
{
    INT8U i;    

    i=Port-1;
    ComLink[i]->RlaConCode&=0xDF;     //清FCB  //change by wyj
    ComLink[i]->FCBNoTurnNum=MAXRETRYNUM;

    //调应用层服务,检测是否发送初始化结束
    ComApp[i]->DLCommand=DL_RESETDL;
    ComApp[i]->LengthIn=0;
    Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                        ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
    if((ComApp[i]->AppCommand&APP_HAVEDATA1)==APP_HAVEDATA1)
        ComLink[i]->FlagData1=TRUE;
    else
        ComLink[i]->FlagData1=FALSE;

    EditSec101_2002Fra10(Port, DLCON);	//编辑应答帧。
    S101_2002SendDataToMISI(Port);

    if(ComLink[i]->BalanMode)
    {
        ComLink[i]->LocalDLOK=0xff;//子站链路已经被主站复位
        if(ComLink[i]->RemoteDLOK==0xff)//这之前主站链路已经被复位
        {
            if(ComLink[i]->StartDL==0xff)//子站重启动初始化后的链路过程
            {
                ComLink[i]->StartDL=0;
                //应用层调用
                ComApp[i]->DLCommand=DL_LINKENABLE;
                ComApp[i]->LengthIn=0;
                Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                                    ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
                S101_2002DLSendProc(Port);//发送初始化结束帧
            }
            else//子站正常运行时的链路过程(说明主站运行过程中复位了)
                CallDLStatus(Port);
        }
        else
            CallDLStatus(Port);
    }
}

void S101_2002RecReqDLStatus(INT8U Port)
{
    INT8U i;
    
    i=Port-1;
    EditSec101_2002Fra10(Port, DLSTATUSOK);
    S101_2002SendDataToMISI(Port);

⌨️ 快捷键说明

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