Command line interface for UART.

UARTでコマンドラインインターフェースを実現するためのライブラリです。

UARTからコマンドが入力されるとReadLine関数をコールバックします。

コマンドのデリミタはCR(0x0d)です。

コマンドはバックスペースで消去できます。

#include "mbed.h"
#include "MjLineSerial.h"

using namespace matsujirushi;

RawSerial pc(USBTX, USBRX);
MjLineSerial line(&pc);

void readLineFunc(const char *str)
{
    if (strcmp(str, "apple") == 0)
    {
        line.puts("RINGO");
    }
    else if (strcmp(str, "orange") == 0)
    {
        line.puts("MIKAN");
    }
    else
    {
        line.puts("unknown.");
    }
    line.puts("\r\n");
    
    line.putc('>');
}

int main()
{
    pc.baud(115200);
    line.attachReadLine(readLineFunc);
    
    line.putc('>');
    for (;;)
    {
        line.task();
    }
}

MjLineSerial.cpp

Committer:
matsujirushi
Date:
2014-11-21
Revision:
5:b7902dd4ab46
Parent:
4:14ef86f5de57

File content as of revision 5:b7902dd4ab46:

#include "MjLineSerial.h"
#include <cstdarg>

#define STRING_STACK_LIMIT    120

namespace matsujirushi {

MjLineSerial::MjLineSerial(RawSerial *serial)
{
    baseSerial = serial;
    readLineFunc = NULL;
    txDelimiter = "\r\n";
    echo = true;
}

int MjLineSerial::putc(int c)
{
    txBuffer.push(c);
    return c;
}

int MjLineSerial::puts(const char *str)
{
    for (; *str != '\0'; str++)
    {
        putc(*str);
    }
    
    return 0;
}

int MjLineSerial::printf(const char *format, ...)
{
    std::va_list arg;
    va_start(arg, format);
    int len = vsnprintf(NULL, 0, format, arg);
    if (len < STRING_STACK_LIMIT) {
        char temp[STRING_STACK_LIMIT];
        vsprintf(temp, format, arg);
        puts(temp);
    } else {
        char *temp = new char[len + 1];
        vsprintf(temp, format, arg);
        puts(temp);
        delete[] temp;
    }
    va_end(arg);
    return len;
}

void MjLineSerial::attachReadLine(void (*func)(const char *str))
{
    readLineFunc = func;
}

void MjLineSerial::task()
{
    while (baseSerial->readable())
    {
        char c = baseSerial->getc();
        switch (c)
        {
        case '\r':
            if (readLineFunc != NULL)
            {
                rxBuffer.push_back('\0');
                if (echo) puts(txDelimiter);
                readLineFunc(rxBuffer.begin());
            }
            rxBuffer.clear();
            break;
        case '\b':
            if (rxBuffer.size() <= 0)
            {
                if (echo) putc('\a');
            }
            else
            {
                rxBuffer.pop_back();
                if (echo) puts("\b \b");
            }
            break;
        default:
            rxBuffer.push_back(c);
            if (echo) putc(c);
            break;
        }
    }
    
    while (!txBuffer.empty())
    {
        if (!baseSerial->writeable()) break;
        baseSerial->putc(txBuffer.front());
        txBuffer.pop();
    }
}

} // namespace matsujirushi