ReAl 0 13 марта, 2009 Опубликовано 13 марта, 2009 · Жалоба LOL : чуть дальше "Но реально не применяю :-), как-то не жмёт пока обычный switch()... "По крайней мере я не пользуюсь этой возможностью не потому, что я о ней не знаю :-) Мне просто не нужен эффект от неё, а я с какого-то фига стараюсь не использовать нечто очень специфическое - хотя иногдасамому непонятно почему. Используют же работающие с IAR его всякие красивости и в ус не дуют. Впрочем, потихоньку прорывает, недавно таки поставил диапазонный case там, где он был удобен, чуть раньше локальную (вложенную) функцию использовал там, где она очень просилась. В подобных же темах часто обсуждается как бы выжать ещё немного объёма и скорости и в таком месте вычисляемый goto вполне в строку. Имеет общие черты как функцй, возвращющих указатели на фунции, так и switch Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Diz 0 14 марта, 2009 Опубликовано 14 марта, 2009 · Жалоба Интересно, а как сделать с набором параллельно работающих конечных автоматов (без RTOS) долго работающую задачу, требующую активного участия процессора ? Например, работу с FAT (сектор может читаться значительное время) или рендеринг экрана для UI (тоже небыстро). Разбивать на отдельные этапы некрасиво и неудобно, а иначе задача будет блокировать другие на долгое время. С подобными вещами не сталкивался, так как у меня обычно много мелких задач и отрабатываются они мгновенно, либо без участия процессора - большую часть времени процессор спит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 14 марта, 2009 Опубликовано 14 марта, 2009 · Жалоба Интересно, а как сделать с набором параллельно работающих конечных автоматов (без RTOS) долго работающую задачу, требующую активного участия процессора ? Например, работу с FAT (сектор может читаться значительное время) или рендеринг экрана для UI (тоже небыстро). Разбивать на отдельные этапы некрасиво и неудобно, а иначе задача будет блокировать другие на долгое время. Да, есть некоторая проблема. Там, где обращение к УВВ гробит интерфейс пользователя, делаем упреждающее чтение в память при включении устройства (ну типа Windows :) ). Там где это невозможно... ну работали же раньше с дискетами? Часики, песочек... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 14 марта, 2009 Опубликовано 14 марта, 2009 · Жалоба Интересно, а как сделать с набором параллельно работающих конечных автоматов (без RTOS) долго работающую задачу, требующую активного участия процессора ? Например, работу с FAT (сектор может читаться значительное время) или рендеринг экрана для UI (тоже небыстро). Разбивать на отдельные этапы некрасиво и неудобно, а иначе задача будет блокировать другие на долгое время.Разбивать на этапы, и других вариантов особо и нет... Ну или хитрое разделение с задачами выполняемыми в прерываниях. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Diz 0 15 марта, 2009 Опубликовано 15 марта, 2009 (изменено) · Жалоба Разбивать на этапы, и других вариантов особо и нет... Ну или хитрое разделение с задачами выполняемыми в прерываниях. Вообщем, для таких вещей напрашивается RTOS. Или разделение на несколько процессоров, если задача позволяет. Изменено 15 марта, 2009 пользователем Diz Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 16 марта, 2009 Опубликовано 16 марта, 2009 · Жалоба Вообщем, для таких вещей напрашивается RTOS. ОЗУ надо побольше, чтоб стеки таких процессов не проваливались. И тогда - хоть setjmp, хоть его обрезанные варианты-решат проблему аж бегом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Diz 0 17 марта, 2009 Опубликовано 17 марта, 2009 · Жалоба Еще один интересный вариант реализации машины состояния на плюсах, использовали в одном проекте. Каждое состояние представляется отдельным классом, унаследованным от базового. Все обработчики событий заданы в базовом классе как виртуальные функции: virtual void eventButtonPressed() = 0 ; virtual void eventTimerExpired() = 0 ; Определяются конкретные обработчики уже в производных классах (состояниях). Также существует указатель, указывающий на текущее состояние (экземпляр класса). По приходу события просто вызывается нужная функция-член из класса по указателю. Преимущества: Базовый класс не обязательно должен быть абстрактным. Некоторые обработчики можно сразу определить в нем и получить реакцию на событие по умолчанию. Как пример, обработчик тика системного таймера, на который надо реагировать одинаково во всех состояниях. Можно сделать более сложную иерархию классов. Унаследовать класс от базового, определить в нем обработчик (напр. eventPacketReceived). От этого класса наследовать еще несколько подсостояний, но там этот обработчик не определять. В итоге подстостояния унаследуют реакцию на eventPacketReceived от своего суперкласса. Получается простая реализация иерархической машины состояний. Можно инкапсулировать в класс данные, нужные только для конкретного состояния - например, счетчик принятых пакетов. Вменяемый плюсовый компилятор делает очень хороший код с оптимизацией - на такие задачи он и рассчитан, вообщем-то. Хорошие IDE умеют показывать иерархию классов, что приятно для визуализации во время кодирования. Недостатки: Много писанины, много однострочных функций. Наглядности без визуализации IDE никакой. Требуется еще одна таблица или switch для выбора метода по приходу события. Компилятор может оказаться невменяемым :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 19 марта, 2009 Опубликовано 19 марта, 2009 · Жалоба Вообщем, для таких вещей напрашивается RTOS. Или разделение на несколько процессоров, если задача позволяет.Какой нафиг RTOS... :) вот буквально последняя задачка, опрос 6 дискретов с тактом 50мкс с фильтрацией (это быстрый процесс) и обмен по уарт на 230400("медленный" процесс), обмен при этом на скорости ~19Кбайт/сек все решает точное деление на состояния автомата обмена по уарту... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Diz 0 19 марта, 2009 Опубликовано 19 марта, 2009 (изменено) · Жалоба Какой нафиг RTOS... :) вот буквально последняя задачка, опрос 6 дискретов с тактом 50мкс с фильтрацией (это быстрый процесс) и обмен по уарт на 230400("медленный" процесс), обмен при этом на скорости ~19Кбайт/сек все решает точное деление на состояния автомата обмена по уарту... Ну, это деление не этапы опять же :-) Иногда хочется использовать готовую библиотеку (для того же FAT) - бить на состояния уже непросто. Проще даже переписать с нуля. Изменено 19 марта, 2009 пользователем Diz Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 20 марта, 2009 Опубликовано 20 марта, 2009 · Жалоба Ну, это деление не этапы опять же :-) Иногда хочется использовать готовую библиотеку (для того же FAT) - бить на состояния уже непросто. Проще даже переписать с нуля. Да, большие готовые библиотеки лишают автоматы всяческих преимуществ... Однако тупик с автоматами... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 20 марта, 2009 Опубликовано 20 марта, 2009 · Жалоба Да, большие готовые библиотеки лишают автоматы всяческих преимуществ... Однако тупик с автоматами... Не, не всегда так все печально..., если есть "жирная"(библиотечная в том числе) функция, то она работает в основном цикле проги, автоматы просто выносятся в прерывания, например в прерывания системного тика (10мс, 1мс, 100мкс, 25мкс...) Конечно при этом нужно "вручную" рулить приоритетами и занимаемым автоматами временем, но как бонус, 100% загрузка проца и максимальные параметры по автоматам(при удачном ручном распределении) Вобщем особых ограничений к использованию автоматов все равно не просматривается.... есть только частные ограничения реализации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 22 марта, 2009 Опубликовано 22 марта, 2009 · Жалоба Интересно, а как сделать с набором параллельно работающих конечных автоматов (без RTOS) долго работающую задачу, требующую активного участия процессора ? Например, работу с FAT (сектор может читаться значительное время) или рендеринг экрана для UI (тоже небыстро). Разбивать на отдельные этапы некрасиво и неудобно, а иначе задача будет блокировать другие на долгое время. ..... С FAT пример неудачен. Сектор то читается драйверком SPI, и пока он читается задача отдыхает (не требует активного участия CPU). Рендеринг экрана - подходящий пример. Посмотрим по аналогии. Есть Borland'овский VCL, где вся графика обслуживается исключительно в основном потоке приложения, и при запуске какой-то длительной задачки в том же основном потоке прорисовка приложения намертво тормозится. Чтобы пользователь не подумал, что программа зависла, можно и нужно было либо стартовать доп поток, либо, что значительно проще - иногда вызвать функцию: Application->ProcessMessages(); Вот так же можно поступить и тут. Что мешает реализовать некую функцию yield / idle - которую любой затяжной процесс сможет вызвать сам, чтобы дать поработать всем остальным процессам? Для того чтобы такую функцию можно было реализовать, необходимо чтобы был список задач(автоматов) с возможностью модификации в Run-Time (чтобы процесс вызывающий эту функцию мог быть удален из списка процессов на время своего испонения). Сосбно вот: typedef void (* p_cb)(void); #define COUNT(arr) (sizeof(arr) / sizeof((arr)[0])) p_cb list[4]; void add_task( p_cb Callback) { for(int i = 0; i < COUNT(list); i++) if (!list[ i ]) { list[ i ] = Callback; break; } } void idle(void) { for(int i = 0; i < COUNT(list); i++) if (list[ i ]) { p_cb cb = list[ i ]; list[ i ] = NULL; cb(); list[ i ] = cb; } } void foo_1(void) { } void foo_2(void) { } // это долгий процесс делающий рендеринг void foo_long(void) { volatile unsigned long x = -1UL; while( x--) { // ... do complex stuff if ( (x & 0xFF) == 0 ) // 255 iterations passed { // дадим поработать другим задачам idle(); } } } void main(void) { add_task( foo_1 ); add_task( foo_2 ); add_task( foo_long ); for(;;) idle(); } Да, большие готовые библиотеки лишают автоматы всяческих преимуществ... Однако тупик с автоматами... Раскидать idle()'ов по ключевым точкам и автоматы получают вторую жизнь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 23 марта, 2009 Опубликовано 23 марта, 2009 · Жалоба Раскидать idle()'ов по ключевым точкам и автоматы получают вторую жизнь. Конкретный пример. Готовая библиотека efsl. Вставка готового порта заняла час. Как по быстрому применить автомат для разделения процессов? Потратить несколько дней на разбиение на куски? Запихнуть процессы в прерывания? Да у меня под отладкой вообще прерывания глючат, все разобраться некогда. Тупик может не с автоматами, а в голове. Завтра выставка :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 23 марта, 2009 Опубликовано 23 марта, 2009 · Жалоба Готовая библиотека efsl. Как по быстрому применить автомат для разделения процессов? Покромсать те части, которые выходят на уровень железа, Yield() вызывать оттуда . Остальное трогать не надо имхо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 24 марта, 2009 Опубликовано 24 марта, 2009 · Жалоба Не нашел, чтобы эта ссылка была упомянута в теме. http://www.state-machine.com/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться