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@4:14ef86f5de57, 2014-11-20 (annotated)
- Committer:
- matsujirushi
- Date:
- Thu Nov 20 13:21:03 2014 +0000
- Revision:
- 4:14ef86f5de57
- Parent:
- 3:e730a11160d7
- Child:
- 5:b7902dd4ab46
Add txDelimieter member.
Who changed what in which revision?
User | Revision | Line number | New 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 | 0:40d65405e747 | 13 | } |
matsujirushi | 0:40d65405e747 | 14 | |
matsujirushi | 0:40d65405e747 | 15 | int MjLineSerial::putc(int c) |
matsujirushi | 0:40d65405e747 | 16 | { |
matsujirushi | 3:e730a11160d7 | 17 | txBuffer.push(c); |
matsujirushi | 3:e730a11160d7 | 18 | return c; |
matsujirushi | 0:40d65405e747 | 19 | } |
matsujirushi | 0:40d65405e747 | 20 | |
matsujirushi | 1:833745ae8a7e | 21 | int MjLineSerial::puts(const char *str) |
matsujirushi | 1:833745ae8a7e | 22 | { |
matsujirushi | 1:833745ae8a7e | 23 | for (; *str != '\0'; str++) |
matsujirushi | 1:833745ae8a7e | 24 | { |
matsujirushi | 1:833745ae8a7e | 25 | putc(*str); |
matsujirushi | 1:833745ae8a7e | 26 | } |
matsujirushi | 1:833745ae8a7e | 27 | |
matsujirushi | 1:833745ae8a7e | 28 | return 0; |
matsujirushi | 1:833745ae8a7e | 29 | } |
matsujirushi | 1:833745ae8a7e | 30 | |
matsujirushi | 0:40d65405e747 | 31 | int MjLineSerial::printf(const char *format, ...) |
matsujirushi | 0:40d65405e747 | 32 | { |
matsujirushi | 0:40d65405e747 | 33 | std::va_list arg; |
matsujirushi | 0:40d65405e747 | 34 | va_start(arg, format); |
matsujirushi | 0:40d65405e747 | 35 | int len = vsnprintf(NULL, 0, format, arg); |
matsujirushi | 0:40d65405e747 | 36 | if (len < STRING_STACK_LIMIT) { |
matsujirushi | 0:40d65405e747 | 37 | char temp[STRING_STACK_LIMIT]; |
matsujirushi | 0:40d65405e747 | 38 | vsprintf(temp, format, arg); |
matsujirushi | 0:40d65405e747 | 39 | puts(temp); |
matsujirushi | 0:40d65405e747 | 40 | } else { |
matsujirushi | 0:40d65405e747 | 41 | char *temp = new char[len + 1]; |
matsujirushi | 0:40d65405e747 | 42 | vsprintf(temp, format, arg); |
matsujirushi | 0:40d65405e747 | 43 | puts(temp); |
matsujirushi | 0:40d65405e747 | 44 | delete[] temp; |
matsujirushi | 0:40d65405e747 | 45 | } |
matsujirushi | 0:40d65405e747 | 46 | va_end(arg); |
matsujirushi | 0:40d65405e747 | 47 | return len; |
matsujirushi | 0:40d65405e747 | 48 | } |
matsujirushi | 0:40d65405e747 | 49 | |
matsujirushi | 1:833745ae8a7e | 50 | void MjLineSerial::attachReadLine(void (*func)(const char *str)) |
matsujirushi | 1:833745ae8a7e | 51 | { |
matsujirushi | 1:833745ae8a7e | 52 | readLineFunc = func; |
matsujirushi | 1:833745ae8a7e | 53 | } |
matsujirushi | 1:833745ae8a7e | 54 | |
matsujirushi | 1:833745ae8a7e | 55 | void MjLineSerial::task() |
matsujirushi | 1:833745ae8a7e | 56 | { |
matsujirushi | 3:e730a11160d7 | 57 | while (baseSerial->readable()) |
matsujirushi | 1:833745ae8a7e | 58 | { |
matsujirushi | 2:84178b3b2824 | 59 | char c = baseSerial->getc(); |
matsujirushi | 1:833745ae8a7e | 60 | switch (c) |
matsujirushi | 1:833745ae8a7e | 61 | { |
matsujirushi | 1:833745ae8a7e | 62 | case '\r': |
matsujirushi | 1:833745ae8a7e | 63 | if (readLineFunc != NULL) |
matsujirushi | 1:833745ae8a7e | 64 | { |
matsujirushi | 1:833745ae8a7e | 65 | rxBuffer.push_back('\0'); |
matsujirushi | 4:14ef86f5de57 | 66 | puts(txDelimiter); |
matsujirushi | 1:833745ae8a7e | 67 | readLineFunc(rxBuffer.begin()); |
matsujirushi | 1:833745ae8a7e | 68 | } |
matsujirushi | 1:833745ae8a7e | 69 | rxBuffer.clear(); |
matsujirushi | 1:833745ae8a7e | 70 | break; |
matsujirushi | 1:833745ae8a7e | 71 | case '\b': |
matsujirushi | 1:833745ae8a7e | 72 | if (rxBuffer.size() <= 0) |
matsujirushi | 1:833745ae8a7e | 73 | { |
matsujirushi | 1:833745ae8a7e | 74 | putc('\a'); |
matsujirushi | 1:833745ae8a7e | 75 | } |
matsujirushi | 1:833745ae8a7e | 76 | else |
matsujirushi | 1:833745ae8a7e | 77 | { |
matsujirushi | 1:833745ae8a7e | 78 | rxBuffer.pop_back(); |
matsujirushi | 1:833745ae8a7e | 79 | puts("\b \b"); |
matsujirushi | 1:833745ae8a7e | 80 | } |
matsujirushi | 1:833745ae8a7e | 81 | break; |
matsujirushi | 1:833745ae8a7e | 82 | default: |
matsujirushi | 1:833745ae8a7e | 83 | rxBuffer.push_back(c); |
matsujirushi | 1:833745ae8a7e | 84 | putc(c); |
matsujirushi | 1:833745ae8a7e | 85 | break; |
matsujirushi | 1:833745ae8a7e | 86 | } |
matsujirushi | 1:833745ae8a7e | 87 | } |
matsujirushi | 3:e730a11160d7 | 88 | |
matsujirushi | 3:e730a11160d7 | 89 | while (!txBuffer.empty()) |
matsujirushi | 3:e730a11160d7 | 90 | { |
matsujirushi | 3:e730a11160d7 | 91 | if (!baseSerial->writeable()) break; |
matsujirushi | 3:e730a11160d7 | 92 | baseSerial->putc(txBuffer.front()); |
matsujirushi | 3:e730a11160d7 | 93 | txBuffer.pop(); |
matsujirushi | 3:e730a11160d7 | 94 | } |
matsujirushi | 1:833745ae8a7e | 95 | } |
matsujirushi | 1:833745ae8a7e | 96 | |
matsujirushi | 0:40d65405e747 | 97 | } // namespace matsujirushi |