Easyelectronics.ru

Электроника для всех
Текущее время: 24 янв 2021, 11:48

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 26 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 20 апр 2016, 19:13 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3808
Откуда: Китай, Пекин
Как правильно организовать приём, обработку и отправку данных?

Мой опыт написания клиент-серверных приложений на Scala мало применим в микроконтроллерах.
Никакой многопоточности, ограничения по памяти.... и проч.

Соответственно, решил разобраться, каковы базовае идеологические постулаты при написании такого кода на микроконтроллерах.
На основе многочисленных статей напримерhttp://www.embedded.com/design/programming-languages-and-tools/4397803/Interrupts-short-and-simple--Part-1---Good-programming-practices

Стали понятны несколько правил.

1)минимизируй использование памяти

2)прерывания (TX, RX) имеют достаточно высокий приоритет. Сделано это для того, чтобы успевать обрабатыать критически важные элементы кода взаимодейчтвовия с внешним миром. который, как известно, не ждёт. Никаких while(...) "ожиданий" в этом коде быть не должно!

3)Вся остальная логика, работу которой допустимо прервать в любой момент, должна происходить в main().

Что имеем по факту.
В результате анализа кода, многочисленных вариантов реализации на GitHub, обнаружил сплошное нарушаение правил.

Какая картина мне видится идеальной.

в потоке RX перывания
Приём данных происходит сразу в тело структур.
Структуры которые, данные которых удалось получить корректно и полностью кладуться в очередь поступивших данных, прочие утилизируются.

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

в потоке TX перывания
происходит извлечение данных из очереди оправки, отправка, и последущая утилизация.

Есть ли где почитать или увидеть, код, максимально близкий к идеалу?

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 20 апр 2016, 19:38 
Старожил

Зарегистрирован: 16 ноя 2012, 07:47
Сообщения: 2881
На примере UART:
обычно, классический метод - Входящие байты складываются в буфер в прерывании. При приеме спецсимвола конца данных, либо по таймауту, отдается управление задаче парсеру, которая уже смотрит что-же там пришло. Если данные летят постоянно - кольцевой буфер, чтобы ничего не потерять, но парсер в любом случае должен успевать разребать входящие посылки. Отправка - если отправляем редко - просто кидаем буфер на передачу, по окончанию передачи выставляем флаг что передатчик свободен. Если опять же отправлять много, и разные таски могут одновременно ломиться к передатчику - либо используем мьютексы, если можно подождать, когда передатчик освободится, либо очередь на отправку, типа FIFO, но это уже кушает оперативку.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 20 апр 2016, 19:38 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 3492
cheblin писал(а):
в потоке RX перывания
Приём данных происходит сразу в тело структур.
Структуры которые, данные которых удалось получить корректно и полностью кладуться в очередь поступивших данных, прочие утилизируются.

задача прерывания переложить байт из регистра в fifo буфер, или перенастроить ДМА.
больше ничего там делать не надо ни разгребать данные, ни проверять контрольные суммы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 20 апр 2016, 20:09 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3808
Откуда: Китай, Пекин
Цитата:
в fifo буфер... больше ничего там делать не надо ни разгребать данные, ни проверять контрольные суммы.


согласен, но не со всем.

минусы: - требуется память для fifo буфера. и потом в MAIN перекидывать эти данные в формат удобный для обработки.

думаю эффективнее будет слегка "подзагрузить" этот поток, сделав его более умным, чтобы он дополнительно выполнял некоторые просейшие задачи. Например.

1)определял начало фрэйма,
2)на основе первых данных был способен сразу выделить и затем заполнить выделенное место получаемыми данными, чтобы в дальнейшем без перекладывания, использовать этот массив, приведя его к желаемой структуре.
3) обнаруживал простейшие, явные ошибки в принимаемых данных, мог утилизировать уже полузполненные структуры.

_________________
unirail.org


Последний раз редактировалось cheblin 20 апр 2016, 20:15, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 20 апр 2016, 20:14 
Старожил

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 7241
Ага, пока вы будете делать "1-2-3" обработчик потеряет кучу данных.

Hold, можно делать и без RTOS. Достаточно main зациклить на SLEEP() и по каждому просыпанию проверять буфер данных (что вы и говорили). Это быстрее семофоров и проще.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 20 апр 2016, 20:23 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3808
Откуда: Китай, Пекин
какие семафоры?? какой RTOS? какой SLEEP()?

я понимаю, если в руках молоток то все задачи - гвозди. у меня тоже есть такой молоток - AKKA, но я его благоразумно отложил в сторонку.

Нужно решение которое будет работать даже на 8 битном контроллере. Если на нем заработает, то на контроллере "пожирнее" заработает подавно.

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 20 апр 2016, 20:59 
Старожил

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 7241
"на 8 битном контроллере"
А у вас на 8 битном контроллере нет цикла SLEEP() (или просто вечного цикла)? Можно посмотреть на такое построение?
Как-бы, невозможно существование системы без фонового процесса.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 20 апр 2016, 21:16 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3808
Откуда: Китай, Пекин
Цитата:
нет цикла SLEEP() (или просто вечного цикла)?

while(1)
{}

это отдалёно похоже на sleep(), в общепринятом смысле - передача управления другим "потокам", НО только если это происходит в "потоке" MAIN(), поскольку по умолчанию у него самый низкий приоритет и все подряд его могут прервать, соответственно это выглядит так, что он заснул и передал управление.

если подобное SLEEP() попытаться проделать в "потоке с более высоким приоритетом" -( прерывания RX или TX), то от такого "засыпания" MAIN управления никогда не получит.

_________________
unirail.org


Последний раз редактировалось cheblin 20 апр 2016, 21:20, всего редактировалось 3 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 20 апр 2016, 21:19 
Старожил

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 7241
main и есть фоновый процесс.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 21 апр 2016, 00:15 
Старожил

Зарегистрирован: 27 мар 2015, 01:22
Сообщения: 2067
cheblin писал(а):
Есть ли где почитать или увидеть, код, максимально близкий к идеалу?

Ну, с учётом бэкграунда ) предлагаю Protothreads

_________________
mcu.goodboard.ru


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 21 апр 2016, 01:46 
Старожил
Аватара пользователя

Зарегистрирован: 05 фев 2010, 16:57
Сообщения: 2193
Откуда: Нальчик
Цитата:
Приём, обработка и отправка данных. Как правильно?
Как правильно - не возможно ответить, пока не поясните что за данные, что и зачем нужно обработать, ну короче общая картина должна быть... Тогда и можно будет подсказать - как правильно...

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 21 апр 2016, 02:58 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2900
Откуда: Санкт-Петербург
Из местных обитателей меня своим кодом очень порадовал Eddy_em. Не помню, как у него насчёт ваших требований, но код чистый, понятный и поддерживать его было бы легко.

Насчёт sleep в main - совершенно каноническая архитектура событийно-ориентированной программы получается: главный тред в цикле дёргает GetMessage и обрабатывает его (а sleep сработает именно как GetMessage: дождётся ближайшего прерывания, не молотя зря процессором, а прерывание создаст событие). Imho удобно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 21 апр 2016, 06:42 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3808
Откуда: Китай, Пекин
Цитата:
предлагаю Protothreads

! огромное, человеческое спасибо! brilliant!
по этому ключевому слову нашел книгу
"Embedded Systems Handbook Networked Embedded Systems" +
"Fundamentals of Wireless Sensor Networks: Theory and Practice"

есть что почитать, и над чем подумать...

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 21 апр 2016, 06:45 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3808
Откуда: Китай, Пекин
Цитата:
кодом очень порадовал Eddy_em

ссылочку бы, если не затруднит. спасибо.

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 21 апр 2016, 06:49 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3808
Откуда: Китай, Пекин
Цитата:
Если скорость потока не большая, то

Ищу решение, которое будет работоспособным в большинстве случаев.
То, что справится с быстрым потоком данных - справится и с медленным.

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 21 апр 2016, 10:39 
Старожил

Зарегистрирован: 27 мар 2015, 01:22
Сообщения: 2067
cheblin писал(а):
есть что почитать, и над чем подумать...

Ещё можно глянуть на QP Actor Frameworks для полноты картины )

_________________
mcu.goodboard.ru


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 21 апр 2016, 11:11 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3808
Откуда: Китай, Пекин
обнаружил.... https://github.com/matianfu/FUNK

FUNK
A C continuation implementation inspired by Adam Dunkels' ProtoThread.
Only 7 C macros and 1 struct definition; less than 100 lines of code.
Simple yet POWERFUL.
Now you can write a coroutine (generator, to be exact) in the following way, quick, simple, and in a natural way.

Enjoy the power of YIELD();

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 21 апр 2016, 11:33 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2900
Откуда: Санкт-Петербург
cheblin, https://github.com/eddyem/stm32samples
С прототредами осторожно - там магия макросов (по счастью, несложная - чай, не BOOST) и довольно специфические ограничения (благо, понятные из кода) типа "local variables are not preserved when the protothread blocks", после Scala (которая, как я понимаю, изрядно защищает от попыток выстрелить себе в ногу) может быть весьма странно и уж точно "неакадемично".
(offtopic) Кстати, а в Scala есть преобразование функции в конечный автомат, как в C# или Питоне? Ну, что все локальные переменные хранятся в виде объекта, а оператор yield сохраняет состояние и позицию?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 21 апр 2016, 12:49 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3808
Откуда: Китай, Пекин
Цитата:
Кстати, а в Scala есть...

https://medium.com/@anicolaspp/how-c-beats-scala-in-async-programming-27d824da02ba#.mmkx7iqq7
если действительно интересно, то читать до конца, особенно комменты.

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 21 апр 2016, 15:04 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3808
Откуда: Китай, Пекин
всё понятно с Protothreads. факически это банальный кодогенератор, с ворохом ограничений. С их слов, его использование упростило написание некоторых проектов...

а по мне, так это не совсем уж и так. разочарование....

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 26 апр 2016, 10:33 
Старожил
Аватара пользователя

Зарегистрирован: 24 июл 2012, 13:54
Сообщения: 856
А вот критичны ли ограничения по памяти?
Подчастую оказывается, что памяти гораздо больше, чем реально нужно. Даже 8кб позволяют развернуть полноценную ОС. С потоками, файлами, плюшками. Ну разве что без сетевого стека. Там поболе надо.


Что касается приёма...
Я в некритичных случаях использую двухуровневую обработку (а то и трёхуровневую). (А некритичный случай... Это почти всегда!)

Например, организация консоли такова:
Сначала стоит драйвер, который складывает данные из приемо-передатчика в кольцевой буфер он работает в прерывании. Затем в основном коде (или в специально выделенном под это дело потоке (... если они таки есть...)) байты по одному считываются из буфера в... Другой буфер. Он выполнен уже линейным, а не в виде кольца. Там формируются сообщения.

По считыванию символа конца строки выполняется обработка команды, а буфер обработчика сбрасывается.

Вариант с fifo очередью принятых байтов хорош своей универсальностью.
Он позволяет отвязать во времени приём и обработку, что в свою очередь позволяет уйти от проблемы: "Куда положить новые данные, если старые еще не обработаны?".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 26 апр 2016, 11:22 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3808
Откуда: Китай, Пекин
1) лишней памяти никогда не бывает
2) про циклический буфер, полностью согласен со всеми. я стараюсь минимизировать его объём.
Цитата:
По считыванию символа конца строки

3)..... а что? только у меня в UART протокол бинарный? МИКРОконтроллер стреляющий текстом - жырнота! чувствую это, даже со своим скаловским бэкграундом...

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 26 апр 2016, 11:47 
Старожил
Аватара пользователя

Зарегистрирован: 24 июл 2012, 13:54
Сообщения: 856
Лишняя память - это когда половина ОЗУ не используется :). Вообще, приемному буферу большим быть необязательно. Оптимальный размер зависит от скорости опроса и баудрейта. Например, при баудрейте 9600... 16байтный буфер - это уже с головой... А вот размер передающего буфера зависит от совсем других вещей. Он критичен к размеру единовременной записи.

Прослойка в виде кольцевого буфера хороша тем, что ей вообще пофиг на протокол. Я привел консоль как пример. Правда у меня бинарного протокола пока нет. Руки не дошли, а готового решения тоже подходящего найти не могу. эксперементирую пока с передачей в виде аскии символов, имитирующих бинарные байты. Так проще отлаживать, ибо все глазами видно.

Консоль нужна для коммуникации человек- контроллер. Опять же, для отладки. Очень упрощает процесс. start-stop. set parammetr. смена коэффициентов тех же пид регуляторов на ходу...

И... не так уж много оно и весит... килобайт семь кода и байт 300 памяти... А сколько радости.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 05 май 2016, 01:57 
Старожил

Зарегистрирован: 02 июл 2010, 23:41
Сообщения: 473
Вопрос обмена данными довольно актуален, поэтому решил сделать для этого библиотечный элемент. Точнее, получились три элемента: посылка команды, посылка пакета и прием пакета.
Алгоритм обмена следующий:
Вначале мастер делает запросы на обмен периферийному МК.
Если добиться ответа не удается, устанавливается соответствующий флаг и мастер делает соответствующую обработку этого флага.
Получение ответа от периферийного МК свидетельствует, что он закончил свои дела и переключился на обмен с мастером.
Далее мастер получает байт статуса, в котором периферийный МК сообщает, все ли у него нормально. Если все хорошо, мастер начинает обмен: либо подает команду, либо передает данные, либо читает данные. Передача идет в ANSI кодировке, т.е. с одним байтом передается только одна тетрада числового байта.
После окончания обмена мастер проверяет, правильно ли дошел пакет. Если неправильно, передает пакет еще раз. Если несколько раз не удается правильно передать пакет, устанавливается соответствующий флаг, по которому мастер совершает соответствующие действия.
Затем сеанс связи заканчивается, и мастер отпускает периферийный МК.

Такой обмен у меня занял довольно приличный объем, в периферийном МК около 760 слов (SRAM – 62 байта). Пишу на макроассемблере, на АБ для AVR.

cheblin писал(а):
только у меня в UART протокол бинарный? МИКРОконтроллер стреляющий текстом - жырнота! чувствую это, даже со своим скаловским бэкграундом...

А в чем проблема передачи текста в 8-битном МК? Думаю, передача текста проще, текст не надо перекодировать.
Возможно, удастся записывать текст сразу в нужное место без приемного буфера.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Приём, обработка и отправка данных. Как правильно?
СообщениеДобавлено: 05 май 2016, 02:11 
Старожил

Зарегистрирован: 20 мар 2013, 11:27
Сообщения: 5380
Alexandr_1 писал(а):
А в чем проблема передачи текста в 8-битном МК? Думаю, передача текста проще, текст не надо перекодировать.
Возможно, удастся записывать текст сразу в нужное место без приемного буфера.

а если числа передавать? их как раз придется переводить в текст и потом обратно
а смысл?
cheblin писал(а):
3)..... а что? только у меня в UART протокол бинарный? МИКРОконтроллер стреляющий текстом - жырнота! чувствую это, даже со своим скаловским бэкграундом...

не только, по моему вполне логично если обмен идет МК <-> МК


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 26 ]  На страницу 1, 2  След.


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB