Этот пример кода обрабатывает содержимое кольцевого буфера [2] bufRX с указателями inRX и outRX. Не существенные с точки зрения обработки ввода пользователя куски кода не показны.
Заголовочный файл decodeRX.h:
#ifndef __DECODERX__
#define __DECODERX__
 
typedef enum
{// Возможные значения для переменной action:
   ACTION_NONE,      // ничего не делать, ожидание команды
   ACTION_BACKSPACE, // удаление символа слева от курсора
   ACTION_TAB,       // действие по клавише Tab (пока ничего не делать)
   ACTION_ENTER,     // обработка введенной команды
   ACTION_SHOW_HELP, // показать подсказку по командной строке
}TCmdAction;
 
typedef enum
{
   SYM_SINGLE,       // ожидание ввода пользователя по одному символу
   SYM_1B            // начало Esc-последовательности
}TDecodeMode;
 
void DecodeConsoleCommands (void);
 
#endif
 
Модуль decodeRX.c:
#include < string.h>
#include "decodeRX.h"
#include "UARTconsole.h"
#include "miscell.h"
#include "umsg.h"
 
static TCmdAction action = ACTION_NONE;
static TDecodeMode decodemode = SYM_SINGLE;
 
static const char trimsymbols [] =
{
   0x08, 0x09, 0x0D, 0x0A, 0
};
 
// Таймаут приема (ввод символов в консоли)
// в единицах 10 мс:
#define RX_TIMEOUT   10
 
static char cmddata[MAX_CMD_LEN];
 
static void GetCmdData (u16 idxstart, u16 idxend)
{
   u16 idx = 0;   
   while ((idxstart != idxend) && (idx < sizeof(cmddata)-1))
   {
      cmddata[idx++] = bufRX[idxstart];
      idxstart++;
      idxstart &= UART_RXBUFMASK;
   }
   cmddata[idx] = 0;
   ltrim ((char*)cmddata, (char*)trimsymbols);
   rtrim ((char*)cmddata, (char*)trimsymbols);
}
 
// Функция обработки получаемых по UART символов (команды
// пользователя, вводимые в консоли). Рассчитана на вызов
// с интервалом 10 мс (из бесконечного цикла main).
void DecodeConsoleCommands (void)
{
   // Счетчик таймаута между повлениями символов
   // (нажатиями клавиш пользователя в терминале):
   static u16 timeoutcnt = RX_TIMEOUT;
   // Индекс начала команды:
   static u16 idxStart = 0;
   u8 sym;
   int cmdlen;
   u16 idx;
   if (inRX == outRX)
   {
      // Символов на приеме нет, декремент счетчика таймаута.
      if (timeoutcnt)
      {
         // Таймаут не истек, декремент таймаута:
         timeoutcnt--;
      }
      else
      {
         // Таймаут истек, проверка ESC-последовательности:
         if (SYM_1B == decodemode)
         {
            umsg("Esc-коды: ");
            GetCmdData(idxStart, outRX);
            cmdlen = strlen((char*)cmddata);
            for (idx=0; idx < cmdlen; idx++)
            {
               umsg("%02X ", cmddata[idx]);
            }
            umsg("\n");
            idxStart = outRX;
            decodemode = SYM_SINGLE;
         }
      }
   }
   else
   {
      // Были обработаны символы, сброс таймаута
      timeoutcnt = RX_TIMEOUT;
   }
      
   while (inRX != outRX)
   {
      // Выборка символа:
      sym = bufRX[outRX];
      outRX++;
      outRX &= UART_RXBUFMASK;
      switch(decodemode)
      {
      case SYM_SINGLE:
         if (0x08 == sym)
         {
            action = ACTION_BACKSPACE;
            idxStart = outRX;
         }
         else if (0x09 == sym)
         {
            action = ACTION_TAB;
            idxStart = outRX;
         }
         else if ('?' == sym)
         {
            action = ACTION_SHOW_HELP;
            idxStart = outRX;
         }
         else if (0x1B == sym)
         {
            decodemode = SYM_1B;
         }
         else if (0x0D == sym)
         {
            GetCmdData(idxStart, outRX);
            action = ACTION_ENTER;
            idxStart = outRX;
         }
         else
         {
            umsg("%c", sym);
         }
         break;
      case SYM_1B:
         break;
      }
   }
   
   switch(action)
   {
   case ACTION_NONE:
      break;
   case ACTION_BACKSPACE:
      umsg("BACKSPACE\n");
      action = ACTION_NONE;
      break;
   case ACTION_TAB:
      umsg("TAB\n");
      action = ACTION_NONE;
      break;
   case ACTION_ENTER:
      umsg("Введена команда %s\n", cmddata);
      action = ACTION_NONE;
      break;
   case ACTION_SHOW_HELP:
      umsg("HELP\n");
      action = ACTION_NONE;
      break;
   }
}
 
Ниже на скриншоте показан результат обработки ввода пользователя в окне терминала. Нажимались клавиши Backspace, Tab, Esc и т. д. (клавиши, показанные в таблице выше). Также демонструется ввод команд и вывод подсказки (HELP) в ответ на ввод символа '?'.
