cli.c

来自「基于ARM和uC/OS-II实现的串口控制台」· C语言 代码 · 共 1,153 行 · 第 1/3 页

C
1,153
字号
        CurCmdBuf[offset + i + 1] = '\0';
        i++;
    }
    
    BufClean();
    Cpy2Buf(CurCmdBuf);
}

/*******************************************************************************
* Function:     KeyTab()
* Description:  
* Calls:        GetCmd()/CurPrompt()/SearchCmd()/GetCmdStatus()/SearchPara()
*               /PrintBuf()/TabLastPara()/BufClean()/Cpy2Buf()
* Called By:    U0RxISR()
*******************************************************************************/
static void KeyTab(void)
{
    char CurCmdBuf[256];
    uint8 CmdID = 0, err = 0, paracnt = 0, offset, ParaID, paraindex;
    CmdInfo *CurCmdDB = NULL;
    
    GetCmd(CurCmdBuf);
    
    CurPrompt();
    
    if(SearchCmd(CurCmdBuf, &CmdID, &err) == ERR_CLI_SEARCHOK)
    {
        switch(GetCmdStatus())
        {
            case USER:
                CurCmdDB = CmdDBUser;
                break;
                
            case PRIVATE:
                CurCmdDB = CmdDBPrivate;
                break;
                
            case CONFIG:
                CurCmdDB = CmdDBConfig;
                break;
                
            case CONFIG_LINE:
                CurCmdDB = CmdDBLine;
                break;
        }
		
        /* 计算输入的命令中参数个数 */
        for(offset = 0; offset < 256 && CurCmdBuf[offset] != '\0'; offset++)
        {
            if(CurCmdBuf[offset] == SPACE && CurCmdBuf[offset + 1] != SPACE)
            {
                paracnt++;
            }
        }
        
		/* 如果有参数输入,且该命令有参数,则依次搜索参数,
		如果参数都搜索成功,则补齐最后一个参数 */
        if(paracnt != 0 && CurCmdDB[CmdID].paraDB != NULL)
        {
            for(paraindex = 1; paraindex <= paracnt; paraindex++)
            {
                if(SearchPara(CurCmdBuf, paraindex, CurCmdDB[CmdID].paraDB, 
                                &ParaID, &err) == ERR_CLI_PARA_OK)
                {
                    continue;
                }
                else
                {
                    PrintBuf();
                    return;
                }
            }
            
            CurCmdDB = CurCmdDB[CmdID].paraDB;
            TabLastPara(CurCmdDB[ParaID].name);
            return;
        }
        else
        {
    	    BufClean();
    	    Cpy2Buf(CurCmdDB[CmdID].name);
    	}
    }
    else
    {
        PrintBuf();
    }
}

/*******************************************************************************
* Function:     KeyAnswer()
* Description:  
* Calls:        
* Called By:    U0RxISR()
*******************************************************************************/
static void KeyAnswer(void)
{
    uint8 i, cnt = 0;
    CmdInfo *CurCmdDB = NULL, *CurCmd = NULL;
    
    SendC(ANS);
    SendStr(BLANKROW);
    
    if(CliRxBuf.Cnt == 0)
    {
        switch(GetCmdStatus())
        {
            case USER:
                CurCmdDB = CmdDBUser;
                break;
                
            case PRIVATE:
                CurCmdDB = CmdDBPrivate;
                break;
                
            case CONFIG:
                CurCmdDB = CmdDBConfig;
                break;

            case CONFIG_LINE:
                CurCmdDB = CmdDBLine;
                break;
        }
        
        for(cnt = 0; CurCmdDB[cnt].name[0] != NULL;cnt++);
        
        for(i = 0; i < cnt; i++)
        {
            CurCmd = &CurCmdDB[i];
            SendStr(CurCmd->name);
            SendC(CR);
            SendC(TAB);
            SendC(TAB);
            SendStr(CurCmd->help);
            SendStr(BLANKROW);
        }
        
        CurPrompt();
    }
    else
    {
        SendStr("this symbol only be used under prompt. \
Using 'man' for command parameters.");
        CurPrompt();
        PrintBuf();
    }
}

/*******************************************************************************
* Function:     KeyBackspace()
* Description:  Backspace键对应操作
* Calls:        SendC()
* Called By:    U0RxISR()
*******************************************************************************/
static void KeyBackspace(void)
{
    uint8 i;
    
    if(CliRxBuf.InsDelPtr > 0 && CliRxBuf.InsDelPtr == CliRxBuf.WrPtr)
    {
        CliRxBuf.WrPtr--;
        CliRxBuf.InsDelPtr--;
        CliRxBuf.Cnt--;
        SendC(BS);
        SendC(SPACE);
        SendC(BS);
    }
    else if(CliRxBuf.InsDelPtr > 0 && CliRxBuf.InsDelPtr < CliRxBuf.WrPtr)
    {
        SendC(BS);
        
        for(i = 0; i < CliRxBuf.WrPtr - CliRxBuf.InsDelPtr; i++)
        {
            CliRxBuf.Buf[CliRxBuf.InsDelPtr + i - 1]
             = CliRxBuf.Buf[CliRxBuf.InsDelPtr + i];
            SendC(CliRxBuf.Buf[CliRxBuf.InsDelPtr + i]);
        }
        
        SendC(SPACE);
        SendC(BS);
        
        for(i = 0; i < CliRxBuf.WrPtr - CliRxBuf.InsDelPtr; i++)
        {
            SendC(BS);
        }
        
        CliRxBuf.WrPtr--;
        CliRxBuf.InsDelPtr--;
        CliRxBuf.Cnt--;
    }
}

/*******************************************************************************
* Function:     KeyCtrlC()
* Description:  Ctrl+C对应操作
*******************************************************************************/
static void KeyCtrlC(void)
{
    BufClean();
    CurPrompt();
}

/*******************************************************************************
* Function:     U0RxISR()
* Description:  UART0接收中断服务程序
* Calls:        
* Called By:    
*******************************************************************************/
void U0RxISR(void)
{
    uint8 rxdata;
    
    while(U0LSR & U0LSR_RDR)
    {
        ResetTimer1();
        rxdata = U0RBR;
        
        switch(FSMKey)
        {
            case DIRECTION_KEY_START:
                if(rxdata == ESC)
                {
                    FSMKey = DIRECTION_KEY_ONE;
                }
                break;
                
            case DIRECTION_KEY_ONE:
                if(rxdata == 0x5b)
                {
                    FSMKey = DIRECTION_KEY_TWO;
                }
                else
                {
                    FSMKey = DIRECTION_KEY_START;
                }
                
                goto JMPOUT;
                
            case DIRECTION_KEY_TWO:
                switch(rxdata)
                {
                    case UP:
                        KeyUp();
                        break;
                        
                    case DOWN:
                        KeyDown();
                        break;
                        
                    case LEFT:
                        KeyLeft();
                        break;
                        
                    case RIGHT:
                        KeyRight();
                        break;
                        
                    case HOME:
                        KeyHome();
                        break;
                        
                    case END:
                        KeyEnd();
                        break;
                        
                    default:
                        break;
                }
                
                FSMKey = DIRECTION_KEY_START;
                goto JMPOUT;
                
            default:
                FSMKey = DIRECTION_KEY_START;
                break;
        }
        
        switch(rxdata)
        {
            case CR:
                KeyEnter();
                break;
                
            case TAB:
                KeyTab();
                break;
                
            case ANS:
                KeyAnswer();
                break;
                
            case BS:
                KeyBackspace();
                break;
                
            case ETX:
                KeyCtrlC();
                break;
                
            default:
                if(rxdata >= 0x20 && rxdata <= 0x7e)
                {
                    InsBuf(rxdata);
                }
                break;
        }
JMPOUT: continue;
    }
}

/*******************************************************************************
* Function:     GetCmd()
* Description:  将命令结构体中的命令数据拷贝到传入的地址,并且结构BUF复位
* Calls:        
* Called By:    
* Input:        CurCmdBuf   要查找的命令字串
* Return:       
*******************************************************************************/
void GetCmd(char *pCurCmdBuf)
{
    uint8 i;
    
    for(i = 0; i < CliRxBuf.WrPtr; i++)
    {
        pCurCmdBuf[i] = CliRxBuf.Buf[i];
    }
    
    pCurCmdBuf[i] = '\0';   /* 在输入的字符串末尾插入0作为结束标志 */
}

/*******************************************************************************
* Function:     GetPara()
* Description:  
* Calls:        
* Called By:    
* Input:        
* Return:       TRUE/FALSE
*******************************************************************************/
BOOL GetPara(char *CurBuf, char *pParaBuf, uint8 ParaNum)
{
    uint8 spcnt = 0, offset = 0, i = 0;
    uint16 len;
    
    len = strlen(CurBuf);
    
    while(1)
    {
        if(CurBuf[offset] == SPACE)
        {
            /* 消除连续空格影响 */
            if(CurBuf[offset + 1] == SPACE)
            {
                offset++;
                continue;
            }
            
            /* 有效空格计数 */
            spcnt++;
            offset++;
            /* 偏移到了BUF的末尾 */
            if(offset == len)
            {
                return FALSE;
            }

            /* 有效空格数是否等于要查找的参数号 */
            if(spcnt == ParaNum)
            {
                break;
            }
        }
        else
        {
            offset++;
            /* 偏移到了BUF的末尾 */
            if(offset == len)
            {
                return FALSE;
            }
        }
    }
    
    /* 拷贝参数到输出BUF中 */
    for(i = 0; CurBuf[offset + i] != '\0' && CurBuf[offset + i] != SPACE; i++)
    {

⌨️ 快捷键说明

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