|
|
  |
Подскажите пожалуйста, про многозадачность. |
|
|
|
Oct 18 2006, 07:29
|
Местный
  
Группа: Свой
Сообщений: 252
Регистрация: 14-09-06
Пользователь №: 20 377

|
Есть несколько задач (программ) которые должны выполнятся с минимальным временем, можно организовать как линейный список функций, которые последовательно вызываются из главной функции main() при условии что время выполнения каждой функции ограничено т.е. внутри функции нет кода который задерживает выполнения (ожидает чего либо). Например одна функция обрабатывает принятый массив с USARTа. другая расшифровывает принятую команду и выполняет ее, подготавливает ответ к отправке (квитирование). Еще пару функций, которые что-то делают (обслуживают клавиатуру, исполнительные устройства). Получается все запутанно, если делать все функции в виде конечных автоматов с минимальным временем работы каждой. Хорошо было бы, если каждая функция выполнялась в виде задачи, ожидает, данные с параллельного потока пускай ждет, получила что хотела, выполняет. Есть задержка в функции скажем, на 20 секунд, пускай ждет, в это время выполняются другие функции. С операционными системами как-то все сложно, может планировщик задач да и все. Какие есть решение не сложные? Механизм взаимодействия функций друг с другом.
|
|
|
|
|
Oct 18 2006, 07:35
|

Частый гость
 
Группа: Свой
Сообщений: 80
Регистрация: 14-04-06
Из: Russia, Orel
Пользователь №: 16 115

|
Ну для этого и придуманы прерывания, например для UARTа.
-->Получается все запутанно, если делать все функции в виде конечных автоматов с минимальным временем работы каждой. Хорошо было бы, если каждая функция выполнялась в виде задачи, ожидает, данные с параллельного потока пускай ждет, получила что хотела, выполняет. Есть задержка в функции скажем, на 20 секунд, пускай ждет, в это время выполняются другие функции.
Сильно смахивает на параллельность операций. В контроллере врятли получиться.
|
|
|
|
|
Oct 18 2006, 07:42
|
Местный
  
Группа: Свой
Сообщений: 252
Регистрация: 14-09-06
Пользователь №: 20 377

|
Цитата(Сергей Б @ Oct 18 2006, 10:35)  Ну для этого и придуманы прерывания, например для UARTа.
-->Получается все запутанно, если делать все функции в виде конечных автоматов с минимальным временем работы каждой. Хорошо было бы, если каждая функция выполнялась в виде задачи, ожидает, данные с параллельного потока пускай ждет, получила что хотела, выполняет. Есть задержка в функции скажем, на 20 секунд, пускай ждет, в это время выполняются другие функции.
Сильно смахивает на параллельность операций. В контроллере врятли получиться. В прерываниях долго сидеть нельзя, там можно формировать массив из принятых данных и отслеживать конец посылки. А внешне проверять адрес контрольную сумму.
|
|
|
|
|
Oct 18 2006, 08:13
|
Участник

Группа: Участник
Сообщений: 58
Регистрация: 13-10-06
Из: Финляндия
Пользователь №: 21 273

|
Цитата(_Алекс @ Oct 18 2006, 10:29)  Получается все запутанно, если делать все функции в виде конечных автоматов с минимальным временем работы каждой. А других вариантов-то и нет. Единственное, если есть функции с наивысшим приоритетом (например, приём/передача данных по интерфейсу на максимальной скорости в большом объёме), их придётся целиком запихивать в прерывания. Можно ещё в некоторых режимах блокировать ненужные функции. Главное - не запутаться в системе флагов.
|
|
|
|
|
Oct 18 2006, 08:27
|

Частый гость
 
Группа: Свой
Сообщений: 80
Регистрация: 14-04-06
Из: Russia, Orel
Пользователь №: 16 115

|
Цитата(GinRider @ Oct 18 2006, 12:13)  Цитата(_Алекс @ Oct 18 2006, 10:29)  Получается все запутанно, если делать все функции в виде конечных автоматов с минимальным временем работы каждой.
А других вариантов-то и нет. Единственное, если есть функции с наивысшим приоритетом (например, приём/передача данных по интерфейсу на максимальной скорости в большом объёме), их придётся целиком запихивать в прерывания. Можно ещё в некоторых режимах блокировать ненужные функции. Главное - не запутаться в системе флагов. Да флагов рожлается огромное количество на сыром коде, но после оптимизации половина выкидывается. Главное, при расположении большого кода в прерывании не забывать об их приоритетах.
|
|
|
|
|
Oct 18 2006, 09:28
|
Участник

Группа: Участник
Сообщений: 58
Регистрация: 13-10-06
Из: Финляндия
Пользователь №: 21 273

|
Цитата(IgorKossak @ Oct 18 2006, 11:52)  Наклёвывается необходимость применения RTOS. По крайней мере никакой мороки с машинами состояний, флагами, и прочим геморроем, не относящимся напрямую к постановке задачи. Ссылок на популярные RTOS, применительно к микроконтроллерам, даже на этом форуме - море. Если используется какой-нибудь высокоуровневый протокол, то да. А если там требуется прочитать клавиатуру да выкинуть что-либо на LCD-дисплей, то получится только напрасная трата ресурсов.
|
|
|
|
|
Oct 18 2006, 09:47
|
Участник

Группа: Новичок
Сообщений: 44
Регистрация: 2-05-06
Пользователь №: 16 710

|
Цитата(GinRider @ Oct 18 2006, 13:28)  Если используется какой-нибудь высокоуровневый протокол, то да. А если там требуется прочитать клавиатуру да выкинуть что-либо на LCD-дисплей, то получится только напрасная трата ресурсов. Придерживаюсь строго полярной точки зрения. RTOS начинает быть полезна уже с клавиатурой и дисплеем, и с любыми другими асинхронными к "протоколу" устройствами. Напротив, если в системе есть только "высокоуровневый протокол" и ничего асинхронного, то RTOS неуместна - нет для нее работы.
|
|
|
|
|
Oct 18 2006, 09:50
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(GinRider @ Oct 18 2006, 12:28)  Цитата(IgorKossak @ Oct 18 2006, 11:52)  Наклёвывается необходимость применения RTOS. По крайней мере никакой мороки с машинами состояний, флагами, и прочим геморроем, не относящимся напрямую к постановке задачи. Ссылок на популярные RTOS, применительно к микроконтроллерам, даже на этом форуме - море.
Если используется какой-нибудь высокоуровневый протокол, то да. А если там требуется прочитать клавиатуру да выкинуть что-либо на LCD-дисплей, то получится только напрасная трата ресурсов. Насколько я понимаю это в любом случае RTOS. Просто в одном случае реализованная своими силами и сильно упрощённая, ну а в другом написанная сторонними производителями, и, возможно сильно усложнённая.  Если свой упрощённый вариант, то я пишу так как не рекомендует писать уважаемый 'IgorKossak'. То есть ввожу флаги состояний, задачи замыкаю на себя, данные напрямую не передаю, общаюсь только ч/з флаги и ОЗУ. (то есть вых. данные одной проги - входные другой). Блоки пишу таким образом, что их перестановка местами м/у собой не влияет на работоспособность программы.
|
|
|
|
|
Oct 18 2006, 11:29
|
Участник

Группа: Участник
Сообщений: 58
Регистрация: 13-10-06
Из: Финляндия
Пользователь №: 21 273

|
Цитата(SasaVitebsk @ Oct 18 2006, 12:50)  Если свой упрощённый вариант, то я пишу так как не рекомендует писать уважаемый 'IgorKossak'. То есть ввожу флаги состояний, задачи замыкаю на себя, данные напрямую не передаю, общаюсь только ч/з флаги и ОЗУ. (то есть вых. данные одной проги - входные другой). Блоки пишу таким образом, что их перестановка местами м/у собой не влияет на работоспособность программы. Программа должна выглядеть так: do{ ReadKeys(); UpdateDisplay(); }while(true); Всё остальное - дело флагов, указателей и счётчиков. Главное - в ассемблерном листинге это выглядит точно так же.
|
|
|
|
|
Oct 18 2006, 11:32
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(_Алекс @ Oct 18 2006, 10:29)  Есть задержка в функции скажем, на 20 секунд, пускай ждет, в это время выполняются другие функции. С операционными системами как-то все сложно, может планировщик задач да и все. Какие есть решение не сложные? Механизм взаимодействия функций друг с другом. В одном из своих проектов я решил подобный вопрос с помощью нехитрого планировщика , который занимался тем, что запускал функции "задачи" по расписанию. Ввел три типа задач: TASK_PERIODIC - запускать постоянно через определенный интервал TASK_SINGLECALL - запустить однократно через определенный интервал TASK_KERNEL - запускать в отдельном _idle_ цикле постоянно (к этому типу относятся всевозможные Dispatcher'ы) Задачи помещаются в отдельные очереди и при вызове могут добавлять/удалять в/из очереди любые другие задачи. Если потребуется выполнение довольно длительной задержки (у меня таки потребовалось) внутри "задачи", то задача обязана вызывать _idle_ цикл, чтобы отрабатывали все "системные" задачи типа TASK_KERNEL (обслуживание времени, I/O и т.п.). От флагов такой подход полностью не избавляет, но все-таки минимизирует чуть-чуть, и экономит ПП. Для сравнения этот планировщик отнимает всего ~500 байт ПП и может занимать меньше, ну а кол-во занимаемого RAM'а регулируется взависимости от потребностей проекта. (по 16 задач каждого типа займет 10*16*3 байт ОЗУ).
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|