1. Инициализация
При старте МРВ загружает драйверы исходя из наличия каналов с соответствующими дополнениями к подтипу.
Для загруженного драйвера вызывается функция Prepare_ххх с соответствующим аргументом type.
Если задано, что блоковые запросы для данного драйвера не формируются (аргумент type_cnv функции Prepare_ххх отличен от нуля), загружается следующий драйвер.
2. Установка признака принадлежности канала к блоковому запросу
Если задано, что блоковые запросы формируются (аргумент type_cnv функции Prepare_ххх равен нулю), МРВ с помощью функции zCompare_xxx устанавливает каналам признаки принадлежности к таким запросам.
Вначале МРВ выполняет проход по базе с ее начала и находит канал с дополнением, соответствующим загруженному драйверу (канал-образец). Этот канал становится первым каналом блока и в дальнейшем инициирует блоковый запрос.
Далее МРВ производит сравнение всех каналов базы с каналом-образцом с помощью функции zCompare_xxx (эта функция вызывается для каждого анализируемого канала). В блок группируются те каналы, у которых тип, подтип, дополнение к подтипу и два младших байта удаленного адреса совпадают с аналогичными параметрами канала-образца, и zCompare_xxx вернула не 0. Таким образом, разработчик драйвера с помощью задания структуры удаленного адреса и алгоритма функции zCompare_xxx может запрограммировать критерии формирования блоковых запросов.
Если анализируемый канал попадает в блок, ему устанавливается соответствующий признак (этот признак не доступен пользователю), zCompare_xxx возвращает ненулевое значение.
3. Формирование и посылка сообщения
После формирования блоков МРВ находит канал-инициатор блокового запроса и вызывает функцию Set_xxx с необходимыми параметрами:
ia – удаленный адрес канала-инициатора запроса;
q_rec – число передаваемых или принимаемых значений (опрашиваемых регистров);
адрес буфера sbuf. Память под буфер выделяет МРВ.
Функция Set_xxx формирует сообщение-строку в требуемом для используемого протокола формате, и помещает это сообщение в буфер sbuf.
Если значение параметра max_send, переданное функцией Set_xxx, больше 0, то МРВ посылает содержимое буфера sbuf в порт. Длина посылаемого сообщения в байтах равна значению max_send.
Если при передаче был сбой, то такт обмена завершается. При этом увеличивается счетчик ошибок, но для канала ничего не меняется.
4. Прием ответа
5. Вызов функции zReadAny_xxx
Если МРВ определяет, что драйвер поддерживает функцию zReadAny_xxx (эта функция может отсутствовать в драйвере), она будет вызываться до тех пор, пока не вернет 0 (это означает, что все байты от устройства приняты, и далее будет вызвана функция Check_xxx). Если zReadAny_xxx возвращает не 0, то МРВ примет еще count_rec байтов от устройства и опять вызовет zReadAny_xxx. Таким способом можно получить от устройства сообщение, длина которого заранее (т.е., на момент вызова Set_xxx) не известна.
6. Проверка корректности полученного ответа
На этом этапе вызывается функция Check_xxx. Если возвращаемое ей значение равно 0, то принятые данные считаются корректными и вызывается функция Get_xxx для расшифровки принятого сообщения.
При отличии от 0 значения, возвращаемого функцией Check_xxx, анализируется величина параметра max_rec. Если он больше 0, то осуществляется прием дополнительных байтов. Количество этих байтов равно значению параметра max_rec.
Если возвращаемое значение параметра max_rec равно 0, то каналу, для которого осуществлялся вызов драйвера, устанавливается признак аппаратной недостоверности. Если при этом значение параметра max_send больше 0, то осуществляется посылка по последовательному порту строки из буфера rbuf. Количество посылаемых байтов равно величине параметра max_send.
7. Расшифровка полученного ответа
На этом этапе осуществляется вызов функции Get_xxx.
Для каналов OUTPUT характеристика завершения передачи данных описывается в элементе p[0].F.fmt[1] массива структур RSDATA:
0 – нормальное завершение передачи данных;
1 – сбой при передаче. Выставить каналу флаг аппаратной недостоверности;
2 – сбой при передаче. Выставить каналу флаг аппаратной недостоверности и флаг повторной передачи.
Для каналов INPUT характеристика завершения приема данных передается в МРВ с помощью параметра type_cnv функции Get_xxx. Его значения передают в МРВ следующую информацию:
99 – получены некорректные данные. Выставить каналу флаг аппаратной недостоверности;
0 или 1 – получены корректные данные. Использовать алгоритм обработки запросов DATA11 (см. ниже);
2 или 3 – получены корректные данные. Использовать алгоритм обработки запросов BLOCKDATA11 (см. ниже);
8,10 – получены корректные значения для каналов блокового запроса (8 – запись полученных значений в архив запрещена, 10 – разрешена). Использовать алгоритм обработки данных DATA11. Элементы p[i] (где i=2k, k=0.1,2...) содержат полученные значения, элементы p[i+1] – соответствующие этим значениям метки времени:
p[i+1].V.d – число секунд с 1 января 1970 года
p[i+1].F.ind[0] – число миллисекунд
12 – получен блок корректных данных для одного канала для записи в архив. Использовать алгоритм обработки данных DATA11. Элементы p[i] (где i=2k, k=0.1,2...) содержат полученные значения, элементы p[i+1] – соответствующие этим значениям метки времени:
p[i+1].V.d – число секунд с 1 января 1970 года
p[i+1].F.ind[0] – число миллисекунд
9,11 – то же, что 8, 10, но использовать алгоритм обработки данных BLOCKDATA11. 9 – запись полученного значения канала в архив запрещена, 11– разрешена.
13 – то же, что 12, но использовать алгоритм обработки данных BLOCKDATA11.
Если в массиве p содержатся метки времени (type_cnv больше 3) значение q_rec необходимо увеличить в два раза, так как для передачи каждого значения канала и метки времени для архива нужно два элемента массива структур RSDATA (q_rec = 2 * q_rec).
Если получено значение type_cnv, равное 12 или 13, МРВ просматривает все каналы базы, совпадающие с каналом, инициировавшим запрос, по типу, подтипу и дополнению к подтипу, и вызывает драйвер с функцией zCompare_xxx с count = -1. На первом же канале, по которому драйвер ответил положительно, из буфера RSDATA считываются записи в количестве q_rec и записываются в архив с индексом этого канала. Объем настроек, используемых при этом функцией zCompare_xxx (включая номер RS и адрес устройства) определяется драйвером. В канале, инициировавшем запрос, записывается значение q_rec.
Если младший бит первого байта параметра type_cnv равен 1 (0x0100), то следующий вызов драйвера выполняется для того же самого канала (переход к обработке очередного канала не производится). Это свойство используется при разработке многопроходных драйверов.
8. Перейти к пункту 2