ЖУРНАЛ СТА 3/2014
полной стоимости процессорного мо- дуля контроллера. Кроме того, в оригинальной много- задачной системе исполнения CoDeSys 2.3 имеется одна особенность, о кото- рой приходится помнить разработчи- кам приложений для контроллеров, чьи производители декларируют под- держку многозадачности: если в про- екте имеется две задачи и более, про- граммные единицы которых ссылают- ся на один и тот же адрес в области входных данных, то программные еди- ницы, выполняющиеся в контексте ме- нее приоритетных задач, вытесняемых более приоритетной задачей, могут функционировать непредсказуемо. Об этом стоит рассказать чуть подробнее, поскольку данная особенность не очень очевидна. В CoDeSys 2.3 сегментом (или об- ластью) входных данных является об- ласть памяти, находящаяся в распоря- жении системы исполнения контролле- ра, в которой компилятор размещает значения всех переменных, объявлен- ных со спецификатором доступа AT %I, то есть отображённых на входные кана- лы периферийных модулей и коммуни- кационных объектов, получаемых конт- роллером по сети. Пусть в проекте CoDeSys 2.3 имеется программа CALC_PRG, выполняю- щаяся в контексте циклической задачи CalcTask с периодом 10 мс и вычисляю- щая значение на канале, доступном в сегменте входных данных приложения по адресу %IB2535. Программа LOG_PRG выполняется под управлением второй циклической задачи LogTask с периодом 5 мс и в каж- дом цикле записывает текущее значе- ние на том же входном канале в кольце- вой буфер размером 16 слов. Поскольку программа LOG_PRG вы- полняется с большей частотой, чем CALC_PRG, и требует меньшего време- ни выполнения за счёт отсутствия условных переходов и инструкций с плавающей точкой, задаче LogTask установлен более высокий приоритет, то есть LogTask может вытеснять CalcTask. Исходные тексты программ и конфигурация задач проекта CoDeSys 2.3 показаны на рис. 8. Пусть на очередном цикле CalcTask программа CALC_PRG прочитала значение wChannelData и, убедившись, что оно отлично от нуля, перешла к на- чалу вычисления выражения, не допус- кающего нулевого значения в знамена- теле. Предположим, что в этот момент возникло некоторое событие, например прерывание системного таймера, по- влекшее за собой вызов планировщика операционной системы контроллера, который выяснил, что пришло время «отдать» процессор задаче LogTask. Не- посредственно перед вызовом LogTask происходит обновление сегмента вход- ных данных из окружения, допустим, из канала модуля аналогового ввода или Holding-регистра MODBUS, причём там вновь оказалось нулевое значение, в результате чего слово по адресу %IB2535 вновь стало равным 0. Далее происходит вызов программы LOG_PRG, которая помещает нулевое значение в кольцевой буфер, завершает свой очередной цикл, после чего управ- ление передаётся ранее вытесненной задаче CalcTask. Но задача CalcTask бы- ла прервана внутри CALC_PRG непо- средственно перед началом вычисления выражения, не допускающего нулевого значения в знаменателе. Теперь при вы- числении выражения программа CALC_PRG загружает нулевое значе- ние из сегмента входных данных и про- бует разделить 23,5 на 0,0, что явно не предусматривалось изначально. В принципе, для переменных, ото- бражаемых на адреса в сегменте вход- 80 СТА 3/2014 АППА РАТ НЫЕ С Р Е ДС Т В А / П РОМЫШЛ Е ННЫЕ КОН Т РОЛЛ Е РЫ www.cta.ru ОФИЦИАЛЬНЫЙ ДИСТРИБЬЮТОР ПРОДУКЦИИ MEN
Made with FlippingBook
RkJQdWJsaXNoZXIy MTQ4NjUy