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

📄 cli_io.c

📁 命令行在嵌入式系统的实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************************
Copyright 200X - 200X+1.

filename     : CLI_Io.c

description  : 本文件实现主机软件基本的输入输出,对外提供统一的接口;
               在实现上依赖终端数据,终端的输入输出功能。

author       : Woodhead

modification : Woodhead    create              2004-12-07
************************************************************************/

#include "Ros.h"
#include "ML.h"
#include "Sys_Ml.h"
#include "Cli_MlPriv.h"
#include "Cli_Private.inc"
#include "Cli_intp.inc"
#include "..\include\Cli_io.h"
#include "CLI_User.inc"

/* 异步输出控制结构,只在本文件中使用 */
static ASYNDISPLAY__S m_DispBase;
static _U8 m_CLIucScroll = SCROLL_MANUAL;

#define IO_FORMAT_STRING(ulTermID, ulInfoID, ulLen)                         \
{                                                                           \
    pFormat = ML_GetString(ulTermID, ulInfoID);                \
    if (pFormat == G_NULL || EOS_StrLen(pFormat) > ulLen - 200)             \
    {                                                                       \
        CLI_RECORD(CLI_STAT_OUTPUT_TOO_LONG);                               \
        MT_ERRLOG(0);                                                       \
        return G_FAILURE;                                                   \
    }                                                                       \
    va_start(arglist, ulInfoID) ;                                           \
    if (vsprintf(szOutPut, pFormat, arglist) >= ulLen)                      \
    {                                                                       \
        CLI_RECORD(CLI_STAT_OUTPUT_TOO_LONG);                               \
        return G_FAILURE;                                                   \
    }                                                                       \
    szOutPut[(ulLen) - 1] = '\0';                                           \
    va_end(arglist) ;                                                       \
}

/* 如果终端是web终端, 返回失败 */
#define RET_FAILURE_IF_IS_WEB_TERM( ulTermID )                              \
{                                                                           \
    if( IS_WEB_TERMID(ulTermID) )                                                   \
    {                                                                       \
        DBG_ASSERT(0);                                                      \
        return G_FAILURE;                                                   \
    }                                                                       \
}

/*-------------------------------------------------------------------*/
/* 函数名称 : IO_PrintToTerm                                         */
/* 功    能 : 将格式化串输出到指定终端                               */
/* 输入参数 : ulTermID:终端ID                                        */
/*            ulInfoID:语种资源ID                                    */
/* 输出参数 : 无                                                     */
/* 返回值   : 成功、失败                                             */
/* 调用说明 : 调用本函数需要确保ulInfoID在语种资源中已经有定义,且该 */
/*            资源字符串的最长不得超过2K                             */
/* 典型示例 : IO_PrintToTerm(1, CLI_LOG_FAILED_TIME,3)               */
/*            其中CLI_LOG_FAILED_TIME 对于中文语种信息为:            */
/*                            "\r\n  你已连续登录失败%d次! "         */
/*-------------------------------------------------------------------*/
_U32  IO_PrintToTerm(_U32 ulTermID, _U32 ulInfoID, ...)
{
    _S8 szOutPut[OUTB_DIRRECT_LENTGH] = "";
    const _S8 *pFormat;
    PTerm_Data_S pTermStruct;
    va_list arglist ;

#if ( CLI_WEB_SUPPORT == G_YES )
    RET_FAILURE_IF_IS_WEB_TERM(ulTermID);
#endif

    CLI_ASSURE_OR_FAIL(CLI_IS_TERMID_VALIDE(ulTermID));

    /* 格式化串的组织 */
    IO_FORMAT_STRING(ulTermID, ulInfoID, OUTB_DIRRECT_LENTGH);

    pTermStruct = m_TDTable[ulTermID - 1].pTermStruct;

    return IO_OutToTerm(pTermStruct, szOutPut);
}

/*-------------------------------------------------------------------*/
/* 函数名称 : IO_Print                                               */
/* 功    能 : 将格式化串输出到当前终端                               */
/* 输入参数 : ulInfoID 多语种资源ID                                  */
/* 输出参数 : 无                                                     */
/* 返回值   : 成功、失败                                             */
/* 调用说明 : 调用本函数需要确保ulInfoID在语种资源中已经有定义,且该 */
/*            资源字符串的最长不得超过2K                             */
/* 典型示例 : IO_Print(CLI_LOG_FAILED_TIME,3)                        */
/*            其中CLI_LOG_FAILED_TIME 对于中文语种信息为:            */
/*                            "\r\n  你已连续登录失败%d次! "         */
/*-------------------------------------------------------------------*/
_U32  IO_Print(_U32 ulInfoID, ...)
{
    _S8 szOutPut[OUTB_DIRRECT_LENTGH] = "";
    const _S8 *pFormat;
    PTerm_Data_S pTermStruct;
    _U32 ulTermID;
    va_list arglist ;

    if ((pTermStruct = CLI_GetCurrentTaskData()) == G_NULL)
        return G_FAILURE;

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

    ulTermID = pTermStruct->ulTermId;

    /* 格式化串的组织 */
    IO_FORMAT_STRING(ulTermID, ulInfoID, OUTB_DIRRECT_LENTGH);

    return IO_OutToTerm(pTermStruct, szOutPut);
}

/*-------------------------------------------------------------------*/
/* 函数名称 : IO_PrintToAllTerm                                      */
/* 功    能 : 将格式化串输出到所有终端                               */
/* 输入参数 : ulInfoID 多语种资源ID                                  */
/* 输出参数 : 无                                                     */
/* 返回值   : 成功、失败                                             */
/* 调用说明 : 暂不对外提供                                           */
/*-------------------------------------------------------------------*/
_U32  IO_PrintToAllTerm(_U32 ulInfoID, ...)
{
    _S8 szOutPut[OUTB_DIRRECT_LENTGH] = "";
    const _S8 *pFormat;
    PTerm_Data_S pTermStruct;
    _U32 ulTermID;
    _U32 ulRet = G_FAILURE;
    va_list arglist ;

    for (ulTermID = 1; ulTermID <= m_ulCliMaxOnlineUser; ulTermID ++)
    {
        pTermStruct = m_TDTable[ulTermID-1].pTermStruct;

        /* 仅输出到用户正确登录的终端 */
        if (pTermStruct->ucTermStatus < TERM_LOGED)
            continue;

        /* 格式化串的组织 */
        IO_FORMAT_STRING(ulTermID, ulInfoID, OUTB_DIRRECT_LENTGH);

        if (IO_OutToTerm(pTermStruct, szOutPut) == G_SUCCESS)
            ulRet = G_SUCCESS;  //只要发送到一个终端成功即告成功
    }

    return ulRet;
}

/*-------------------------------------------------------------------*/
/* 函数名称 : IO_SendToTerm                                          */
/* 功    能 : 将格式化串输出到当前终端                               */
/* 输入参数 : ulTermID:终端ID,ulInfoID 语种信息ID                   */
/* 输出参数 : 无                                                     */
/* 返回值   : 成功、失败                                             */
/* 调用说明 : 调用本函数需要确保ulInfoID在语种资源中已经有定义,且该 */
/*            资源字符串的最长不得超过1K. 该函数的返回值仅表示发送到 */
/*            异步输出队列的成功与失败,并不表示输出的正常与否       */
/* 典型示例 : IO_PrintToTerm(1, CLI_LOG_FAILED_TIME,3)               */
/*            其中CLI_LOG_FAILED_TIME 对于中文语种信息为:            */
/*                            "\r\n  你已连续登录失败%d次! "         */
/*-------------------------------------------------------------------*/
_U32  IO_SendToTerm(_U32 ulTermID, _U32 ulInfoID, ...)
{
    _S8 szOutPut[OUTBUFF_LENGTH] = "";
    const _S8 *pFormat;
    va_list arglist ;

#if ( CLI_WEB_SUPPORT == G_YES )
    RET_FAILURE_IF_IS_WEB_TERM(ulTermID);
#endif

    CLI_ASSURE_OR_FAIL(CLI_IS_TERMID_VALIDE(ulTermID));

    /* 格式化串的组织 */
    IO_FORMAT_STRING(ulTermID, ulInfoID, OUTBUFF_LENGTH);

    return IO_InsertDispInfo(ulTermID, szOutPut);
}

/*-------------------------------------------------------------------*/
/* 函数名称 : IO_SendToAllTerm                                       */
/* 功    能 : 将格式化串异步输出到所有终端                           */
/* 输入参数 : ulInfoID 多语种资源ID                                  */
/* 输出参数 : 无                                                     */
/* 返回值   : 成功、失败                                             */
/* 调用说明 : 调用本函数需要确保ulInfoID在语种资源中已经有定义,且该 */
/*            资源字符串的最长不得超过1K. 该函数的返回值仅表示发送到 */
/*            异步输出队列的成功与失败,并不表示输出的正常与否       */
/* 典型示例 : IO_SendToAllTerm(CLI_LOG_FAILED_TIME,3)                */
/*            其中CLI_LOG_FAILED_TIME 对于中文语种信息为:            */
/*                            "\r\n  你已连续登录失败%d次! "         */
/*-------------------------------------------------------------------*/
_U32  IO_SendToAllTerm(_U32 ulInfoID, ...)
{
    _S8 szOutPut[OUTBUFF_LENGTH];
    const _S8 *pFormat;
    _U32 ulTermID, ulRet = 0;
    va_list arglist ;
    PTerm_Data_S pTermStruct;

    for (ulTermID = 1; ulTermID <= m_ulCliMaxOnlineUser; ulTermID++)
    {
        //获取此结构指针只用来判断当前终端是否为MML,如果是,则不输出信息
        pTermStruct = m_TDTable[ulTermID - 1].pTermStruct;

        if(pTermStruct->iSocket != SOCKET_FOR_MML)    //如果不是MML连接方式,才输出信息
        {
            /* 格式化串的组织 */
            IO_FORMAT_STRING(ulTermID, ulInfoID, OUTBUFF_LENGTH);

            ulRet &=IO_InsertDispInfo(ulTermID, szOutPut);
        }
        else
        {
            continue;
        }
    }

    if (ulRet == G_SUCCESS)
    {
        return G_SUCCESS;
    }
    return G_FAILURE;
}

/*-------------------------------------------------------------------*/
/* 函数名称 : IO_OutString                                           */
/* 功    能 : 直接输出字符串到当前终端                               */
/* 输入参数 : szOutput 输出信息串                                    */
/* 输出参数 : 无                                                     */
/* 返回值   : 成功、失败                                             */
/* 调用说明 : 直接输出,该函数的调用者多为调试信息输出与特殊要求的   */
/*            输出,如果当前任务非终端任务,则输出到串口               */
/* 典型示例 : IO_OutString("\r\n  正确输出.")                        */
/*-------------------------------------------------------------------*/
_U32  IO_OutString(const _S8 *szOutput)
{
    PTerm_Data_S pTermStruct;

    if ((pTermStruct = CLI_GetCurrentTaskData()) == G_NULL)
    {
        /*如果当前任务非终端任务,而串口已经登录,则打印到串口*/
        pTermStruct = m_TDTable[0].pTermStruct;
        if (pTermStruct->ucTermStatus < TERM_LOGED)
            return G_FAILURE;
    }

    return IO_OutToTerm(pTermStruct, szOutput);
}

/*-------------------------------------------------------------------*/
/* 函数名称 : IO_OutString                                           */
/* 功    能 : 直接输出字符串到调试终端                               */
/* 输入参数 : szOutput 输出信息串                                    */
/* 输出参数 : 无                                                     */
/* 返回值   : 成功、失败                                             */
/* 调用说明 : 该接口只提供给调试模块的调试输出使用                   */
/* 典型示例 : IO_DebugOutString("\r\n  函数调用错误!")               */
/*-------------------------------------------------------------------*/
_U32  IO_DebugOutString(_S8 *szOutput)
{
    PTerm_Data_S pTermStruct;

    CLI_ASSURE_OR_FAIL( szOutput != G_NULL);

    /* 调试用户可能不在命令行终端, 可能从其他终端(如web网管)登录, 返回成功 */
    if( ! CLI_IS_TERMID_VALIDE(m_sUserTable[0].ulTermId) )
    {
        return G_SUCCESS;
    }

    if (m_sUserTable[0].ucUserStatus >= TERM_LOGED)
        pTermStruct = m_TDTable[m_sUserTable[0].ulTermId - 1].pTermStruct;
    else
        return G_FAILURE;

    if (pTermStruct->ucTermStatus == TERM_WAIT_RESPONSE)
    {
        /* 如果终端处于等待从设备命令返回的阶段,不应有任何其它的输出干扰 */
        return G_FAILURE;
    }

    return IO_OutToTerm(pTermStruct, szOutput);
}

/*********************************************************************/
/* 函数名称 : IO_InsertDispInfo()                                    */
/* 函数功能 : 将准备输出的信息插入到输出队列                         */
/* 输入参数 : ulTermID:终端ID, szOutput 输出的信息串                 */
/* 输出参数 : 无                                                     */
/* 返回     : 成功、失败                                             */
/* 上层函数 :                                                        */
/* 创建者   :                                                        */
/* 修改记录 :                                                        */
/*********************************************************************/
_U32 IO_InsertDispInfo(_U32 ulTermID, _S8 *szOutput)
{
    struct AsynDisplay_Element_S *pAsynDispItem;
    _S8 *pOutput;
    PTerm_Data_S pTermStruct;

    CLI_ASSURE_OR_FAIL(CLI_IS_TERMID_VALIDE(ulTermID) && szOutput != G_NULL);

    /* 如果队列已满,新来信息不再入列,直接返回 */
    if (CLI_INCCYCLE(m_DispBase.ulLastPos, ASYN_DISPLAY_NUM) == m_DispBase.ulFirstPos)
        return G_FAILURE;

    pTermStruct = m_TDTable[ulTermID - 1].pTermStruct;
    /* 如果发送的目的终端尚未正确登录,取消发送 */
    if (pTermStruct->ucTermStatus < TERM_LOGED || pTermStruct->ulTimeLeft == 0)
        return G_FAILURE;

    /* 为输出信息申请一块空间 */
    pOutput = (_S8 *)ROS_MemAlloc(EOS_StrLen(szOutput) + 1, ROS_MEM_ALLOC_OPT_LEAK_CHECK);
    if (pOutput == G_NULL)
    {
        MT_ERRLOG(0);
        return G_FAILURE;
    }

⌨️ 快捷键说明

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