Вопрос про многопоточность (МП)

Tucoso
Offline
Зарегистрирован: 23.08.2018

Вопрос про многопоточность (МП).

 

Добрый день.

 

Есть потребность в организации работы нескольких задача на ATmega328:

 - ввод данных с энкодера,

 - вывод данных на экран,

 - работа по сети (rs485).

 

Насколько реально реализовать эти задачи в МП режиме, да и вообще насколько подобный микроконтроллер уместен для МП (не принимая во внимание примеры с миганием 2-3 светодиодов с разной частотой) ?

 

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

 

Так же я не горю желанием использовать МП через «конечные автоматы» (protothread) по этому в качестве МП я рассматриваю вариант:

 - с вытесняющей МП (через таймер)

 - или коопертивной МП.

 

Причем как я понимаю в обоих вариантах придется под каждый поток формировать свой стек.

 

У меня не большой опыт программирования микроконтроллеров и вот что меня смущает:

 

Если взять библиотеку «AVR Threads» то в примере авторы выделяют под один поток стек в 128 байт для друго 512 байт, что как то жирно с учетом того что в ATmega328 2k SRAM.

 

Сколько в среднем по больнице глубина стека в типичных приложениях ?

 

А если нужно 4-5 потоков ? Подключать внешнею SRAM, на подобие 23K256 и там хранить стеки и увеличивать квант времени для потока ? Но это уже монстр получается :(

 

Кооперативная МП смущает тем что при написание алгоритма надо будет все время помнить о передаче управления следующему потоку, да и опять же вопрос со стеком :(

 

«Как сделать так что бы ничего не делать» ?

-NMi-
Offline
Зарегистрирован: 20.08.2018

Нужно просто включить ГОЛОВУ и отойти от концепции "скетчей" и написать всё самому ... да хоть на... С(++) и тгда будет счЯсЬе  )))

)))  могу дать "скетч" мигания 12-ю светодиодами с ШИМ-модуляцией+дисплей+джойстик,правда почти весь на ASM     )))

Tucoso
Offline
Зарегистрирован: 23.08.2018

Безусловно я согласен с Вашей концепцией о включение головы.

Но в то же время хотелось бы воспользоваться опытом людей прошедшие этот путь, почему бы и нет ?

За код спасибо, но было бы просто мего-супер если бы Вы обрисовали концепцию того как вы это реализовали. Машина-состояний ? Поделитесь пожалуйста опытом :) 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вот личный вариант. Но "многопоточность" там своеобразная. http://arduino.ru/forum/programmirovanie/tsifrovye-avtomaty-v-klassakh-p...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Tucoso пишет:

Но в то же время хотелось бы воспользоваться опытом людей прошедшие этот путь, почему бы и нет ?

Невозможно воспользоваться чужим опытом, не имея своего.

 

PS. А многозадачность "по таймеру" для МК идея безусловно вредная: если мы говорим о пользовательской системе типа Windows, частота прерываний определяется характеристиками человека. МК в основном общается не с человеком, а с периферийными устройствами, характерные времена для которых могут лежать в очень широких пределах. Соответственно, и выбрать квант времени пригодный хотя бы для большей части задач просто не получится.

Tucoso
Offline
Зарегистрирован: 23.08.2018

Насколько я понял, это из области автоматов.

Данная идея меня смущает необходимость переосмысливать подход в реализации алгоритмов: вместо традиционного подхода делать все последовательно, придется описывать алгоритм через состояния, заводить флаги состояний, все это как то контролировать.

 

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

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Когдато тоже пытался http://arduino.ru/forum/programmirovanie/ochered-sobytii

Tucoso
Offline
Зарегистрирован: 23.08.2018
Но ведь можно ввести механизм примитивных приоритетов. Например выполнять некоторые потоки в списки «расписания» через раз, тем самым выделять больше времени, хоть и кантованного, для «важных» потоков.
 
Или все это хрень и оно не годно для МК и надо смотреть в стороны машин состояния ?
 
Касательно опыта: мое мнение заключается в том что, не стоит самому реализовать (ну только если не just for fun) механизм вынесняющей многоготочности что бы _например_ убедится что для МК это не подходит. Не эффективнее ли спросить на профильных форумах, где например могу подсказать что сие дело без перспективно и 90% промышленных решений на МК делаются через машины состояний, _например_. А может и наоборот :)
b707
Offline
Зарегистрирован: 26.05.2017

Tucoso - поменяйте классическую ардуину на СТМ32-дуину с 20К SRAM и запустите на ней RTOS

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

я юзаю самописные таймеры + очередь сообщений.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

RTOS вполне реализуется даже на НАНО .. только это не поможет ТС-у ни разу.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Когда мне нужно сделать что-то реально параллельно, я просто ставлю отдельный  МК на каждый поток. В результате проблема многозадачности вырождается в проблему связи между МК, которая в моих проектах намного проще, т.к. не ахти как много им надо общаться. При нынешней цене на МК (особливо на PIC, да и на AVR тоже), вполне себе решение. Тем более для хоббийных задач, когда не нужно усираться, чтобы было на копейку дешевле, чем у конкурентов.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Это уже многоядерность, однако. ;)

Tucoso
Offline
Зарегистрирован: 23.08.2018

Arhat109-2 пишет:

RTOS вполне реализуется даже на НАНО .. только это не поможет ТС-у ни разу.

Отчасти в этом и вопрос. Хотелось бы что бы МК не только со скрипом выполнял "обвертку" для управления потоками но и что-то полезное успевал делать.
 
Та же библиотека AVR Threads, 4 потока с примитивным кодом работает, вопрос лишь в том далеко ли можно уехать если в потоках будет полномосштабное выполнение поставленных задач или все тут же упрется в SRAM.
 
По скорости выполнения я прикинул так - высосав из пальца значение 400, я принял это за количество команд которое поток должен выполнить за квант времени. Один из авторов библиотеку по работе вытесняющей многопоточностью писал что на переключение поток будет уходить +/- 160 операций. С учетом частоты ATmega328 в 16Mhz получается ((400+160)/16^6) * 10^ 6 = 35 микросекунды, т.е. поток каждый из 5ти потоков будет прерыватся на 35х4=140 микросекунд. По мне так комфортно время, но может я и ошибаюсь, поправте.
 
В виду не большого опыта программирования МК мне сложно оценить какой размер стека будет формировать тот или иной код, сколько скушается кучи на переменные, обычно разрабатывая бизнес-приложения на Java об этом не задумываешься.
DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

тебе реально нужно параллельное выполнение? 

Tucoso
Offline
Зарегистрирован: 23.08.2018

Да, я очень хотел бы все сделать в потоках.

Я к этому привык (разработка бизнес-приложений и решение инженерных задач на Java) и очень-очень не хотел бы менять подход к разработке.
andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Tucoso пишет:

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

То, что сейчас есть в МК - и есть самый что ни на есть традиционный код. В отличие от большинства современных наворотов.

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

Как только у нас появляется многозадачность, сразу возникает необходимость изолировать задачи от "железа". Дабы избежать конфликтов. А это ресурсы, и немалые.

А в еще большей степени - граничения. Причем - очень существенные. На ПК мы можем мириться с этими ограничениями только потому, что существуют МК, у которых этих ограничений нет. И именно многообразная периферия, работающая на МК и подключаемая к ПК, дает возможность решать реальные задачи на ПК, не замечая этих ограничений.

Tucoso пишет:

... т.е. поток каждый из 5ти потоков будет прерыватся на 35х4=140 микросекунд. По мне так комфортно время, но может я и ошибаюсь, поправте.

Повторюсь: то, что комфортно лично для Вас, может оказаться совершенно некомфортно для периферии, с которой МК должен работать.
МК ведь создан для работы с железом, а не для задач обработки данных.
 
Не пытайтесь перевалить на МК задачи, для которых предназначен ПК, адекватно распределяйте работу между ними, и Вы поймете, что то, что имеется, подходит для решения каждым своих задач наиболее оптимальным способом.
Т.е. не нужна в МК никакая многозадачность кроме той, что обеспечивается механизмом прерываний, а также другой периферией. И не просто не нужна, а вредна.
sadman41
Offline
Зарегистрирован: 19.10.2016

Если не хочешь менять подход - подтягивай железо до уровня привычного.

Законы эволюции никакая каменноголовая дума пока не изменила: изменяйся или вымрешь.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

Законы эволюции никакая каменноголовая дума пока не изменила: изменяйся или вымрешь.

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Tucoso, вот простенькийц пример: https://code.google.com/archive/p/arduino-tvout/

Здесь 8-разрядный микроконтроллер с тактовой частотой 16 МГц без всякой суперскалярности и пр. формирует видеосигнал разрешением 128х96 пикселей.

По пропорции ПК с процессором на 3.2 ГГц должен быть способен сделать подобное, но уже с разрешением 1920х1280.

Попытайтесь написать приложение под Windows, которое формировало бы аналоговый видеосигнал в таком разрешении.

Вот Вам и ответ на вопрос: а нужно ли пытаться имитировать на МК возможности, имеющиеся на ПК.

 

https://www.youtube.com/watch?v=9JmTvSu9sG8

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Tucoso пишет:

Arhat109-2 пишет:

RTOS вполне реализуется даже на НАНО .. только это не поможет ТС-у ни разу.

Отчасти в этом и вопрос. Хотелось бы что бы МК не только со скрипом выполнял "обвертку" для управления потоками но и что-то полезное успевал делать.
 
Та же библиотека AVR Threads, 4 потока с примитивным кодом работает, вопрос лишь в том далеко ли можно уехать если в потоках будет полномосштабное выполнение поставленных задач или все тут же упрется в SRAM.
 
По скорости выполнения я прикинул так - высосав из пальца значение 400, я принял это за количество команд которое поток должен выполнить за квант времени. Один из авторов библиотеку по работе вытесняющей многопоточностью писал что на переключение поток будет уходить +/- 160 операций. С учетом частоты ATmega328 в 16Mhz получается ((400+160)/16^6) * 10^ 6 = 35 микросекунды, т.е. поток каждый из 5ти потоков будет прерыватся на 35х4=140 микросекунд. По мне так комфортно время, но может я и ошибаюсь, поправте.
 
В виду не большого опыта программирования МК мне сложно оценить какой размер стека будет формировать тот или иной код, сколько скушается кучи на переменные, обычно разрабатывая бизнес-приложения на Java об этом не задумываешься.
...

Да, я очень хотел бы все сделать в потоках.

Я к этому привык (разработка бизнес-приложений и решение инженерных задач на Java) и очень-очень не хотел бы менять подход к разработке.

1. Забудьте про JAVA и все её навороты при работе с микроконтроллерами. Стоимость их реализации не перевешивает удобства и полезности ни в одном глазу (тут сейчас начнут спорить недокодеры).

2. Потоки в JAVA это реализация класса Threads, который в реальных многопоточных/многоядерных и пр. системах опирается на реализацию ОС - все те же потоки, семафоры, сигналы и мьютексы. То есть, это "надстройка" снижающая "уровень вхождения" за счет потери производительности. Впрочем вся жаба предназначена именно для этого. (тут можете опять спорить, мне - без разницы).

3. Да, на переключение контекста в AVR (не только 328p, практически любой МК AVR) потребуется сохранить-восстановить контекст, который имеет 32 РОН + SREG + TIMSK + мелочи по поиску адреса, установления стека и т.д. Итого около 34 операций чтения-записи в память, каждая по 2 такта.  34*2*2 = 136 тактов. То есть оценка в 160 тактов - близка к истине, если смена контекста прописана оптимально. Кое что можно "упростить" но не более чем до 80-100тактов, учитывая "особенности компилятора" (непереносимо в будущее).

4. 400 команд это не 400 тактов как Вам показалось. В среднем в потоке команды чтения/записи в память составляют около 1/3, а они все .. по 2 такта. Также все команды, имеющие "операнд" в команде (2 слова) тоже работают по 2 такта. То есть 400команд это "в среднем" 600-700 тактов ЦП. Впрочем, не суть важно.

5. На одном ядре можно сделать только вытесняющую многопоточность. И если у Вас 4 потока, то каждый поток будет ждать не *4, а *3 (N-1 -- ждем остальных, кроме себя) единиц времени исполнения потока. В больших ОС (жаба - привет!) время исполнения потока как правило нормировано и составляет 1 миллисекунду (к вопросу "Вас устраивает 35 мксек"). На AVR многопоточность удобно размещать на таймере .. watchdog, но он умеет работать не шустрее .. 8мсек. Удобно тем, что он автоматом вызывает "сброс" МК на нулевой адрес, где и стоит размещать "диспетчер задач".

6. Количество потребного стека оценивается достаточно просто, ибо в нем храняться исключительно: а) адреса возврата из вызванных процедур вложенно, б) все параметры вложенных вызовов, не входящие в "регистры-параметров" компилятора и в) все локальные переменные вложенных вызовов не влезшие в регистровое поле МК. Всё, ничего иного там нет. Соответственно, раз Вы имеете "опыт разработки инженерных решений" (в чем я лично сомневаюсь), то Вам не составит труда оценить потребный размер стека под каждый свой поток. Но .. я сильно сомневаюсь, если читать то что Вы написали уже.

7. Диспетчер задач - в общем-то примитивный алгоритм, и для его решения есть готовые наброски в виде setjump(), longjump() .. ознакомьтесь. В принципе, возможно создание диспетчера, который контекст будет хранить .. на стеке самого потока. Тут уже было обсуждение такого решения.

8. Сколько задач "потянет Мега"? (Нано, УНО .. они все едины практически с этой кочки зрения - 16Мгц и AVR) .. В среднем, процедура обработки и управления тем или иным устройством в моей практике не превышает макс .. 100 команд. Плюс процедуры вычислений тех или иных моментов .. тут сложнее. Ещё сложность в том, что чтение окр. среды происходит по большей части .. по прерываниям, что само по себе "элемент многозадачности и потоков" .. аппаратный.

9. Разработка многопоточного приложения де факто мало чем отличается от .. автоматного стиля для конечных автоматов. Там все ровно тоже самое: есть КА (поток), который получает данные извне (слушатель КА) и делает нечто, в общем-то наплевав на остальные КА в системе. Если требуется он может "сообщить" состоянием (семафором, послать сигнал потоку) другому КА, что тому следует сделать .. все ровно тоже самое.

Ну вот как-то из этих соображений и следует действовать далее. :)

Tucoso
Offline
Зарегистрирован: 23.08.2018

sadman41 пишет:

Если не хочешь менять подход - подтягивай железо до уровня привычного.

Законы эволюции никакая каменноголовая дума пока не изменила: изменяйся или вымрешь.

Я приношу извинения, но почему так часто люди любят давать результирующею оценку без фактуры - "изменяйся или вымрешь". Кто то из комментаторов сказал, что да, мол многопоточность в МК не реализуема, она не будет работать, а если будет то % полезного времени на код будет ниже плинтуса ? А я тут все ною и ною, дайте мне многопоточность!

Так почему Вы с разбегу предлагаете мне изменить подход к реализации задачи?
 
Все же исходит от задачи, ее я описал в самом начале. Там что, что-то сверх естественное, сверх ресурсо-емкое ?
 
Я был бы полностью согласен с Вам, если было бы предложено реализовать осциллограф на ATmega и впихнуть многопоточность для отрисовки GUI или реализовать задачу в которой от МК требовалось бы реакция отклика приближенная к частоте МК.
 
Есть конкретное железо есть задача, вопрос можно ли ее решить вот таким способом. Но ответ - "делай как все" или меняй условия.
 
Извините за резкость.
Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Да вполне реализуемо. И осцилограф вполне монстрячиться и с отдельным потоком на вывод и с памятью тоже легко пилиться и многое иное делается, чего "не бывает" .. Ви знаете .. 16 мегагерц это о-очень много! Это практически IBM PC AT x286 в "спичечном коробке" .. а там и не такое выделывали.. ;)

sadman41
Offline
Зарегистрирован: 19.10.2016

Tucoso пишет:

sadman41 пишет:

Если не хочешь менять подход - подтягивай железо до уровня привычного.

Законы эволюции никакая каменноголовая дума пока не изменила: изменяйся или вымрешь.

Я приношу извинения, но почему так часто люди любят давать результирующею оценку без фактуры - "изменяйся или вымрешь". Кто то из комментаторов сказал, что да, мол многопоточность в МК не реализуема, она не будет работать, а если будет то % полезного времени на код будет ниже плинтуса ? А я тут все ною и ною, дайте мне многопоточность!

Так почему Вы с разбегу предлагаете мне изменить подход к реализации задачи?
 
 
Да я Вам, вобщем-то, ничего не предлагал - просто констатировал факт. Какие батарейки "побольше" в ИЖ-Комби не засунь - Теслой ему от этого не быть. А Вы, как я вижу, желаете экстраполировать найденный способ устроения "многозадачности" в бесконечность выполняемых задач. Если это не так, то простите.
 
Тут много людей проходило - майнить собирались на 328-м МК, видеопотоки гонять через радио и прочую шляпу вешать на долларовый МК. Заканчивалось всё одинаково - срачем, криками "я чо, не муж... выпускник академиев, в натуре?!" и нулевым результатом после многочисленных потуг.
 
А уж сколько на МК тащится подходов к программированию с ПК - пальцев не пересчитать. Только вот что-то RAM быстро заканчивается у прожектеров и джипеги разворачиваются медленно.
 
Однако, если запузырите такую многозадачность, чтобы и сенсоры (обмен данными с которыми прерывать зачастую нельзя) успевали и экранчики рисовали веселые картинки и сеть пуляла байты во все стороны - я только поапплодирую.
Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ну обыкновенный Линукс как-то же пищит, рисует и в сеть пуляет вполне себе .. с дискретностью потока в 1мсек .. :) Идаже делал это ещё на 386-м проце, который тоже далеко не "гигагерцовый" .. может проблема не в гигагерцах или "новизне камня" (возьмите СТМ32..) а в кривых ручонках, что действительно "тащат с ПК" кучки гумна на микроконтроллеры, даже не понимая сколько и чего там помазано поверх того, что реально работает в коде (1-3% от объема)? :)

И это, как-то не обнаружил аплодисментов в теме за осцилограф с частотой сьема 592 килогерца .. не обманывайте вьюношу .. :)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

sadman41 пишет:

Однако, если запузырите такую многозадачность, чтобы и сенсоры (обмен данными с которыми прерывать зачастую нельзя) успевали и экранчики рисовали веселые картинки и сеть пуляла байты во все стороны - я только поапплодирую.

И я. 

sadman41
Offline
Зарегистрирован: 19.10.2016

Давайте не забывать, что Линукс не процессором пуляет в сеть, а сетевушкой за $10, как минимум. Которая и буферизует и ошибки обрабатывает и контрольные суммы считает, да и много чего другого. И показывает Линупс отдельной видеокартой... и пр. и др.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Только в сетевушку и видеокарту тоже все это пулять необходимо и с не меньшей скоростью .. и на той же EGA особо не разбежишься, а 16 кадров в сек она пуляла даже на 286-м. А пищать Линукс так умеет и вовсе встроенным динамиком и изначально умел. В общем-то "параллельно". :)

Tucoso
Offline
Зарегистрирован: 23.08.2018

Arhat109-2

 
Большое спасибо, за ответ.
 
1. Да безусловно я отдают себе отчет какое расстояние между JRE и МК.
2. В этом Вы абсолютно правы. Упоминание Java было лишь в контексте желания перенести опыт и принцип разработки кода на МК.
5. Реализацию через Watchdog видел и было обсуждение, которое сводилось к тому что не стоит трогать то что предназначено не для этого. Хотя идея раелизации через WD мне очень импанирует.
 
6. Возможно под "опытом разработки инженерных решений" мы друг-друга не поняли, имелось ввиду задачи CAD\CAM-систем. Как правило в таких задачах нету потребности смотреть за стеком и памятью. Что касается, размера стека, то я не берусь спорить по структуре его наполнения (вы скорее всего будите компетентнее), но вопрос в том что если я вызываю функцию из сторонней библиотеки (да хоть тот же Arduino Serial.println(..)) как оценить сколько вызовов подпрограм (вложений) будет сделано сколько переменных положится в стек. Безусловно после возврата из функции стек "здуется обратно", но под это "раздувание" заранее нужно ограничить память, что бы расширяющийся стек не потер чего другого. Вопрос заключается в статистике, например - в среднем по больнице не большие приложений написанные с использованием библиотек Arduino раздувают стек до 200 байт, и тогда я со спокойным сердцем ориентируюсь на 200+10% байт размер стека и прикидываю сколько потоков влезет в МК и чего останется на переменные.
 
9. А вот тут я не соглашусь, в случае с автоматами необходимо будет алгоритм дробить на части реализующие какуе-то микро-задачи обусловленные или алгоритмической законченностью (например вывод строки на экран) или заканчивающееся асинхронной операцией (ожидание новых данных в UART). А хочется как-то без этих "приключений".
Tucoso
Offline
Зарегистрирован: 23.08.2018

sadman41 пишет:

Однако, если запузырите такую многозадачность, чтобы и сенсоры (обмен данными с которыми прерывать зачастую нельзя) успевали и экранчики рисовали веселые картинки и сеть пуляла байты во все стороны - я только поапплодирую.

Я обещаю выложить результаты какие бы они не были :)

 
sadman41
Offline
Зарегистрирован: 19.10.2016

С видео не разбирался особо, но в сетевой адаптер не нужно постоянно пулять непрерывным потоком. Есть процессорное время - закинул в буфер / прочитал из него, нет - абонент подождет. Если бы всё было шоколадно и без сетевушек - никто бы не стал делать специализированные разгружающие чипы. Впрочем, думаю, Вы и сами понимаете, что бесконечно на лошадь грузить нельзя - хоть ее Буцефалом назови, хоть Линуксом.

Конечно, если рассматривать вариант "как я на ассемблере написал софтину, которая крутила фонарики и гимн спикером играла одновременно", то можно вспомнить и демосцену. Там все соки давили из системы, однако всё это и оставалось уделом горстки гиков, упражняющихся в затачивании алгоритмов под определенное железо. Да и товарищ не собирается переходить на данный уровень, как я понял. Он хочет AVR-JRE сделать, чтобы потом находится в комфортной среде.

-NMi-
Offline
Зарегистрирован: 20.08.2018

9. Разработка многопоточного приложения де факто мало чем отличается от .. автоматного стиля для конечных автоматов. Там все ровно тоже самое: есть КА (поток), который получает данные извне (слушатель КА) и делает нечто, в общем-то наплевав на остальные КА в системе. Если требуется он может "сообщить" состоянием (семафором, послать сигнал потоку) другому КА, что тому следует сделать .. все ровно тоже самое.

Погодьте-ка чутка. Давайте представим примитивный "умный" примус с дисплеем, часами и датчиком давление по I2C. Клавиатурка на 1838. Датчик температуры 1W. Ну и, для понта, прилепим туда любой радиомодуль по SPI. Нахлабучим это всё на кол RTOS и что получим?

Давайте разберём транзакцию (к примеру) с дисплеем. 20*4=80 да плюс по 4 бита уже 160 и управляющие команды + старт-стопы. Округлим до 200 байт для простоты)))  Вот мы открыли сессию по I2C, дисплей нам ответил и мы засылаем в него всю пачку данных за один раз (ардуинщики - это я про С+ или около!!!) и тут! вдруг мы не успеваем всё передать а управление передаётся другому потоку!

Так вот, как вы думаете, будет ли корректно работать такой код???

-NMi-
Offline
Зарегистрирован: 20.08.2018

Arhat109-2 пишет:

Только в сетевушку и видеокарту тоже все это пулять необходимо и с не меньшей скоростью ..

Правильно. Только не забываем про DMA и всё становится на свои места)))

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

6. Точно также как и свои функции. Открываете исходник и смотрите сколько там вложенных вызовов. Тут нет скомпилированных DLL модулей с закрытым кодом.

9. Вы просто ещё не разобрались в КА .. там все точно также банально ..

10 Рассинхронизм "атомарных" действий решается достаточно просто несколькими способами, от "отключить многозадачность для критического куска", до реорганизовать кусок убрав критичность. Тут как раз фигня написана про дисплей .. по нему (LCD1602) уже были баталии и было показано как примитивный драйвер I2C вполне нормально пуляет в него строки за 95микросекунд..

ssss
Offline
Зарегистрирован: 01.07.2016

-NMi- пишет:

Погодьте-ка чутка. Давайте представим примитивный "умный" примус с дисплеем, часами и датчиком давление по I2C. Клавиатурка на 1838. Датчик температуры 1W. Ну и, для понта, прилепим туда любой радиомодуль по SPI. Нахлабучим это всё на кол RTOS и что получим?

Давайте разберём транзакцию (к примеру) с дисплеем. 20*4=80 да плюс по 4 бита уже 160 и управляющие команды + старт-стопы. Округлим до 200 байт для простоты)))  Вот мы открыли сессию по I2C, дисплей нам ответил и мы засылаем в него всю пачку данных за один раз (ардуинщики - это я про С+ или около!!!) и тут! вдруг мы не успеваем всё передать а управление передаётся другому потоку!

Так вот, как вы думаете, будет ли корректно работать такой код???


На копеечном стм32ф0... с его ДМА и прерываниями - как два пальца... 12-15 задач не проблема... даже без РТОС...

-NMi-
Offline
Зарегистрирован: 20.08.2018

Да, но речь то про AVR )))

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

-NMi- пишет:

Да, но речь то про AVR )))

А ссовцу пох, ему лишь бы дерьма на вентиллятор вкинуть.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Arhat109-2 пишет:

Только в сетевушку и видеокарту тоже все это пулять необходимо и с не меньшей скоростью .. и на той же EGA особо не разбежишься, а 16 кадров в сек она пуляла даже на 286-м. А пищать Линукс так умеет и вовсе встроенным динамиком и изначально умел. В общем-то "параллельно". :)

Речь не о скорости а о наличии пауз в 1 мс или более.

Процессор пихнул себе по-быстрому в видеопамять или буфер видеокарты, а то и вовсе - настроил DMA и может несколько мс курить. Т.е. многозадачность в данном случае чисто аппаратная. 

Я уже привел пример: попытайтесь только процессором сформировать видеосигнал с разрешением 1920х1280. Теоретически его производительности должно хватить, но пауза даже в 1 мкс, не говоря об 1 мс, сразу испортит всю картинку, а то и собъет синхронизацию.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Я уже Вам ответил: на 286 и EGA у меня драйвер вполне бегал 16 кадров в сек с разрешением 640х480 (другого там не было) катая на скоростях под 5 мегабайт в сек. в Ягушку.. да, было сильно хитрО закручено, ибо реализован был "псевдографический режим" а-ля спектрум .. и Вы путаете вывод в буфер драйвера и ФОРМИРОВАНИЕ ТВ-изображения НА ЭКРАНЕ (без памяти). Дергать развертку в нужных тактах - не есть задача НИКАКОГО даже микро- контроллера (для этого есть специально обученные схемы - счетчики, см. "Специалист" для просветления).

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

-NMi- пишет:

Давайте разберём транзакцию (к примеру) с дисплеем. 20*4=80 да плюс по 4 бита уже 160 и управляющие команды + старт-стопы. Округлим до 200 байт для простоты)))  Вот мы открыли сессию по I2C, дисплей нам ответил и мы засылаем в него всю пачку данных за один раз (ардуинщики - это я про С+ или около!!!) и тут! вдруг мы не успеваем всё передать а управление передаётся другому потоку!

Так вот, как вы думаете, будет ли корректно работать такой код???

1. В ардуишной реализации буфер I2C - 32 байта. Первый - управляющий. Соответственно, все, что мы попытаемся запихнуть свыше 31 байта, будет потеряно.

2. Допустим мы работаем с союмтвенным софтовым I2C без всяких буферов, как говорится, по факту. Вы будете смеяться, но работать - будет. I2C - протокол с синхросигналом, где нормируются только минимальные длительности, максимальные могут быть какими угодно. Так что если мы прервем передачу по I2C на середине бита (даже не байта!), то по окончании прерывания протокол возобновит свою работу как ни в чем не бывало.

 

Так что пример - неудачный. А удачный пример я уже приводил - формирование полного телевизионного сигнала. И, кстати, передачу по Serial тоже прерывать нельзя ввиду отсутствия внешнего синхросигнала.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Arhat109-2 пишет:

Я уже Вам ответил: на 286 и EGA у меня драйвер вполне бегал 16 кадров в сек...

Нифига Вы не ответили.

Вот если бы было "на 286 без видеоадаптера.." и далее по тексту - тогда другое дело.

И путаю не я, а Вы. Еще раз приведу ссылку, которую уже давал: https://code.google.com/archive/p/arduino-tvout/

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

-NMi-
Offline
Зарегистрирован: 20.08.2018

2. Допустим мы работаем с союмтвенным софтовым I2C без всяких буферов, как говорится, по факту. Вы будете смеяться, но работать - будет. I2C - протокол с синхросигналом, где нормируются только минимальные длительности, максимальные могут быть какими угодно. Так что если мы прервем передачу по I2C на середине бита (даже не байта!), то по окончании прерывания протокол возобновит свою работу как ни в чем не бывало.

Так что пример - неудачный.

Возможно, я не притендую на очевидность. Но, если почитать мой "пример" ещё раз и вникнуть, зачем я "прилепил" на шину I2C аж целых ТРИ устройства, многое станет очевидным. Я прекрасно знаю как работает I2C шина и тд. и тп.  НО... Допустим, мы прервали сессию связи с дисплеем по причине "невлезания" в квант времени, отданый RTOS потоку. И, допустим, следующий квант времени будет отдан опросу часиков. Поток СБРОСИТ шину и обратится УЖЕ к часикам!!! Повторный квант потока продолжит работу с дисплеем НО, до дисплея эти данные уже не дойдут! И будет наинтереснейший глюк, когда как вроде всё работает НО иногда глючит. Так шо...  )))

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Путаете Вы, и уже обьяснил почему. То что по ссылке некто приплел МК к задаче ни разу не требующей его .. так тут и как включить выключатель люстры ардуиной вопрошают .. не показатель ни разу. Маяться дурью можно по всякому. Не пример, ещё раз. И повторять тут нечего.

triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

Tucoso пишет:

Насколько реально реализовать эти задачи в МП режиме,

Нет проблем. Кооперативная многопоточность делается в пол пинка, универсально, без извращений с автоматами и без ковыряния в железе: подключаете библиотеку coos для Ардуино, пишите свои независимые друг от друга потоки/задачи, они будут исполняться (квази)одновременно. Тысячу потоков не потянет (памяти и производительности не хватит), но 5-10 потоков - легко. 

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

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Можно и кооперативно, можно и вытесняюще, можно даже расширить типовой таймер millis() который будет исполнять задачи через timer_hook (тоже были образцы тут), можно прикрутить эту библиотеку, есть вариант на timer1 .. свой лисапед сварганить - вечерок посидеть, делов-то. Времени уйдет меньше чем потрачено на поломанные копья тут. :)

.. только это всё не для ТС-а.. хотя .. раз обещал показать - пусть делает. :)

triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

Arhat109-2 пишет:

.. только это всё не для ТС-а..

Ерунда, кооперативная ось как раз для него, все его "хотелки" выполняются.  Он пока слегка "плавает", например, думает, что для каждой задачи/потока "нужен свой стек". Однако не нужен. Нужен небольшой клочок памяти для хранения контекста задачи, это все. В coos эта память отжирается, когда задается макс. число задач COOS_MAX_TASKS.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

triac, вот допустим у вас работа разбирать и собирать планшеты или смарфоны и они потом работали. Можно ли заниматься разборкой и сборкой паралельно. Ну допустим надо выявить неисправность, заказать запчати и собрать. Легко если у вас несколько столов, легко если в процессе разборки вы укладываете запчасти в отведеную коробку. Но это проблематично если у вас привычка что в процессе разборки вы разбрасываете запчасти везде. Ну если с одним то куда ни шло. Но если вы их разбираете "многозадачно".  Думаю проблема многозадачности у ТС возникла из-за неприятия менять себя и свои привычки. Ну как же он привык он это всегда делал. А собирала и приводила в порядок код тетя Джава. А здесь тети Джавы нет, все приходится ручками. Вот и спрашивает если у кого-то подобная тетя Джава на одолжить.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

qwone, Ви не представляете какая у нас с сыном на рабочем столе "многозадачность" и, судя по вашей метафоре .. усё "на стеке" (как попало) .. зафотать? :)

triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

qwone пишет:

 Думаю проблема многозадачности у ТС возникла из-за неприятия менять себя и свои привычки. Ну как же он привык он это всегда делал. А собирала и приводила в порядок код тетя Джава. А здесь тети Джавы нет, все приходится ручками. Вот и спрашивает если у кого-то подобная тетя Джава на одолжить.

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

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ну .. ежели "диспетчер задач" + типовой malloc() + небольшие макросы типа моего ovfGetCount(), ifMillis().. для упрощения работы с КА и событийной логикой, вкупе с парой недоклассов, называть "осью" .. то да. :)

triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

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