串行命令解析

时间:2014-01-29 10:41:09

标签: c embedded

我对C和编程很新,我试图实现 一个简单的命令解析器函数,它应该执行以下操作:

从串行线读取字符并解析字符串“boot \ n”。 如果我收到此命令,我想通过串行输出应用程序的名称。 对于命令“boot AppName \ n”,我将使用AppName中给出的名称启动应用程序。 我怎样才能通过一个非常简单的解析器实现这一点,简单来说就是代码复杂性?

static void parse_input(void)
{
    uint16_t i;
    char input_buf[30];
    char c;

    read_character(&c);
    if (c == '\n') /* sync character */
        for (i=0; i < 20; i++)
        {
            read_character(&c);
            input_buf[i] = c;
        }
    /* check for string "boot" in input buffer */
    /* maybe string compare? */
}

THX

3 个答案:

答案 0 :(得分:2)

鉴于你正在使用固定大小的输入缓冲区,我只是满足于:

fflush(stdout);
if ((fgets(input_buf, 30, stdin)) == NULL)
{
    puts("No input...");
    return;
}
if ((strncmp(buffer, "boot", 4)) != 0)
{//boot was NOT found
    printf("Command: %s is unknown\n", buffer);
    return;
}
//boot was found, so something like:
char *token = strtok(buffer, " \n");
while(token != NULL)
{
    token = strtok(NULL, " \n");
    if (token) printf("To boot -> %s\n", token);
}

后者只是“chunking”字符串,使用空格作为分隔符。因此,在第一次调用后,令牌将指向boot,然后它将指向随后的单词(如果有)。

当然,更简单的方法就是

char *boot_what = buffer+5;
buffer[4] = '\0';

但这意味着缓冲区的前5个字符确实是'b''o''o''t'' ',最简单的方法是:

char *boot_ptr = strstr(buffer, "boot ");

因为strstr返回指向给定字符串中找到字符串的位置的指针......啊,好好利用<string.h>中的函数找到最适合你的函数purpouse。

答案 1 :(得分:1)

我认为最好的方法是使用状态机如下:

  • 取一个整数变量state,最初等于0,表示找不到任何字符。

  • 此变量将是switch语句

  • 的条件
  • 案例0:继续扫描字符,直到找到'b',您将state更新为1

  • 对于案例1,同样,您将搜索'o',如果您遇到任何其他字符,请将state重置为0

  • 同样适用于'o''t'

  • "boot"之后的任何内容将成为您的AppName。

答案 2 :(得分:1)

获取串行数据和解析的另一种方法如下我修改了你的代码

static void parse_input(void)
{
    uint16_t i;
    char input_buf[30];
    char c;
    char cmdBuf[ 1024 ];    /* character input buffer */

    int bufPos = 0;

    memset(cmdBuf,0, 1024);
    for(;;) 
    {
        read_character(&c);
        if( ( c == '\r') || ( c == '\n' ) ) 
        {
          if( ( 1 + bufPos ) < 1024 ) {
                cmdBuf[bufPos++] = '\0';
            }

            if(cmdBuf[0] != 0)
            {
                //serial data available in cmdBuf
                //here your code what to do
               //whether you application or other stuff

            }

            break;
        }
        else 
        {
            if( c == '\b' ) 
            {
                if( bufPos > 0 ) {
                    bufPos--;
                }
            }
            else 
            {
                if( ( 1 + bufPos ) < 1024 ) {
                    cmdBuf[bufPos++] = c;
                }
            }
        }
    }

}