命令解释器的设计及实现

1 命令解释器的设计及实现

命令解释器的实现较为简单,流程简单归纳为:

  • 打印命令提示符
  • 读取一行字符串
  • 解析命令,执行操作,必要时打印结果

主要实现了如下命令:
在这里插入图片描述
实现代码如下:
cli.h:

/**
 * @brief 命令解释器设计
 * @details
 * @author 01课堂 李述铜 http://01ketang.cc
 * @date 2017-06-01
 * @version 1.0
 * @copyright 版权所有,禁止用于商业用途
 */
#ifndef CLI_H
#define CLI_H

#define CLI_TASK_PRIO                     0
#define CLI_CMD_PROMATE_SIZE            64
#define CLI_TASK_ENV_SIZE               512
#define CLI_CMD_HISTORY_SIZE            1024
#define CLI_CMD_BUFFER_SIZE             128

void CLIInit (void);

#endif //CLI_H

cli.c:

/**
 * @brief 命令解释器设计
 * @details
 * @author 01课堂 李述铜 http://01ketang.cc
 * @date 2017-06-01
 * @version 1.0
 * @copyright 版权所有,禁止用于商业用途
 */
#include <string.h>
#include "tinyOS.h"
#include "cli.h"
#include "uart.h"
#include "extio.h"
#include "WaveGen.h"

#define TERMINAL_BS     0x08
#define TERMINAL_SPACE  ' '
#define TERMINAL_CR     '\r'
#define TERMINAL_LF     '\n'
#define TERMINAL_TAB    '\t'

// 空白字符
static const char spaceCh[] = {TERMINAL_SPACE, TERMINAL_CR, TERMINAL_LF, TERMINAL_TAB, '\0'};
static const char * unknownPinMsg = "Unknown Pin\r\n";
static const char * unknownCmdMsg = "Unknown Command!\r\n";
static const char * noEnoughParamMsg = "No Enough Param!\r\n";

// 任务相关
static tTaskStack cliTaskEnv[CLI_TASK_ENV_SIZE];     // 任务1的堆栈空间
static tTask cliTask;

// 命令行提示缓冲区
static char promoteBuffer[CLI_CMD_PROMATE_SIZE];

/**
 * 显示消息
 */
static void showMsg (const char * msg) {
    UartWrite(msg, strlen(msg));
}

/**
 * 输出显示字符
 * @param ch
 */
static void showCh (const char ch) {
    UartWrite(&ch, 1);
}

/**
 * 显示提示符
 */
static void showPromote (void) {
    UartWrite(promoteBuffer, strlen(promoteBuffer));
}

/**
 * 更改提示符
 */
static void setPromote (const char * newPromote) {
    strncpy(promoteBuffer, newPromote, sizeof(promoteBuffer));
    promoteBuffer[sizeof(promoteBuffer) - 1] = '\0';
}

/**
 * 提示符修改命令
 */
static void promoteCmd (void) {
    char * promote = strtok(NULL, spaceCh);
    if (promote == NULL) {
        showMsg(noEnoughParamMsg);
        return;
    }

    setPromote(promote);
}

/**
 * 将引脚名转换为内部序号
 * @param pinCh
 * @return
 */
static ExtIOPin convertPinNum (char * pinCh) {
    ExtIOPin pinNum;

    if (pinCh == NULL) {
        return ExtIOPinEnd;
    }

    pinNum = (ExtIOPin)(*pinCh - '0');
    if (pinNum >= ExtIOPinEnd) {
        return ExtIOPinEnd;
    }

    return pinNum;
}

/**
 * 外部IO命令解析
 */
static void extioCmd () {
    char * type = strtok(NULL, spaceCh);
    if (type == NULL) {
        showMsg(noEnoughParamMsg);
        return;
    }

    if (strstr(type, "get")) {      // 命令extio get pin
        ExtIOPin pin;
        ExtIOState state;

        pin = convertPinNum(strtok(NULL, spaceCh));
        if (pin == ExtIOPinEnd) {
            showMsg(unknownPinMsg);
            return;
        }

        state = ExtIOGetState(pin);
        showMsg((state == ExtIOHigh) ? "1\r\n" : "0\r\n");
    } else if (strstr(type, "set")) {   // 命令extio set pin value
        ExtIOPin pin;
        char * value;

        pin = convertPinNum(strtok(NULL, spaceCh));
        if (pin == ExtIOPinEnd) {
            showMsg(unknownPinMsg);
            return;
        }

        value = strtok(NULL, spaceCh);
        if (value == NULL) {
            showMsg(noEnoughParamMsg);
            return;
        }

        ExtIOSetState(pin, *value == '0' ? ExtIOLow : ExtIOHigh);
    } else if (strstr(type, "dir")) {   // 命令extio dir pin in/out
        ExtIOPin pin;
        char *outType;

        pin = convertPinNum(strtok(NULL, spaceCh));
        if (pin == ExtIOPinEnd) {
            showMsg(unknownPinMsg);
            return;
        }

        outType = strtok(NULL, spaceCh);
        if (outType == NULL) {
            showMsg(noEnoughParamMsg);
            return;
        }

        ExtIOSetDir(pin, strstr(outType, "in") ? 1 : 0);
    } else {
        showMsg(noEnoughParamMsg);
    }
}

/**
 * 波形输出命令解析
 */
static void waveCmd () {
    char *type = strtok(NULL, spaceCh);
    if (type == NULL) {
        showMsg(noEnoughParamMsg);
        return;
    }

    if (strstr(type, "square")) {      // 命令wave square
        WaveSelectType(WaveSquare);
    } else if (strstr(type, "start")) {
        WaveStartOutput();
    } else if (strstr(type, "stop")) {
        WaveStopOutput();
    } else {
        showMsg(noEnoughParamMsg);
    }
}

/**
 * 未知命令处理
 */
static void unknowCmd (void) {
    showMsg(unknownCmdMsg);
}

/**
 * 读取一行数据,如果命令超过则截断
 */
static void readLine (char * buffer, uint32_t maxLen) {
    uint32_t index = 0;

    while (index < maxLen) {
        char ch;

        UartRead(&ch, 1);
        switch (ch) {
            case TERMINAL_BS:   // 退格键
                if (index > 0) {
                    buffer[index--] = '\0';
                    showCh(TERMINAL_BS);
                    showCh(TERMINAL_SPACE);
                    showCh(TERMINAL_BS);
                }
                break;
            case TERMINAL_CR:
                showCh(TERMINAL_LF);
            default:
                showCh(ch);

                buffer[index++] = ch;
                if ((ch == '\n') || (ch == '\r') || (index >= maxLen)) {
                    buffer[index] = '\0';
                    return;
                }
                break;
        }
    }
}

/**
 * 解析命令
 */
static void processCmd (char * cmdLine) {
    char * cmdStart;

    // 获取开头
    cmdStart = strtok(cmdLine, spaceCh);
    if (cmdStart == NULL) {
        return;
    }

    // 识别命令
    if (strstr(cmdStart, "extio")) {
        extioCmd();
    } else if (strstr(cmdStart, "wave")) {
        waveCmd();
    } else if (strstr(cmdStart, "promote")){
        promoteCmd();
    } else {
        unknowCmd();
    }
}

/**
 * 解释器任务
 * @param param
 */
void cliTaskEntry (void * param) {
    static char cmdBuffer[CLI_CMD_BUFFER_SIZE];

    for (;;) {
        showPromote();
        readLine(cmdBuffer, sizeof(cmdBuffer));
        processCmd(cmdBuffer);
    }
}


/**
 * 命令解释器设计
 */
void CLIInit (void) {
    strcpy(promoteBuffer, ">>");
    tTaskInit(&cliTask, cliTaskEntry, (void *) 0x0, CLI_TASK_PRIO, cliTaskEnv, sizeof(cliTaskEnv));
}



参考资料:

  1. 手把手教你学用嵌入式操作系统

猜你喜欢

转载自blog.csdn.net/SlowIsFastLemon/article/details/106420320
今日推荐