реклама на сайте
подробности

 
 
17 страниц V  « < 7 8 9 10 11 > »   
Reply to this topicStart new topic
> Система, управляемая событиями и SST(super-simple tasker), Выделено из "ООП. Классы и динамические объекты"
brag
сообщение Sep 13 2016, 11:04
Сообщение #121


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Посмотрел FatFs - это блокирующий стиль, async IO там не предусмотрено, значит эту библиотеку я использовать не буду, а поскольку я ею никогда не пользовался, то и отправлять на свалку нечего, а так с удовольствием бы это сделал sm.gif
Благо, у меня есть своя написана давно за неделю, правда она не публичная.
В демо-проекте будем использовать что-то другое. Что - еще посмотрим. Может свою реализацию выложу в каком-то определенном виде, чтобы не было конфликтов интересов.

Значит что будет в демо-проекте - пару кнопок(плей, стоп), будем читать с флешки, декодировать и прогирывать MP3, одновременно будет мигать диод по таймеру, и одновременно будем воспроизводить анимацию на LCD. Также на SPI повесим термометр и будем раз в секунду считывать с него показания и отображать на LCD, это чтобы на практике посмотреть, как сериализировать доступ к шине.
Код максимально простой и понятный.
Проект сделаем под ПК, чтобы каждый смог запустить и опробовать в действии. Симулятор прерываний у меня давно написан и работает, SPI и флешка, gpio и дисплей - нарисуем, это не сложно. И того будет 2 модуля - симулятор и наша програмка. Кто захочет - запросто запустит саму програмку под свой МК в своей схеме, придется только самому проинициализировать железо и завернуть обработчики прерываний на наш проект.
Ну это еще будет видно как оно точно будет, пока так даю предварительную информацию.

Цитата
Т.е. - как это задача2 будет завершена? А её куча локальных переменных, дерево вызовов процедур (запись во флешь была вызвана на некоем довольно глубоком уровне вложенности функций) - куда это всё? Где это всё хранить? Как это всё передать задаче3? Если не на стеке - то это крайне неудобно.

Вы не прочитали внимательно ветку с самого начала и не имеете представления как это работает, так же не имеете опыта работы в данном стиле, поэтому Вам кажется, что это неудобно.
Велосипедисту на автомобиле тоже ехать неудобно, если он впервые сел за руль sm.gif
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 13 2016, 11:17
Сообщение #122


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(brag @ Sep 13 2016, 15:44) *
Но выполнение этого кода в любой момент может быть прервано(вытеснено) другим более приоритетным кодом(будь то прерыванием или любым другим событием)[/b]. Если нужна сериализация доступа к ресурсу(будь то флешка или что либо другое)- используется не огромный стек и тяжеленные мютексы, а быстрые легковесные очереди(FIFO), часто lock-free. Стек на весь проект один единственный.

Слишком много перечитывать - не осилю.
Насчёт вытеснения более приоритетной задачей - тут нет проблем, всё ясно. Но вот как быть с сериализацией доступа к ресурсу из нескольких задач приоритетом? Если у Вас стек единый, это значит что по мере вытеснения задач, одна прерывается другой и используемые ими области стека будут смежными. В этом случае я не предсталяю каким образом отдать управление менее приритетной задаче, которая занимает стек по бОльшим адресам, когда более приоритетная задача вдруг входит в состояние ожидания ресурса.

Цитата(brag @ Sep 13 2016, 17:04) *
Вы не прочитали внимательно ветку с самого начала и не имеете представления как это работает, так же не имеете опыта работы в данном стиле, поэтому Вам кажется, что это неудобно.

В каком стиле? Я именно и спрашиваю про Ваш "стиль". Мне интересно.
Работу нескольких задач без блокировок и на едином стеке и с сериализацией ресурсов я реализовывал. И без всяких очередей. На кэллбэках. Но алгоритм всего построения ПО в таком стиле он очень далёк о традиционного вида нескольких задач-обработчиков сообщений.
Вот и интересуюсь - может Вы что-то новое изобрели. Всё мне читать лень - мне интересен сам принцип.
Go to the top of the page
 
+Quote Post
brag
сообщение Sep 13 2016, 11:18
Сообщение #123


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Цитата
Слишком много перечитывать - не осилю.

Это очень мало, все максимально сжато, флуд можете смело пропускать. Чтобы чему-то научиться читать нужно гораздо больше.

Цитата
когда более приоритетная задача вдруг входит в состояние ожидания ресурса.

Такого никогда не происходит, ожиданий здесь нет. Все таки рекомендую почитать ветку, если это Вам интересно.

Цитата
В каком стиле?

Неблокирующем асинхронном.

Цитата
И без всяких очередей.

Без очередей не получится. Очередь - это "сердце" асинхронного движка(стиля). Без очереди Вы не сможете сериализовать доступ к ресурсу работая в асинхронном стиле.
Цитата
На кэллбэках. Но алгоритм всего построения ПО в таком стиле он очень далёк о традиционного вида нескольких задач-обработчиков сообщений.

Да, он очень далек, но он имеет много преимуществ перед блокирующим, А чтобы было удобно работать - нужен, как минимум С++11 с его лямбдами.
В асинхронном стиле очень удобно работать на Javascript поскольку там есть замыкания и сборка мусора. Но мы пока еще не дорасли до применения этого(или подобного) языка на МикроКонтроллерах, но очень уверенно к этому двигаемся и рано или поздно к этому придем. Я сейчас изучаю язык Rust, очень большие надежды на него. Если не он, то найдем что-то другое, или будем плюсы(17-е) допиливать, всякими шаблонами и др. стандартными для этих 17х плюсов средствами.
Благо, в однопоточном асинхронном стиле сборщик мусора гораздо проще, тк время жизни обьектов меньше, один поток, один стек.

Хотя динамические очереди это уже от части сборка мусора - сами же очереди и следят за выделением/освобождением памяти под данные задач, а не пользователь.
Вот посмотрел пару своих сложных проектов по диагонали - new/delete встречаю в коде очень и очень редко! Так что это еще один плюс SST - в подавляющем большинстве случаев сборка мусора происходит сама собой прозрачно для пользователя и очень эффективно.
В блокирующем многопоточном стиле сборщик мусора очень сложный и тяжелый и в МК он ессно не влезет.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 13 2016, 11:40
Сообщение #124


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(brag @ Sep 13 2016, 17:18) *
Да, он очень далек, но он имеет много преимуществ перед блокирующим, А чтобы было удобно работать - нужен, как минимум С++11 с его лямбдами.
В асинхронном стиле очень удобно работать на Javascript поскольку там есть замыкания и сборка мусора. Но мы пока еще не дорасли до применения этого(или подобного) языка на МикроКонтроллерах, но очень уверенно к этому двигаемся и рано или поздно к этому придем. Я сейчас изучаю язык Rust, очень большие надежды на него. Если не он, то найдем что-то другое, или будем плюсы(17-е) допиливать, всякими шаблонами и др. стандартными для этих 17х плюсов средствами.

Если он также далёк от традиционного вида (наиболее удобного для чтения и разбирания исходников), то тогда не надо. На кэллбэках я реализую то же самое, но без всяких очередей и на обычном си.
Да кстати - хорошо, стек не переполняется у Вас, а очереди - они могут у Вас переполнится? Не стек так очереди.
И динамическая память в ембеддед - это не айс. Лучше всячески избегать её.
Go to the top of the page
 
+Quote Post
brag
сообщение Sep 13 2016, 11:52
Сообщение #125


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Цитата
сли он также далёк от традиционного вида (наиболее удобного для чтения и разбирания исходников), то тогда не надо. На кэллбэках я реализую то же самое, но без всяких очередей и на обычном си.

Анука покажите, как Вы без очереди сериализуете доступ к шине SPI, когда на ней 2 абсолютно непредсказуемых устройства к которым может понадобится доступ в абсолютно непредсказуемое время, например когда шина уже занята? Желательно на примере кода.

Цитата
Да кстати - хорошо, стек не переполняется у Вас, а очереди - они могут у Вас переполнится? Не стек так очереди.

Необходимый размер очереди очень легко просчитывается, в отличии от стека. Стек невозможно просчитать, когда код сложный из виртуальных функций, а хуже того - рекурсии. Потом резервирование памяти под очередь в 4-кратном размере от расчетного - это каких-то лишних 50-100 байт, в то время, как для стека - это килобайт и более, на практике разница в 10 и больше раз. Это во первых.
А во вторых переполнение очереди отслеживается программно и зачастую даже прозрачно для пользователя, любое переполнение очереди - это recoverable error, в то время как переполнение стека - это крах всей системы.

Цитата
И динамическая память в ембеддед - это не айс.

Для тех, кто не умеет с ней работать sm.gif
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 13 2016, 13:05
Сообщение #126


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(brag @ Sep 13 2016, 17:52) *
Анука покажите, как Вы без очереди сериализуете доступ к шине SPI, когда на ней 2 абсолютно непредсказуемых устройства к которым может понадобится доступ в абсолютно непредсказуемое время? Желательно на примере кода.

Элементарно:
Предположим, что освобождение шины происходит в конце DMA-транзакции вызовом соответствующего ISR.
Любая задача, желающая произвести транзакцию по SPI, вызывает функцию ReqSPI() и завершается.
Тогда упрощённо это будет выглядеть например так:
CODE
static char volatile spiAct = 0; //при !=0 - идёт транзакция по SPI
static char volatile spiReq = 0; //при !=0 - идёт транзакция по SPI или есть запрос
static void (*endAct)();

//Установка состояния ожидания для прерывания num
#define IntSet(num) { NVIC.SETPEND[(num) >> 5] = 1u << ((num) & 0x1F); }
//Сброс состояния ожидания для прерывания num
#define IntClr(num) { NVIC.CLRPEND[(num) >> 5] = 1u << ((num) & 0x1F); }

void ReqSPI()
{
CPU_SR_ALLOCATE();
ENTR_CRT_SECTION(); //вход в крит. секцию (собственно - запрет прерываний)
if (!spiReq) {
spiReq = 1;
IntSet(NVIC_SPI); //программно активируем прерывание завершения транзакции SPI
}
EXIT_CRT_SECTION();
}

extern "C" void isrSPI() //ISR SPI
{
void (*p)();
if (spiAct) {
spiAct = 0;
//здесь делаем работу, необходимую при завершении транзакции по SPI
//например:
DeactivateCS();
if (endAct) endAct();
}
spiReq = 0;
if (!(p = SpiStartUser1())) //запросим пользователя1 нужна ли ему транзакция по SPI
if (!(p = SpiStartUser2())) //запросим пользователя2 нужна ли ему транзакция по SPI
...
if (!(p = SpiStartUserN())) return; //в данный момент нет пользователей желающих поработать с SPI
spiReq = 1;
IntClr(NVIC_SPI);
spiAct = 1;
ActivateCS();
endAct = p();
}
//Любой пользователь шины SPI (задача-пользователь), когда хочет произвести
//транзакцию по SPI, вызывает ReqSPI() и завершается.
//После сразу (если шина была свободна) или по её освобождении, будут в порядке
//приоритета вызваны функции с SpiStartUser1() по SpiStartUserN(), пока одна из
//них не вернёт указатель на функцию программирующую собственно железо SPI и
//запускающую транзакцию. Эта функция также возвращает указатель на функцию
//принимающую нотификацию о завершении транзакции SPI.


Цитата(brag @ Sep 13 2016, 17:52) *
код сложный из виртуальных функций, а хуже того - рекурсии.

А не надо в ембеддед использовать виртуальные функции и рекурсии и тогда всё нормально будет со стеком.
Go to the top of the page
 
+Quote Post
brag
сообщение Sep 13 2016, 13:38
Сообщение #127


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



jcxz, большое спасибо за код, именно так я и хотел, чтобы в таком духе развивалась тема.
Но это у Вас получилась очередь, только не динамическая(которую заполняет сам код в рантайме), а статическая, которую заполняет программист.
Вот этот код-это уже очередь, при чем приоритетная(User1 имеет высший приоритет, а UserN - низший):
Код
if (!(p = SpiStartUser1())) //запросим пользователя1 нужна ли ему транзакция по SPI
if (!(p = SpiStartUser2())) //запросим пользователя2 нужна ли ему транзакция по SPI
...
if (!(p = SpiStartUserN())) return; //в данный момент нет пользователей желающих поработать с SPI

Только пользоваться ею не удобно. У меня изначально, когда я только начинал учится асинхронщине примерно такое и выходило.
Потом эти цепочки ифов я заменил на просмотр односвязного списка User-ов, а потом и вовсе вместо списка втулил RingBuffer-FIFO User-ов, сначала ячейки были фиксированного размера, а затем стали динамические. Так и родилась концепция задач/очереди задач(то есть велосипед) в моей голове sm.gif

Цитата
А не надо в ембеддед использовать виртуальные функции и рекурсии и тогда всё нормально будет со стеком.

Да любой динамически изменяемый указатель на функцию уже виртуальная функция, а хуже того - запросто может быть рекурсивная. Можно конечно и их не использовать, но тогда зачем С и даже асм сдался вместе с их компиляторами, можно запросто в машинных кодах писать и все будет в шоколаде.
Инструкций indirect jump/indirect call проца при этом тоже ессно использовать не нужно, потому что эти инструкции - это уже виртуальные функции и динамический полиморфизм sm.gif
и в следствии этого Ваш анализатор стека должен полностью уметь выполнять код программы, как это делает проц(то есть быть полным симулятором проца), мало того, он должен уметь создавать такие ситуации, когда размер стека вызовов будет максимально-возможным. Я делал подобный анализатор - очень сложная задача, так и не довел его до ума, но пользовался им постоянно и постоянно его допиливал. А после перехода на SST-модель отправил этот анализатор(вместе с несколькими месяцами своей жизни) на свалку sm.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 13 2016, 13:51
Сообщение #128


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (jcxz @ Sep 13 2016, 16:05) *
А не надо в ембеддед использовать виртуальные функции
Объясните пожалуйста, что же такого страшного есть в виртульных функциях?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 13 2016, 14:10
Сообщение #129


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Сергей Борщ @ Sep 13 2016, 19:51) *
Объясните пожалуйста, что же такого страшного есть в виртульных функциях?

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

Цитата(brag @ Sep 13 2016, 19:38) *
jcxz, большое спасибо за код, именно так я и хотел, чтобы в таком духе развивалась тема.
Но это у Вас получилась очередь, только не динамическая(которую заполняет сам код в рантайме), а статическая, которую заполняет программист.
Вот этот код-это уже очередь, при чем приоритетная(User1 имеет высший приоритет, а UserN - низший):

Не знаю почему Вы это называете очередью. Ну да ладно.
Это и есть разделение доступа к ресурсу, основанное на кэллбэках. Такой метод позволяет делать сериализацию доступа к ресурсам на одном стеке и иногда я им пользуюсь.
Тут не задача-пользователь запрашивает ресурс произвести операцию с ним, а ресурс (т.е. - его диспетчер) запрашивает задачи-пользователи желают-ли они произвести с ним операцию.
Но вот код задач становится гораздо хуже читаемым. Так как в классическом виде с блокировками ресурсов, выполнение идёт в порядке строк функции. А здесь будет разорвано на отдельные функции - зрительно нарушен порядок следования. В этом главный минус.
Go to the top of the page
 
+Quote Post
brag
сообщение Sep 13 2016, 14:28
Сообщение #130


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Цитата(jcxz @ Sep 13 2016, 17:02) *
Т.е. - я хотел сказать, что без них используемый размер стека проще определить.

Без них стек считается очень просто, а с ними - очень сложно.

Цитата
У меня изначально, когда я только начинал учится асинхронщине примерно такое и выходило.
Потом эти цепочки ифов я заменил на просмотр односвязного списка User-ов, а потом и вовсе вместо списка втулил RingBuffer-FIFO User-ов, сначала ячейки были фиксированного размера, а затем стали динамические.

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

Цитата
Не знаю почему Вы это называете очередью. Ну да ладно.

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

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

Это из за отсутствия опыта работы в данном стиле, языковой и рантайм поддержки. Мне бы без С++11 тоже было работать в этом стиле очень трудно. В общем асинхронный стиль требует языков более высокого уровня, например javascript с его замыканиями, худо бедно эти замыкания делаются на ламбдах и шаблонах С++11.
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Sep 13 2016, 15:23
Сообщение #131


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(brag @ Sep 13 2016, 16:38) *
Так и родилась концепция задач/очереди задач(то есть велосипед) в моей голове sm.gif

Ваша модель, если я правильно понял ваши объяснения, называется Акторами и давно реализована в шарпе, джаве, скале. Вы её разбавили ненужым уточнением в виде SST. Обе концепции вполне способны существовать в отрыве от друг друга.
Go to the top of the page
 
+Quote Post
brag
сообщение Sep 13 2016, 15:32
Сообщение #132


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Цитата(Kabdim @ Sep 13 2016, 18:23) *
Ваша модель, если я правильно понял ваши объяснения, называется Акторами и давно реализована в шарпе, джаве, скале. Вы её разбавили ненужым уточнением в виде SST. Обе концепции вполне способны существовать в отрыве от друг друга.

Да, что-то типа того. Правда я в скале и шарпе не силен, не могу точно сказать.
Сама концепция(асинхронные события с приоритетами и вытеснением) существует давно, но начала активно применятся относительно недавно.
Go to the top of the page
 
+Quote Post
Guest_TSerg_*
сообщение Sep 13 2016, 15:55
Сообщение #133





Guests






Цитата(brag @ Sep 13 2016, 18:32) *
Сама концепция(асинхронные события с приоритетами и вытеснением) существует давно, но начала активно применятся относительно недавно.

Ну да, конечно. Вот только разработчикам бортовых систем класса "Буран" и подобных ему в других областях - не надо это говорить даже шепотом.
Go to the top of the page
 
+Quote Post
brag
сообщение Sep 13 2016, 16:46
Сообщение #134


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Не знаю что там с Бураном, даже понятие не имею что это такое sm.gif Асинк-стиль был наверное еще до блокирующего, по идеи, хз. Говорю, как вижу своими глазами. Аsync io, например в винде существует очень давно, но активно начали применять относительно недавно. Такие проекты, как NodeJS, async IO в Qt, Nginx появились уже после традиционных блокирующих решений. А в никсах так вообще изначально был только блокинг-io(хотя сигналы существуют тоже очень давно), потом были всякие костыли(и есть до сих пор), а только потом появился действительно асинхронный ввод/вывод, да и то не во всех никсах.
Или взять базы данных - раньше все было исключительно блокинг, а сейчас переходят на нон-блокинг, а новые БД(например MongoDB) - вообще чисто асинхронные изначально.
В общем, сейчас, с приходом высоко-уровневых языков и новомодных техник асинхронный подход получил новый виток развития.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Sep 13 2016, 18:07
Сообщение #135


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



bb-offtopic.gif
Цитата
Не знаю что там с Бураном, даже понятие не имею что это такое

Буран это такая космическая хреновина которая полностью в автоматическом режиме вышла на орбиту и приземлилась потом ) Было это в далеком 1988 году wink.gif
https://ru.wikipedia.org/wiki/%D0%91%D1%83%...B1%D0%BB%D1%8C)


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post

17 страниц V  « < 7 8 9 10 11 > » 
Reply to this topicStart new topic
5 чел. читают эту тему (гостей: 5, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 06:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.01515 секунд с 7
ELECTRONIX ©2004-2016