Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
8-CHto-takoe-mnogozadachnost.docx
Скачиваний:
4
Добавлен:
18.09.2019
Размер:
5.81 Mб
Скачать

1) Опросить управление (дана команда «начать»?). 2) Если «да», то пустить отсчет периода времени t и 3) «свалиться» в цикл регистрации отсчетов.

Как закончить регистрацию?

Если в п.4) цикла получена команда «прекратить», просто выйти из цикла обработки отсчетов.

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

Что может находиться в фоновой программе? Это могут быть любые действия, не связанные с реальным временем, либо !! необходимость точно так же управлять чем-нибудь еще (регулировать другую величину на объекте).

Фоновую программу можно выполнять, пока ждем истечения t. Как только интервал t истек, фоновую программу следует на время прекратитью

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

Тогда можно в обработчике прерывания от таймера делать действия 1)…4) из (1)

1) Измерить 2) Обработать 3) Записать (в массив в памяти) или передать (напр., через UART) 4) Воспринять управляющее воздействие, команду (изменить период t, прекратить регистрацию,…) 5) Выйти из прерывания.

Начать регистрацию можно так (предполагается, что обработчик написан и загружен в память, и что вектор прерывания установлен:

1) Настроить таймер на отсчет t и запустить его, 2) Разрешить прерывание от таймера

Если в обработчике (шаг 4) получена команда «прекратить», можно просто остановить таймер (оставив разрешенным прерывание от него), либо запретить прохождение запроса от таймера, либо и то и другое.

Если получена команда «изменить» t, то прямо в обработчике прерывания можно изменить содержимое регистра уставки таймера.

и – измерение, о – обработка, з/п – запись/передача, у – управление, фон – фоновая программа.

Минимальный период между измерениями ограничен максимальным временем работы обработчика, выполняющего «измерение+обработку».

Обратим внимание, что в обработчике (в строго заданное время) необходимо выполнить только «Измерить», а остальные действия можно закончить «не позже, чем до следующего измерения», как вариант, не в обработчике, а во внешней программе.

В связи с этим, можем отметить, что Действия Реального Времени можно подразделить на два типа:

1) Вроде взятия отсчета: точно в данный момент, как опоздание, так и опережение плохо 2) Вроде реакции на событие (срабатывание датчика) – не позже, чем. Позже – очень плохо, раньше – немного лучше, а иногда, чем раньше, тем лучше (торможение при обнаружении препятствия).

Между прерываниями может исполняться фоновая программа. Ее прерывает обработчик, выполняющий измерение. При этом непонятно, как передавать управление блокам «о-з/п-у» а затем возвращать управление «фону».

А как же можно организовать выполнение действий «не позже» вне обработчика прерывания? Это хочется сделать так, чтобы эти действия начали выполняться лишь тогда, когда очередной результат измерения сформирован (в обработчике). В фоновой программе может исполняться что-то менее важное, возможно, к фону не предъявляется никаких требований реального времени.

Как же в этом случае передавать управление на модули «обработка‑запись‑управление»? И в чем смысл переноса «о-з/п-у» из обработчика?

Вот какую структуру взаимодействия хочется получить.

Что делать, если требуется регистрировать несколько величин, для каждой из которых задан свой ti ?

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

Здесь тоже возникают вопросы. Что, если прерывание от второго таймера придет в то время, когда выполняется обработчик первого таймера или наоборот? В одном из этих случаев непременно обработка запроса, пришедшего позже, будет задержана (значит, будет задержан момент одного из измерений, а этого хочется избежать). Чем короче высокоприоритетный обработчик, тем меньше будет ошибка времени для низкоприоритетного измерения. В этом смысл максимального сокращения времени выполнения всех обработчиков прерываний – в них должно быть только то, что ОЧЕНЬ критично ко времени выполнения.

И снова повторим вопрос: а как передавать управление на части «о-з/п-у», (которых теперь будет несколько), и из этих частей на возобновление фоновой программы? На рис. эти «проблемные» передачи управления отмечены штриховыми стрелками

Таймеров в микросистеме не так уж много: в ADuC702x – четыре, в M68HC12 – восемь. Но:

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

Отметим еще одну особенность всех рассмотренных фрагментов: их структура укладывается в схему: «что-нибудь сделать» ‑‑‑ «ожидать события», или наоборот: «ожидать события» ‑‑‑ «что-нибудь сделать»

Например:

«Ожидать истечения периода времени ‑ измерить – обработать – записать (или передать)».

Если измерение выполняется в обработчике прерывания, а все остальные действия вне обработчика, то:

1) (Обработчик вызывается периодически по таймерному преыванию, т.е. когда истечет период времени – это ожидание времени) в обработчике: (W) 2) Измерение 3) Запись в переменную

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

Во внешнем модуле выполняются остальные действия:

1) Ожидание нового значения в переменной 2) Обработка (например, усреднение нескольких результатов, или/и преобразование из числа в строку символов в нужной системе счисления) 3) Запись в массив результатов или передача через последовательный интерфейс, или .... 4) Отработка управляющего воздействия

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

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

Для каждой (i-й) измеряемой величины отдельный модуль для обработки, который должен (в цикле) выполнять следующие действия:

1) Ожидание нового значения в переменной (W) 2) Обработка (преобразование) 3) Запись в общий для всех величин буфер передачи. (A)

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

Отдельный и общий для всех измеряемых величин модуль будет осуществлять передачу через последовательный интерфейс. Он должен (опять в цикле) выполнять следующие действия:

1) Ожидание новых данных в общем буфере передачи (W) 2) Ожидание освобождения передатчика (W) 3) Передача очередного символа

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

При такой организации взаимодействия модулей возникает ряд проблем:

  1. Смещение (запаздывание) моментов измерения относительно идеальных (определяемых теоремой отсчетов).

  2. Возможность пропуска результата во i-му каналу, так как процессор может быть занят другими модулями.

  3. Как передавать управление на модули обработки отсчетов, когда появляется новый результат?

  4. Как вызывать модуль передачи, когда буфер передачи не пуст?

  5. Как отдавать управление фоновым процессам, когда нечего делать, и забирать от них управление, когда надо «измерять – обрабатывать – передавать».

  6. Как запускать и останавливать процесс измерения по конкретному каналу?

Замечание: функциональности, на которые можно разбить программу реального времени, имеют различные требования реального времени от «никаких» до очень жестких. Можно пытаться упорядочить функциональности по степени срочности:

  1. функциональности, к которым не предъявляется требований реального времени (могут ждать долго, в пределе, сколько угодно – их помещают на самый низкоприоритетный уровень, фоновые процессы);

  2. … к которым предъявляются нежесткие(???) требования реального времени (средний уровень приоритета);

  3. наиболее приоритетные функциональности – жесткое реальное время (высокий уровень приоритета)

  4. действия, которые не терпят никакого отлагательства – их следует помещать в обработчики прерываний.

Разделение на группы – вопрос системного проектирования. Отчасти может быть выполнено с использованием некоторых формальных методов, отчасти является неформальным (эвристическим) решением.

Остается пока открытым вопрос, как это реализовать в программе.

Из рассмотрения этого примера можем вывести такое заключение:

В модулях, на которые мы разбили функциональности, необходимые для выполнения «измерений – обработки – передачи» отсчетов нескольких меняющихся с разной скоростью величин, есть однотипные действия: ‑ ожидание (истечения интервала времени, появления нового значения переменной и др.) ‑ организация совместного доступа к общему массиву, к общему интерфейсу и т.п. Второе – это на самом деле тоже ожидание: пока один модуль записывает в буфер данные, соответствующие одному измерению, остальные должны ждать.

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

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

Иногда количество повторений известно заранее (зафиксировать заданное количество отсчетов). В других случаях выход из цикла должен происходить в результате выполнения некоторого условия: внутреннего для цикла (достигли символа-ограничителя в буфере, типа «конец строки»). В других случаях условие для выхода из цикла является внешним по отношению к телу цикла. Организовать анализ выполнения такого условия можно, выполняя внутри цикла проверку значения какой-либо внешней переменной, модификация которой производится НЕ в теле цикла, а другим фрагментом кода. Как же этот другой фрагмент кода может получить управление? В частности, это может быть обработчик какого-либо аппаратного запроса прерывания, не имеющий прямого отношения к данному циклическому фрагменту.

Итак, мы выделили среди разных функциональностей, которые необходимо реализовать при программировании задачи измерения нескольких меняющихся величин, группу однотипных – организацию доступа к общим (разделяемым) ресурсам для нескольких программных модулей.

Обеспечение разделяемого доступа к ресурсам обычно является функцией операционной системы. Операционная система должна организовать разделение ресурсов между программными модулями, и, в первую очередь, распределение процессорного времени – запуск на выполнение одного или другого программного модуля. В терминологии ОС это называется «управление задачами».

Многозадачность

Многозадачность - это процесс переключения процессора между несколькими задачами. Многозадачная система похожа на систему, основанную на «программе, управляемой запросами прерываний», но с несколькими фонами. Многозадачность увеличивает использование процессора, а также обеспечивает возможность модульной конструкции приложения. Один из самых важных аспектов многозадачности состоит в том, что она позволяет программисту управлять сложностью, присущей приложениям реального времени. К тому же, при использовании многозадачности прикладные программы проще в написании и поддержке .

В последующем изложении будем рассматривать в качестве примера реализацию операционной системы реального времени µC/OS (произносится «микроСиОс»). Эта ОСРВ была написана американским специалистом по встраиваемым системам Jean J. Labrosse и развивается созданной им фирмой Micrium (www.micrium.com) с 1992 г по настоящее время. За это время появилось три поколения: µC/OS, µC/OS-II и µC/OS-III.

Jean написал и издал двумя изданиями замечательную книгу «MicroC/OS-II The Real Time Kernel». Ссылки в данном документе будут делаться на второе издание книги Second Edition, 2002 by CMP Books.

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

Последнюю информацию о uC/OS-II можно получить на сайте автора:

http://www.micrium.com

(Лекция 2)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]