Отлаживаем протокол AT комманд для ESP WROOM 02
Протокол AT команд - протокол управления модемом через подачу управляющих команд , начинающихся с символов AT.
Разделяются порции данных символами CR LF ('\n\r'). Так исторически сложилось с незапамятных времен.
Тренируемся на модуле, взятом из ккт Меркурий 185, просто потому, что он был по рукой.

Нас интересует задача : установить TCP соединение по протоколу HTTP, запросить данные GET запросом и принять данные со страницы сайта.
Схема подключения есть:

Управляется ESP WROOM 02 по каналу UART на скорости 115200.
Подал команду, ждем ответа. Парсим ответ. И так далее.
Проблема №1 : многообразие вариантов ответов на AT команды
Может использоваться эхо, т.е. твоя посланная команда будет сначала присылаться тебе полностью обратно от приемника (для контроля приема) , а может эхо и не использоваться.
Главная путаница в том , что на некоторые AT команды подтверждаются в ответом 'n\r\OK\n\r', 'n\r\ERROR\n\r', а некоторые нет .
К тому же некоторые команды (с основном оп TCP соединениям) возвращают сначала что-то типа 'n\r\OK\n\r', 'n\r\ERROR\n\r' , а потом позже 'n\r\CONNECT OK\n\r' , 'n\r\SEND OK\n\r'.
Надо по идеи учитывать (отрабатывать) все возможные варианты ответов.
А вот как это делать (т.е. парсить данные) , одновременно успевая принимать очередные данные из порта - вот это проблема №2.
Проблема №2 решается через прерывания и очереди FreeRTOS
Задержка получения данных по TCP соединению может доходить до 30-40сек (это нормально).
По прерыванию HAL_UART_RxCpltCallback очередные данные быстро помещаются в приемную очередь xQueueSendToBackFromISR.
Если не успевать принимать байты будет вылетать HAL_UART_ErrorCallback, что сигнализирует о не правильной работе UART (скорее очередной байт не был считан и его затер последующий).
То есть это очень важный момент. Быстро принял байт , поместил в очередь и вышел.
Очень помогает логический анализатор
Без него ребята процесс может стать практически невозможным.

Как показывает логический анализатор ответы приходят (к счастью) пачками :
Например сначала приходит эхо, в которое в конце сразу добавлено 'n\r\OK\n\r' или 'n\r\ERROR\n\r'
Потом через некоторое время (зависит от команды) может прийти еще ответ (данные или результат выполнения).
Все это будет помещаться в очередь через xQueueSendToBackFromISR(..).
Далее основной FreeRtos поток программы вынимает последовательно данные из очереди через xQueueReceive и уже "не спеша" начинает анализировать (парсить) ответ.
Тут есть важный момент как понять , что приняты все данные в ответе или надо еще ждать прихода байтов.
Тут надо индивидуально разбираться с каждой командой.
С простыми командами где максимум в ответе эхо и краткий результат типа (OK | ERROR) проблем нет.
С командами с тройным ответом , где в ответе эхо , потом результат, (потом непонятная пауза), а потом данные все посложнее.
Как на практике было установлено самые трудные команды , это когда ESP уже работает по WiFi с интернетом . Тут задержки бывают очень длительные.
ECHO RESULT DATA
Решено применить такую стратегию:
ECHO приходит быстро : ждем прихода из очереди первого символа допустим 1000 ms (firstMaxExpectedBlockTime=1000).
Задержку ожидания следующего байта делаем намного меньше , так как идет пачка (tinyExpectedBlockTime=5).
Таким образом если через 5ms не приходит очередной байт из очереди - значит пачка закончилась.
И можно перейти в режим ожидания следующей пачки с периодом конечно же опять побольше (firstMaxExpectedBlockTime=1000).
Главная особенность здесь , что после приема последнего байта пачки мы ждем всего 5мс, а потом можем даже успеть по-парсить принятые байты, до прихода следующей пачки.
А можем перевести поток в блокирующий режим опять на firstMaxExpectedBlockTime (1000) командой xQueueReceive и таким образом не нагружать систему.
Если вторая пачка успела начать приниматься через firstMaxExpectedBlockTime мс, то все хорошо (все идет по плану) и мы после приема первого байта пачки опять устанавливаем для следующего байта период tinyExpectedBlockTime(5мс) .
Принимаем вторую пачку.
И если у нас еще ожидается приход данных,через довольно неопределенное время , то устанавливаем ожидание DataMaxExpectedBlockTime (30000мс) и тупо ждем данных. Если данные пошли переключаемся на ожидание устанавливаем tinyExpectedBlockTime (5мс).
И таким образом после прихода последнего байта данных + 5мс мы завершаем прием.
Этот способ работает максимально быстро.
Но он не учитывает конечно , что пачек может быть и побольше.
Для нашей задачи эта стратегия работает.
К счастью в длинном ответе на GET запрос указывается количество байтов в ответе и в теле ответа. И это надо использовать для проверки.
Вот пример ответа
'\n\rSEND OK\n\r
\n\r+IPD,248:HTTP/1.1 200 OK\n\r
Server: nginx/1.10.2\n\r
Date: Sat, 04 Jan 2020 09:36:41 GMT\n\r
Content-Type: text/html\n\r
Transfer-Encoding: chunked\n\r
Connection: keep-alive\n\r
X-Powered-By: PHP/5.3.3\n\r
X-SERVER: linwebng04\n\r
X-SERVER: linwebng04\n\r
\n\r
e // длина тела
\n\rxxyyzzssddffgg\n\r
0
\n\r\n\r
'
Примечание : Внимание : линия RTS задействована в канале UART с ESP.

Открытый проект как обычно прикладываю
Файлы для скачивания
*
заработал TCP клиент через ESP WROOM 02