• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопрос Атомарность выполнения команды (команда-ответ)

koluna

Member
Всем привет!

Может ли модуль в интервале между приемом одной команды, ее обработкой и ответом на нее отправить +IPD или что-то в этом роде?
Допустим, мы послали модулю какую-нибудь команду. Он ее выполняет. И вдруг, приходят данные по сети... Когда модуль об этом сообщит? Немедленно или только после того, как выполнит команду и ответит на нее?
 
  • Like
Реакции: rst

=AK=

New member
Я думаю, первый вариант вполне возможен. Ибо абсолютно непонятно, с какого момента времени модуль должен был бы заткнуться и не посылать +IPD. С момета, когда модуль определил, что вы ему прислали валидную АТ-команду? Или с момента, когда вы послали первую букву "А" какой-то АТ-команды? Или с момента прихода падающего фронта в приемнике, вдруг это старт-бит, начало пересылки буквы "А"?

Пожалуй, рассчитывать можно только на атомарность ответов от модуля. Если он начал гнать +IPD, то передаст все обещанные данные. Если начал отвечать на АТ-команду, то ответит целиком. Другие варианты как-то нелогичны получаются.
 

rst

Member
Вот GSM-модули, к примеру, иногда так делают... слава Богу не все и не часто ;)
Рассказывали страшилки, когда один ответ приходил внутри другого...
Так бывает когда пишут прошивку безграмотные школьники. Я сам сталкивался с таким багом в Bluetooth-модуле WT12 (от Bluegiga).
По идее для AT-командного протокола сообщения ограничены кодами "\r" или "\n". Т.е. - всё, что между первым символом строки и ближайшим "\r" или "\n" следует считать единым (атомарным) кадром. Я собственно все парсеры АТ-команд так и пишу исходя из данного условия.
Так что возможны и 1-й и 2-й варианты.
Невозможно только чтобы асинхронное сообщение (+IPD...) приходило внутри строки. Но если прошивку писали такие же бездари как и прошивку WT12 - то и такое возможно. Но пока, исходя из моего опыта использования ESP8266, я таких багов не встречал.

PS: В случае с асинхронным сообщением +IPD - я использую то же самое правило, что описал выше, с вычетом блока двоичных данных, который считаю непрерывным и на время приёма которого, парсинг строк отключается.
Хотя конечно это всё должно быть описано в документации. Но .... что есть то есть..... :(
 

rst

Member
Если начал отвечать на АТ-команду, то ответит целиком. Другие варианты как-то нелогичны получаются.
Это не так для ESP8266, да и для других АТ-командных устройств.
Ответом на команду может быть как одно так и несколько синхронных сообщений от модуля. Каждое сообщение - это отдельная строка. Вот она - должна быть атомарна. А количество строк ответа на команду - различно в зависимости от команды и других условий.
Парсер ответа на команду, при обработке последовательности строк ответа на команду, должен быть готов между этих строк обнаружить и обработать и асинхронное сообщение от модуля (или несколько).

PS: Терминология:
синхронное сообщение - сообщение от модуля, являющееся результатом выполнения ранее посланной модулю команды (примеры: "OK", "ERROR" и т.п.);
асинхронное сообщение - сообщение то модуля, сообщающее о некоторых событиях в модуле, напрямую не связанное с выполнением поданной модулю команды (происходящее асинхронно относительно процесса выполнения команды) (примеры: "+IPD", "WIFI DISCONNECT" и т.п.).
 

rst

Member
Пример где ответом на команду будет несколько синхронных сообщений ESP8266 с асинхронными ответами между ними.
Да любая команда с многострочным ответом, например +CIPSENDBUF - в ответ на неё приходит несколько строк синхронного ответа, но между ними может затесаться любое асинхронное сообщение - например сообщение о разрыве другого сокета.
 

=AK=

New member
Да любая команда с многострочным ответом, например +CIPSENDBUF - в ответ на неё приходит несколько строк синхронного ответа, но между ними может затесаться любое асинхронное сообщение - например сообщение о разрыве другого сокета.
То есть, вы думаете, что вместо ожидаемого ответа:

<current segment ID>, <segment ID of which sent successfully>
OK
>

можно увидеть

<current segment ID>, <segment ID of which sent successfully>
ERROR
OK
>

где ERROR - затесавшийся асинхронный ответ? Хмм, а вам не кажется, что ваше предположение мало того что умозрительно и не имеет подтверждения в виде реальных наблюдений, оно вдобавок приводит к гарантированным ошибкам в работе? Поскольку в приведенном мною примере ERROR будет интерпретитрован как ответ на CIPSENDBUF.

Очень сомнительно, чтобы АТ команды были реализованы так, как вы предполагаете. Мало того, что для этого надо заранее держать разработчиков за идиотов, которые не способны видеть дальше своего носа и не могут предвидеть коллизий типа приведенной выше. Кроме того, они должны быть довольно изобретательными идиотами, которые исхитрились использовать в этом месте многозадачность (а иначе как это реализовать?) - даже если АТ прошивка построена без многозадачности.
 

rst

Member
где ERROR - затесавшийся асинхронный ответ?
Вы как читаете что я писал?? :confused:
С чего это ERROR - асинхронное сообщение?
См. выше что я имею в виду под асинхронными сообщениями.
ERROR - это синхронное сообщение, так как это всегда - ответ на команду. Затесаться оно не может.
Хмм, а вам не кажется, что ваше предположение мало того что умозрительно и не имеет подтверждения
Я ничего не предполагаю. Я это видел многократно, когда писал задачу управления ESP8266 через АТ-команды.
Если у Вас нет опыта работы с ESP8266 через АТ-команды, то обратите внимание на сообщения других участников на этой ветке, которые тоже с этим сталкивались.
И этот описанный мной алгоритм, он не высосан из пальца - точно так же работают другие AT-командные устройства: GSM-, Bluetooth- модули и др.
Очень сомнительно, чтобы АТ команды были реализованы так, как вы предполагаете. Мало того, что для этого надо заранее держать разработчиков за идиотов, которые не способны видеть дальше своего носа и не могут предвидеть коллизий типа приведенной выше.
А в чём именно коллизия?
И если не так, то объясните тогда как оно по-Вашему должно работать? :)
Разработчиков ESP8266 за идиотов не считаю - не встретил ещё серьёзных багов в его работе. А вот среди разработчиков других АТ-командных девайсов есть видимо именно идиоты (я описывал выше ситуацию с WT12).
 
Последнее редактирование:

=AK=

New member
Вы как читаете что я писал?? :confused:
С чего это ERROR - асинхронное сообщение?
Я вас дважды просил привести пример, но безрезультатно. Я АТ команды давно забросил в силу их бессмысленности, писал по памяти.

Хорошо, уточняю:

<current segment ID>, <segment ID of which sent successfully>
+IPD, 1, 9:
ERROR
OK
>

См. выше что я имею в виду под асинхронными сообщениями.
ERROR - это синхронное сообщение, так как это всегда - ответ на команду. Затесаться оно не может.
Странно как-то. По-вашему, когда я принимаю данные по +IPD, то пакет данных прерваться не может, даже если представляет собой многострочное сообщение. А когда принимаю ответ на команду - может. А в честь чего такая разница, и, повторяю вопрос, как это вообще можно реализовать?

Предлагаемое вами поведение требует сложной, неординарной реализации. Вместо того, чтобы заполнить некий буфер ответом на синхронную команду и выдать его целиком, ESP должен разбить ответ на строки и после выдачи каждой строки проверять, а нет ли в очереди еще чего-то на выдачу. А зачем это делать, какой смысл, какую цель преследовали разработчики, усложняя себе и другим жизнь?

Я ничего не предполагаю. Я это видел многократно, когда писал задачу управления ESP8266 через АТ-команды.
Я такого никогда не видел, когда писал задачу управления ESP8266 через АТ-команды.

Если у Вас нет опыта работы с ESP8266 через АТ-команды, то обратите внимание на сообщения других участников на этой ветке, которые тоже с этим сталкивались.
В этой ветке вы единственный, кто утверждает, что видел такое с ESP.
 

=AK=

New member
rst, oчевидно, это вы писали в BBS Espressif: "Non-atomic" +CIPSEND bug - ESP8266 Developer Zone И очевидно на основании именно этого инцидента вы делаете свои заявления. Однако интерпретируете вы тот инцидент ошибочно. Команда AT+CIPSEND явлется составной. В первой части вы послали команду и получили атомарный ответ из двyх строк:

Send to ESP: AT+CIPSEND=1,xxx\r\n
Receive from ESP: OK\r\n
Receive from ESP: >

Теперь, пока вы посылаете заданное количество данных, ESP вправе высыпать вам что угодно, поскольку заранее неизвестно, как долго вы будете слать свои данные. Может, вы целый час будете сопли жевать. И в течении этого времени вы обязаны отрабатывать сообщения от ESP, поскольку и соединение вполне может отвалиться, и т.п.

Однако после того, как вы закончили передачу данных, командный процессор ESP ответит вам опять таки атомарным двухстрочным ответом:

Receive from ESP: OK\r\n
Receive from ESP: SEND OK\r\n

И ничего между этими двумя строками не появится. Так что ваша гипотеза о том, что ESP обеспечивает некую "строковую атомарность", ничем не подтверждается.
 

rst

Member
Хорошо, уточняю:
нет.
Странно как-то. По-вашему, когда я принимаю данные по +IPD, то пакет данных прерваться не может,
В блоке данных +IPD нет строк, это блок двоичных данных.
Предлагаемое вами поведение
Ещё раз, повторяю по слогам: я ничего не предполагаю, я пишу о том, что наблюдал.
Я такого никогда не видел, когда писал задачу управления ESP8266 через АТ-команды.
Если работать в стиле "послал пару байт, подождал несколько секунд, послал ещё" - никогда не увидите.
Вероятность попадания асинхронного сообщения между строк ответа на команду очень мала, происходит крайне редко и это можно наблюдать только когда идёт интенсивный обмен с ESP8266, причём по нескольким соединениям одновременно, и причём некоторые соединения постоянно то открываются, то разрываются.
В этой ветке вы единственный, кто утверждает, что видел такое с ESP.
Да ладно?? :cool:
Читать Вы видимо совсем не умеете. Этот тред с чего начался? Самое первое сообщение в состоянии прочитать?
Или вот ещё одно, в этой же ветке:
Вопрос - Ответы модуля
 

=AK=

New member
В блоке данных +IPD нет строк, это блок двоичных данных.
А что, по-вашему, двоичные данные не могут оказаться строками, что ли? Что пошлю, то и придет. В данном примере послан такой двоичный блок данных, 9 байт

\r\nERROR\r\n

Ещё раз, повторяю по слогам: я ничего не предполагаю, я пишу о том, что наблюдал.
В третий раз, по слогам, приведите конкретный пример того, что наблюдали. А свою интерпретацию наблюдений приводить не надо, она ошибочная.

Читать Вы видимо совсем не умеете. Этот тред с чего начался? Самое первое сообщение в состоянии прочитать?
А вы не в состоянии отличить вопрос от утверждения. Человек спросил - может ли это быть. А вам померещилось, что oн утверждает, что такое видел.

Или вот ещё одно, в этой же ветке:
Вопрос - Ответы модуля
B своем первом же ответе в этой ветке я про это говорил. Пока ESP не начал отвечать, он может прислать что угодно. Но как только пошел ответ - он будет атомарным, сколько бы строк в нем ни было.

Так что ваши измышления никакой почвы не имеют. Вам асинхронные сообщения приходили в промежутке между началом команды и началом ответа. А вам померещилось, что они приходили между строками ответа.
 
Последнее редактирование:

pvvx

Активный участник сообщества
В третий раз, по слогам, приведите конкретный пример того, что наблюдали. А свою интерпретацию наблюдений приводить не надо, она ошибочная.
Что, программа "Баунти" у Espressif опять заработала? :)
Нахаляву за указание ошибки получить бабло хотите? :)
Там много ошибок, во всех версиях прошивок "AT" у Espressif, как и неоднозначностей. Только вот они не присылают бабки всем, а только выбранным ими. :)
 

rst

Member
А вы не в состоянии отличить вопрос от утверждения. Человек спросил - может ли это быть. А вам померещилось, что oн утверждает, что такое видел.
Человек спросил дважды. Создал отдельную тему. Да, наверное просто так, от нечего делать... Как некоторые диванные теоретики тут, ни строки кода не написавшие...
Пока ESP не начал отвечать, он может прислать что угодно. Но как только пошел ответ - он будет атомарным, сколько бы строк в нем ни было.
Есть какие-то факты, подтверждающие это? Или как всегда - из пальца высосали? Приведите конкретные факты, подтверждающие это.
А вам померещилось, что они приходили между строками ответа.
Дядя, идите в подворотню откуда вылезли - хамить тут не надо. Вы - никто. Толку от Вас 0.
С чего Вы вообще перевозбудились-то раз не работаете с АТ-командами и даже не знаете о чём речь?
 

=AK=

New member
Человек спросил дважды. Создал отдельную тему. Да, наверное просто так, от нечего делать... Как некоторые диванные теоретики тут, ни строки кода не написавшие...

Есть какие-то факты, подтверждающие это? Или как всегда - из пальца высосали? Приведите конкретные факты, подтверждающие это.
Дядя, идите в подворотню откуда вылезли - хамить тут не надо. Вы - никто. Толку от Вас 0.
С чего Вы вообще перевозбудились-то раз не работаете с АТ-командами и даже не знаете о чём речь?
Бремя доказательства лежит на вас, ибо вы единственный, кто утверждает, что это видел. Если вам мерещится, что заданный кем-то вопрос является утверждением, то вследствие этого нет и никакого доверия и вашим заявлениям "я это видел". Мало ли что вам еще померещится. Никто не обязан опровергать любую глупость, которая втемяшилась в голову каждoмy тупому хамлy.

Я вас спрашивал, это вы писали сообщение в BBS Espressif под ником Rst7? Отмечу, что вы вообще ни на один вопрос не ответили, как об стенку горох. Наверняка ведь вы, а на вопросы отвечать вам манеры не позволяют. Вот в BBS вы привели реальное наблюдение того, что было на самом деле, верю. А выводы из этого наблюдения вы сделали ложные. В меру своего интеллекта, который вы тут наглядно демонстрируете в разных формах проявления.
 
Последнее редактирование:

DIYMan

New member
Подтверждаю проблему с конкурентными запросами к ESP и отсутствием атомарности:

Вводные: AT-прошивка 0.40, режим множественных подключений (4 клиента), поднят сервер. ESP довольно интенсивно спамят с внешнего мира (вебморда), плюс из контроллера (Atmega2560) по UART в ESP пишется куча данных - MQTT и т.п.

Реализована параллельная неблокирующая обработка, когда в очередь помещаются команды, и по мере их разгребания происходит чудо :)

Трабла в следующем: как известно, ESP по приходу входящих данных плюёт в порт +IPD,<link id>,<data length>:<data>. Естественно, такую информацию надо отрабатывать безусловно - есть ли там что в очереди или нет - пришли данные, будь добр их разобрать и послать ответ. Однако (на конкретном примере) - неконтролируемо происходит пересечение клиентов, т.е.:

1. в ESP посылается AT+CIPSTART=1,"IP address",80;

2. В ответ приходит 1,CONNECT - пока всё штатно, после этой строки, по идее - уже можно писать в ESP данные вызовом AT+CIPSENDBUF;

3. ВНЕЗАПНО в порт падает +IPD,1,14:<тут данные>, и я понимаю, что это данные запроса с вебморды!

Т.е. получаем что: ПОСЛЕ вызова AT+CIPSTART ESP почему-то считает себя вправе законнектить другого клиента в этот же слот! Как итог - полкило волос на жопе уже вырвано, ибо данная трабла просто не поддаётся формализации.

Вот логи, демонстрирующие штатную и нештатную работу.

1. Штатный:
Requested to write data to IoT using ESP...
ESP: ==>> AT+CIPSTART=1,"TCP","184.106.153.149",80
<== ESP: 1,CONNECT
ESP: client connected - #1
ThingSpeak connected!
Write IOT DATA TO STREAM...
GET /update?api_key=zzzzz&field1=29.12&field2=28.73&field3=29.44&field4=37.40 HTTP/1.1
Accept: */*
User-Agent: greenhouse
Host: api.thingspeak.com


<== ESP: OK
ESP: ==>> AT+CIPSENDBUF=1,164
<== ESP: 5,4
<== ESP: OK
<== ESP: >
ESP: > received, start write from client to ESP...
<== ESP:
<== ESP: Recv 164 bytes
<== ESP: 1,5,SEND OK
ESP: Client data written, ID=1
ESP: start parse +IPD, received=+IPD,1,555:
ESP: Client data available, ID=1
ESP: Client data available, ID=1
IOT done, success: true
ESP: +IPD parsed.
ESP: ==>> AT+CIPCLOSE=1
<== ESP: 1,CLOSED
ESP: client disconnected - #1
ThingSpeak disconnected.
<== ESP: OK
Видно, что запрос к ThingSpeak отработал, в ответку пришли данные, всё зашибись. Второй вариант - с пересечением клиентов:

Requested to write data to IoT using ESP...
ESP: ==>> AT+CIPSTART=1,"TCP","184.106.153.149",80
<== ESP: 1,CONNECT
ESP: client connected - #1
ThingSpeak connected!
Write IOT DATA TO STREAM...
GET /update?api_key=zzzz&field1=29.18&field2=28.69&field3=29.49&field4=37.30 HTTP/1.1
Accept: */*
User-Agent: greenhouse
Host: api.thingspeak.com


ESP: start parse +IPD, received=+IPD,1,14: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ВОТ ЭТА ХРЕНОВИНА, ЭТО ЗАПРОС С ВЕБМОРДЫ!!!
ESP: Client data available, ID=1
ESP: +IPD parsed.
<== ESP: 1,CONNECT
ESP: client connected - #1
<== ESP: 1,CLOSED
ESP: client disconnected - #1
ThingSpeak disconnected.
Т.е. во втором случае после CIPSTART мне в порт падают в этого же клиента данные, которых там, блин, быть не должно, т.к. этим клиентом сейчас коннектимся, по идее. Более того, у меня нет уверенности, что во втором случае ответ 1,CONNECT - это ответ на команду AT+CIPSTART, а не статус, что клиент 1 успел подконнектиться быстрее, чем ESP отработало AT+CIPSTART.

Ловится это дело ТОЛЬКО при интенсивной нагрузке, и может выскочить не сразу, но - выскакивает обязательно. Чтобы было понятно: запросы к ESP с вебморды - несколько раз в секунду, запросы к ESP от контроллера - тоже примерно так же.

Во втором примере видно, что атомарность нарушена - мне не вернули ни OK, ни ERROR, вместо этого упал неатомарный ответ 1,CONNECT, который сообщает о подключении внешнего клиента, хотя я запрашивал соединение вовне, и за ним - неатомарный же +IPD. OK или ERROR я так, ессно, и не дождался, т.к. внутренний клиент ВНЕЗАПНО превратился во внешнего. В логике в ответ на AT+CIPSTART ессно, ждётся один из статусов, который описан в даташите на AT-команды - OK, ERROR, ALREADY CONNECTED. Но, как показывает практика - можно и не дождаться.

Для пояснения - строка "Write IOT DATA TO STREAM..." и последующие данные - это не актуальный AT+CIPSENDBUF - это просто помещение в очередь на последующую обработку, как только придёт OK.


Короче, проблема есть, как с ней жить - непонятно. Теоретиков просьба не беспокоить, с теорией всё норм, практика вот не вывозит, от слова "совсем". Состояния конечных автоматов были сто раз уже проверены, налицо реальное пересечение по времени внешнего и внутреннего коннекта в один слот. Как по мне - типичный баг AT-прошивки.

Вопрос, собственно, простой - как с этим жить? Возможно, в более поздних версиях AT-прошивок такого не наблюдается - кто подскажет? Отказаться от AT-прошивки - не надо предлагать, это крайняя мера.
 
Последнее редактирование:
Сверху Снизу