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();
    }
}
Committer:
matsujirushi
Date:
Fri Nov 21 10:48:30 2014 +0000
Revision:
5:b7902dd4ab46
Parent:
4:14ef86f5de57
Add echo member.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
matsujirushi 0:40d65405e747 1 #include "MjLineSerial.h"
matsujirushi 0:40d65405e747 2 #include <cstdarg>
matsujirushi 0:40d65405e747 3
matsujirushi 0:40d65405e747 4 #define STRING_STACK_LIMIT 120
matsujirushi 0:40d65405e747 5
matsujirushi 0:40d65405e747 6 namespace matsujirushi {
matsujirushi 0:40d65405e747 7
matsujirushi 0:40d65405e747 8 MjLineSerial::MjLineSerial(RawSerial *serial)
matsujirushi 0:40d65405e747 9 {
matsujirushi 0:40d65405e747 10 baseSerial = serial;
matsujirushi 1:833745ae8a7e 11 readLineFunc = NULL;
matsujirushi 4:14ef86f5de57 12 txDelimiter = "\r\n";
matsujirushi 5:b7902dd4ab46 13 echo = true;
matsujirushi 0:40d65405e747 14 }
matsujirushi 0:40d65405e747 15
matsujirushi 0:40d65405e747 16 int MjLineSerial::putc(int c)
matsujirushi 0:40d65405e747 17 {
matsujirushi 3:e730a11160d7 18 txBuffer.push(c);
matsujirushi 3:e730a11160d7 19 return c;
matsujirushi 0:40d65405e747 20 }
matsujirushi 0:40d65405e747 21
matsujirushi 1:833745ae8a7e 22 int MjLineSerial::puts(const char *str)
matsujirushi 1:833745ae8a7e 23 {
matsujirushi 1:833745ae8a7e 24 for (; *str != '\0'; str++)
matsujirushi 1:833745ae8a7e 25 {
matsujirushi 1:833745ae8a7e 26 putc(*str);
matsujirushi 1:833745ae8a7e 27 }
matsujirushi 1:833745ae8a7e 28
matsujirushi 1:833745ae8a7e 29 return 0;
matsujirushi 1:833745ae8a7e 30 }
matsujirushi 1:833745ae8a7e 31
matsujirushi 0:40d65405e747 32 int MjLineSerial::printf(const char *format, ...)
matsujirushi 0:40d65405e747 33 {
matsujirushi 0:40d65405e747 34 std::va_list arg;
matsujirushi 0:40d65405e747 35 va_start(arg, format);
matsujirushi 0:40d65405e747 36 int len = vsnprintf(NULL, 0, format, arg);
matsujirushi 0:40d65405e747 37 if (len < STRING_STACK_LIMIT) {
matsujirushi 0:40d65405e747 38 char temp[STRING_STACK_LIMIT];
matsujirushi 0:40d65405e747 39 vsprintf(temp, format, arg);
matsujirushi 0:40d65405e747 40 puts(temp);
matsujirushi 0:40d65405e747 41 } else {
matsujirushi 0:40d65405e747 42 char *temp = new char[len + 1];
matsujirushi 0:40d65405e747 43 vsprintf(temp, format, arg);
matsujirushi 0:40d65405e747 44 puts(temp);
matsujirushi 0:40d65405e747 45 delete[] temp;
matsujirushi 0:40d65405e747 46 }
matsujirushi 0:40d65405e747 47 va_end(arg);
matsujirushi 0:40d65405e747 48 return len;
matsujirushi 0:40d65405e747 49 }
matsujirushi 0:40d65405e747 50
matsujirushi 1:833745ae8a7e 51 void MjLineSerial::attachReadLine(void (*func)(const char *str))
matsujirushi 1:833745ae8a7e 52 {
matsujirushi 1:833745ae8a7e 53 readLineFunc = func;
matsujirushi 1:833745ae8a7e 54 }
matsujirushi 1:833745ae8a7e 55
matsujirushi 1:833745ae8a7e 56 void MjLineSerial::task()
matsujirushi 1:833745ae8a7e 57 {
matsujirushi 3:e730a11160d7 58 while (baseSerial->readable())
matsujirushi 1:833745ae8a7e 59 {
matsujirushi 2:84178b3b2824 60 char c = baseSerial->getc();
matsujirushi 1:833745ae8a7e 61 switch (c)
matsujirushi 1:833745ae8a7e 62 {
matsujirushi 1:833745ae8a7e 63 case '\r':
matsujirushi 1:833745ae8a7e 64 if (readLineFunc != NULL)
matsujirushi 1:833745ae8a7e 65 {
matsujirushi 1:833745ae8a7e 66 rxBuffer.push_back('\0');
matsujirushi 5:b7902dd4ab46 67 if (echo) puts(txDelimiter);
matsujirushi 1:833745ae8a7e 68 readLineFunc(rxBuffer.begin());
matsujirushi 1:833745ae8a7e 69 }
matsujirushi 1:833745ae8a7e 70 rxBuffer.clear();
matsujirushi 1:833745ae8a7e 71 break;
matsujirushi 1:833745ae8a7e 72 case '\b':
matsujirushi 1:833745ae8a7e 73 if (rxBuffer.size() <= 0)
matsujirushi 1:833745ae8a7e 74 {
matsujirushi 5:b7902dd4ab46 75 if (echo) putc('\a');
matsujirushi 1:833745ae8a7e 76 }
matsujirushi 1:833745ae8a7e 77 else
matsujirushi 1:833745ae8a7e 78 {
matsujirushi 1:833745ae8a7e 79 rxBuffer.pop_back();
matsujirushi 5:b7902dd4ab46 80 if (echo) puts("\b \b");
matsujirushi 1:833745ae8a7e 81 }
matsujirushi 1:833745ae8a7e 82 break;
matsujirushi 1:833745ae8a7e 83 default:
matsujirushi 1:833745ae8a7e 84 rxBuffer.push_back(c);
matsujirushi 5:b7902dd4ab46 85 if (echo) putc(c);
matsujirushi 1:833745ae8a7e 86 break;
matsujirushi 1:833745ae8a7e 87 }
matsujirushi 1:833745ae8a7e 88 }
matsujirushi 3:e730a11160d7 89
matsujirushi 3:e730a11160d7 90 while (!txBuffer.empty())
matsujirushi 3:e730a11160d7 91 {
matsujirushi 3:e730a11160d7 92 if (!baseSerial->writeable()) break;
matsujirushi 3:e730a11160d7 93 baseSerial->putc(txBuffer.front());
matsujirushi 3:e730a11160d7 94 txBuffer.pop();
matsujirushi 3:e730a11160d7 95 }
matsujirushi 1:833745ae8a7e 96 }
matsujirushi 1:833745ae8a7e 97
matsujirushi 0:40d65405e747 98 } // namespace matsujirushi
matsujirushi 5:b7902dd4ab46 99