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

📄 cli_io.c

📁 命令行在嵌入式系统的实现
💻 C
📖 第 1 页 / 共 3 页
字号:

    EOS_StrCpy(pOutput, szOutput);

    /* 输出信息入列 */
    pAsynDispItem = &(m_DispBase.s_AsynShowPool[m_DispBase.ulLastPos]);
    pAsynDispItem->pString  = pOutput;
    pAsynDispItem->ulTermID = ulTermID;

    m_DispBase.ulLastPos = CLI_INCCYCLE(m_DispBase.ulLastPos, ASYN_DISPLAY_NUM);

    return G_SUCCESS;
}

/* 异步输出的主任务函数体*/
_VOID IO_AsynDispTask(_U32 ulArg1, _U32 ulArg2)
{
    struct AsynDisplay_Element_S *pAsynDispItem;
    PTerm_Data_S pTermStruct;
    _U32 i, ulLen;
    (_VOID)ulArg1;
    (_VOID)ulArg2;

    IO_DispBaseInit();
    for (; ;)
    {
        if (m_DispBase.ulFirstPos == m_DispBase.ulLastPos)
        {
            CLI_DELAY(10);
            continue;
        }

        /* 提取一条显示信息,注意内存的释放 */
        pAsynDispItem = &(m_DispBase.s_AsynShowPool[m_DispBase.ulFirstPos]);
        m_DispBase.ulFirstPos = CLI_INCCYCLE(m_DispBase.ulFirstPos, ASYN_DISPLAY_NUM);

        if ((pAsynDispItem->ulTermID > m_ulCliMaxOnlineUser )
         || (pAsynDispItem->ulTermID == 0)
         || (pAsynDispItem->pString == G_NULL))
        {
            ROS_MemFree(pAsynDispItem->pString);
            continue;
        }

        pTermStruct = m_TDTable[pAsynDispItem->ulTermID - 1].pTermStruct;

        if (pTermStruct->ucTermStatus < TERM_LOGED || pTermStruct->ulTimeLeft == 0)
        {
            CLI_RECORD(CLI_STAT_ASYNOUT_TERM_ERR);
            ROS_MemFree(pAsynDispItem->pString);
            continue;
        }

        EOS_StrCpy(pTermStruct->szSendBuf, pAsynDispItem->pString);
        CLI_SendToTerm(pTermStruct);

        /* 如果该终端正处于命令编辑状态,重新显示提示符与命令编辑的内容 */
        if (pTermStruct->iEditStatus == COMMAND_INPUT
         && pTermStruct->ucTermStatus < TERM_EXECCMD)
        {
            CI_DisplayPrompt(pTermStruct);
            if ((ulLen = EOS_StrLen(pTermStruct->szEditBuf)) > (_U32)pTermStruct->iCurrentPos)
            {
                for (i = 0; i < ulLen - (_U32)pTermStruct->iCurrentPos; i++)
                    IO_OutToTerm(pTermStruct, "\x1b[1D");
            }
        }
        else
        {
            IO_OutToTerm(pTermStruct, "\r\n");
        }

        pAsynDispItem->ulTermID = 0;
        ROS_MemFree(pAsynDispItem->pString);

        if (m_DispBase.ulFirstPos % 5 == 0)
        {
            CLI_DELAY(1);
        }
    }
}

/*********************************************************************/
/* 函数名称 : IO_OutToTerm()                                         */
/* 函数功能 : 组织输出字符串,并根据终端调用函数输出                 */
/* 输入参数 : pTermStruct   终端任务数据                             */
/*            szOutString  输出字符串                                */
/* 输出参数 : 无                                                     */
/* 返回     : 成功、失败                                             */
/* 上层函数 :                                                        */
/* 创建者   :                                                        */
/* 修改记录 :                                                        */
/*********************************************************************/
_U32 IO_OutToTerm(PTerm_Data_S pTermStruct, const _S8 *szOutString)
{
    _S8 cTmp;
    const _S8 *szOut;
    const _S8 *pcTmp;
    _U32 ulStrLen;
    _U32 ulTmp;

    CLI_ASSURE_OR_FAIL(pTermStruct != G_NULL);

    if (CLI_GetCurrentTaskData() == G_NULL)
    {
        pTermStruct->ulDispLineCount = 0;
    }

    if ((pTermStruct->ulDispLineCount == CLI_INVALID
             && pTermStruct->ucTermStatus == TERM_EXECCMD)
      || pTermStruct->ucTermStatus == TERM_SLEEPING)
        return G_SUCCESS;

    szOut = szOutString;
    /* 如果发送缓冲中还存在没有显示的内容,先显示之 */
    if (pTermStruct->szSendBuf[0] != '\0')
        CLI_SendToTerm(pTermStruct);

    /* 如果输出的信息长度超过任务缓冲允许的范围,分段输出 */
    pcTmp = szOut;
    ulStrLen = EOS_StrLen(szOutString);

    while (*pcTmp != '\0' && pcTmp < szOutString + ulStrLen)
    {
        if (*pcTmp == '\r' || *pcTmp == '\n' || pcTmp - szOut > LINE_LENGTH)
        {
            EOS_StrNCpy(pTermStruct->szSendBuf, szOut, (_U32)(pcTmp - szOut));
            pTermStruct->szSendBuf[pcTmp - szOut] = '\0';
            CLI_SendToTerm(pTermStruct);

            if (*pcTmp == '\r' || *pcTmp == '\n')
                szOut = pcTmp++; /* 这里需要递加,跳过接下来的\r或\n */
            else
                szOut += (pcTmp - szOut);

            /* 显示每满一屏要作处理, 需要预留一行用作提示信息输出  */
            if (++pTermStruct->ulDispLineCount >= LINE_PER_PAGE - 1)
            {
                pTermStruct->ulDispLineCount = 0;

                /* 如果是手动分屏,需要按任意键继续 */
                if (pTermStruct->ucScroll == SCROLL_MANUAL && pTermStruct->ucTermStatus == TERM_EXECCMD)
                {
                    EOS_StrCpy(pTermStruct->szSendBuf,
                           "\r\n  --- More ---");
                    CLI_SendToTerm(pTermStruct);

                    /*如果输入CTL_C或终端非正常状态,终止显示*/
                    while ((cTmp = IO_GetCharByPeek()) != G_NULL
                         && cTmp != KEY_CTRL_C)
                    {
                        ;
                    }
                    if ((cTmp == KEY_CTRL_C)
                     || (cTmp = IO_GetChar()) == KEY_CTRL_C
                     || (cTmp == G_NULL)
                     || !IS_TERM_NORMAL(pTermStruct))
                    {
                        for (ulTmp = 0; ulTmp < 15; ulTmp++)
                            EOS_StrCat(pTermStruct->szSendBuf, "\x1b[1D");
                        EOS_StrCat(pTermStruct->szSendBuf, "                     \x1b[1A");
                        CLI_SendToTerm(pTermStruct);

                        pTermStruct->ulDispLineCount = CLI_INVALID;
                        return G_SUCCESS;
                    }
                    else if (cTmp == '\r' || cTmp == '\n')
                    {
                        pTermStruct->ulDispLineCount = LINE_PER_PAGE - 1;
                    }

                    for (ulTmp = 0; ulTmp < 15; ulTmp++)
                        EOS_StrCat(pTermStruct->szSendBuf, "\x1b[1D");
                    EOS_StrCat(pTermStruct->szSendBuf, "                     \x1b[1A");
                    CLI_SendToTerm(pTermStruct);
                }
                /* 如果是自动分屏,查看是否有键入CTRL+C试图终止,没有则继续 */
                else
                {
                    while ((cTmp = IO_GetCharByPeek()) != G_NULL
                         && cTmp != KEY_CTRL_C)
                    {
                        ;
                    }

                    if (cTmp == KEY_CTRL_C)
                    {
                        pTermStruct->ulDispLineCount = CLI_INVALID;
                        return G_SUCCESS;
                    }

                    CLI_DELAY(100);
                    while ((cTmp = IO_GetCharByPeek()) != G_NULL
                         && cTmp != KEY_CTRL_C)
                    {
                        ;
                    }

                    if (cTmp == KEY_CTRL_C)
                    {
                        pTermStruct->ulDispLineCount = CLI_INVALID;
                        return G_SUCCESS;
                    }
                }
            }
        }
        pcTmp++;
    }

    EOS_StrCpy(pTermStruct->szSendBuf, szOut);
    return CLI_SendToTerm(pTermStruct);
}


/*-------------------------------------------------------------------*/
/* 函数名称 : IO_GetChar                                             */
/* 功    能 : 从终端接收一个字符                                     */
/* 输入参数 : 无                                                     */
/* 输出参数 : 无                                                     */
/* 返回值   : 接收到的字符                                           */
/* 调用说明 : 该函数调用导致任务阻塞,直到终端有输入或超时。注意该函 */
/*            数的调用需要判断返回值,如果返回NULL则可能是终端异常, */
/*            建议程序释放当前资源,不再继续处理当前事件             */
/* 典型示例 : cTmp = IO_GetChar();                                   */
/*-------------------------------------------------------------------*/
_S8 IO_GetChar(_VOID)
{
    _S8 cCharReceived;
    PTerm_Data_S pTermStruct;

    if (((pTermStruct = CLI_GetCurrentTaskData()) == G_NULL)
       || pTermStruct->iSocket == SOCKET_FOR_MML)
    {
        MT_ERRLOG(0);
        return G_NULL;
    }

    if (CLI_ReceiveFromTerm(pTermStruct, pTermStruct->ulTimeLeft) != G_SUCCESS)
    {
        CLI_RECORD(CLI_STAT_RECEIVE_ABNORMAL);
        return G_NULL;
    }

    cCharReceived = pTermStruct->szRecvBuf[0];
    pTermStruct->szRecvBuf[0] = '\0';
    pTermStruct->iRecvLen     = 0;

    return cCharReceived;
}

/*-------------------------------------------------------------------*/
/* 函数名称 : IO_GetChar                                             */
/* 功    能 : 从终端接收缓冲读取一个字符                             */
/* 输入参数 : 无                                                     */
/* 输出参数 : 无                                                     */
/* 返回值   : 读取到的字符                                           */
/* 调用说明 : 该调用直接读取当前终端的接收缓冲,如果无内容则返回空   */
/* 典型示例 : cTmp = IO_GetCharByPeek();                             */
/*-------------------------------------------------------------------*/
_S8  IO_GetCharByPeek(_VOID)
{
    _S8 cCharReceived;
    PTerm_Data_S pTermStruct;

    if ((pTermStruct = CLI_GetCurrentTaskData()) == G_NULL)
    {
        return G_NULL;
    }

    CLI_ReceiveFromTerm(pTermStruct, 0);

    cCharReceived = pTermStruct->szRecvBuf[0];
    pTermStruct->szRecvBuf[0] = '\0';
    pTermStruct->iRecvLen = 0;

    return cCharReceived;
}

/*-------------------------------------------------------------------*/
/* 函数名称 : IO_GetString                                           */
/* 功    能 : 从当前终端接收一个字符串                               */
/* 输入参数 : ulSize  :字符串允许的最大长度                          */
/*            ucMode  :输入模式:0-字符回显,1-星号回显             */
/* 输出参数 : szInput :接收的的输入字符串                            */
/* 返回值   : 成功、失败                                             */
/* 调用说明 : 该调用导致终端任务阻塞,直到超时或接收到回车键. 调用者 */
/*            应对返回值进行判断, 如果失败,则认为接收到的内容无效,  */
/*            导致这种情况的最大可能是终端异常,程序应当立即返回,让 */
/*            系统去识别并处理这种异常                               */
/* 典型示例 : if (IO_GetString(&szUsername, 16, 0) != G_SUCCESS)     */
/*                return G_FAILURE;                                  */
/*-------------------------------------------------------------------*/
_U32  IO_GetString(_S8 *szInput, _U32 ulSize, _S8 ucMode)
{
    _S32 i;
    PTerm_Data_S pTermStruct ;

    if ( G_NULL == szInput)
    {
        MT_ERRLOG(0);
        return G_FAILURE;
    }
    if (((pTermStruct = CLI_GetCurrentTaskData()) == G_NULL)
       || pTermStruct->iSocket == SOCKET_FOR_MML)
    {
        MT_ERRLOG(0);
        return G_FAILURE;
    }

    /* 初始化任务数据的编辑环境变量(缺省状态下为适应命令行的输入)  */
    pTermStruct->iMaxLen      = (_S32)ulSize ;
    pTermStruct->szEditBuf[0] = '\0' ;
    pTermStruct->iCurrentPos  = 0 ;

    if (ucMode == EN_GETSTRING_FOR_COMMAND)
    {
        EOS_StrCpy(pTermStruct->szInputCmd, pTermStruct->pWS->szCmdString);
        if (pTermStruct->szInputCmd[strlen(pTermStruct->szInputCmd) - 1] != 0x20)
        {
            EOS_StrCat(pTermStruct->szInputCmd, " ");
        }
        EOS_StrCat(pTermStruct->szInputCmd, pTermStruct->szEditBuf);
        EOS_StrCpy(pTermStruct->szEditBuf,  pTermStruct->szInputCmd);
        pTermStruct->iCurrentPos  = (_S32)strlen(pTermStruct->szEditBuf) ;

        pTermStruct->iEditStatus  = COMMAND_INPUT;
    }
    else
        pTermStruct->iEditStatus  = STRING_INPUT;

    for(;;)

⌨️ 快捷键说明

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