Перейти на главную Журналы

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 [139] 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175

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

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

Програ.м.мы следует строить по принципам, применяемым в операционных систе.мах, - на основе .модульной и многоуровневой структуры, поскольку это существенно упрощает разработку сложных систем. Должна быть определена спецификация отдельных модулей, начиная с интерфейсов между аппаратными и программными компонентами системы. К основной информации об интерфейсах относится и структура сообщений, которы,\ш будут обмениваться програ.м.мныс модули. Это не означает, что из.менения в определении интерфейсов не могут вводиться после начала разработки програ.ммы. Но чем позже они вносятся, тем больше затрат потребует изменение кода, тестирование и т. д. С другой стороны, следует быть готовы.м к тому, что некоторые изменения спецификаций все равно будут происходить в процессе разработки программы, поскольку продвижение в работе позволяет лучше увидеть проблему.

Следует принимать во внимание эффективность реализации функций операционной системы. Нельзя считать, что способ, которым в операционной системе реализованы тс или иные услуги, дан раз и навсегда, - для проверки того, насколько хороню удовлетворяются временные ограничения, желательно провести оценку, например с помощью эталонных тестовых программ {benchmark). Если результаты тестов неприемлемы, то одним из решений .может быть разработка программ, замещающих соответствующие стандартные .модули операционной системы. Такое решение требует очень осторожного и дифференцированного подхода, в частности замещение может выполняться не всегда, а только для определенных процессов.

10.6.3. Структура программы реального времени

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

Например, задачи для управления движением манипулятора робота (раздел 2.2.,3) можно организовать следующим образом:

-- считать с диска описание траекторий;

- пягсчитать следующее положение манипулятора (опорное значение);



- считать с по.мощью датчиков текущее положение;

- вычислить необходимый сигнал управления;

- выполнить управляющее действие;

- проверить, что опорное значение и текуп1ее положение совпадают в пределах заданной точности;

- получить данные от оператора;

~ остановить робота в случае нештатной ситуации (напри.мер сигнал прерывания от аварийной кнопки).

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

Принципиальной особенностью програ.мм реального вре.мени является постоянная готовность и отсутствие условий нормального, а не аварийного завершения. Если про-фамма не исполняется и не обрабатывает данные, она остается в режиме ожидания прерывания/события или истечения некоторого интервала времени. Программы реального времени - это последовательный код, исполняю1цийся в бесконечном цикле. В каком-то месте програм.мы есть оператор, приостанавливающий исполнение до наступления внешнего события или истечения интервала времени. Обычно программа структурируется таким образо.м, что оператор end никогда не достигается

while true do (* бесконечный цикл *) begin (* процедура обработки *)

wait event at #2,28 (* внешнее прерывание *)

(* код обработки *)

end; (* процедура обработки *) end. (* выход из программы; никогда не достигается *)

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

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

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

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



встствующими модулями после компиляции. При этом в памяти хранится несколько копий Одной подпрограммы.

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

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

10.6.4. Обработка прерываний и исключений

Системы рса/льного времени соединены с внешней средой (физический процесс) через аппаратные интерфейсы. Доступ к интерфейсам и внешним данным ocyniecTB-лястся либо но опросу, либо по прерыванию.

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

Получение данных но прерыванию (interrupt) происходит иначе. Интерфейсное устройство, получившее новые данные, привлекает внимание ЦП, посылая ему сит-нал прерывания через системную шину. По отношению к текущему процессу прерывания являются асинхронны.ми событиями, требующими немедленной реакции. Получив сигнал прерывания, процессор приостанавливает исполнение текушето процесса, сохраняет в стеке его контекст, считывает из таблицы адрес программы обработки прерывания и передаст ей управление. Эта программа называется обработчиком прерывания (intermpthandler). Другой вариант обработки прерываний заключается в том, что планировщик выбирает из очереди ожидания этого события или прерывания следующий процесс и переводит его в очередь готовых процессов.

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




0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 [139] 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175