DIM 2037 TrimDef ExecuteProcessSafe WEB_MetaContentType
DEMO_TESTBENCH
Главными достижениями данного выпуска являются:
обновление DIM и его библиотек;
обновление стандартной библиотеки DaqPascal.
DIM обновлен до актуальной версии 20.37.
В этой версии исправлены некоторые ошибки (проявляющиеся при очень
большой нагрузке). В версии для Linux добавлена компиляция
бинарных файлов (benchmarkClient/Server), ранее не включенных
в сборку. Также добавлен демо клиент/сервер на языке C,
работающий с очередью сообщений.
Обновлена стандартная библиотека DaqPascal.
В нее добавлены функции:
TrimDef(s,def) - обрезание строки (s) со значением по умолчанию (def),
ExecuteProcessSafe(cmd,arg,opt,timeout) - выполнение команды (вызов процесса) с ожиданием результата,
WEB_MetaContentType(Data) - задание мета-тега типа и кодировки HTML.
Данные функции были созданы в процессе перевода Crw32 под Linux и добавлены для того, чтобы не накапливались несовместимости
кода старой и новой версии пакета.
Также сделаны внутренние изменения кода для синхронизации версий с новым пакетом.
Эти изменения носят (в основном) косметический характер (например замена LineEnding на EOL,
добавление AdaptFileName), и призваны сохранить единство кодовой базы.
В демо конфигурации DEMO_TESTBENCH
добавлен @Test 20 для проверки работы операций и функций со специальными
значениями NAN, INF. Причиной добавления тестов является обнаруженная Н.Гуриным
некорректность работы некоторых операций с NAN.
Будем постепенно исправлять, с помощью этого теста.
По факту, в Crw32 ошибок операций с NAN много.
В новой версии пакета их не обнаружено.
Добавлены новые команды и опции в Главной Консоли.
@voice -l - список звуков в виде таблицы
@voice -f - список звуков с путями файлов
@env -l - список переменных окружения
@env -l CRW - список переменных окружения, содержащих шаблон
@log -m 1 - режим ведения журнала (0/1/2=silent/echo/debug.out)
@log message - занести в журнал сообщение в соответствии с режимом
Для использования функций в программу рекомендуется включить
библиотеку типов _typ_StdLibrary,
т.к. в ней определен тип TVector
(библиотека уже входит в шаблон стандартной программы):
program demo;
...
type
{------------------------------}{ Declare uses program types: }
{$I _typ_StdLibrary} { Include all Standard types, }
{------------------------------}{ And add User defined types: }
...
var
iv,rv:TVector;
...
procedure ClearApplication;
begin
iv:=ivec_init(0);
rv:=rvec_init(0);
...
end;
...
procedure FreeApplication;
begin
ivec_free(iv);
rvec_free(rv);
...
end;
...
procedure InitApplication;
begin
iv:=ivec_init(100); // Выделение памяти для 100 элементов
rv:=rvec_init(100);
...
end;
...
procedure PollApplication;
var i:Integer; { Index } ix:Integer; rx:Real; { Integer, Real value }
begin
...
ix:=ivec_get(iv,i); // Чтение - Аналог ix:=iv[i];
rx:=rvec_get(rv,i); // Чтение - Аналог rx:=rv[i];
ivec_set(iv,i,ix); // Запись - Аналог iv[i]:=ix;
rvec_set(rv,i,rx); // Запись - Аналог rv[i]:=rx;
// Циклы чтения-записи по элементам вектора:
for i:=0 to ivec_length(iv)-1 do ix:=ivec_get(iv,i); // Чтение
for i:=0 to ivec_length(iv)-1 do ivec_set(iv,i,ix); // Запись
ivec_setlength(iv,200); // Изменение размера массива
...
end;
Векторные функции предназначены для работы с динамическими массивами,
т.е. массивами большого объема, а также массивами переменной длины,
которая может меняться в процессе работы программы.
Использование динамических массивов предпочтительнее, чем выделение
большого сегмента данных, т.к. память расходуется экономнее.
Кроме того, векторы лучше защищены от ошибок доступа (типа неверного индекса).
Поскольку векторы хранятся в строках, в прикладной программе может
потребоваться скорректировать максимальную длину строки
(Compiler.slenmax).
В демо конфигурации DEMO_TESTBENCH
добавлен @Test 19 для проверки работы новых функций.
По измерениям время вызова ivec_get/set составило около 170 ns,
т.е. около 6 миллионов операций чтения/записи в секунду.
Этого вполне достаточно для прикладных задач.
Добавлены функции для работы с командами операционной системы.
Это функции
RunSysCommand,
RunSysCommandAsText.
Функции вызывают заданную команду операционной системы (консольную
программу или сценарий оболочки), считывают её вывод (stdout)
и код возврата. Выполнение команды ограничено заданным временем
(Timeout).
С новой функцией программы операционной системы фактически становятся
библиотечными функциями, доступными в любой прикладной программе.
Например, версию Windows можно прочитать как:
var code:Integer; ver:String;
ver:=RunSysCommandAsText('cmd /c ver','','',code,2000);
if (code=0) then writeln('Version = ',ver);
Новые возможности весьма полезны, однако ими не стоит злоупотеблять,
т.к. вызов команд операционной системы - относительно дорогая операция.
Не следует делать это без необходимости.
Данный выпуск посвящен в основном средствам поддержки многоплатформенных программ.
В интерпретатор DaqScript добавлены константы и функции:
IsUnix - работаем под Unix?
IsLinux - работаем под Linux?
IsWindows - работаем под Windows?
lng_unknown - идентификатор неопределенного языка интерфейса
lng_english - идентификатор языка интерфейса English
lng_russian - идентификатор языка интерфейса Russian
cp_utf7 - идентификатор кодировки UTF-7 (65000)
cp_utf8 - идентификатор кодировки UTF-8 (65001)
cp_none - идентификатор неопределенной кодировки (65535)
guilanguage() - функция возвращает идентификатор языка интерфейса CRW-DAQ
Эти константы и функции можно использовать в сценариях DaqScript,
выполняемых в В Главной Консоли CRW-DAQ:
@if IsUnix then @echo Unix is running
@if IsWindows then @echo Windows is running
rus=eq(guilanguage(),lng_russian)
eng=eq(guilanguage(),lng_english)
if rus then @echo Привет
if eng then @echo Hello
Это позволяет выполнять разные действия в зависимости от платформы.
В консоли &CronSrv добавлен оператор @If,
позволяющий использовать в заданиях &CronSrv
условные выражения по типу:
@if IsUnix then @Run xterm
@if IsWindows then @Run cmd
В сочетании с командой @Cron это позволяет использовать
условные выражения в стартовых/стоповых сценариях прикладных программ.
Следует уточнить такой момент: оператор @if реализован в
Главной Консоли, а также в консоли &CronSrv, но в самом
интерпретаторе DaqScript его (пока) нет. Поэтому надо следить,
в каком контексте (в какой консоли) выполняется выражение:
Eval('@if IsUnix then @echo Unix') - ошибка при выполнении в программе DaqPascal
@If IsUnix then @echo Unix - ошибка при выполнении в консоли DAQ устройства
@Cron @If IsUnix then @echo Unix - корректно выполняется в консоли CronSrv
@System @Async @If IsUnix then @echo Unix - корректно выполняется в Главной Консоли
Cron('@if IsUnix then @echo Unix') - корректно выполняется в консоли CronSrv
Напоминаем, что вызов @Cron cmd посылает команду cmd в
консоль &CronSrv, а вызов @System @Async cmd
посылает команду cmd в Главную Консоль, поэтому в этом случае
выражение @if допустимо. Однако надо напомнить, что при такой
посылке в другую консоль выполняться оно будет асинхронно.
IsUnix - работаем под Unix?
IsLinux - работаем под Linux?
IsWindows - работаем под Windows?
SizeOfPointer - размер указателя в байтах, 4/8 для 32/64 битного ЦПУ
DefaultSystemCodePage - системная кодировка: CP_1251(Windows) или CP_UTF8 (Unix)
cp_utf8 - идентификатор кодировки UTF-8 (65001)
cp_none - идентификатор неопределенной кодировки (65535)
cp_1251 - идентификатор русской кодировки Windows (1251)
cp_866 - идентификатор русской кодировки DOS (866)
Также добавлены функции адаптации имен файлов под правила ОС:
AdaptFileName,
AdaptExeFileName,
AdaptFileNameMode.
Эти функции предназначены для поддержки многоплатформенных программ.
Они адаптируют (преобразуют) имена файлов (например, прочитанные из
файла конфигурации) под правила данной операционной системы.
Предполагается, что программы DaqPascal могут быть запущены
на разных платформах (Unix/Linux,Windows).
Предполагается, что вызов AdaptFileName или AdaptExeFileName
является первым шагом в цепочке обработки имени файла (например, после
чтения из файла конфигурации):
f:=ReadIni('ProgName'); // Допустим, ProgName = ../Utility/Test.cmd
f:=AdaptExeFileName(f); // Unix: f = ../utility/test.cmd
f:=AdaptExeFileName(f); // Windows: f = ..\Utility\Test.cmd
f:=DaqFileRef(f,''); // Добавляем путь файла
Функции AdaptFileName или AdaptExeFileName выполняют
первичную адаптацию имени файла под правила текущей операционной
системы:
Удаляются лишние пробелы,
Исправляются разделители каталогов (\ или /),
В Unix системах имя файла преобразуется в нижний регистр,
Вызов AdaptExeFileName также исправляет расширение файла,
добавляя/убирая .exe у исполняемых файлов, либо заменяя
.cmd на .sh у сценариев.
Подробнее см. описание функций.
Адаптация имен файлов нужна для того, чтобы корректироввать имена файлов
в гибридной среде, где имена файлов могут быть записаны в конфигурации
или получены по сети от компьютера, работающего на другой платформе
(Windows,Unix/Linux). После адаптации имя файла, по крайней мере,
будет соответствовать формату, принятому для текущей операционной
системы.
Если раньше типичным (идеоматическим) вызовом, например,
для чтения имени EXE файла из конфигурации был:
Обновлен редактор
Origami
с мелкими поправками от А.Жирунова.
В сборку UnixUtils добавлен логгер glogg (альтернатива wintail).
Изменился алгоритм работы MarkdownViewer.
Раньше он для файла file.md просто создавал файл file.md.html.
Теперь он проверяет существование файлов file.htm или file.html.
Если один из этих файлов найден, результат записывается в этот файл.
Это позволяет сохранять привычные имена файлов документации,
но при этом генерировать их из файлов *.md.
В будущем рекомендуется всю прикладную документацию делать в *.md,
а файлы *.htm генерировать из *.md с помощью MarkdownViewer.
Это намного упростит создание справочных файлов и снизит трудозатраты.
Небольшие изменения в документации DIM.
В разделе "Соглашения о именовании" добавлена информация об ограничении
длины имен сервисов, компьютеров и задач.
Очень серьезные изменения в документации HTML.
В новой версии пакета для всех текстовых файлов будет использоваться
универсальная кодировка utf-8, а имена файлов будут использоваться
в нижнем регистре (соглашение для Linux, в связи с тем, что
имена файлов регистро-чувствительны).
В переходный период (от Crw32 к CrwDaq) у нас большая часть документации
будет общей для обеих версий.
Крайне хотелось бы избежать наличия двух версий файлов документации в разных кодировках.
По этой причине было решено перевести ВСЮ документацию CRW32 (только HTML) в кодировку
utf-8, а имена HTML файлов - в нижний регистр.
Для этого был создан сценарий,
который ищет все файлы *.htm*, переводит их имена в нижний регистр, переводит кодировку
в utf-8, устанавливает charset=utf-8, переводит все ссылки (href,src)
в нижний регистр.
Обработке подверглось более 1000 файлов - только HTML, имеющие
кодировки ANSI.
Некоторые файлы (содержащие href=data:image) были пропущены, т.к. base64
чувствителен к регистру и при смене регистра ссылок изображение ломается.
Отчет см тут.
Вроде бы все должно сработать верно, но при таком массовом изменении
отдельные HTML-ссылки могли поломаться. Будем со временем исправлять.
Поскольку это касается только документации, существенного влияния
на работу прикладных систем возникнуть не должно.
В результате сейчас все файлы HTML (за исключением нескольких
файлов) хранятся в кодировке utf-8, что позволяет их использовать
как в старой, так и в новой версии пакета.
29.11.2023
DownSampling DownSampling.Tail
Данный выпуск посвящен доработке алгоритмов
управления дискретностью (DownSampling).
Серьезно доработаны алгоритмы понижения дискретности
DownSampling,
см. также
описание.
Причиной доработок послужили две проблемы, обнаруженные Н.Гуриным
в процессе тестирования.
"Поломка" алгоритма отображения данных при наличии "дырок"
(интервалов с отсутствующими данными) в отображаемой кривой.
Проявляется в том, что вместо графика рисуются 2 точки и прямая.
Нарушение монотонности графика при добавлении новых точек
графика в режиме Online.
Первая проблема была решена путем серьезной доработки алгоритмов
понижения дискретности (DownSampling).
В новой версии предприняты все меры для того, чтобы наличие "дырок"
не приводило к сбою алгоритма рисования.
Для решения второй проблемы был введен дополнительный параметр
DownSampling.Tail (дословно - "хвост").
Этот параметр задает число хвостовых точек (в конце кривой), которые
сохраняются неизменными и не затрагиваются при выполениии процедуры
понижения дискретности. При добавлении новых точек данных хвостовой
участок кривой позволяет рисовать новые данные, поступающие в режиме
Online, без разрывов и искажений.
Теперь диалог параметров DownSampling выглядит так:
Изменены параметры для задания начальных значений дискретности
в конфигурации:
Файл Crw32.ini
Секция [System]
Параметр DefDownSamplingParams = 1, 15, 4096, 2, 3
где:
1 - алгоритм LargestTrianleThreeBuckets
15 - режим, разрешающий использование дискретности
4096 - абсолютный порог для числа точек
2 - число точек на пиксель для вычисления порога
3 - число точек в "хвосте", которые не изменяются
Есть надежда, что на этом тема проблем с алгоритмом DownSampling
будет закрыта.
Главными достижениями данного выпуска являются:
добавление шестнадцатеричных констант ($xxxx);
добавление восьмеричных констант (&xxxx);
добавление двоичных констант (%xxxx).
В компилятор
DaqPascal
добавлена возможность задавать целочисленные константы (литералы)
не только в обычной (десятичной) нотации (записи), но также и
в шестнадцатеричной, восьмеричной и двоичной нотации.
Например:
const b10 = 255; // Decimal constant, base 10
const b16 = $FF; // Hexadecimal constant, base 16
const b8 = &377; // Octal constant, base 8
const b2 = %11111111; // Binary constant, base 2
Символы ($,&,%) служат признаком констант
по основанию (16,8,2) соответственно.
Поскольку символ & служит синонимом оператора and,
с восмеричными константами надо быто осторожными.
Символ & рассматривается как признак восьмеричной константы
только тогда, когда следующим символом идет восьмеричная цифра (0..7).
Поэтому возможны ситуации неоднозначной интерпретации выражений,
для устранения которых рекомендуется использовать скобки.
Новые средства добавлены для улучшения совместимости прикладного кода
DaqPascal с компилятором FreePascal.
Разумеется, задачи обеспечения полной совместимости не стоит -
эти компиляторы решают разные задачи. Однако иметь некоторую степень
совместимости неплохо, т.к. судя по практике, сходные фрагменты кодов
часто используются в разных контекстах (DaqPascal,
DieselPascal, FreePascal).
Выдержка из справки компилятора Free Pascal:
For integer type constants, Free Pascal supports four formats:
1. Normal, decimal format (base 10). This is the standard format.
2. Hexadecimal format (base 16), in the same way as Turbo Pascal does.
To specify a constant value in hexadecimal format, prepend it with a dollar sign ($).
Thus, the hexadecimal $FF equals 255 decimal.
Note that case is insignificant when using hexadecimal constants.
3. As of version 1.0.7, Octal format (base 8) is also supported.
To specify a constant in octal format, prepend it with an ampersand (&).
For instance 15 is specified in octal notation as &17.
4. Binary notation (base 2).
A binary number can be specified by preceding it with a percent sign (%).
Thus, 255 can be specified in binary notation as %11111111.
Перевод:
Для констант целочисленного типа Free Pascal поддерживает четыре формата:
1. Обычный, десятичный формат (основание 10). Это стандартный формат.
2. Шестнадцатеричный формат (база 16), точно так же, как это делает Turbo Pascal.
Чтобы указать постоянное значение в шестнадцатеричном формате, добавьте к нему знак доллара ($).
Таким образом, шестнадцатеричный $FF равен 255 десятичным.
Обратите внимание, что регистр несущественен при использовании шестнадцатеричных констант.
3. Начиная с версии 1.0.7, также поддерживается восьмеричный формат (базовый 8).
Чтобы указать константу в восьмеричном формате, добавьте к ней амперсанд (&).
Например, 15 указано в восьмеричной системе счисления как &17.
4. Двоичная система счисления (основание 2).
Двоичное число можно указать, поставив перед ним знак процента (%).
Таким образом, 255 может быть указано в двоичной системе счисления как %111111111.
В DaqPascal добавлены функции преобразования:
inttostrbase,
strtointbase,
которые преобразуют сроку в число или число в строку по различным
системам счисления (двоичной, восьмеричной, десятичной, шестнадцатеричной).
Эти функции частично дублируют уже существующие (например, для десятичной
или шестнадцатеричной систем), однако для других систем (например,
двоичной и восьмеричной) аналогов не было.
Функция strtointbase также умеет преобразовывать строки с явным
указанием системы счисления символами ($,&,%).
Таким образом, новые функции являются хорошим дополнением к имеющемуся
набору функций преобразования.
В демо конфигурации DEMO_TESTBENCH
добавлен @Test 18 для проверки работы новых функций преобразования.
01.11.2023
параметры в кавычках DEMO_SHM DownSampling
origami
Главными достижениями данного выпуска являются:
управление дискретностью (DownSampling);
парамеры мнемосхем в кавычках;
обновление Origami;
обновление DEMO_SHM.
Параметры (Hint,Tag,GeneralMap) мнемосхем в файлах
*.CRC
теперь можно задавать
в кавычках.
Используется
либо кодировка URL,
либо (двойные) кавычки (").
Распознавание формата идет по первому значимому символу (отличному от пробелов).
Если это двойные кавычки ("), то извлекается строка в кавычках,
иначе используется кодировка URL, как и было раньше.
Обновлена ДЕМО конфигурация
DEMO_SHM,
в которой
мнемосхемы
сделаны в новом стиле (с кавычками).
Для ускорения рисования графиков в окнах CurveWindow добавлена
команда управления дискретностью (или понижения уровня дискретности -
DownSampling).
Для иллюстрации работы DownSampling имеется демонстрационный
пример,
а также
описание.
Понижение дискретности (DownSampling) - это способ кардинально
(в десятки раз) повысить скорость отображения графиков
при большом числе точек (например, больше 2000). Идея понижения
дискретности проста. На экране есть ограниченное число пикселей,
например, 1920 пикселей по горизонтали. Строить график функции
с числом точек, намного превышающим число пикселей - бессмысленно,
т.к. близкие точки все равно сольются на экране в одну точку
(или один отрезок линии). Поэтому можно понизить число отображаемых
точек до разумного предела. Тогда их отображение происходит намного
быстрее. Фактически при понижении дискретности отображается только часть
точек из кривой, а остальные точки отбрасываются. Другими словами,
DownSampling - это выборка данных с пониженным числом точек,
представляющая (на экране) исходный (большой) массив данных.
Главным вопросом реализации DownSampling является
репрезентативность данных, т.е. качество представления (на экране)
большого объема данных с помощью выборки гораздо меньшего объема.
Для обеспечения репрезентативности был разработан целый ряд алгоритмов,
некоторые из которых описаны в диссертации Sveinn Steinarssonss_msthesis.pdf
из университета Рейкьявика (Исландия). Предложенные в диссертации
алгоритмы позволяют делать выборки данных, которые при отображении
графиков дают изображение, мало отличающееся от изображения,
построенного по всему (большому) массиву данных. При этом получается
большой (в десятки раз) выигрыш в скорости построения графиков.
Как следует из приведенного выше описания, DownSampling
применяется только к большим данным (т.е. кривым с большим
числом точек - назовем его DataLeng).
Кривые с числом точек ниже порога отображаются без понижения
дискретности (в исходном виде). Для вычисления порога для пониженного
числа точек (назовем его DownLeng) применяется следующий метод.
Задается DownSampling.Method - алгоритм выборки данных
для отображения из исходного массива.
Рекомендуемый алгоритм - LargestTrianleThreeBuckets.
Задается DownSampling.Mode - режим работы, т.е. набор
битовых флагов:
Бит 0 - разрешить использование DownSampling.
Бит 1 - разрешить использование AbsLen.
Бит 2 - разрешить использование PerPix.
Задается DownSampling.AbsLen - абсолютный порог для длины
данных (т.е. для числа точек кривой).
Задается DownSampling.PerPix - число точек на пиксель.
Порог длины данных вычисляется как DownLeng=PerPix*PixWidth,
где PixWidth - ширина графика в пикселях.
При работе алгоритма перед построением графика вычисляется порог для
числа точек как DownLeng=Min(AbsLen,PerPix*PixWidth),
где PixWidth - ширина графика в пикселях.
Если длина данных не превышает порога (т.е. DataLeng<=DownLeng),
график рисуется "как есть", без понижения дискретности.
Если число точек кривой больше порога и понижение дискретности разрешено,
применяется заданный алгоритм DownSampling.Method.
При этом число точек для отображения не будет превышать
пороговое значение независимо от размера исходных данных.
На панели инструментов окна кривых появилась команда "Дискретность".
Её вид зависит от параметров дискретности:
-
понижение дискретности запрещено и график построен
без понижения дискретности.
-
дискретность разрешена и график был построен
с использованием понижения дискретности.
-
дискретность разрешена, но график был построен
без понижения дискретности,
т.к. число точек кривой оказалось ниже порога.
При нажатии кнопки появляется диалог:
В этом диалоге можно задать параметры понижения дискретности.
Также команда "Дискретность" помещена в меню "Правка".
Для задания начальных значений дискретности добавлен параметр
конфигурации:
Файл Crw32.ini
Секция [System]
Параметр DefDownSamplingParams = 1, 7, 4096, 2
где:
1 - алгоритм LargestTrianleThreeBuckets
7 - режим, разрешающий использование дискретности
4096 - абсолютный порог для числа точек
2 - число точек на пиксель для вычисления порога
В конфигурацию окон кривых DAQ системы добавлен параметр
UsesDownSampling,
принимающий значения 0/1 (по умолчанию 1).
Этот параметр позволяет отключать/включать использование дискретности.
Алгоритм понижения дискретности позволяет кардинально (в десятки раз)
повысить скорость рисования графиков при большом (более 2000 точек)
числе точек кривой, причем скорость рисования будет слабо зависеть
от объема данных в кривой, т.к. выборка будет понижать число точек
до заданного порогового уровня.
При этом использование режима увеличения (zoom) позволяет
при необходимости рассматривать массив больших данных с любой степенью
подробности. При масштабировании рисуется только фрагмент кривой,
попавший в поле графика, так что начиная с определенного уровня
увеличения понижение дискретности автоматически выключается, когда
в поле графика попадает число точек ниже порога.
Это позволяет рассматривать данные быстро и без потери качества.
В целом алгоритм управления
дискретностью является значительным шагом вперед
и позволяет эффективно работать с данными большого объема
с высокой производительностью.
Обновлен редактор
Origami
с поправками от А.Жирунова.
В новой версии поддерживаются мнемосхемы с надписями в кавычках.
В дистрибутив добавлен инсталлятор
install-daqgroup-fpcupdeluxe-x86.exe,
подготовленный Н.Гуриным.
Это портабельная версия Free Pascal и Lazarus.
Это средство для разработчиков.
Главными достижениями данного выпуска являются:
обновление SMI;
сборка SMI под AstraLinux;
новая группа функций shm_xxx для работы с общей памятью;
обновление SmiGenGui.lm9.
Обновлена версия SMI (Конечные Автоматы)
с версии 5702 на актуальную 5801.
Обновление было сделано в ходе работ по сборке
SMI под AstraLinux - целесообразно
было делать сборку из последней версии, а заодно
обновить сборку SMI под Windows.
Сборка SMI под AstraLinux оформлена как
deb пакет install-daqgroup-smi.deb.
Обновлена утилита SmiGenGui для управления
и наблюдения SMI - теперь она кросс-платформенная
и работает также под AstraLinux, где она включена
в пакет crwkit.
Поскольку в гибридной (Windows/Linux) среде
мы будем постоянно сталкиваться с проблемами формата текстовых файлов
1) EOL - перевода строки LF или CRLF 2) UTF8 - перевода файлов в кодировку UTF8 или CP1251
то нужен удобный иструмент для пакетного (массового) определения файлов
с неверной кодировкой и их преобразования в правильный формат.
Для этого были сделаны команды
unix fixeol -t *.txt проверка корректности EOL для файлов *.txt
unix fixeol *.txt исправление маркеров EOL для файлов *.txt
unix fixeolzen *.txt проверка корректности EOL в графическом режиме (для Commander)
unix fixeolzen *.txt исправление маркеров EOL в графическом режиме (для Commander)
unix fixutf8 -t *.txt проверка корректности UTF8 для файлов *.txt
unix fixutf8 *.txt исправление маркеров UTF8 для файлов *.txt
unix fixutf8zen *.txt проверка корректности UTF8 в графическом режиме (для Commander)
unix fixutf8zen *.txt исправление маркеров UTF8 в графическом режиме (для Commander)
Эти команды включены в пакет crwkit, а также для удобства
интегрированы на панель инструментов DoubleCommander.
Под Windows реализована пока только утилита fixeol,
включенная в UnixUtils. В будущем (когда будет время) есть
планы сделать (по аналогии) и другие утилиты и интегрировать их в
TotalCommander.
В DaqPascal введена еще одна группа 10 функций для IPC
(взаимодействия между процессами) через общую память
(SHM = shared memory)
shm_init,
shm_ref,
shm_free,
shm_delink,
shm_iop,
shm_rop,
shm_fop,
shm_sop,
shm_ctrl,
shm_ioresult.
Библиотека появилась в ходе работ по переводу пакета под FreePascal
и является универсальной (DaqPascal,Delphi,FreePascal,
Windows/Unix), что облегчает создание клиент-серверов,
написанных на разных языках программирования для разных систем.
Создана ДЕМО конфигурация
DEMO_SHM,
иллюстрирующая работу клиент-серверых программ с общей памятью
в качестве механизма OPC.
Есть описание.
Обратите внимание - в этом примере используется справочный файл index.md.html.
При этом исходным редактируемым файлом справки является index.md, из которого
получается index.md.html. Это хорошая практика - с одной стороны, редактирование
*.md файлов намного легче и быстрее, при хорошей структуре документа. С другой
стороны, формат *.html более переносимый и поддерживается всеми браузерами
непосредственно, без установки дополнительных плагинов.
Эта практика рекомендуется к использованию во всех прикладных системах.
Надо лишь не забывать после редактирования *.md файлов обновлять
(одним кликом) файл *.md.html. Пожалуй, это наиболее разумная
методика подготовки справочных файлов.
В StdLibrary добавлена функция
ExtractNameValuePair
для разбора выражений типа Name=Value, при этом часть внутренних библиотек переделана
на эту функцию (унификация кода).
Главными достижениями данного выпуска являются:
обновление библиотек DieselPascal;
обновление DimMonitor.lm9 и DimStatGui.lm9.
Обновлены библиотеки DieselPascal.
Изменения коснулись функций вычисления специальных каталогов программы:
Dir:=GetAppDataDir(false,true); // Локальный каталог данных программы, например:
// Win10: C:\Users\main\AppData\Roaming\DaqGroup\dimmonitor
// Linux: /home/alex/.local/share/daqgroup/dimmonitor
Dir:=GetAppConfigDir(false,true); // Локальный каталог настроек программы, например:
// Win10: C:\Users\main\DaqGroup\dimmonitor
// Linux: /home/alex/.config/daqgroup/dimmonitor
InitAppFolders; // Создать локальный каталог данных и настроек,
// вызывается один раз в начале программы.
Пример для DimMonitor - Linux:
GetAppDataDir(0,0) = /home/alex/.local/share
GetAppDataDir(0,1) = /home/alex/.local/share/daqgroup/dimmonitor
GetAppDataDir(1,0) = /usr/share
GetAppDataDir(1,1) = /usr/share/daqgroup/dimmonitor
GetAppConfigDir(0,0) = /home/alex/.config
GetAppConfigDir(0,1) = /home/alex/.config/daqgroup/dimmonitor
GetAppConfigDir(1,0) = /etc
GetAppConfigDir(1,1) = /etc/daqgroup/dimmonitor
Пример для DimMonitor - Win10:
GetAppDataDir(0,0) = C:\Users\main\AppData\Roaming
GetAppDataDir(0,1) = C:\Users\main\AppData\Roaming\DaqGroup\dimmonitor
GetAppDataDir(1,0) = C:\ProgramData
GetAppDataDir(1,1) = C:\ProgramData\DaqGroup\dimmonitor
GetAppConfigDir(0,0) = C:\Users\main
GetAppConfigDir(0,1) = C:\Users\main\DaqGroup\dimmonitor
GetAppConfigDir(1,0) = C:\ProgramData
GetAppConfigDir(1,1) = C:\ProgramData\DaqGroup\dimmonitor
Функции используются для работы с специальными каталогами программы в
многоплатформенной среде - каталоги будут подстраиваться под данную
конкретную систему.
При этом каталог GetAppDataDir используется
для хранения данных и текущих настроек программы,
а каталог GetAppConfigDir - для хранения файлов конфигурации.
Настройки и данные условно делятся
на глобальные (для всех пользователей)
и локальные (только для данного пользователя).
Соответственно есть два вида каталогов - глобальные и локальные.
Кроме того, в имена каталогов могут включаться (или не включаться)
Vendor (производитель) и AppName (имя программы).
Вызов GetAppDataDir(global,subdir) возвращает каталог данных программы, где
можно хранить текущие настройки или временные данные. Для локальных/глобальных настроек
используется флаг global=false/true; при указании флага subdir
к имени каталога добавляется Vendor/AppName. Для наших задач будет
использоваться Vendor=DaqGroup, а AppName - имя исполняемого
файла программы без пути и расширения. Под Linux все имена приводятся
к нижнему регистру (чтобы избежать проблем с регистрами имен файлов).
В программе DimMonitor.lm9 локальный каталог данных используется
для хранения INI файлов с настройками.
Обновлены утилиты DimMonitor.lm9 и DimStatGui.lm9.
DimMonitor.lm9 доработан в плане отображения данных и
поддержки (двух) языков интерфейса пользователя.
Утилиту можно еще долго улучшать, но в первом приближении она готова
для использования как в качестве отладочной утилиты, так и для работы
в составе прикладных систем на базе DIM.
Обновлена ДЕМО конфигурация
DEMO_EM2RS
с доработками от А.Жирунова.
Главными достижениями данного выпуска являются:
функции управления спин-блокировками;
обновление Origami;
обновление DieselPascal;
функция EOL конца строки;
обновление DIM и его библиотек;
обновление DimMonitor.lm9 и DimStatGui.lm9.
DIM обновлен до актуальной версии 20.35.
В этой версии исправлены некоторые ошибки.
Кроме того, под Windows мютексы заменены на более быстрые
критичекие секции, что (потенциально) повышает скорость работы и
снижает нагрузку процессора.
Обновлены утилиты DimMonitor.lm9 и DimStatGui.lm9.
Они сделаны кроссплатформенными и работают под обеими системами
(Windows,Linux).
Кроме того, DimMonitor.lm9 доработан в плане отображения
данных и доведен с тестовой до рабочей версии.
В программе DimMonitor.lm9 есть возможность запускать
несколько экземпляров и сохранять настройки в *.ini
файле с последующей (авто) загрузкой и запуском монитора.
Например:
По умолчанию *.ini файлы (если явно не указан путь) сохраняются
в профиле пользователя (что-нибудь типа c:\Users\main\AppData\Roaming\dimmonitor\dimmonitor_1.ini).
Это позволяет запускать окна для наблюдения различных параметров через
DIM одной командой с автоматически загружаемыми параметрами.
Это делает DimMonitor.lm9 вполне рабочим инструментом для
диагностики и отображения состояния DAQ систем.
В системный калькулятор (т.е. интерпретатор Главной Консоли)
добавлены функции:
SpinCountDef(n) - счетчик спин-блокировок по умолчанию.
SpinCountTag() - счетчик спин-блокировок для тегов.
Вызов SpinCountSys() возвращает счетчик спин-блокировок,
используемый в системе по умолчанию, если явно не задан другой.
По моим измерениям:
Для WinXP значение SpinCountSys() равно 0.
Для Win10 значение SpinCountSys() равно 2000.
Вызов SpinCountDef(n) возвращает текущий счетчик спин-блокировок,
используемый в программе по умолчанию и затем задает ему новое значение n.
Начальное значение счетчика -1, что означает "использовать
системное значение по умолчанию из SpinCountSys()".
При задании другого (неотрицательного) значения задается значение
счетчика спин-блокировок, используемое для большинства объектов
блокировки (на базе критических секций), кроме тегов.
Вызов SpinCountTag(n) возвращает текущий счетчик спин-блокировок,
используемый для блокировки тегов и затем задает ему новое значение n.
Начальное значение счетчика равно SpinCountSys().
При задании другого значения задается счетчик спин-блокировок,
используемый для блокировки тегов.
Счетчики SpinCount влияют на работу критических секций.
При обнаружении блокировки критическая секция крутится (spin)
в цикле ожидания SpinLock, ожидая, пока либо освободится
блокировка, либо счетчик итераций достигнет заданного предела
SpinCount.
После этого либо происходит захват критической секции, либо перевод
потока в спящий режим, что довольно долго, т.к. связано с системным
вызовом, который занимает как минимум микросекунду (т.е. несколько
тысяч тактов процессора).
Задание правильного значения счетчика SpinCount
позволяет снизить нагрузку процессора на многоядерных системах
в случае конкуренции потоков за ресурсы (в нашем случае - теги,
кривые и т.д.). Оптимальное значение счетчика зависит от типичного
времени блокировки ресурсов. Если блокировки ресурсов происходят
на короткое время, счетчик можно уменьшить. Если блокировки более
длительные, счетчик увеличивают. Однако нет смысла делать счетчик
слишком большим, т.к. если время спин-блокировки превышает время
системного вызова для блокировки потоков, то выгода от использования
спин-блокировки исчезает. В то же время если счетчик слишком мал,
программа не успеет освободить блокировку и поток уйдет в сон.
Разумным выглядит значение счетчика в диапазоне [0-2000].
Для выяснения оптимального значения SpinCount нужно
провести тестирование.
По крайней мере такая возмоность сейчас есть.
Было давно замечено, что в больших прикладных системах иногда возникает
довольно высокая нагрузка процессора даже при отсутствии большого числа
данных. Это веротно связано с конкуренцией большого числа потоков за
доступ к ресурсам (например, тегам и кривым). При этом происходит
либо чрезмерно частое переключение потоков, либо избыточные потери
времени в циклах ожидания спин-блокировок. Задание оптимального значения
счетчиков спин-блокировок позволит (как ожидается) снизить нагрузку
процессора при работе большого числа потоков.
Для определения оптимального значения SpinCount нужно
провести серьезную работу по тестированию производительности
на больших системах при различных значениях SpinCount.
В DaqPascal введена еще одна функция для маркера конца строки
EOL, которая является синонимом
LineEnding и sLineBreak.
Название EOL = End Of Line является широко распространенной
аббревиатурой, которая к тому же коротка, легко произносима и понятна.
Названия LineEnding и sLineBreak широко применяются
в кодах Free Pascal и поэтому должны присутствовать в библиотеке,
однако использовать их неудобно из-за громоздкости - получается
длинный, тяжеловесный код.
Использование короткого и ясного маркера EOL удобнее и улучшит
читабельность прикладного кода.
Краткое резюме: вместо CRLF теперь
используем EOL.
Обновлен редактор
Origami
с мелкими правками от А.Жирунова.
Обновлена ДЕМО конфигурация
DEMO_EM2RS
с доработками от А.Жирунова.
DieselPascal обновлен до актуальной версии 2.1.6.
В этой версии в Дизель исправлены некоторые ошибки,
добавлена константа EOL = LineEnding,
добавлены константы и типы, нужные для
рисования StringGrid.OnDrawCell().
23.04.2023
DieselPascal 2.1.2 dpSystem dpTask
Главными достижениями данного выпуска являются:
обновление DieselPascal и его библиотек.
DieselPascal обновлен до актуальной версии 2.1.2.
В этой версии в Дизель добавлены функции работы со списком переменных окружения,
экранными координатами мыши и ряд других полезных добавлений, некоторые из которых описаны в
daqgroupnews.md.
Также поправлены библиотеки dpSystem.pas, dpSysUtils.pas, dpTask.pas, dpGuiUtils.pas,
чтобы корректно работал запуск процессов (функции task_run) под Linux и работа с окнами.
Проблема была связана с тем, что в Linux по-другому сделан механизм наследования
переменных окружения. В прежней версии библиотеки наследовалось начальное окружение,
переданное процессу при запуске, а изменения, сделанные в программе после запуска,
не передавались. Теперь изменения, сделанные с помощь SetEnv(),
передаются в дочерний процесс верно.
Библиотека DieselPascal существенно переработана для обеспечения кроссплатформенной совместимости.
Работа в этом отношении еще не завершена и будет продолжаться по мере необходимости.
Пока сделанных изменений достаточно для создания кросссплатформенных утилит,
корректно работающих с процессами в обоих системах.
Обновлены все *.lm9 утилиты (около 20) в соответствии с изменениями в библиотеках.
Такое массовое обновление, будем надеяться, часто делать не придется - а сейчас особый
случай, связанный с переходом под Linux. Большинство утилит DieselPascal
должны (номинально) запускаться под Windows и Linux и, как минимум,
показывать интерфейс и выполнять простейшие команды графического интерфейса.
Хотя корректно работать под обеими системами пока могут только отдельные утилиты
(например demoping).
Главными достижениями данного выпуска являются:
обновление Origami;
добавление драйверов вакууметров DEMO_VMCD, DEMO_VTRD;
обновление и новые опции DieselPascal и его библиотек.
DieselPascal обновлен до актуальной версии 2.1.0.
В этой версии файл evars.cfg со списком строк вида NAME=Value,
содержащий пользовательские переменные окружения, может располагаться в двух местах
(в том числе в обоих сразу):
в системном каталоге расположения исполняемых файлов Дизеля ($DIESEL_EXE_DIR), и
в локальном каталоге пользовательской конфигурации ($DIESEL_LOCALSET_DIR).
Сначала считывается системный файл $DIESEL_EXE_DIR/evars.cfg,
а затем пользовательский файл $DIESEL_LOCALSET_DIR/evars.cfg,
так что локальная конфигурация может переопределять системные значения переменных окружения,
что позволяет гибко настраивать программное окружение утилит DieselPascal.
При задании переменных окружения из файла их имена приводятся к верхнему регистру.
Для утилит под Windows это неважно, а под Linux регистр играет роль.
Обновлена утилита Crw32.Utils.LM9 и все утилиты *.lm9.
В опциях проекта ExternalPath сделана замена %DieselPascal_External%
на $DIESELPASCAL_EXTERNAL в стиле Linux. Для утилит под Windows
это эквивалентная замена, а для утилит под Linux регистр играет роль.
Все переменные окружения DieselPascal заданы в верхнем регистре.
Во всех утилитах *.lm9 теперь указаны опции проекта
Также в обоих версиях (Win32 и Linux) внешние библиотеки помещены
в $DIESEL_EXE_DIR\external и $DIESEL_SCRIPT_DIR\external, так что
эти библиотеки стали доступными для всех программ DieselPascal.
Теперь утилиты DieselPascal стало можно запускать не только из среды пакета CRW-DAQ,
но из любого места, при этом при запуске из пакета будет доступна локальная (для пакета) библиотека
$DIESELPASCAL_EXTERNAL, при запуске вне пакета будет доступна локальная (для пользователя)
библиотека $DIESEL_SCRIPT_DIR\external, а общая библиотека $DIESEL_EXE_DIR\external
доступна для всех пользователей, а не только для того, кто устанавливал DieselPascal.
Получается довольно гибкая система управления библиотеками.
Обновлены External библиотеки DieselPascal.
Внесены изменения для совместимости с Linux.
Добавлен модуль dpLinux и демо demoping.lm9.
Это демо иллюстрирует запуск процессов с перехватом консольного
ввода-вывода - проверено под Win-x32/x64 и AstraLinux-x64.
Теперь проблема создания графических утилит на базе консольных программ
с графическим интерфейсом на DieselPascal в принципе решена.
Поправлена документация к функции InitDevice().
Обновлен редактор
Origami
с правками от А.Жирунова. Смотрите журнал новостей в редакторе.
Главными достижениями данного выпуска являются:
почта daqgroup@mail.ru;
новости daqgroupnews.md и заметки daqgroupnotes.md;
обновление Origami;
добавление драйверов вакууметров DEMO_VMCD, DEMO_VTRD;
обновление Painter и ДЕМО DEMO_PAINT_GUILIB, DEMO_PAINT_GOSTLIB;
обновление и новые опции DieselPascal;
обновление утилиты Crw32.Utils.lm9
обновление unixutils и MarkdownViewer.
Для нужд группы автоматизации DaqGroup заведена почта
daqgroup@mail.ru.
По этому адресу (который легко запомнить) можно вести переписку по развитию пакета,
а также указывать его в Copyright для продуктов коллективной разработки.
Канонический вид строки Copyright для DaqGroup имеет вид:
Начиная с этого момента
в папке репозитория /srv/public/mirror/addons/
будут располагаться:
Новости DaqGroup (отсортированные по датам) по репозиторию и системе
AstraLinux:
в формате Markdowndaqgroupnews.md
и в формате HTMLdaqgroupnews.md.html.
Введение новых файлов связано с тем, что мы переходим на AstraLinux и пакет будет обновляться реже.
А новости (по программированию в системе AstraLinux) где-то надо размещать.
Поэтому все новости по AstraLinux будут размещаться только в новых файлах.
Сделано обновление UnixUtils: обновлена утилита MarkdownViewer.
Теперь она умеет обрабатывать конструкцию [[toc]]
(эта конструкция должна располагаться на отдельной строке).
Также появилась опция --convert-only:
unix markdownviewer demo.md - генерирует demo.md.html и открывает его в Firefox
unix markdownviewer demo.md --convert-only - просто генерирует файл demo.md.html (не открывает)
Новая опция позволяет конвертировать файлы в пакетном режиме (например, в процессе инсталляции),
когда файлы надо конвертировать, но не требуется открывать для просмотра.
Обновлены стили markdownviewer.css в UnixUtils,
чтобы заработала подсветка синтаксиса при генерации Markdown.
Над палитрой еще стоит поработать, но в принципе уже пригодно для работы.
Сделать одинаковую палитру в браузерном плагине и в markdownviewer
затруднительно, т.к. синтаксические анализаторы (prism и pandoc)
по-разному классифицируют конструкции языка и свести их в одну таблицу не удается.
Поэтому подсветка будет несколько отличаться в зависимости от движка.
Обновлен редактор
Origami
с правками от А.Жирунова. Смотрите журнал новостей в редакторе.
Добавлены ДЕМО конфигурации
DEMO_VMCD,
DEMO_VTRD,
содержащие драйверы для вакууметров от А.Жирунова.
Обновлены библиотеки и документация графической системы
Painter.
Обновились библиотеки:
GuiLib,
GostLib,
в которые добавлены новые графические элементы,
проведена оптимизация кода библиотек.
Обновление подготовил Н.Гурин.
DieselPascal обновлен до актуальной версии 2.0.26, которая компилируется под lazarus 2.2.4.
В этой версии по моей специальной просьбе автор (Юрий Копнин) добавил следующие опции:
При старте сценария DieselPascal создает переменные окружения:
DIESEL_EXE_DIR каталог расположения исполняемых файлов Дизеля
например: C:\Program Files\VisualTech\DieselPascal\exewindows\
DIESEL_EXE_PID идентификатор PID текущего выполяемого процесса Дизеля
например: 7728
DIESEL_LOCALSET_DIR каталог для локальных данных Дизеля
например: C:\Documents and Settings\main\DieselPascal\
DIESEL_SCRIPT_DIR каталог, где расположен текущий выполняемый *.lm9 скрипт
например: C:\CRW32EXE\RESOURCE\
DIESEL_SCRIPT_NAME полное имя файла текущего выполяемого *.lm9 скрипта Дизеля
например: C:\CRW32EXE\RESOURCE\Crw32.Utils.lm9
Указанные переменные можно использовать в дочерних процессах, запускаемых
из сценария, т.к. при запуске процессов переменные окружения наследуются.
Также эти переменные окружения можно использовать в опциях проекта для
указания расположения внешних модулей (External), что позволяет
организовать полноценную стандартную библиотеку, путь к которой вычисляется
по переменным окружения (это сделано с прицелом на AstraLinux).
Если в каталоге расположения исполняемых файлов Дизеля ($DIESEL_EXE_DIR)
расположен файл evars.cfg со списком строк вида Name=Value,
то по списку из этого файла создаются дополнительные переменные окружения.
Эти переменные окружения также можно использовать в дочерких процессах
или для формирования имени каталога External для внешних модулей.
В дизайнере Дизеля, в меню "Опции\Опции проекта" на закладке
"Внешние модули" теперь можно указывать расположение внешних
библиотечных модулей External в виде списка, разделенного
точкой с запятой (;), например:
При вычислении каталога External происходит выделение из списка
строк, разделенных точкой с запятой, затем подстановка переменных окружения
и проверка существования каталога. За результат поиска принимается первый
существующий каталог в списке.
Новые опции DieselPascal позволяют гибко управлять расположением
и поиском каталога External для внешних (библиотечных) модулей.
В будущем планируется сделать общую (для Windows и Linux)
библиотеку, так чтобы проекты могли запускаться из обоих систем и находить
нужные им библиотеки. Также возможен запуск сценариев DieselPascal
с разными вариантами окружения. Например, при запуске из графической оболочки
используется один вариант библиотек, а при запуске из среды пакета - другой.
Новые опции сделаны с дальним прицелом на использование DieselPascal
в смешанной среде (Windows-AstraLinux), где расположение
файлов библиотек может меняться в зависимости от системы и окружения.
Обновлена утилита Crw32.Utils.LM9.
На закладке Tools добавлена кнопка Run Command
для запуска программ с окружением DieselPascal.
Полезно для практики и тестирования.
04.03.2023
AstraLinux zenity zenity-demo crw-daq-style-guide-ru.md
lazarus 2.2.4 DieselPascal 2.0.24 daqgroup-diesel deb
daqgroup-dim deb /opt/dim
Painter(v) GuiLib GostLib
DEMO_PAINT_GOSTLIB DEMO_PAINT_GUILIB DEMO_MDBS
Главными достижениями данного выпуска являются:
добавление инструкции crw-daq-style-guide-ru.md по стилю программирования;
добавление программы zenity под Windows;
обновление и версии DIM и DieselPascal под AstraLinux;
пакеты daqgroup-dim и daqgroup-diesel для AstraLinux.
В документацию под заголовком
Style
добавлена инструкция по стилю программирования
crw-daq-style-guide-ru.md.
Там даны рекомендации и описаны правила именования программных объектов,
оформления и форматирования программного кода для повышения его качества
и рассмотрены другие практические вопросы разработки прикладного ПО.
Рекомендуется к ознакомлению всем участникам DaqGroup.
Документ разработал (в основном) Н.Гурин.
В сборку UnixUtils добавлена программа zenity.
Эта программа позволяет организовывать простые графические диалоги
в командах и командных сценариях (bat, cmd, sh).
Программа zenity разработана первоначально под Unux и работает
в Windows, в Linux и под wine.
Это позволяет выполнять определенные действия единообразно во всех системах.
Графические возможности zenity довольно многочисленны - она содержит
диалоги для информационных сообщений, подтверждения действий, ввода строк и паролей,
задания календарных дат, цветовых констант и имен файлов, выбора элементов из списка,
отображения прогресса длительных операций и т.д.
Программу zenity можно применять как для системных сценариев (инсталляторы, программы для настройки системы),
так и для прикладных программ (вызов тех или иных диалоговых команд из программ DaqPascal, мнемосхем и т.д.).
Например, можно выполнять команды в Главной Консоли:
Также добавлена команда zenity-demo, которая иллюстрирует работу
программы zenity и позволяет получить рабочие шаблоны для создания
прикладного кода. Наберите в Главной Консоли:
@run unix zenity-demo
Программа zenity-demo выполняет примеры графических диалогов и показывает
(в консоли и в log файле) команды, которые этот диалог выполняют.
Поскольку команды Главной Консоли позволяют взаимодействовать с DAQ системой,
через посылку сообщений можно организовывать графические диалоги, которые могут управлять
работой прикладных DAQ систем, например:
Более сложные диалоги можно оформить в виде командных сценариев cmd, которые вызываются через главную консоль.
Таким образом, программа zenity расширяет возможности системного и прикладного программирования.
В сборку DIM добавлена папка dim_make, содержащая дополнительные файлы
для сборки (компиляции) бинарных файлов под AstraLinux, а также файлы, нужные для "дебианизации"
(создания deb пакетов для семейства дистрибутивов debian) бинарной сборки. В архив включены только
служебные файлы, нужные для сборки deb пакетов AstraLinux, а сами бинарные файлы копируются
(после компиляции) для сборки в отведенные для этого папки. Таким образом, DIM будет собираться под
AstraLinux в виде deb пакета с именем daqgroup-dim, что удобно для инсталляции.
Пока что пакет будет располагаться в каталоге
/srv/public/mirror/addons/astra-linux/astra-tools/daqgroup-dim
репозитория DaqGroup (со временем расположение может измениться).
Инсталляцию можно запускать из файлового менеджера "кликом" на deb пакет.
Для удаления пакета можно использовать команду sudo apt remove daqgroup-dim;.
В бинарную сборку пакета daqgroup-dim также входят ярлыки для запуска/остановки программ DNS,
DID, webDID и сценарий (systemd_dimdns.sh) для запуска DIM DNS
как сервиса с именем dimdns.service.
После инсталляции пакета daqgroup-dim бинарные файлы находятся в рабочем каталоге
/opt/daqgroup/programs/common/dimsite/dim.
Каталог бинарных файлов проецируется (с помощью символичеcкой ссылки) на более удобный для использования
каталог /opt/dim,
который (отныне) будет постоянным каталогом расположения DIM.
То есть, например, DIM DNS расположен в файле /opt/dim/dns.
Таким образом, вопрос поддержки DIM под AstraLinux практически решен.
В сборке install-daqgroup-devel обновлен lazarus до актуальной версии 2.2.4.
DieselPascal обновлен до актуальной версии 2.0.24, которая компилируется под lazarus 2.2.4.
В репозиторий добавлена бинарная сборка DieselPascal под AstraLinux - пакет daqgroup-diesel,
а также файлы, нужные для "дебианизации" (создания deb пакетов для семейства дистрибутивов debian)
этой бинарной сборки.
В архив включены только служебные файлы, нужные для сборки deb пакетов AstraLinux,
а сами бинарные файлы копируются (после компиляции) для сборки в отведенные для этого папки.
Таким образом, DieselPascal будет собираться под AstraLinux в виде deb пакета
с именем daqgroup-diesel, что удобно для инсталляции.
Пока что пакет будет располагаться в каталоге
/srv/public/mirror/addons/astra-linux/astra-tools/daqgroup-diesel
репозитория DaqGroup (со временем расположение может измениться).
Инсталляцию можно запускать из файлового менеджера "кликом" на deb пакет.
Для удаления пакета можно использовать команду sudo apt remove daqgroup-diesel;.
В бинарную сборку пакета daqgroup-diesel также входят ярлыки для запуска проектов
и средства настройки.
После инсталляции пакета daqgroup-diesel бинарные файлы находятся в рабочем каталоге
/opt/daqgroup/programs/common/visualtech/diesel.
Каталог бинарных файлов проецируется (с помощью символичеcкой ссылки) на более удобный для использования
каталог /opt/diesel,
который (отныне) будет постоянным каталогом расположения DieselPascal.
То есть, например, CrossDesigner расположен в файле /opt/diesel/CrossDesigner.
Кроме того, бинарные файлы (CrossMachine, CrossDesigner, DManager)
проецируются (симлинками) также на каталог
/usr/local/bin,
который находится в PATH, поэтому вызывать DieselPascal
можно также по короткому имени, например:
CrossMachine /opt/diesel/examples/tetris.lm9
Таким образом, вопрос поддержки DieselPascal под AstraLinux практически решен.
В составе сборки также реализована контрольная панель для запуска и разработки
проектов DieselPascal, а также управления проектами и настройками.
В частности, через панель управления можно сделать привязку типа файла
(MIME тип application/x-diesel) к интерпретатору DieselPascal,
чтобы файлы *.lm9 запускались автоматически по нажатию кнопки мыши.
Эти дополнительные средства реализованы срествами bash+zenity.
Инсталлятор также устанавливает в меню Пуск\Разработка меню для запуска
DieselPascal. Таким образом, на примере DieselPascal реализован
полный цикл создания инсталляционного пакета, включая интергацию в оболочку.
Неплохо для начала.
Интерпретатор DieselPascal уже показал свою полезность в среде Windows
и пакета CRW-DAQ как средство для создания графического интерфейса утилит,
работающих в консольном режиме. Поскольку под Linux мир консольных утилит
огромен и весьма развит, DieselPascal несомненно будет еще более полезным
в среде AstraLinux.
Теперь DieselPascal можно считать штатным средством AstraLinux.
В недалекой перспективе планируется проведение адаптации библиотек DieselPascal
под AstraLinux, и тогда можно будет использовать его с большим эффектом.
Обновлены библиотеки и документация графической системы
Painter.
Обновились библиотеки:
GuiLib,
GostLib,
в которые добавлены новые графические элементы
(компрессоры, вакууметры, кнопки-снежинки).
Обновление подготовил Н.Гурин.
Обновлены ДЕМО конфигурации
DEMO_PAINT_GUILIB,
DEMO_PAINT_GOSTLIB,
использующие графические элементы Painter.
В DEMO_PAINT_GUILIB входит папка GUILIB_TEST_SCALE,
в которой проверяется масштабирование графических элементов.
Обновление подготовил Н.Гурин.
Обновлена конфигурация
DEMO_MDBS,
в которой устранена ошибка с записью цифровых каналов (coil).
Обновление подготовил А.Жирунов.
Можно констатировать, что работы по освоению системы AstraLinux и переходу на неё идут успешно.
Решены вопросы с (стандартным) репозиторием программных пакетов в закрытой сети.
Созданы основные скрипты для инсталляции системы, развертывания репозитория, настройки среды.
Освоена техника создания программных пакетов для инсталляции прикладных программ.
Пакеты DIM и DieselPascal портированы под AstraLinux.
Работа по созданию средств поддержки AstraLinux продолжается.
26.12.2022
DataBaseBrowser StrTimeFmt &FdbSrv DEMO_TESTBENCH
Всех поздравляю с наступающим Новым Годом и Рождеством.
Главными достижениями данного выпуска являются:
добавление функции StrTimeFmt;
доработка сервера &FdbSrv.
В этом выпуске проведена доработка &FdbSrv и DatabaseBrowser.
Остальные изменения носили вспомогательный характер (для решения этих задач).
Сделаны мелкие улучшения в Database Browser.
Сделано сохранение таблиц (результатов SQL запросов) в файл.
Добавлено пользовательское форматирование полей даты/времени в таблицах (до миллисекунд).
Теперь можно также выводить дату/время в виде вещественных чисел в различных единицах.
В результате встроенный Database Browser в чем-то даже превосходит другие браузеры СУБД
(например, время в миллисекундах есть далеко не везде).
Добавлена функция StrTimeFmt(fmt,ms)
для форматирования времени, аналогичная FormatDateTime,
только время задается в миллисекундах от начала эры.
Это (в будущем) основная функция форматирования времени, она работает существенно быстрее,
чем форматирование вручную (через разложение времени на компоненты и вызовы Str,StrFix,StrFmt).
Её введение связано с базами данных, где нужно быстро форматировать время в SQL запросах.
В демо конфигурации DEMO_TESTBENCH
добавлен @Test 17 для проверки работы функции StrTimeFmt.
Функция работает корректно и выдает такие результаты:
Вызов StrTimeFmt и функции GetDateTime на её основе
занимает 2.2 микросекунды, что в 3 раза быстрее,
чем вызов предыдущей версии GetDateTime на основе
разложения времени на компоненты и вызова StrFmt.
Быстрая функция преобразования времени нужна для формирования
больших SQL запросов при работе с базами данных.
Библиотечная функция
GetDateTime(ms)
переделана через вызов StrTimeFmt, которая, как было показано,
работает в 3 раза быстрее.
Это положительно повлияет на производительность прикладных программ.
В вычислитель выражений (eval) добавлены функции
MSecRangeMin(),
MSecRangeMax(),
задающие допустимый диапазон значений миллисекунд
[0..315537897599999]
в функциях времени, в диапазоне даты-времени
[0001.01.01-00:00:00.000..9999.12.31-23:59:59.999].
Также заведены константы
MSecRangeMin,
MSecRangeMax
для задания диапазона допустимых времен.
Эти константы можно использовать, например, для проверки меток времени.
Серьезно доработан сервер
&FdbSrv
для сохранения данных в формате СУБД типа Firebird.
Обновлено его описание.
Ради этого, собственно, затевался релиз. Суть решаемой проблемы была вот в чем.
Для записи данных в БД есть (принципиально) два пути - "классический",
через SQL запросы, и "быстрый" через recordset (AddNew/Update).
Второй метод быстрее, т.к. данные передаются в двоичном виде, без перевода в текст и обратно.
Однако было обнаружено, что recordset округляет метки времени TimeStamp
до секунд (в то время как базы данных могут сохранять их с высокой точностью -
до миллисекунд и лучше). Поэтому если требуется сохранять данные с точностью
по времени лучше секунды, то этот метод не работает. Вместо него используется
классическая передача данных в SQL запросах типа insert into TABLE ....
Для передачи сразу целого блока строк (а не по одной строке таблицы)
используется блочный оператор, например:
EXECUTE BLOCK AS BEGIN
insert into "DEMO.DIM_PING.CPU_LOAD" (X_TIME,Y_VALUE) values ('2022-12-25 23:56:50.1230','1.5');
insert into "DEMO.DIM_PING.CPU_LOAD" (X_TIME,Y_VALUE) values ('2022-12-25 23:56:51.4560','1.2');
...
END
При этом время передается с миллисекундной точностью.
Управление сервером &FdbSrv выполняется с помощью ряда команд
и параметров конфигурации, которые подробно описаны в документации.
В частности, можно задавать период сохранения, точность по времени
и режим передачи (быстрый или классический).
Теперь сервер &FdbSrv (вроде бы) полностью готов к работе.
На этом тема поддержки СУБД (предварительно) закрыта.
Точнее, она переходит в разряд прикладных задач.
Теперь прикладные разработчики могут использовать
DbApi, DbLibrary и &FdbSrv
для решения текущих задач автоматизации.
Перелистывая новости, можно констатировать, что прошедший год был
довольно продуктивным. В пакет добавились Регулярные Выражения,
Конечные Автоматы и Базы Данных. Неплохой результат.
Главными достижениями данного выпуска являются:
обновление и доработка библиотеки DbApi;
добавление функций библиотеки DbLibrary для работы с СУБД;
функции времени MsToDaqTime, DaqTimeToMs;
сервер &FdbSrv сохранения данных в формате Firebird;
пример DEMO_DIM_PING с сохранением в &FdbSrv.
В этом выпуске проведена доработка библиотек DbApi, DbLibrary и средств поддержки СУБД.
Сделан сервер &FdbSrv для сохранения данных в формате Firebird.
Остальные изменения носили вспомогательный характер (для решения этих задач).
В библиотеке DbApi доработаны функции
db_ctrl,
db_open,
добавилось несколько свойств.
Изменения потребовались для поддержки обновления данных через метод db_update
объекта recordset (без явного SQL запроса).
Также доработана документация по функциям DbApi.
А.Жируновым доработана DEMO конфигурация
DEMO_DBQUERY
для иллюстрации функций DbApi для работы с СУБД.
Теперь пример может выполнять полный набор операций с данными:
просмотр, редактирование, добавление и удаление записей (строк таблиц);
выполнение SQL запросов; чтение списка доступных таблиц; выбор файла БД.
Для ДЕМО вполне достаточно.
В библиотечный модуль DbLibrary
добавлен ряд новых функций для работы с СУБД.
Это ряд служебных функций, облегчающих прикладное программирование,
а также функции для создания новых БД, чтения списка таблиц, и т.д.
Читайте документацию по
DbLibrary.
delims:=ParamStr('[:punct:]')+ParamStr('[:space:]'); // Разделители - знаки пунктуации и пробелы
word:=ExtractWordDelims(1,Buffer,delims); // Извлекаем слова только из букв и цифр
Наборы символов кореллируют с функцией
IsLexeme,
которая умеет распознавать различные группы символов.
Например IsLexeme(s,lex_alnum); соответстует набору [:alnum:].
Обновлена демо конфигурация DEMO_TESTBENCH.
Там добавлен @Test 16 для проверки работы функций DbApi для recordset.
Использование функций db_recordset, db_addnew, db_update позволяет выполнять
запись в СУБД без явного SQL запроса, передавая данные в двоичном виде,
т.е. без преобразования данных в текст SQL запроса.
Это наиболее быстрый (без накладных расходов на интерпретацию SQL запроса)
и точный (без ошибок округления при переводе в текст) способ добавления/изменения
данных, который рекомендуется к использованию для задач, требующих высокой
производительности и максимальной точности.
На этом работу над DbApi и DbLibrary можно считать (предварительно) завершенной.
Если не будет найдено явных ошибок, на этом Api мы будем работать еще долго.
Введено еще два правила для анализа лексем:
lex_SqlName,
lex_FbdName.
Это правила именования (идентификаторов) для SQL (по стандарту)
и для Firebird и ряда других популярных СУБД
(это расширение стандарта - допускается символ $ в именах).
Надо заметить, что правила именования в разных СУБД отличаются,
например, в PostgreSQL имена могут начинаться с подчеркивания (_),
а по стандарту (и в большинстве других СУБД) - нет.
Введено еще три правила для анализа лексем:
lex_Section,
lex_AtCall,
lex_AtCmnd.
Правило lex_Section служит для обнаружения [заголовков секций].
Правило lex_AtCall служит для быстрого определения @команд в потоке обработки данных.
Правило lex_AtCmnd служит для более точного определения @команд при подготовке к обработке.
На панель инструментов добавлено еще несколько кнопок, изменен их порядок и группирование.
Это сделано для удобства разработчиков.
Обновлен DatabaseBrowser, добавлены шпаргалки по SQL и внесены мелкие правки в связи с тем,
что таблицы и поля могут иметь имена в кавычках, например, "EGP.DATA.TABLE".
Такие имена можно использовать для таблиц и полей, которые не попадают под
правила простых имен SQL - см. lex_SqlName.
В текстовом редакторе добавлена команда Reopen (ПереОткрыть файл).
Эта команда считывает заново редактируемый текст из файла.
Команда используется с ситуации, когда текст был отредактирован
в другом редакторе и надо загрузить новую версию текста из файла.
В текстовом редакторе добавлен монитор, который автоматически отслеживает
актуальность текста в текстовом редакторе по метке времени и размеру файла.
Этот монитор включается/отключается параметром системной конфигурации
Crw32.ini [System] Timer_MonitorTextEditor.
Небольшая доработка (устранение мелких недочётов) ДЕМО системы управления
SCE_BACC_BSTR
вакуумной системой бустера на базе Конечных Автоматов проведена Н.Гуриным.
Обновлен модуль StdTimes.
В него добавлены функции преобразования единиц времени:
MsToDaqTime(ms),
DaqTimeToMs(tm).
Это функции перевода единиц времени основных функций времени
time и msecnow.
Перевод между этими единицами несложен и делался обычно напрямую,
через формулу:
msecnow=TimeBase+(Time*TimeUnits).
Однако лучше использовать явные функции преобразования,
чтобы исключить возможные ошибки при воспроизведении формул.
Теперь такие функции есть.
Обычно время в кривых хранится в единицах time, а в алгоритмах
управления чаще используется msecnow.
Новые функции преобразования времени помогут переводить время
в нужные для расчетов единицы.
Сделана массовая замена (изменения коснулись 218 файлов) в шаблоне программ DaqPascal.
Причина в том, что последовательность символов <== оказалась "токсичной"
для Notepad++, который воспринимает их как начало комментария HTML
(хотя это не соответствует определению - комментарий HTML начинается с <!==).
Это создавало определенные проблемы - ломалось форматирование при редактировании Markdown,
в которые включался шаблон.
По иронии судьбы, изменения коснулись строки:
{$I _std_main}{<== Please never change this code ***}
заменился на
{$I _std_main}{*** Please never change this code ***}
Поскольку изменения проходили автоматоматическим алгоритмом (утилита TextReplacer),
причем большим блоком текста, исключающим случайности,
то я не ожидаю от замены каких-то проблем.
Однако, учитывая большое число затронутых файлов,
надо быть готовым к любым неожиданностям.
В стандартной библиотеке StdLib:
Функция IsSectionName(s)
реализована через IsLexeme(s,lex_Section).
В шаблоне template.pas
стандартной библиотеки StdLib и в шаблоне утилиты DaqCreator
добавлена техника Cleanup
(там где это уместно).
Эта техника (использовавшаяся ранее в ряде прикладных программ) была объявлена в предыдущем релизе,
а теперь закреплена и описана в документации DaqPascal.
Используйте её для повышения надежности прикладного кода.
В окне редактирования программ DaqPascal сделана кнопка вызова консоли устройства.
При разработке это удобно, т.к. консоль часто нужна для просмотра отладочных сообщений.
Теперь консоль устройства всегда будет под рукой.
В пакет добавлен сервер
&FdbSrv
для сохранения данных в формате СУБД типа Firebird.
Имеется описание.
В стандартной библиотеке StdLib добавлена поддержка &FdbSrv:
константа FdbSrv с именем &FdbSrv,
переменная devFdbSrv со ссылкой на сервер.
Обновлена тестовая система DEMO_DIM_PING.
В ней сделано сохранение данных (списка кривых) с помощью сервера &FdbSrv.
Это пример использования сервера &FdbSrv в прикладных системах.
Главными достижениями данного выпуска являются:
обновление библиотеки DbApi;
обновление функции GetStringVar;
доработка средств защиты (Guard) и системного меню;
добавление функций библиотеки DbLibrary для работы с СУБД;
доработка демо конфигурации DEMO_SCE\SCE_BACC_BSTR для иллюстрации Конечных Автоматов.
В этом выпуске проведена доработка библиотек DbApi, DbLibrary и средств поддержки СУБД.
Доведена до рабочего состояния демо конфигурация DEMO_SCE\SCE_BACC_BSTR для иллюстрации Конечных Автоматов.
Также доработана служба защиты (уровни доступа) и системное меню - они сделаны настраиваемыми.
В библиотеке DbApi доработаны функции
db_ctrl,
db_recordset,
добавилось свойство Source (это SQL команда для чтения записей).
Изменения потребовались для поддержки обновления данных через метод db_update
объекта recordset (без явного SQL запроса).
В стандартной библиотеке доработана функция
GetStringVar(Text,Name,Value).
Прежняя версия читала ВСЕ выражения "Name=Value" в тексте (Text), так что (в случае наличия дубликатов)
принималось ПОСЛЕДНЕЕ из них. Это противоречило поведению других функций (например, чтения конфигурации).
Обычно принимается ПЕРВОЕ найденое выражение, подходящее по условиям поиска (это к тому же быстрее).
Теперь функция переработана и оптимизирована и должна работать быстрее и правильнее.
Доработка функции была нужна для корректной работы библиотеки DbLibrary.
В практику прикладного программирования рекомендуется ввести технику Cleanup, описанную ниже.
Мотивация - дисциплинировать разработчиков в плане корректной работы с ресурсами (строками, объектами) в модулях (процедурах и функциях).
Идея состоит в том, чтобы выделить очистку всех локальных ресурсов в отдельную локальную процедуру Cleanup.
Это облегчит проверку очистки и её самосогласованность (т.к. очистка делается в двух местах - при входе и выходе из процедуры/функции).
В шаблоны редактора DaqPascal
добавлены
процедуры и
функции,
содержащие подпрограммы очистки Cleanup для корректной работы
со строками и другими ресурсами.
Например:
{
Return string with reverse chars order.
}
function ReverseStr(arg:String):String;
var s:String; i:Integer;
procedure Cleanup;
begin
s:=''; // Здесь делаем очистку всех локальных строк.
end;
begin
Cleanup;
for i:=Length(arg) downto 1 do s:=s+arg[i];
ReverseStr:=s;
Cleanup;
end;
Использование процедуры Cleanup с очисткой строк и (возможно) других переменных
гарантирует корректную работу менеджера строк, облегчает программирование
(т.к. очистка переменных теперь делается в одном месте, а не в двух).
Имя процедуры очистки (Cleanup) можно считать стандартным (рекомендуемым).
Поскольку это локальная процедура, она может использоваться без ограничений
в любом числе процедур и функций.
Для корректной работы со строками теперь достаточно двух простых правил:
вызывать локульную очистку Cleanup в начале и в конце процедуры/функции, и
в процедуре Cleanup инициализировать пустой строкой все строки, объявленные локально в процедуре/функции.
Процедуру очистки Cleanup рекомендуется размещать сразу после объявления локальных переменных,
чтобы было легко увидеть, какие именно переменные очищаются.
Очистку рекомендуется делать компактно, в порядке объявления переменных, чтобы легче было проверить полноту их списка.
Размещение каждого оператора в отдельной строке в данном случае неуместно, т.к. лишь затрудняет чтение.
Например:
procedure Something(...);
var a,b,c,d,e,f:String;
procedure Cleanup;
begin
a:=''; b:=''; c:=''; d:=''; e:=''; f:='';
end;
...
begin
Cleanup;
... Do Something ...
Cleanup;
end;
В более сложных случаях, например, при наличии локальных объектов
(регулярных выражений, текстов, задач и т.д.),
которые надо инициализировать в начале и освобождать в конце,
можно исспользовать расширенную модификацию техники Cleanup,
включающую параметр (how) для различения способа
очистки - инициализация (how<>0) или завершение (how=0).
Например:
{
Return string with reverse lines order.
}
function ReverseLines(arg:String):String;
var s:String; lines,i:Integer;
procedure Cleanup(how:Integer);
begin
s:=''; // Здесь делаем очистку всех локальных строк.
if (how<>0) then lines:=text_new else FreeAndZero(lines); // Инициализируем/освобождаем локальные объекты.
end;
begin
Cleanup(1);
iNul(StringToText(lines,arg));
for i:=text_numln(arg)-1 downto 0 do s:=s+text_getln(lines,i)+LineEnding;
ReverseLines:=s;
Cleanup(0);
end;
Использование Cleanup является универсальной (применимой всегда) техникой программирования,
которая дисциплинирует и делает программы надежнее, а потому рекомендуется к использованию во всех
прикладных программах.
В библиотечный модуль DbLibrary
добавлен ряд новых функций для работы с СУБД.
Это, например, функции для организации чтения списка всех таблиц (на основе библиотеки шаблонов).
Читайте документацию.
Проведена доработка средств Защитника Guard, который теперь сделан конфигурируемым.
Теперь для каждого защищаемого действия в секции
Crw32.ini [Guard.Permissions]
прописан уровень доступа (Lock, Guest, User, Root),
нужный для выполнения этого действия.
Например:
[Guard.Permissions]
TFormCircuitWindow.ClickSensor require Guest ; разрешения по умолчанию для нажатия сенсоров
TProgramDevice.ConsoleInput require Root ; разрешения для консоли прикладной программы
... и так далее ...
Для сенсоров введен параметр
GuardLevel,
который задает персональный уровень доступа Защитника для данного сенсора.
Если этот параметр не заадан, для сенсора используется значение по умолчанию,
заданное в TFormCircuitWindow.ClickSensor.
Для проверки работы этого свойства в конфигурации
DEMO_DIM_PING
защищена кнопка "Инструменты" на панели инструментов главной мнемосхемы.
Эта кнопка теперь нажимается только на уровне Root.
Остальные сенсоры имеют уровень по умолчанию Guest.
Хотя Защитник используется довольно редко, он является необходимой частью системы.
Его доработка давно стояла в очереди на выполнение.
Теперь он должен функционировать как положено.
Проведена доработка системного меню пакета, которое теперь сделано конфигурируемым.
Теперь для каждого пункта меню в секции
Crw32.ini [System.Menu.ShortCut.Table]
прописана горячая клавиша (ShortCut) или 0, если не она задана.
Теперь горячие клавиши меню можно менять, не меняя программного кода пакета.
Николай Гурин серьезно доработал ДЕМО систему управления
SCE_BACC_BSTR
вакуумной системой бустера на базе Конечных Автоматов, доведя её до рабочего состояния.
Это модельная система, т.е. (абстрактная) симуляция некоторой гипотетической
вакуумной системы, для иллюстрации управления с помощью Конечных Автоматов.
Модельная система служит для отладки библиотек, демонстрации работы Конечных Автоматов,
а также в качестве прототипа для создания будущих систем управления такого вида.
А сейчас это готовое учебное пособие для ознакомления с технологией построения
распределенных модульных систем управления на принципе Конечных Автоматов.
Этот пример будет дорабатываться в следующих версиях пакета.
Можно констатировать успешное завершение
первого этапа разработки средств поддержки Конечных Автоматов.
На втором этапе будет идти доработка и "причесывание" этих средств,
чтобы сделать технологию Конечных Автоматов более удобной, пригодной
для работы прикладных программистов средней квалификации.
Третьим этапом будет внедрение, т.е. широкое применение технологии
Конечных Автоматов для создания прикладных систем управления.
Алексей Жирунов обновил (доработал) DEMO конфигурацию
DEMO_DBQUERY
для иллюстрации функций DbApi для работы с СУБД.
Теперь ДЕМО умеет не только отображать, но и редактировать таблицы:
менять записи или добавлять новые записи.
Пока что это сделано простейшим методом (через SQL запросы).
В будущем (возможно) будет вариант с записью в таблицы через
Recordset (это более быстрый метод обмена данными).
Так или иначе, библиотека DbApi для работы с СУБД
функционирует и пригодна для применения в прикладных задачах.
Можно констатировать успешное завершение
первого этапа разработки средств поддержки Баз Данных.
На втором этапе будет идти доработка и "причесывание" этих средств,
чтобы сделать библиотеку DbApi/DbLibrary более удобной, пригодной
для работы прикладных программистов средней квалификации.
Третьим этапом будет внедрение, т.е. широкое применение Баз Данных
с библиотекой DbApi/DbLibrary для создания прикладных систем управления.
Главными достижениями данного выпуска являются:
доработка средств поддержки языка разметки документов Markdown;
документация по Markdown;
сервисная процедура FreeAndZero;
добавление функций библиотеки DbLibrary для работы с СУБД;
добавление функции poseol;
обновление функций task_readln, pipe_readln, com_readln.
Этот выпуск посвящен доработке средств поддержки формата Markdown и документации к нему.
Также продолжена работа по поддержке СУБД - обновлена библиотека DbLibrary.
Кроме того, добавлены/обновлены важные функции (poseol, task_readln, pipe_readln,
com_readln), связанные с обработкой строк. Необходимость доработки этих функций связана с тем,
что в гибридных системах (Windows, Linux, контроллеры) маркеры конца строки (EOL)
могут отличаться от CRLF и их требуется корректно обрабатывать.
Доработано браузерное дополнение (addon) MarkdownViewer.
Это дополнение работает в Windows/Linux и Firefox/Chrome и позволяет отображать
файлы Markdown. Дополнение небольшое (300кб) и универсальное, поэтому его было решено включить в
основной пакет runtime (а также commander). Инсталляция делается вручную (т.к. браузер
все равно запрашивает подтверждение на установку).
Собрана документация по языку Markdown и создан файл описания
daqgroup_markdown_manual
для ознакомления с языком Markdown и с особенностями его версии для DaqGroup,
который должен прочитать каждый разработчик DaqGroup.
В пакете предприняты меры поддержки формата Markdown (чтобы справки правильно открывались и т.д.).
Отныне формат Markdown может считаться одним из основных форматов технической документации пакета.
Разработчикам рекомендуется использовать Markdown для создания справочных файлов в новых системах,
а также разной сопроводительной документации (журналы, протоколы, рабочие записи).
Формат Markdown прост и хорошо приспособлен для этого.
В стандартную библиотеку добавлена сервисная процедура
FreeAndZero(ref)
для удаления и обнуления ссылки динамического объекта любого типа, поддерживаемого в DaqPascal,
см. RefInfo(ref,'Type').
Особенно внимательно изучите
дисциплину
работы со ссылками. Это позволит создавать более надежные программы.
В библиотечный модуль DbLibrary
добавлен ряд новых функций для анализа данных СУБД (функции проверки и сопоставления типов данных, преобразования даты/времени).
Также создана группа функций для составления строк подключения (ConnectionString) на основе библиотеки шаблонов.
Читайте документацию.
В диалоге Инструменты\Браузер Баз Данных на закладке Account сделан генератор кодированных паролей для баз данных.
Эти пароли согласованы с функцией db_build_connectionstring и служат для того, чтобы можно было заносить в коды программ
или конфигурационные файлы пароли для доступа к базам данных, но которые нельзя просто так узнать. Закодированные пароли имеют
смысл только для вызова db_build_connectionstring, которая умеет их декодировать. Кодирование паролей делается одним из
8 методов (Blowfish,GOST,RC2,RC4,RC5,RC6,BASE64,HEX). Два из последних метода слабо защищены (легко декодируются),
остальные дают достаточную защиту (рекомендуемый метод RC6, mode=6). Используется это как-то так:
pwd:='2aKRkiKfZr67'; // Password encrypted with mode 6
cs:=db_build_connectionstring('Firebird','localhost','employee.fdb','SYSDBA',pwd,'dialect=3;pagesize=1024;',6);
Функция db_build_connectionstring задумана в качестве основной функции для генерации строк подключения.
Она основана на библиотеке шаблонов строк подключений, которая хранится в системном INI файле.
При вызове функция ищет в списке шаблонов строку по заданным ключевым словам, а затем заменяет в ней
переменные параметры подключения (имя сервера, имя базы данных, имя пользователя, пароль), а также
добавляет необязательный список дополнительных опций. Пароль может быдь закодирован,
режим кодирования (mode) указывается при вызове.
В компиляторе DaqPascal снято ограничение
на длину строковых литералов (строковых констант), которая была равна 132 символам.
Теперь ограничение поднято до 240 символов (т.е. до максимальной длины строки).
В функции WordDelims сделана возможность сброса
набора символов - разделителей слов в исходное состояние [\t\r\n ,;=] вызовом s:=WordDelims(Dump(0));.
Кроме того, в процедуре старта программ DaqPascal также сделан сброс WordDelims в исходное состояние.
Это защитит программу от сбоев при ошибках, связанных с неверным заданием символов-разделителей, если нарушается
логика работы worddelims (напомним - при каждой операции с символами разделителей слов надо обязательно
в начале сохранять, а в конце восстанавливать стандартные символы разделителей).
Добавлена функция PosEol для анализа строк в гибридной
сетевой среде, где могут встречаться разные маркеры конца строки (EOL, end of line).
Её рекомендуется использовать вместо Pos(CRLF,data) при анализе потоков данных (в драйверах),
т.к. в сетевом потоке могут присутствовать данные с другими разделителями (маркерами конца строки).
Например, в Linux используется LF, а в контроллерах - часто используется CR.
Ориентация только на CRLF в сетевой среде ненадежна.
Обновлена демо конфигурация DEMO_TESTBENCH.
Там сделана документация (help) полностью на Markdown, а также добавлены новые примеры работы с БД.
Кроме того, там сделан @Test 15 для проверки работы функции PosEol.
В библиотечных функциях
Task_Readln,
Pipe_Readln,
Com_Readln
анализ буфера теперь сделан на PosEol.
Коды функций значительно упростились и (вероятно) ускорились, т.к. в прикладном коде теперь
не надо делать довольно сложный анализ маркеров CR,LF.
Эти сложности теперь скрыты за вызовами PosEol.
Будем надеяться, что при этом ничего не поломалось.
На всякий случай старые версии модулей сохранены в каталоге
obsolete.
Главными достижениями данного выпуска являются:
средства поддержки языка разметки документов Markdown;
доработка потоковой модели и процедуры завершения программ DaqPascal;
доработка модуля StdTimes - добавление функций преобразования единиц времени;
инструмент Database Browser для работы с СУБД;
доработка функций DbApi и библиотеки DbLibrary для работы с СУБД.
Этот выпуск посвящен доработке функций DbApi и библиотек (DbLibrary, SmiProxy, StdTimes),
а также языку разметки документов Markdown.
Кроме того, выполнена доработка потоковой модели опроса (Polling)
и связанной с этим процедуры остановки программ DaqPascal.
Поправлены ошибки обнаруженные в справочном файле по теме DbApi.
В сборку пакета добавлена поддержка языка разметки документов Markdown.
Этот язык ставит целью облегчение создания технической документации.
Он прост, компактен и удобен.
В будущем, вероятно, значительная часть документации будет делаться в Markdown.
Язык разметки Markdown гораздо проще HTML,
но позволяет получать хорошо отформатированные тексты, удобные для чтения.
При этом важно, что текст на Markdown выглядит читабельно при редактировании в обычном текстовом редакторе,
поэтому хорошо подходит для "полевых" условий, когда могут быть недоступны специальные средства просмотра Markdown.
В крайнем случае документ можно прочитать как простой текст.
По договоренности, файлы Markdown могут иметь расширения:
.md (как основное), .mkd, .mkdn,
.mdwn, .mdown.markdown (как дополнительные).
Кодировка символов не регламентируется, но (на будущее) рекомендуется
сохранять Markdown файлы в кодировке UTF-8-BOM.
Поддержка Markdown сделана комплексно:
Команда unix MarkdownViewer filename.md "на лету" конвертирует
файл Markdown во временный файл HTML и отображает его в Firefox.
Команда доступна в Главной Консоли пакета, а также в панели инструментов Commander
- кнопка .
Внутри себя команда MarkdownViewer использует команды конвертеров
pandoc.exe или markdown.pl.
Команду MarkdownViewer можно использовать, например, для вызова справки
в формате Markdown по кнопке из DAQ-системы.
В редакторе Notepad++ добавлено два расширения MarkdownViewer++ и NppMarkdownPanel
для отображения и редактирования Markdown файлов.
Для браузера Firefox подготовлено три дополения (в формате .xpi) и инсталлятор,
который можно вызвать из панели инструментов Commander (раздел Multimedia).
Во всех перечисленных инструментах в меру возможностей сделан единый (по крайней мере похожий)
стиль оформления, напоминающий стиль этого справочного файла.
Собрана документация по Markdown - в формате Markdown.
Её достаточно, чтобы овладеть техникой создания документации в формате Markdown.
В планах на будущее - постепенный перевод технической документации на Markdown.
По крайней мере, новую документацию теперь можно создавать на Markdown.
Добавлены DEMO для DAQ-системы от Э.Братишки:
DEMO_APC,
DEMO_IPPON,
DEMO_BIRGER
с драйверами соответсвующих устройств. Сделано красиво, хорошая работа.
Как было обещано в прошлом релизе, доработана потоковая модель процедуры остановки (Stop) для программ DaqPascal.
В предыдущей версии программы DaqPascal стартовали и опрашивались в своем собственном программном потоке (что логично),
но завершались в основном потоке (что вообще-то нелогично). Это было сделано для экономии времени разработки.
Такое поведение (ранее) было безразлично для прикладных систем, однако (теперь) для программ, (неявно) использующих
COM-объекты (например, регулярные выражения на движке VBScript.RegExp или базы данных на движке ADO),
это создает потенциальные проблемы, т.к. COM-объекты обычно привязаны к потоку
(потоковая модель COM STA, single-threaded apartment).
Если COM-объекты создаются в одном потоке, использовать и завершать их надо в том же потоке.
В новой версии пакета процедуры остановки (Stop) для программ DaqPascal выполняются в собственном программном потоке,
в котором происходили старт и цикл опросов.
Для синхронизации потоков применяется комбинация временного запрета потоков и переменных-флагов, сигнализирующих о старте/завершении.
Процедура должна работать корректно, но все же надо внимательно понаблюдать, не сломалось ли что-нибудь.
Для контроля потоковой дисциплины также введен счетчик (TProgramDevice.PollingViolationCounter),
который фиксирует факты нарушения потоковой модели (т.е. вызова программ в неверном потоке).
Теперь все (потоковые) ограничения на использование объектов DbApi сняты. Библиотека должна работать корректно.
В предыдущей версии пакета найдена серьезная ошибка (TPolling.Execute), которая может проявляться в снижении производительности
при большом числе потоков (программ DaqPascal) и нестабильной работе объектов COM.
Суть ошибки в том, что стандартная пара вызовов CoInialize/Couninitialize делалась не в начале/конце потока (как нужно),
а в каждом цикле опроса (что избыточно и вообще неверно).
Ошибка внесена по невнимательности при адаптации потоков TPolling к объектам COM.
Использования этой версии (20221106) следует избегать.
Доработан цикл опроса потоков (TPolling) для удовлетворения требований потоковой модели COM STA.
Исправлена ошибка, описанная выше.
Также в потоки опроса (TPolling) добавлены циклы обработки сообщений (в литературе их называют message pump)
по типу while PeekMessage(m,0,0,0,PM_REMOVE) do DispatchMessage(m).
Обработка очереди сообщений - требование модели COM STA, который её (возможно) использует.
Если очередь сообщений не используется, цикл просто ничего не делает.
Накладные расходы при этом вроде бы невелики (незаметны).
Тем не менее использование обработки сообщений в потоках опроса (TPolling) сделано опциональным, т.к. оно нужно далеко не всегда.
Параметр Crw32.ini [System] TPolling.DefMsgPump задает значение по умолчанию для глобального флага использования
цикла сообщений в потоках опроса (сейчас - 0, т.е. отключено, как и было ранее).
При необходимости цикл опроса конкретного потока (программы) читается или задается через вызов
ParamStr('Polling.UseMsgPump'):
sNul(ParamStr('Polling.UseMsgPump 1')); // Поток опроса теперь использует очередь сообщений
writeln('UseMsgPump='+ParamStr('Polling.UseMsgPump')); // Узнать использует ли программа очередь сообщений
Использование очереди сообщений надо включать (при старте программы DaqPascal), если в ней используются COM объекты,
например, объекты ADO при использовании функций DbApi доступа к СУБД.
sNul(ParamStr('Polling.Delay 50')); // Теперь период опроса 50 ms
writeln('Period='+ParamStr('Polling.Delay')); // Узнать период опроса потока
sNul(ParamStr('Polling.Priority tpHighest')); // Теперь приоритет tpHighest
writeln('Priority='+ParamStr('Polling.Priority')); // Узнать приоритет потока
writeln('ThreadId='+ParamStr('Polling.ThreadId')); // Узнать идентификатор потока
Теперь фактически можно управлять потоками опроса программ DaqPascal динамически,
в том числе через сообщения типа DevPostCmd(dev,'@ParamStr Polling.Priority tpTimeCritical').
Однако злоупотреблять этим, конечно, не стоит.
В стандартный модуль DbLibrary включено задание Polling.UseMsgPump 1 при старте.
Это значит, что модуль сам настраивает потоковую модель опроса (включая очередь сообщений),
нужную для использования COM объектов, так что прикладному программисту не надо об этом заботиться.
Работаете с СУБД - включаете стандартный модуль DbLibrary - получаете всё что надо.
В стандартный модуль StdLib включена печать параметров потока опроса Polling при старте.
Это полезно прикладному программисту для напоминания об используемых параметрах опроса потоков.
Значение "по умолчанию" для максимальной длины строк (Compiler.slenmax) в DaqPascal увеличено до 8 MB.
Это сделано на случай больших текстов при создании SQL запросов в DbApi.
Обновлен модуль
SmiProxy:
изменено поведение процедур smi_set_state, smi_terminate_action и smi_move_to.
// Сохранение текущего состояния:
smi_set_state(''); // эквивалентно smi_set_state(smi_proxy_state_name)
smi_terminate_action(''); // эквивалентно smi_terminate_action(smi_proxy_state_name)
smi_move_to(''); // эквивалентно smi_terminate_action(smi_proxy_state_name)
// Задание ошибочного состояния, которого нет в списке состояний прокси-объекта:
smi_set_state('BAD STATE'); // генерирует ошибку и вызывает smi_set_state(smi_proxy_state_name)
smi_terminate_action('BAD STATE'); // генерирует ошибку и вызывает smi_terminate_action(smi_proxy_state_name)
smi_move_to('BAD STATE'); // генерирует ошибку и вызывает smi_terminate_action(smi_proxy_state_name)
Это изменение связно с тем, что при попытке задать неизвестное состояние FSM переходится в состояние
&UNDEFINED_STATE и застревает в нем (до перезапуска FSM).
Поэтому сделана проверка наличия состояния, в которое хотим переходить.
Это предохраняет прикладного программиста хотя бы от грубых ошибок.
Если новое состояние неверно, сохраняется текущее состояние.
Это логично.
Необходимость функций времени связана, в первую очередь, с DbApi, где время может задаваться в различных форматах.
Добавлена DEMO конфигурация для DAQ-системы от А.Жирунова:
DEMO_EM2RS,
с драйвером шагового двигателя.
Обновлены Origami, Kirigami с мелкими правками от А.Жирунова.
В DaqPascal добавлены константы типа тегов:
tag_type_nil,
tag_type_int,
tag_type_real,
tag_type_string.
Это давно было пора сделать для улучшения читабельности прикладных программ. Теперь это доступно.
В новых программах рекомендуется использовать:
вместо if typetag(tag)=0 ... ==> if typetag(tag)=tag_type_nil ...
вместо if typetag(tag)=1 ... ==> if typetag(tag)=tag_type_int ...
вместо if typetag(tag)=2 ... ==> if typetag(tag)=tag_type_real ...
вместо if typetag(tag)=3 ... ==> if typetag(tag)=tag_type_string ...
Использование численных констант по-прежнему возможно (кто привык),
но для читабельности кода символьные константы предпочтительнее (особенно новичкам).
В библиотечный модуль DbLibrary
добавлен ряд новых функций для анализа данных СУБД. Читайте документацию.
При старте DAQ системы добавлен вывод в консоль информации об ошибках и проблемах загрузки,
чтобы сразу были видны значения счетчиков ошибок.
При выполнении команды @help в консоли устройства DaqPascal теперь,
кроме печати справки в консоли этого устройства, проверяется наличие одноименных с исходным .pas файлом
справочных файлов (.htm или .md; у файла .htm - приоритет).
Если такие файлы найдены, то они открываются в браузере.
Это позволяет делать справочные файлы в формате HTML или Markdown.
А вот печать в Главную консоль теперь (по умолчанию) отключена.
Режим печати справки устройства в Главной Консоли можно включить/выключить вызовом @help echo 1/0.
Также можно включить/отключить режим вывода справки в браузере командой @help browse 1/0.
Новое свойство команды @help позволяет быстро создавать компактную и качественную справку
по программам в виде файлов .md. на языке Markdown.
Пример приведен в конфигурации DEMO_TESTBENCH.
Язык Markdown очень удобен для создания справок по программам в силу своей простоты и компактности.
Теперь для каждого программного файла .pas можно (и рекомендуется) заводить его описание в формате Markdown
в одноименном файле .md, и оно будет вызываться по команде @help. Это удобно для разработчиков.
Например, при разработке драйверов в файле .md можно хранить описание этого драйвера.
В разделе Crw32.ini [DaqSys.DeviceConsole.FavoriteCommands] заведен список наиболее популярных команд,
часто используемых в консоли устройств. Этот список теперь загружается в "историю ввода" консоли устройств,
который связан с "выпадающим списком" в поле "Input" консольного окна каждого программного устройства.
Так что теперь при загрузке системы часто используемые команды будут под рукой.
В разделе меню Link\Home\Install добавлен инсталлятор дополнений Firefox для поддержки Markdown.
Это "довесок" 1.5МВ к основному дистрибутиву, но зато всегда будет под рукой.
Добавлена DEMO конфигурация DEMO_DBQUERY
для иллюстрации функций DbApi для работы с СУБД.
Пока эта конфигурация работает только с SQLite и имеет ограниченный набор возможностей.
В будущем пример будет, возможно, доработан.
И кстати, справочный файл для DEMO_DBQUERY
создан в формате Markdown. Такая справка весьма компактна и создается очень быстро.
В сборке движков engines теперь есть DieselPascal, Tcl/Tk, Python, Perl, NodeJs, Ruby.
У нас активно используются DieselPascal (для утилит пакета) и Tcl/Tk (используется в SMI).
Язык Perl добавлен потому что на нем написан классический интерпретатор (Markdown.pl).
Остальные движки собраны "на всякий случай", в связи с их высокой популярностью.
Это позволяет создавать и выполнять скрипты на любом из этих языков.
В разделе меню Инструменты добавлен Браузер Баз Данных для поддержки СУБД.
Этот браузер сделан на базе функций DbApi, поэтому всё что работает там, будет работать и в DaqPascal.
Браузер позволяет формировать строки запроса, подключаться к СУБД, выполнять SQL запросы к СУБД,
считывать данные из СУБД в таблицы. Это незаменимый инструмент работы с СУБД, позволяющий быстро
проверить доступность серверов СУБД, проверить работу SQL команд и т.д.
В секции описания устройств добавлен параметр FavoriteCommands, в котором указывается имя секции, в которой находится
список "любимых команд" для данного устройства.
Этот список команд будет появляться в выпадающем списке Input консоли данного устройства.
Пример есть в конфигурации DEMO_TESTBENCH.
[&testbench]
FavoriteCommands = [&testbench.FavoriteCommands]
[]
[&testbench.FavoriteCommands]
@Help
@DebugFlags 3
@DebugFlags 15
@Test 0
@Test 1
... и так далее ...
[]
Если список любимых команд не нужен, вместо секции можно поставить прочерк (-).
Если список любимых команд не указан, используется список "по умолчанию" из системной конфигурации.
Главными достижениями данного выпуска являются:
добавление большой библиотеки функций DbApi для работы с СУБД.
Этот выпуск посвящен добавлению библиотеки функций DbApi в компилятор DaqPascal,
позволяющий работать с Базами Данных (СУБД).
Добавлена группа (43) функций DbApi -
db_xxxx,
которая позволяет работать с Базами Данных (СУБД).
Библиотека построена на принципе движков (engines), т.е. предполагает единый
программный интерфейс, при возможности разных его реализаций.
В настоящее время реализован один движок на базе ADO.
Возможно, со временем появятся другие движки (с сохранением того же API).
Технология ADO (active data objects) базируется на COM объектах и предполагает
единый программный интерфейс для доступа ко всем СУБД, что предполагает наличие драйверов
(их называют провайдерами - provider), адаптирующих конкретную СУБД к интерфейсу ADO.
То есть это работает примерно так:
Для Interbase/Firebird есть свободно распространяемый в исходных кодах драйвер ODBC Driver for Firebird,
разработанный группой Phoenix.
Этот драйвер позволяет использовать встроенный в Windows провайдер MSDASQL для доступа
к СУБД Firebird. Этот драйвер входит в сборку install-daqgroup-database и устанавливается
автоматически, что сразу делает его доступным при инсталляции указанного пакета.
Также для Interbase/Firebird есть свободно распространяемый провайдер IBProvider,
идентифицируемый именем LCPI.IBProvider.5.Free.
Он входит в сборку install-daqgroup-database, но устанавливается вручную
(т.е. не устанавливается автоматически).
Для других СУБД также достаточно найти и установить драйверы ODBC или провайдеры,
чтобы сделать их доступными для работы с DbApi.
Есть также работающий
пример,
наглядно показывающий использование функций DbApi.
В функции ParamStr добавлен параметр OleDbProviderNames
со списком имен установленных провайдеров OLEDB/ADO.
Использование - ParamStr('OleDbProviderNames').
В функции ParamStr добавлена
группа параметров
идентификации процесса:
ParamStr('MainInstance') - идентификатор экземпляра приложения
ParamStr('MainThreadId') - идентификатор главного потока программы
ParamStr('CurrentThreadId') - идентификатор текущего потока программы
ParamStr('CurrentProcessId') - идентификатор текущего процесса - PID
ParamStr('ApplicationHandle') - идентификатор окна приложения (скрытого)
ParamStr('MainFormHandle') - инентификатор окна главной формы приложения
Эти идентификаторы могут пригодиться для самых разных целей,
в основном для организации связей с другими программами.
Добавлена команда Главной Консоли @list OleDbProviderNames
для просмотра установленных провайдеров ADO. Полезный инструмент для разработчиков.
В функции ParamStr добавлен параметр OdbcDriverNames
со списком имен установленных драйверов ODBC.
Использование - ParamStr('OdbcDriverNames').
Добавлена команда Главной Консоли @list OdbcDriverNames
для просмотра установленных драйверов ODBC. Полезный инструмент для разработчиков.
Небольшие изменения в классе TPolling (добавлена инициализация/завершение COM).
Это понадобилось для корректной работы библиотеки DbApi в многопоточном режиме.
Небольшие изменения в обработчике исключений и в реестре объектов (модуль _alloc.pas).
Для прикладных программистов это неважно, но для средств диагностики пакета - полезно.
Заведен библиотечный модуль DbLibrary.
Он (по замыслу) содержит функции, расширяющие возможности DbApi.
Пока там немного функций, но они будут добавляться по мере накопления опыта работы с БД.
В конфигурации DEMO_TESTBENCH
добавлены тесты (@Test 12, @Test 13)
для проверки и иллюстрации работы библиотеки DbApi.
Тест 12 считывает данные из демонстрационного файла СУБД Firebird (c:\Crw32exe\Demo\DEMO_DATA\employee.fdb).
Тест 13 считывает данные из демонстрационного файла СУБД SQlite (c:\Crw32exe\Demo\DEMO_DATA\toc.db).
Считывание производится с помощью связки провайдера MSDASQL и драйверов ODBC.
Провайдер MSDASQL - встроенный в дистрибутив Windows и не требует установки.
Драйверы ODBC устанавливаются по умолчанию при инсталляции пакета database.
Поэтому все должно работать без специальных настроек.
Несколько слов о реализации DbApi.
В силу особенностей технологии COM, объекты DbApi "привязаны" к одному потоку.
Это создает определенные проблемы, т.к. в текущей реализации пакета старт/стоп программ DaqPascal
(когда RunCount равен 1/INF) происходит в основном потоке, а не в потоке опроса программы.
По этой причине (пока) не получится создавать постоянные соединения (db_connection),
вызывая их инициализацию/завершение в процедурах InitApplication/FreeApplication.
То есть пока надо ориентироваться на синхронное соединение-чтение-закрытие,
когда запрос, получение ответа и освобождение объекта соединения делается
в одном вызове процедуры опроса.
Это, безусловно, не соответствует основному приципу пакета (асинхронный режим как основной режим работы),
но эта проблема будет решаться и со временем это ограничение, вероятно, отпадет.
Несколько слов о применении СУБД.
SQLite пригодна для хранения локальных настроек и параметров прикладных программ.
Для хранения данных её вряд ли стоит применять - данные будут недоступны по сети,
т.к. эта СУБД в принципе локальная.
Эта СУБД устанавливается по умолчанию при инсталляции пакета database,
так что должна быть доступна всегда (при условии, что IT не будут чинить препятствий
с установкой драйверов).
Firebird пригодна для хранения не только настроек, но и измеряемых данных.
При этом данные будут доступны по сети, т.к. эта СУБД клиент/серверная.
Эта СУБД у нас уже устанавливается по умолчанию при инсталляции пакета database,
она компактная и удобная в настройке, так что будем считать её основным вариантом на будущее.
В будущем планируется сделать сервер сохранения данных по типу &DatSrv,
чтобы данные записывались в файлы формата этой СУБД (можно вместе с DAT-файлами).
Другие СУБД в принципе могут быть подключены через провайдеры OLEDB/ADO
или драйверы ODBC через встроенный провайдер MSDASQL.
В частности, свободно доступны ODBC драйверы для
MySQL
и PosgreSQL.
Эти СУБД могут использоваться для связи с другими системами (например, Tango).
При необходимости эти драйверы будут включены в дистрибутив.
В первом приближении вопрос поддержки СУБД решен.
Требуется массированное тестирование.
Добровольцы, шаг вперед!
17.10.2022
MousePos case SmiProxy @view logo Logos ShowLogoDelay
DEMO_SCE\SCE_BACC_BSTR
Главными достижениями данного выпуска являются:
обновление библиотек SMI;
утилита MousePos для отображения координат мыши;
исправление оператора case;
добавление команды @view logo;
добавление параметра ShowLogoDelay;
демо конфигурация DEMO_SCE\SCE_BACC_BSTR для иллюстрации Конечных Автоматов.
В этом выпуске обновлены библиотеки SMI; добавлена утилита MousePos;
исправлен оператор case в компиляторе DaqPascal;
сделаны средства борьбы с мельканием окон при старте;
продолжена работа по Конечным Автоматам.
В меню Инструменты добавлена утилита MousePos.
Эта утилита отображает в окошке кооринаты мыши, а также размеры "выделения" (после щелчка левой кнопкой мыши).
Способ выделения (просто щелчек или с удержанием левой кнопки мыши) меняется двойным щелчком над окном MousePos.
Назначение утилиты MousePos - облегчение работы, связанной с разметкой и размещением графических элементов на экране.
Например, при создании мнемосхем или при конфигурировании размещения окон через @windraw.
Исправлен недочет в реализации оператора
case,
который заключался в генерации ошибки времени исполнения,
если ни одна из альтернатив case не подходит с проверяемым значением.
Это делало оператор case неудобным и небезопасным для программирования.
Теперь оператор case продолжает выполнение со следующего за ним оператора, если альтернативы выбора не найдены.
То есть теперь оператор case можно использовать безопасно, он больше не вызывает ошибок исполнения.
При использовании оператора case надо иметь в виду, что он (пока еще?)
не поддерживает диапазоны (типа 1..4 - их можно заменять перечислением 1,2,3,4),
а также не поддерживает альтернативу else (иногда её можно заменить предварительной инициализацией результата).
Кроме того, оператор case выполняется путем линейного поиска значений в таблице альтернатив
в порядке их определения в коде - до первого найденного значения.
Поэтому (с точки зрения производительности) при большом (более 10) числе альтернатив рекомендуется ставить наиболее частые (типичные)
альтернативы первыми - это несколько увеличит скорость работы оператора case.
Кроме исправления недочета было увеличено максимальное число допустимых альтератив (с 30 до 256).
В конфигурации DEMO_TESTBENCH
добавлен тест (@Test 11) для проверки и иллюстрации работы оператора case.
В Главной Консоли добавлена команда @view logo для отображения "заставки",
которая скрывает все дочерние окна внутри главного окна:
@view logo show "Подождите секунду..." - Показываем обычную заставку с надписью
@view logo show -daq "Подождите секунду..." - или показываем заставку для DAQ-системы
@view logo show -bmp Resource\Bitmap\daq_system_logo.bmp "Подождите минутку..." - или заставку с данной BMP
... - Делаем что-то с окнами
@view logo hide - Убираем заставку
Заставка призвана убрать мелькание окон при загрузке DAQ конфигурации.
Команды отображения/отмены заставки можно применять, например, в скриптах [&Cron.StartupScript]
для более приятной загрузки.
В силу особенностей работы цикла опроса (Главная Консоль начинает опрашивается после обработки очереди событий Windows),
для корректной работы заставки команду @view logo надо "встраивать" в задания Cron следующим образом.
Обычно в системе есть главная мнемосхема (например DEMO.MAIN.CTRL), для которой создается Cron-задание *.HOME
("расставить окна по домам", в данном случае - задание DEMO.MAIN.CTRL.HOME).
В этом задании с помощью @windraw ...|Fast|Eval=@system @view log show ... задается команда заставки,
которая выполняется в очереди обработки сообщений Windows.
В конце Cron-здания заставка убирается командой @eval @system @async @silent @view logo hide
[&CronSrv.StartupScript]
...
@cron.tab DEMO.MAIN.CTRL.HOME 0 0 0
@cron.job DEMO.MAIN.CTRL.HOME @WinDraw DEMO.MAIN.CTRL|Fast|Eval=@system @view logo show -daq "Подождите секунду..."
@cron.job DEMO.MAIN.CTRL.HOME ...
@cron.job DEMO.MAIN.CTRL.HOME ... здесь расположены обычные команды рисования ...
@cron.job DEMO.MAIN.CTRL.HOME ...
@cron.job DEMO.MAIN.CTRL.HOME @async @async @async @async @async @eval @system @async @silent @view logo hide
При использовании такой конструкции при каждом исполнении команды HOME будет показана заставка,
которая скроет за собой мелькание при прорисовке большого числа окон.
По завершении рисования заставка убирается.
Работа заставки теперь также иллюстрируется на примерах
DEMO_DOZA,
DEMO_UNIHEATER,
в которые добавлен соответствующий код,
см. файл doza_main_init.cfg
или файл duh_main_init.cfg.
Для устранения мелькания окон при загрузке и старте DAQ-системы в секции [DAQ] добавлен параметр
ShowLogoDelay, который задает время (в секундах) на отображение
заставки с сообщением о старте DAQ-системы. По умолчанию это ноль (т.е. заставка убирается сразу после старта системы).
Заставка закрывает собой экран, чтобы сделать невидимым раздражающее мелькание окон в первые секунды после старта DAQ-системы.
Отмена заставки происходит либо по истечении заданного времени, либо командой @view logo hide в Главной Консоли,
которую можно послать, например, из стартового сценария &CronSrv.StartupScript.
Для этого можно поместить в конце сценария команду
Это значит, что при использовании стандартной конфигурации ~~\Resource\DaqSite\Default\CronSrv.cfg
можно не заботиться об отображении и отмене заставки, чтобы скрыть мелькание окон при загрузке и старте системы.
Если длительности заставки по умолчанию (60 сек) не хватает,
её можно (пере)определить в основном конфигурационном файле DAQ-системы, где надо просто указать, например,
[DAQ] ShowLogoDelay = 90 для того, чтобы убрать мелькание окон при загрузке.
Таким образом, при использовании стандартной конфигурации ~~\Resource\DaqSite\Default\CronSrv.cfg
(которая уже давно входит практически во все прикладные системы)
автоматически должно исчезнуть мелькание окон при загрузке и старте системы.
Для устранения мелькания окон при выполнении команды HOME надо модифицировать
задание Cron как было описано выше.
Обновлен модуль
SmiProxy
и его документация.
Добавлены полезные функции (например, smi_proxy_state, smi_move_to).
В сборку шрифтов (install-daqgroup-fonts.exe) добавлены корпоративные шрифты:
от СберБанка - шрифты Sb Sans Text, Sb Sans Display, Sb Sans Interface;
от РЖД - шрифты RussianRail G Pro, FSRAILWAY;
от РосБанка - шрифт Rosbank SansTT;
от Тинькофф - шрифт Tinkoff Sans;
от РосАтома - шрифт Rosatom.
Эти шрифты входят в рекомендуемый и документально закрепленный фирменный стиль соответствующих корпораций.
Их можно применять для оформления программных интерфейсов или документов в стиле интересующей корпорации.
Напоминаем, что для пакета CRW-DAQ основным рекомендованным шрифтом является PT Mono,
а дополнительными - PT Sans и PT Sans Narrow.
Заведена папка
Resource\Logos
для хранения логотипов некоторых корпораций
(Росатом, Роскосмос и других).
Создана первая версия ДЕМО системы управления на базе Конечных Автоматов
DEMO_SCE.
Пока там незавершенная (частично работающая) версия вакуумной системы бустера
SCE_BACC_BSTR.
Это модельная система, т.е. (абстрактная) симуляция некоторой гипотетической
вакуумной системы, для иллюстрации управления с помощью Конечных Автоматов.
Модельная система нужна для отладки библиотек, демонстрации работы Конечных Автоматов,
а также в качестве прототипа для создания будущих систем управления такого вида.
Этот пример будет дорабатываться в следующих версиях пакета.
Пока это "затравка" на будущее.
Просьба к разработчикам: использовать в новых системах (и заменить в действующих) ссылки на стандартные
серверы в каталоге ~~\Resource\DaqSite\Default\, т.е. например:
Ссылка на Default конфигурации серверов позволит безболезненно менять свойства "по умолчанию"
для стандартных серверов, не затрагивая их основную конфигурацию (а лишь включая дополнительные файлы).
Так, например, в сервере &CronSrv в конфигурацию по умолчанию добавлена стартовая команда
отображения заставки при старте и отмены заставки после старта,
при этом основная конфигурация сервера не изменилась.
Такая замена произведена в ряде DEMO конфигураций основного пакета (runtime).
Устранен внутренний (довольно безобидный) баг, связанный с дисбалансом LockDraw/UnlockDraw.
Обновлена утилита SmiGenGui - добавлен отдельный фонт (PT Sans Narrow, 8pt) для имени домена,
т.к. домен может иметь довольно длинное имя.
04.10.2022
DaqPasEditor.cmd htonl htohl htons ntohs
Главными достижениями данного выпуска являются:
обновление библиотек SMI; добавление группы функций htonl;
добавление кнопки компиляции и вызова внешнего редактора программ DaqPascal в DAQ системе;
утилита DaqPasEditor.cmd для вызова внешнего редактора программ DaqPascal;
список функций во встроенном редакторе программ DaqPascal.
В этом выпуске обновлены библиотеки SMI; добавлена группа функций htonl;
добавлены функции компиляции и внешнего редактирования программ DaqPascal.
В ходе работ по конечным автоматам обновлены библиотеки SMI для прокси серверов.
Добавлены функции (например, smi_test_state), устранены мелкие ошибки.
В диалоге свойств программ DaqPascal добавлена кнопка компиляции.
Она будет полезна, например, для перезапуска программных устройств.
Либо для перекомпиляции при редактировании внешним редактором.
В диалоге свойств программ DaqPascal добавлена кнопка вызова внешнего редактора.
Это команда (для Главной Консоли), которая определена в параметре
Crw32.ini [DaqSys] OpenDaqPascalEditor,
которая вызывает командный файл
DaqPasEditor.cmd,
которому передается (в аргументах) имя редактируемого файла и имя устройства.
Командный файл вызывает внешний редактор (например, notepad++) для редактирования указанного файла.
Обратите внимание - одновременно открывать внешний и внутренний редактор не рекомендуется во избежание конфликтов.
Добавлена группа функций
htonl(hl),
ntohl(nl),
htons(hs),
ntohs(ns)
для подготовки данных при организации приемо-передачи в сети.
Эти функции переставляют порядок байтов в числах, чтобы обеспечить верную передачу потоковых данных
независимо от архитектуры процессоров.
В сети TCP/IP принят сетевой (net) порядок передачи чисел "от старшего значащего байта к младшему"
независимо от архитектуры приемо-передатчика.
На конкретном компьютере машинное (host) представление чисел может отличаться от сетевого.
Например, в архитектуре x86 порядок хранения чисел "от младшего байта к старшему".
Поэтому для передачи в сетевой поток числа надо приводить к сетевому представлению вызовом htonl,
а при приеме - приводить к машинному представлению вызовом ntohl.
Эти функции помогут правильно организовывать протоколы связи для обмена данными
при использовании каналов (pipe) и рекомендуются для использования при разработке драйверов устройств.
В конфигурации DEMO_TESTBENCH
добавлен тест (@Test 10) для проверки и иллюстрации работы функций htonl и ntohl.
По измерениям на типичном CPU:i7-4700MQ-2.4GHz время вызова функций htonl составляет
порядка 24 ns (т.е. 32 ns в цикле при 8 ns на пустой цикл).
Высокая скорость работы (по сравнению с перестановкой байтов "вручную") делает функции htonl
наиболее предпочтительными для использования в сетевых программах, реализующих протоколы связи.
В вычислитель выражений (eval, калькулятор, главная консоль) также добавлена группа функций
htonl, ntohl, htons, ntohs. Пригодится.
В редакторе кода программ DaqPascal добавлена кнопка f().
Эта команда открывает (справа) панель Функции со списком процедур и функций,
который позволяет быстро перемещаться по тексту программы по именам объявленных процедур и функций.
Это особенно полезно для больших программ с длинным текстом программного кода (например, драйверов).
Навигация по списку функций позволит значительно ускорить поиск нужного фрагмента кода
и тем самым повысить производительность труда прикладных программистов.
Регулярное выражение для поиска задается в параметре Crw32.ini [DaqSys] DaqPascalPatternFx,
по умолчанию это шаблон: /^\s*(procedure|function)\s+([_a-zA-Z][_a-zA-Z0-9]*)/img.
Список функций обновляется при
1) нажатии кнопки f() и
2) при сохранении изменений (т.е. при сбросе флага Modified).
Во время редактирования текста список функций не меняется, пока текст не будет сохранен.
24.09.2022
_WINE.PAS _VBOX.PAS detectwine() detectvbox()
Главными достижениями данного выпуска являются:
модули _WINE, _VBOX;
программа detectwine.exe;
функции detectwine(), detectvbox().
В этом выпуске добавлены утилиты для обнаружения виртуальных сред (WINE, VirtualBox).
Добавлены модули для обнаружения виртуальных сред исполнения:
_WINE.PAS - для среды WINE,
_VBOX.PAS - для среды VirtualBox.
Введение модулей связано с возрастающим значением виртуальных сред исполнения.
Эти утилиты сделаны для применения в командных файлах.
Средства обнаружения WINE и VirtualBox позволяяют определить факт их наличия.
Основной пакет успешно запускается и работает в этих средах, однако для полной адаптации к ним еще
предстоит выполнить большую работу (если возникнет необходимость), т.к. многие вспомогательные средства
там не работают или работают некорректно (в первую очередь это касается командных файлов и утилит).
Средства обнаружения помогут скорректировать эти вспомогательные средства.
Скорректированы правила проверки имен
lex_FsmName,
lex_SmiName
в полном соответствии с библиотекой SMI - для обеспечения полной совместимости.
До этого там работало несколько другое правило (были разрешены дополнительные символы,
которые недопустимы в SMI).
Оптимизирована служба "антизомби"
(модули dpAntiZombie.pas
и dpCrwDaqSys.pas
в библиотеке DieselPascal).
Эта служба автоматически завершает работу программы DieselPascal, если родительский процесс завершился
(чтобы не оставались висящие "зомби"-процессы, которые не могут корректно работать без родительского процесса).
Раньше проверка работы родительского процесса шла путем чтения списка процессов, что относительно трудоемко.
Теперь проверка работы родительского процесса идет путем проверки статуса процесса, что гораздо быстрее.
Это снижает загрузку системы при большом числе работающих утилит DieselPascal.
Главными достижениями данного выпуска являются:
переменные DimSite_Root, SmiSite_Root;
редактор блок-схем и диаграмм Mermaid;
программа smi_kill и утилита smi_control;
утилита DaqCrcMove.LM9;
обновление консольных утилит Crw32.Utils.lm9.
В этом выпуске добавлены/обновлены утилиты для прикладных разработчиков,
а также продлолжена разработка/отладка библиотек для Конечных Автоматов SMI++,
и сопутствующих им утилит.
Добавлена утилита DaqCrcMove.LM9
для вызова утилиты сдвига (выбранных) сенсоров мнемосхем.
Эта утилита может облегчить редактирование мнемосхем, состоящих из подсистем,
когда возникает необходимость сдвинуть группу сенсоров (относящихся к одной из подсистем)
на заданную пользователем величину (пикселей).
Фактически это означает изменение параметра Pos = ... на соответствующую величину.
Утилита ориентирована на обработку (сдвиг) выбранных сенсоров из заданного файла CRC.
Предполагается, что мнемосхемы разных подсистем описываются в отдельных CRC файлах,
чтобы облегчить их редактирование и поддержку.
В консольные утилиты Crw32.Utils.LM9 на закладке DAQ добавлена кнопка
DaqCrcMove для вызова утилиты сдвига сенсоров мнемосхем.
Для тестирования и иллюстрации работы Конечных Автоматов создано 2 тестовых файла:
test.sml,
test_bug.sml.
Оба файла содержат абстрактный (не имеющий ассоциированных прокси-объектов)
автомат FSM, включающий:
управление условным экспериментом RUN
(с типом RUN_TYPE, сборщиком событий EVT_BUILDER, журналом LOGGER)
и автопилот AUTO_PILOT для организации цикла экспериментов.
Эти тестовые файлы можно компилировать, запускать и наблюдать (мониторировать)
в автономном режиме с помощью утилиты SmiGenGui,
например для изучения работы Конечных Автоматов.
Пример test.sml содержит пример с программным таймером (на языке SML),
который (при включении автопилота) перезапускает RUN каждые 10 секунд.
Пример test_bug.sml содержит пример с логической ошибкой,
которая (при включении автопилота) приводит к "зацикливанию" и подвисанию
машины состояний.
Этот пример добавлен для иллюстрации проблем, к которым может привести
неверное построение кода Конечного Автомата (на языке SML).
Утилита SmiGenGui содержит в себе необходимый минимум для цикла разработки
Конечных Автоматов на языке SML.
А тесты позволяяют "поиграть" с Конечными Автоматами на готовых примерах.
В инструментарий
DaqConstructor
добавлен редактор
Mermaid.
Редактор Mermaid (русалка ) служит для создания
блок-схем и диаграмм состояний из простого текстового описания.
Этот инструмент будет полезен для изображения Конечных Автоматов (машин состояний, FSM)
в удобном для восприятия графическом виде.
Исходным кодом служит простое текстовое описание блок-схемы,
например, код State1-->State2 описывает прямоугольники
[State1], [State2], изображающие состояния, со стрелкой между ними.
На основе этого описания Mermaid генерирует графическое изображение
в виде блок-схемы.
В первой версии Mermaid присутствует базовый функционал,
который со временем будет расширяться и дополняться по мере возможностей.
Обновление предоставил А.Жирунов с мелкими правками А.Курякина.
Редактор Mermaid следует рассматривать как часть инструментария и библиотек
для построения систем управления на приципе Конечных Автоматов.
Системы управления на базе Конечных Автоматов предполагают диалог между программистами
(реализующими автомат) и методистами (физиками, проектирующими и использующими автомат).
Графические диаграммы и блок-схемы, которые позволяет рисовать редактор Mermaid,
облегчают диалог между специалистами разного рода.
В стартовый сценарий Crw32.ini [StartupScript]
введены переменные окружения DimSite_Root, SmiSite_Root.
Они указывают на местоположение каталогов DimSite, SmiSite,
для библиотек DIM, SMI.
Это сделано для поддержки (дочерних) утилит и командных сценариев,
использующих технологии DIM, SMI.
В сборку UnixUtils добавлена команда crw-daq-finder для поиска установок пакета CRW-DAQ.
Ищет в реестре информацию об установвленных экземплярах CRW-DAQ и выдает список каталогов установки.
Например:
Утилита полезна как для разработчиков (при работе в командной сроке), так и для командных сценариев,
если требуется узнать места установки пакета CRW-DAQ.
Утилита распознает только установленные (стандартным инсталлятором) копии пакета,
которые регистрируются в системном реетре.
Она не ищет копии пакета, которые просто распакованы (скопированы) из архива.
В сборку SMI++ добавлена программа smi_kill.exe для корректного завершения работы доменов SMI.
Эта программа входит в состав исходных кодов SMI, но по умолчанию не компилировалась.
Теперь в дистрибутив будет входить (кроме исходного кода) и откомпилированный бинарный файл.
Например:
в сеансе CMD:
set DIM_DNS_NODE=localhost предварительно надо задать DIM DNS
smi_kill DEMO завершение работы SMI домена DEMO
Команда smi_kill завершает процесс Конечного Автомата smiSM.exe,
который обслуживает указанный при вызове домен SMI (в данном примере это DEMO),
при этом переменная окружения DIM_DNS_NODE должна быть (заранее) задана.
В сборку UnixUtils добавлена команда smi_control для работы с технологией SMI.
По замыслу - это объединенная (комплексная) утилита, которая позволяет:
получать список работающих доменов с заданным DNS;
компилировать (транслировать) SML файл в объектный SOBJ файл;
запускать откомпилированный объектный файл домена с помощью менеджера Конечных Автоматов smiSM.exe;
завершать работу заданного домена SMI,
и выполнить другие команды для работы с технологией SMI.
Таким образом, утилита объединяет в один мощный инструмент множество разрозненно существующих программ,
входящих в библиотеку SMI, что облегчает их использование.
Например:
-- получить список доменов SMI, работающих с данным DNS
unix smi_control -list -dns localhost
-- компилировать SML файл
unix smi_control --verb --compile c:\Crw32exe\Demo\DEMO_SMITEST\Config\test.sml
-- компилировать SML файл и запустить домен TEST
unix smi_control -compile -run -dns localhost -dom TEST -cd %Temp% c:\Crw32exe\Demo\DEMO_SMITEST\Config\test.smlunix smi_control -compile -run -dns localhost -dom TEST -cd c:\Crw32exe\Demo\DEMO_SMITEST\Config -sml test.sml
-- выполнить команду dnsRunning (проверка работы DNS)
unix smi_control --dns localhost --exe dnsRunning.exe
-- завершить работу домена TEST с заданным DNS
unix smi_control --kill --dns localhost --dom TEST
-- узнать версию
unix smi_control --version
-- получить справку
unix smi_control --help
Утилита полезна как для разработчиков (при работе в командной сроке), так и для командных сценариев,
если требуется компилировать, запускать, останавливать и проверять работу Конечных Автоматов SMI.
В новой версии сделана возможность подтверждения (confirm) операций.
В теге CONF_i содержатся биты:
Бит 0 - подтверждение включения нагревателя.
Бит 1 - подтверждение выключения нагревателя.
Бит 2 - подтверждение чтения/записи параметров из INI файла.
Если соответствующий бит присутствует, перед выполнением операции
будет выдан диалог запроса для подтверждения её выполнения.
Также обновлена документация UniHeater.
Кроме того, файлы автоматически генерируемых изображений (barbmp)
перенесены в системную папку, чтобы не "замусоривать" каталог
прикладной системы.
Обновлена версия DimTree.
В новой версии добавлены:
Кнопки + (pаскрыть всё) и - (cвернуть всё).
Кнопка Find (диалог поиск/закладки - Find/Bookmark DIM Services).
Функции поиска и быстрого перемещения по списку найденных DIM сервисов.
Функции закладок для быстрого перемещения по списку закладок DIM сервисов.
Новые функции поиска/закладок нужны для облегчения и ускорения диагностики и отладки
распределенных систем на базе технологии DIM.
Добавлены функции преобраазования регистров (отдельных) символов
upcase,
locase.
Данные функции давно надо было сделать, они полезны при символьном анализе строк.
Эти функции затрагивают только символы a-zA-Z, т.е. символы ASCII.
Остальные символы передаются "как есть".
Данные функции быстрые, т.е. они работают намного быстрее,
чем регистровое преобразование строки из одного символа
через вызов Up/LoCaseStr.
В конфигурации DEMO_TESTBENCH
добавлен тест 9 (@Test 9) для проверки и иллюстрации работы функций upcase и locase.
Продолжена разработка библиотек Конечных Автоматов.
Коррекции вносились в модули SmiProxy (незначительные),
SmiuiSrv (добавлены 2 функции и 1 команда),
FsmManager (внутрениие изменения).
22.06.2022
IsLexeme lex_FsmName lex_SmiName lex_DimName
FSM API fsm_name_rule DEMO_SMITEST
Главными достижениями данного выпуска являются:
обновление функций синтаксического анализа IsLexeme;
обновление библиотеки FSM API;
обновление демо DEMO_SMITEST.
В этом выпуске продлолжена разработка библиотек
для Конечных Автоматов SMI++,
и сопутствующих им утилит.
В ходе разработки библиотек SMI++ выяснилось, что имена
объектов/состояний/действий в SMI могут содержать не только
буквы/цифры, но и символы [&:-.].
Поэтому потребовалось изменить синтаксический анализ SMI/FSM.
Кроме того, в качестве типа проверяемой лексемы (typ) теперь также можно использовать ссылку на регулярное выражение
regexp_init(..).
В этом случае для проверки используется regexp_test(..),
например:
rex:=regexp_init(0,'/^[_a-zA-Z]+[_a-zA-Z0-9]*$/i'); // Создать объект - регулярное выражение
if IsLexeme(s,rex) then ... // Проверка выражения s
if regexp_test(rex,s) then ... // Проверка выражения s (эквивалент)
bNul(regexp_free(rex)); // Не забываем освободить регулярное выражение
Это расширение IsLexeme(..) позволяет использовать регулярные выражения единообразным способом
вместе с предопределенными константами, делая эту функцию универсальным инструментом синтаксического
анализа теста.
Добавлена функция FSM APIfsm_name_rule(typ).
Она возвращает правило имен функции IsLexeme для заданного типа (typ).
Необходимость этой функции связана с тем, что разные компоненты имен FSM теперь имеют разные правила.
Например, допускается имя состояния &Busy, но домена с таким именем быть не должно.
Поэтому правило имен определяется по типу элемента.
Библиотеки функций FSM API, FsmManager модифицированы так, чтобы их можно было использовать
для многодоменных систем, т.е. систем, в которых есть несколько взаимодействующих в сети доменов SMI.
В таких системах, в частности, допускаются имена вида DOMAIN::OBJECT для ссылок на объекты другого домена.
В предыдущей версии действовало правило имен IsLexeme(name,lex_Name), в котором символ [:] не допускался.
Теперь в именах действует правило fsm_name_rule(typ), которое для объектов, состояний и действий
допускает использование имен с символами [&:.-].
Обновлены серверные программы SmiProxy.exe, SmiuiSrv.exe в связи с обновлением библиотек FSM API.
В конфигурации DEMO_TESTBENCH
модифицирован тест 4 и 8 (@Test 4, @Test 8) для проверки и иллюстрации работы функций islexeme и FSM API.
Обновлена демо конфигурация
DEMO_SMITEST.
Приведена в соответствие с библиотеками.
В новой версии демо-конфигурация сделана с двумя доменами (DEMO и AUTO), для иллюстрации взаимодействия доменов.
Соответсвенно есть два SML файла в каталоге Config:
run_con_demo.sml и
run_con_auto.sml.
Домены запускаются с помощью сервера &SmiSrv:
[ConfigFileList] ; General Purpose Servers ; включить стандартную
ConfigFile = ~~\Resource\DaqSite\Default\SmiSrv.cfg ; конфигурацию &SmiSrv
[]
...
[&SmiSrv.StartupScript] ; В начале работы &SmiSrv:
@dimdnslaunch ; запустить локальный DIM DNS
@dim_dns_node localhost ; задать DIM_DNS_NODE
@smitranslate run_con_demo.sml ; компилировать run_con_demo.sml
@smismstart DEMO run_con_demo.sobj -dns localhost ; и запустить с ним домен DEMO
@smitranslate run_con_auto.sml ; компилировать run_con_auto.sml
@smismstart AUTO run_con_auto.sobj -dns localhost ; и запустить с ним домен AUTO
@smismguard 60000 ; сторожевой таймер перезапуска
[]
[&SmiSrv.FinallyScript] ; В конце работы &SmiSrv:
@smismstop * ; завершить серверы SMI
[]
Домен AUTO содержит объекты { PILOT, DEMO::RUN }.
При этом объект AUTO::DEMO::RUN а домене AUTO объявлен как /ASSOCIATED,
т.к. он является прокси объектом, который представляет логический объект DEMO::RUN из домена DEMO.
Прокси-объект AUTO::DEMO::RUN имеет тот же набор состояний (state) и действий (action),
но не имеет кода реализации, т.к. его реализует логический объект DEMO::RUN из домена DEMO.
Кроме того, в прокси-объекте дополнительно присутствует состояние DEAD /dead_state на случай потери связи.
Объект AUTO::DEMO::RUN а домене AUTO используется в коде логического объекта PILOT
для реализации "АВТОПИЛОТА", т.е. внешнего управления объектом DEMO::RUN.
С точки зрения "АВТОПИЛОТА", весь домен DEMO представляется одним логическим объектом DEMO::RUN,
представленным своим "аватаром" AUTO::DEMO::RUN, т.е. замещающим прокси-объектом, описывающим его состояния.
Вся сложность реализации объектов домена DEMO скрыта за этим прокси-объектом.
Домен DEMO содержит объекты { AUTO::PILOT, RUN, RUN_TYPE, LOGGER, EVT_BUILDER }.
При этом объект DEMO::AUTO::PILOT а домене DEMO объявлен как /ASSOCIATED,
т.к. он является прокси объектом, который представляет логический объект AUTO::PILOT из домена AUTO.
Прокси-объект DEMO::AUTO::PILOT имеет тот же набор состояний (state) и действий (action),
но не имеет кода реализации, т.к. его реализует логический объект AUTO::PILOT из домена AUTO.
Кроме того, в прокси-объекте дополнительно присутствует состояние DEAD /dead_state на случай потери связи.
Замещающий объект DEMO::AUTO::PILOT в домене DEMO используется для создания графического интерфейса,
т.е. отображения состояний и обработки действий объекта AUTO::PILOT из домена AUTO.
Это позволяет делать графические интерфейсы единообразно, по принципу "одно окно - один домен - один SML файл",
но при этом использовать любые нужные в работе объекты SMI из любых доменов.
Таким образом, в данном примере два домена активно взаимодействуют друг с другом через прокси-объекты.
Именно таким образом можно строить многоуровневые иерархические системы управления, в которых
различные уровни управления взаимодействуют друг с другом через механизмы SMI.
Разработка библиотек для Конечных Автоматов SMI++ приближается к завершению, хотя
есть еще нерешенные вопросы (например, с сохранением/передачей/редактированием параметров объектов,
а также с наборами объектов - как их использовать в GUI).
Однако уже сейчас можно пробовать создавать прикладные системы на базе Конечных Автоматов SMI.
Демо конфигурация DEMO_SMITEST
может служить примером и прототипом для создания таких систем.
Обновлен модуль
SmiProxy
и его документация.
Изменено (упрощено) конфигурирование модуля.
Функции модуля синхронизованы с версией FsmManager.
Обновлен модуль
SmiuiSrv
и его документация.
Функции модуля синхронизованы с версией FsmManager.
В первом приближении библиотеки работают.
Их еще придется неоднократно дорабатывать,
однако уже можно пробовать использовать для прикладных систем.
Программы SmiProxyLogger, SmiProxyEvtBuilder добавлены
в шаблоны редактора в разделе Daq-Pas-Program.
Это шаблоны для создания прокси - программ для Конечных Автоматов.
Обновлена демо конфигурация
DEMO_SMITEST.
Приведена в соответствие с библиотеками.
14.05.2022
SmiuiSrv SmiGenGUI.LM9 DEMO_SMITEST
Главными достижениями данного выпуска являются:
обновление модуля SmiuiSrv;
обновление утилиты SmiGenGUI.LM9;
обновление DEMO_SMITEST.
В этом выпуске продлолжена разработка библиотеки SmiuiSrv,
которая реализует клиента Конечных Автоматов SMI++,
и сопутствующих ей утилит.
Обновлен библиотечный модуль SmiuiSrv,
добавлена обработка параметров логических объектов.
Модуль пока считается экспериментальным ("в разработке"), но он уже
функционирует и постепенно приближается к окончательной рабочей версии.
Требуется доработка и тестирование, но как-то пользоваться уже можно.
Обновлена библиотека модулей DieselPascal\External,
в которую добавлено несколько полезных функций общего назначения
(WordIndex и другие). Также добавлен модуль dpCrcUtils для облегчения
генерации CRC-файлов. Этот модуль разработан для использования в утилите
SmiGenGUI.LM9, но может применяться и для других утилит, связанных
с генерацией CRC-файлов.
Обновлена утилита SmiGenGUI.LM9,
в которой добавлена страница (закладка) DAQ
для генерации файлов конфигурации CFG и мнемосхем CRC.
Сначала (на странице SML) задается имя SML-файла
с кодом Конечного Автомата.
Затем (на странице DAQ) выполняется разбор файла (Parse SML).
При этом заполняются списки обнаруженных обьектов (objects),
параметров (parameters) и наборов объектов (objectsets).
Надо выбрать (select) те из них, которые войдут в конфигурацию.
При этом также можно указать главный (main) и ведущий (lead) объект.
После этого на закладке параметров (parameters) нужно задать
параметры генератора - префикс тегов, имя устройства - обработчика GUI,
имя окна, параметры шрифтов, геометрические параметры кнопок и полей.
После этого можно выполнить генерцию конфиграции (Make CFG)
и мнемосхем (Make CRC). Сгенерированный текст можно наблюдать
в окне, копировать в буфер обмена или сохранить в файл.
Обновлена ДЕМО конфигурация
DEMO_SMITEST
для иллюстрации новых функций библиотеки SmiuiSrv.
Удален библиотечный модуль SmiuiRtl, который теперь заменен
модулем SmiuiSrv.
Это была неудачная попытка реализации библиотеки для SMI GUI,
которая была заменена на более эффективную реализацию.
Главными достижениями данного выпуска являются:
обновление Origami;
обновление Painter(v) и GuiLib;
обновление модуля SmiuiSrv;
обновление DEMO_SMITEST.
Этот выпуск посвящен в основном продлолжению разработки
библиотеки SmiuiSrv,
которая реализует клиента Конечных Автоматов SMI++.
Небольшие изменения в библиотеке FSM API:
свойство fsm_ctrl(ref,'color') сделано доступным для всех контейнерных элементов
(ранее было только для состояний).
Небольшие изменения в интерфейсе основного пакета: в меню Link\DAQ System
добавлено 5 ссылок на утилиты, добавленные в нескольких прошлых релизах:
DimMonitor.LM9, Dim_benchmark.LM9, DimStatGui.LM9,
SmiGenGui.LM9, Com0com.LM9.
Цель состоит в том, чтобы сделать инструментарий разработчиков быстро доступным.
Обновлена стандартная библиотека, где после введения процедур
MessageBoxDialogEx, EditMessageBoxDialogExDefaultHandler
проведена оптимизация по размеру кода (устранен дублирующийся код).
Обновлена библиотека
SmiuiSrv,
в которой сделано много изменений - реализация меню действий, цвета элементов FSM и т.д.
Библиотека постепенно приближается к окончательной рабочей версии.
В консольные утилиты Crw32.Utils.LM9 на закладке DAQ добавлена кнопка
SmiGenGUI .
Это вызов утилиты SmiGenGUI.LM9 для наблюдения и отладки Конечных Автоматов.
В утилитe SmiGenGUI.LM9 добавлена закладка SML,
в которой есть средства для наблюдения и отладки Конечных Автоматов,
компиляции SML файлов транслятором smiTrans.exe,
запуска и остановки сервера Конечных Автоматов smiSM.exe.
Есть также инструмент для создания и наблюдения журнальных Log-файлов,
полезных в процессе создания, отладки и поддержки Конечных Автоматов.
Также добавлена закладка Help, чтобы справочный материал по SMI был "под рукой".
Вместе с ранее созданными средствами мониторинга утилита SmiGenGUI.LM9
становится одним из основных средств разработки, отладки и поддержки
Конечных Автоматов SMI.
Обновлена ДЕМО конфигурация
DEMO_SMITEST
для иллюстрации новых функций библиотеки SmiuiSrv.
Это первая версия практически полностью функционального демонстрационного
Конечного Автомата.
Обновлен редактор мнемосхем Origami.
Обновление содержит исправления ошибок и доработки интерфейса (по просьбам пользователей).
Обновление предоставил А.Жирунов.
Добавлена ДЕМО конфигурация
DEMO_IMG400
для иллюстрации драйвера контроллера вакуумных датчиков фирмы Pheiffer Vacuum IMG400.
Код предоставили М.Ефремов и Н.Гурин.
Обновлены библиотеки и документация графической системы
Painter.
Обновилась библиотека:
GuiLib,
в которые добавлены новые графические элементы
(в основном кнопки для ToolBar - [Painter(v).GuiLib.Cmd.xxx]).
Обновление подготовил Н.Гурин.
Обновлены ДЕМО конфигурации
DEMO_PAINT_GUILIB,
DEMO_PAINT_GOSTLIB,
использующие графические элементы Painter.
В DEMO_PAINT_GUILIB входит папка GUILIB_TEST_SCALE,
в которой проверяется масштабирование графических элементов.
Обновление подготовил Н.Гурин.
Главными достижениями данного выпуска являются:
обновление программы SmiuiSrv.exe и модуля SmiuiSrv;
обновление DEMO_SMITEST.
Этот выпуск посвящен в основном продлолжению разработки
программы SmiuiSrv.exe и библиотеки SmiuiSrv,
которая реализует клиента Конечных Автоматов SMI++.
Обновлена программа
SMIUISRV.EXE
- добавлено чтение версии и других параметров DIM DNS.
Обновлена библиотека
SmiuiSrv,
в которой сделано много изменений - связка с тегами, контроль наличия связи и т.д.
В стандартную библиотеку добавлены процедуры
MessageBoxDialogEx,
EditMessageBoxDialogExDefaultHandler,
WarningEx,
InfoBoxEx,
которые значительно расширяют возможности стандартного диалога MessageBox,
позволяя привязывать положение диалога к нажатому сенсору, а также задавать
команду, выполняемую при нажатии кнопки OK или Yes.
Обновлена демо конфигурация
DEMO_SMITEST
для иллюстрации новых функций библиотеки SmiuiSrv.
Главными достижениями данного выпуска являются:
программа SmiuiSrv.exe и модуль SmiuiSrv;
добавление функций fsm_link, fsm_modified;
обновление DEMO_LAKESHORE;
обновление движка DieselPascal;
обновление сборки DIM.
Этот выпуск посвящен в основном программе SmiuiSrv.exe,
которая реализует клиента Конечных Автоматов SMI++,
а также обновлениям некоторых компонентов.
Добавлена программа
SMIUISRV.EXE
(SMI User Interface Server).
Эта программа может подключаться к серверу SMI++ (домену Конечных Автоматов)
и отслеживать его состояние, а также посылать ему команды.
Эта программа нужна для реализации клиента GUI для Конечных Автоматов.
Вызов программы выглядит примерно так:
SMIUISRV -verb -auto -dns localhost -dom DEMO -sleep 1000
где
-verb подробный режим отображения (verbose)
-auto автоматическое подключение всех объектов домена при запуске
-dns localhost задает имя сервера имен DIM_DNS_NODE
в данном случае задает его равным localhost
-dom DEMO задает имя SMI домена, к которому надо подключиться
в данном случае это домен DEMO
-sleep 1000 делает паузу на 1000 мс после подключения к домену
пауза используется для более надежного подключения
Программа SMIUISRV.EXE будет работать в составе модуля SmuUiSrv на языке DaqPascal,
который находится на этапе разработки и будет отвечать за создание GUI для Конечных Автоматов.
Добавление программы SMIUISRV.EXE - важный шаг в реализации Конечных Автоматов.
Обнаружена и исправлена небольшая ошибка в модуле _FSM.PAS.
Она была связана с неверным результатом fsm_path(ref) для элементов типа fsm_type_objectset.
Добавлена функция
fsm_link.
Эта функция позволяет "привязать" к элементу FSM целочисленную ссылку (link) с именем.
Например, это может быть тег, кривая, номер входа-выхода и т.д.
Например:
Привязка:
tag:=findtag('COUNTER'); // Поиск тега COUNTER
iNul(fsm_link(fsm,'tagCounter='+Str(tag))); // Запись (привязка) тега COUNTER под именем 'tagCounter'
Использование:
tag:=fsm_link(fsm,'tagCounter'); // Чтение тега по имени 'tagCounter'
bNul(iSetTag(tag,123)); // Использование тега
Добавлена функция
fsm_modified.
Эта функция позволяет "маркировать" элементы FSM как "модифицированные", т.е. измененные.
Это удобно для организации обработки событий, когда изменение состояний происходит в одном месте
(например, в процедуре чтения сообщений из сети), а обработка - в другом месте (например, в общем цикле опроса).
Маркировка элементов как "модифицированных" позволяет помечать изменившиеся элементы для последующей обработки.
В конфигурации DEMO_TESTBENCH
модифицирован тест (Test8) для проверки и иллюстрации работы функций fsm_link, fsm_modified.
Обновлен движок DieselPascal от версии 2.0.17 до версии 2.0.21.
Добавлена поддержка в Runtime некоторых свойств (например Anchor),
а в дизайнере в Свойства Проекта добавлены "Аргументы командной строки",
что удобно для отладки (можно передавать опции запуска при отладке).
Обновлена сборка DIM с версии 20.32 до актуальной версии 20.33.
Обновления коснулись в основном DimBridge, где ускорен процесс запуска и изменен его порядок
(команды запускаются первыми, информационные сервисы - потом).
Добавлен библиотечный модуль
SmiuiSrv,
обслуживающий программу сервера
SMIUISRV.EXE
(SMI User Interface Server).
Эта библиотека будет использоваться для создания прикладных программ (GUI),
основанных на Конечных Автоматах (SMI).
Поскольку библиотека довольно большая и используется не всегда,
то она не включается в StdLibrary автоматически (неявно),
а должна включаться включаться явно, как описано в документации.
Библиотека пока в стадии разработки, но уже частично функционирует.
Она обеспечивает запуск/завершение/перезапуск процесса SMIUISRV.EXE,
прием и передачу данных и команд от SMI к FSM.
Остается реализовать привязку FSM к GUI.
Обновлена демо конфигурация
DEMO_SMITEST
для иллюстрации работы библиотеки SmiuiSrv.
02.04.2022
Origami DEMO_LAKESHORE DimMonitor.lm9 Crw32.Utils.LM9 DIM
Главными достижениями данного выпуска являются:
добавлена утилита DimMonitor.lm9;
обновление DEMO_LAKESHORE;
обновление Origami;
обновление DIM.
Этот выпуск посвящен в основном утилите DimMonitor,
а также обновлениям некоторых компонентов.
Добавлена утилита
DimMonitor.lm9.
Утилита DimMonitor.lm9 является графической "надстройкой" над консольными утилитами DimStat и DimSrv.
Она служит для наблюдения (в виде таблицы) конкретных (заранее выбранных) DIM сервисов.
Вызов делается примерно так:
@run DimMonitor просто запуск (первый экземпляр)
@run /sw7 dim monitor просто запуск (другой способ)
@run DimMonitor --number 2 запуск второго экземпляра
@run DimMonitor --number 3 --ini DimMonitor_3.ini запуск 3-го экземпляра с загрузкой INI файла
Как следует из примеров, можно запускать несколько экземпляров монитора и загружать набор сервисов,
заранее созданный в программе и сохраненный в INI файле.
Созданная утилита является первой версией, которая (вероятно) еще будет дорабатываться.
В консольные утилиты Crw32.Utils.LM9 на закладке DAQ добавлена кнопка
DIM Monitor GUI.
В штатные утилиты
(как в консольную, так и в графическую версию "Инструменты/Панель управления DIM")
добавлен вызов DimMonitor.lm9 (до трех экземпляров).
Обновлена сборка DIM с версии 20.30 до актуальной версии 20.32.
Обновлен редактор мнемосхем Origami.
Обновление содержит добавление новых графических элементов и мелкие доработки интерфейса.
Обновление предоставил А.Жирунов.
Обновлена ДЕМО конфигурация
DEMO_LAKESHORE
для иллюстрации работы драйвера криогенного контроллера.
Обновление предоставил А.Жирунов.
Добавлен прокси драйвер для сериализации устройств с протоколом PfeifferPfeifferProxy
и библиотеки для него.
Драйвер предоставил А.Жирунов.
Добавлена ДЕМО конфигурация
DEMO_EDUTC110
для иллюстрации работы с протоколом Pfeiffer.
ДЕМО предоставил А.Жирунов.
Главными достижениями данного выпуска являются:
добавлены функции работы с текстами text_indexof, text_remove;
обновление Painter(v), GostLib и GuiLib;
обновление Origami.
Этот выпуск сделан в продолжение работ по Конечным Автоматам.
А также обновлению отдельных компонентов.
Добавлена документация по Конечным Автоматам.
smi_man_ru.pdf - перевод документации SMI, с некоторыми добавлениями.
fsm_brief_ru.pdf - краткий обзор SMI, пока не законченный.
Добавлены библиотечные функции для работы с тестами:
Text_IndexOf,
Text_Remove.
Функции нужны для реализации библиотек Конечных Автоматов, которые
интенсивно работают с текстами.
Обновлен библиотечный модуль
SmiProxy
для создания прокси-серверов SMI на языке DaqPascal.
Теперь эта библиотека (автоматически) включает в себя модуль FsmManager.
Использование FsmManager позволило унифицировать и упростить чтение SML файлов
(теперь для этого используется процедура из модуля FsmManager).
Теперь также не надо заботиться об обновлении цвета тега состояния, он обновляется автоматически.
Это значит, что прикладной код прокси программ будет еще компактнее и проще.
Обновлена демо конфигурация
DEMO_SMITEST
для иллюстрации работы
библиотеки SmiProxy с учетом сделанных в библиотеке изменений.
Обновлены библиотеки и документация графической системы
Painter.
Обновились библиотеки:
GuiLib,
GostLib,
в которые добавлены новые графические элементы:
[Painter(v).GuiLib.ListButton.Arrow],
[Painter(v).GuiLib.ListButton.Triangle],
[Painter(v).GostLib.Pump.Sublimation.xxx],
[Painter(v).GostLib.Vacuometer.Penning.xxx].
Обновление подготовил Н.Гурин.
Обновлена тестовая конфигурация
DEMO_PAINT_GUILIB
для иллюстрации работы новых графических элементов.
Главными достижениями данного выпуска являются:
добавление 21 функции для поддержки Конечных Автоматов (FSM):
fsm_new, fsm_free, fsm_ref, fsm_root, fsm_type, fsm_parent,
fsm_name, fsm_path, fsm_ctrl, fsm_count, fsm_items,
fsm_get_iparam, fsm_set_iparam, fsm_get_fparam, fsm_set_iparam,
fsm_get_sparam, fsm_set_sparam, fsm_add, fsm_find,
fsm_get_state, fsm_set_state;
первая версия модуля FsmManager.
Поздравляю всех с праздником Защитника Отечества - 23 февраля.
Этот выпуск сделан в продолжение работ по Конечным Автоматам.
В основном он посвящен новым функциям для работы с FSM.
Это очень важный шаг для решения задачи создания средств поддержки Конечных Автоматов.
Одно из достоинств FSM состоит в том, что она хорошо приспособлена для решения
задач управления и алгоритмов, работающих в режиме опроса (polling),
который характерен для задач управления вообще и пакета CRW-DAQ в частности.
При работе в режиме опроса возникает проблема сохранения переменных состояния для обработки
в следующем цикле опроса, так как обработка данных выполняется не в однократно вызываемой процедуре,
а в ряде последовательных периодических вызовов программы управления.
Для этого, конечно, есть переменные, теги, кривые, записи и хеш-списки,
но это разрозненные, слабо структурированные данные.
FSM API предоставляет возможность создавать четко структурированные объекты,
в которых можно хранить данные, необходимые для работы FSM.
Предполагается, что встроенные функции FSM API образуют минимальный базис поддержки FSM,
обеспечивающий быстрые динамические структуры данных, который будет дополнен сервисными
библиотеками на языке DaqPascal, которые потребуются для практического применения FSM.
Например, это чтение и сохранение SML файлов с описанием прикладных FSM,
построение динамических интерфейсов (мнемосхемы, меню и т.д.).
В конфигурацию DEMO_TESTBENCH
добавлен тест (Test8) для проверки и иллюстрации работы функций FSM API.
Функции FSM API дополняются библиотечным модулем
FsmManager
со средствами прикладной разработки (чтение и разбор SML файлов и прочее).
Сейчас этот модуль находится в разработке, но основной функционал уже работает.
В процессе разработки и отладки модуля FsmManager функции FSM API
работали стабильно, ошибок пока не было найдено.
Разработка модуля будет продолжена.
Добавлены примеры sml_samples
файлов на языке SML с установок CERN.
Обновлена конфигурация DEMO_SMITEST.
Добавлена команда тесстирования модуля FsmManager - чтение SML файла и вывод
содержимого FsmManager в консоль и файл ..\Temp\*.lst.
Главными достижениями данного выпуска являются:
добавление поддержки большого числа именованных цветов;
актуальная таблица цветов crw-daq-colors.htm;
команда @list colors;
функции и константы для работы с именованными цветами.
Этот выпуск сделан в продолжение работ по Конечным Автоматам.
В основном он посвящен функциям для работы с именованными цветами.
Эти функции оказались нужны для реализации библиотеки Конечных Автоматов.
Добавлена команда @view showfront ... для рисования окна и его активизации (BringToFront).
Например:
В панели управления DAQ-система добавлена функция вывода краткой статистики по текущей DAQ конфигурации.
При нажатии на строку статуса (StatusBar) выводится что-то вроде:
2022.02.14-13:21:19 => DAQ работает.
Файл C:\Crw32exe\Demo\DEMO_TESTBENCH\Config\!DEMO_TESTBENCH.CFG
Найдено тегов:0, кривых:0, устройств:3, графиков:0, мнемосхем:0, сенсоров:0.
Найдено ошибок работы DAQ: 0, проблем конфигурации: 0.
Время от загрузки DAQ: 0-00:00:08.312 (8.312 sec)
Время работы DAQ: 0-00:00:03.687 (3.687 sec)
Это удобный способ быстро определить, какая конфигурация сейчас работает и каков её текущий статус.
В примерах реализации Конечных Автоматов, взятых в CERN, есть много
ссылок на цвета состояний (каждое состояние Автомата имеет свой цвет).
Было скачано и проанализировано большое число файлов, взятых из различных
работающих в CERN систем, на основании этого построена суммарная таблица цветов.
Оказалось, что в Конечных Автоматах в CERN используются в основном не физические
цвета (типа Red, Green, Blue), а функциональные цвета (_3DFace, FwForeground),
описывающие функцию (назначение) цвета.
В таблице функциональных цветов часть цветов оказалось общесистемной (типа _3DFace),
а часть специфической для Конечных Автоматов (типа FwForeground).
В обширном наборе цветовых констант, которые поддерживал пакет, тем не менее
не хватало функциональных цветов, т.е. цветов, которые связаны не
с именами физических цветов, а с именами графических элементов или функций.
Например, цвет фона и текста кнопки, окна или заголовка окна являются
функциональными и могут зависеть от текущих настроек системы.
В пакет добавлена поддержка около 30 системных функциональных цветов, т.е. цветов,
связанных с определенными типами графических элементов или определенными функциями ОС.
Особенность этих цветов в том, что они не являются строгими константами,
а определяются текущими настройками Windows, т.е определяются в сеансе работы.
Например, цвет _BtnFace - цвет фона стандартной кнопки.
Системные функциональные цвета начинаются со знака подчеркивания, чтобы подчеркнуть их особую роль.
Однако для удобства определены также простые константы без знака подчеркивания.
Например _BtnFace, BtnFace, clBtnFace и cl_BtnFace
будут синонимами при вызове ParamStr('ColorCode _BtnFace').
В файлах CRC синонимами будут _BtnFace и BtnFace.
В сценариях Painter синонимами будут cl_BtnFace и clBtnFace.
Список системных функциональных цветов есть, например, в файле
ColFun.crc.
Также в пакет добавлена поддержка около 50 системных функциональных цветов JCOP,
т.е. цветов, взятых с большого числа установок, работающих в CERN.
Все эти цвета начинаются с префикса Fw (от Framework), т.к.
установки используют общие библиотеки JCOP Framework.
Список функциональных цветов JCOP есть, например, в файле
ColJFw.crc
Добавлена команда @list colors:
@list colors - вывод имен цветов в Главную Консоль
@list colors pas - вывод таблицы цветов в формате Pascal
@list colors crc - вывод таблицы цветов в формате CRC (Painter)
@list colors htm - просмотр таблицы цветов в формате HTML
Эта команда позволяет посмотреть актуальную (в данном сеансе) таблицу
именованных цветов. Особенно удобно смотреть в формате HTML.
Команда @list colors htm обновляет файл
crw-daq-colors.htm
с актуальной с таблицей цветов, доступных в пакете CRW-DAQ,
и затем открывает его в окне Web обозревателя.
При указании имени файла в конце команды файл записывается молча
(окно браузера не открывается).
Вызов команды @list colors htm Resource\Manual\crw-daq-colors.htm
прописан в стартовом сценарии пакета, так что файл
crw-daq-colors.htm
содержит актуальную (в данной сессии работы) таблицу цветов.
Для удобства кроме указанных в таблице имен цветов (типа Blue)
в пакете определены также имена с префиксом cl (типа clBlue),
используемые в сценариях Painter.
А для функциональных цветов (типа _BtnFace) доступны простые
названия без знака подчеркивания (типа BtnFace).
Ссылка на актуальную (в данной сессии работы) таблицу цветов
crw-daq-colors.htm
помещена в топ-лист на главную страницу справки, чтобы облегчить поиск.
Предполагается, что таблица цветов будет использоваться при разработке
интерфейсов пользователя, в том числе с использованием
Конечных Автоматов.
В демонстрационных конфигурациях (DEMO_SMITEST, DEMO_UNIHEATER)
вызовы ParamStr('ColorCode ...') заменены на новые функции преобразования цветов,
это получается короче и удобнее.
В конфигурацию DEMO_TESTBENCH
добавлен тест (Test7) для проверки и иллюстрации работы функций StringToColor.
В соответствии с обновленным набором цветов обновлены утилиты
barbmp,
ledbmp,
и соответственно обновлена ссборка UnixUtils.
Теперь в скриптах, использующих эти утилиты, тоже можно использовать
функциональные цвета (типа BtnFace или Tooltip).
С этими добавлениями тема именованных цветов, надеюсь, закрыта.
Таблица цветов (физических и функциональных) будет использоваться
для реализации интерфейса Конечных Автоматов.
Главными достижениями данного выпуска являются:
добавление функций кодирования backslash_encode, backslash_decode, backslash_encoder_ctrl.
Этот выпуск сделан в продолжение работ по Конечным Автоматам.
В основном он посвящен функциям кодирования с обратным слешем (\).
Эти функции оказались нужны для реализации библиотеки Конечных Автоматов.
Добавлены функции
backslash_encode,
backslash_decode,
backslash_encoder_ctrl.
Эти функции служат для кодирования текста или двоичных данных с помощью экранирования обратным слешем (\).
Такой метод кодирования используется, например, в языках C/C++ для задания строк в тексте программ.
Этот кодировщик удобен для кодирования данных, содержащих в основном текст, т.к. после кодирования
текст сохраняет читабельность.
Но при этом он становится пригодным для передачи по каналам связи,
т.к. управляющие символы заменяются на печатные символы.
С помощью backslash_encoder_ctrl можно управлять набором символов,
которые будут экранироваться или передаваться HEX-кодом, что позволяет
кодировать текст при наличии дополнительных ограничений.
Например, экранирование пробелов позволяет хранить или передавать
любой текст в виде одной неразрывной строки.
Новый кодировщик будет удобен для отладочного вывода
или реализации разных протоколов связи.
Мотивацией создания функций послужило то, что этот метод кодирования
используется в Конечных Автоматах (SMI).
Значит, в DaqPascal он тоже будет нужен.
В конфигурацию DEMO_TESTBENCH
добавлен тест (Test6) для проверки и иллюстрации работы функций backslash_encode/decode.
Главными достижениями данного выпуска являются:
доработка библиотеки регулярных выражений (RegExp),
доработка RegExp Калькулятора.
Этот выпуск сделан в продолжение работ по Конечным Автоматам.
В основном он посвящен доработке библиотеки RegExp.
Регулярные выражения (RegExp) нужны для реализации
библиотеки Конечных Автоматов.
Доработан и почищен (от лишних ссылок и счетчиков) калькулятор Регулярных Выражений
RegExp Builder.
Добавлена функция regexp_escape(arg).
Она экранирует специальные символы RegExp, делая строку (arg) пригодной для шаблона RegExp.
Рекомендуется использовать эту функцию для конструирования шаблонов Регулярных Выражений.
Устранена некорректность в реализации regexp_replace.
Некорректность была в том, что она выполняла замену всех соответствий,
даже при выключении флага Global.
Теперь при отключении глобального поиска замена выполняется один раз, как и положено.
В библиотеку Регулярных Выражений добавлен движок
regexp_pcrelib с именем
TPerlRegEx
на основе библиотеки PCRE 7.9 (Perl Compatible Reg Exp).
Этот движок использует загружаемую библиотеку pcrelib.dll (отсюда и название).
Он может служить в качестве дополнительного и в каком-то смысле эталонного,
т.к. достаточно давно используется в качестве основного в языке Perl.
На нем можно проверять работу сложных Регулярных Выражений.
Если не возникнет новых проблем, работы по введению
регулярных выражений RegExp пока завершены.
Главными достижениями данного выпуска являются:
коррекция библиотеки регулярных выражений (RegExp),
доработка RegExp Калькулятора.
Этот выпуск сделан в продолжение работ по Конечным Автоматам.
В основном он посвящен доработке RegExp Калькулятора
и исправлению найденных недоработок реализации RegExp.
Регулярные выражения (RegExp) потребовались для реализации
библиотеки Конечных Автоматов.
Существенно доработаны функции RegExp.
В целом устранена путаница, возникшая с модификаторами RegExp.
По умолчанию (для совместимости с другими движками) все модификаторы отключены.
Их можно включить вызовом regexp_ctrl(rex,'Modifiers=im') или задать
в выражении (?im). Последняя конструкция не рекомендуется,
т.к. модификатор g имеет неоднозначное значение в разных движках
(global или greedy).
Лучше использовать выражение /Pattern/igm, описанное ниже,
где все модификаторы предсказуемы (g=global).
Теперь допускается шаблон примерно того же вида как в JavaScript,
что-то типа /Шаблон/модификаторы, например /Шаблон/igm.
В программе это выглядит так:
rex:=regexp_init(regexp_def,'/Text-to-find/igm');
Это работает следующим образом. Если строка шаблона начинается с слеша
/, заканчивается слешем /m с допустимыми модификаторами
(m) из списка (igmrsx) в конце, то слешы отбрасывается из шаблона,
а модификаторы (после сброса всех модификаторов в ноль) устанавляваются
в соответсвии с заданными значениями.
Это поведение можно выключить флагом regexp_ctrl(rex,'UseSlash=0'),
который по умолчанию включен.
Если требуется использовать шаблон, начинающийся с слеша, его можно
заэкранировать как \/ или [/].
Справка по RegExp
существенно дополнена, добавлен полезный калькулятор
RegExp Builder.
В нем можно конструировать и вычислять регулярные выражения на JavaScript.
Это полезный инстумент в дополнение к RegExp Калькулятору.
Существенно переработан RegExp Калькулятор.
В него добавлен Benchmark - режим измерения производительности,
который может вычислять время выполнения операций (путем зацикливания
и измерения времени цикла).
Сделано много мелких доработок для повышения удобства и функциональности.
С помощью измерения производительности RegExp был существенно
оптимизирован (особенно вызов Exec).
Добавлена переменная Crw32.ini [System] regexp_default_options = ....
Эта переменная задает опции (параметры) по умолчанию для RegExp.
Переменная имеет вид:
Главными достижениями данного выпуска являются:
добавление функций regexp_xxxx и связанных с ними констант,
реализация библиотеки регулярных выражений (RegExp),
создание RegExp Калькулятора.
Этот выпуск сделан в продолжение работ по Конечным Автоматам.
Добавлена группа функций для обработки
регулярных выражений
(RegExp - Regular Expression):
regexp_init,
regexp_free,
regexp_ref,
regexp_ctrl,
regexp_test,
regexp_exec,
regexp_replace,
regexp_matchnum,
regexp_matchpos,
regexp_matchlen,
regexp_matchstr,
а также связанных с ними констант
regexp_def,
regexp_pas,
regexp_vbs.
Реализация RegExp основана на "движках" (engine), т.е. библиотеках,
реализующих регулярные выражения, с общим программным интерфейсом API.
В настоящее время в сборку входит два движка - один встроенный, написанный
на Object Pascal, а другой - внешний, от VBScript.RegExp.
Движки имеют свои особености и возможности, разную скорость и полноту
соответствия стандартам. В любом случае иметь выбор лучше, чем не иметь его.
В будущем возможно добавление и других движков (но с тем же API).
Необходимость библиотеки регулярных выражений стала очевидна в ходе
работ по Конечным Автоматам.
Регулярные выражения нужны, например, для облегчения разбора файлов
SML с описанием Конечных Автоматов.
В конфигурацию DEMO_TESTBENCH
добавлен тест (Test5) для проверки и иллюстрации работы библиотеки RegExp.
Добавлена переменная Crw32.ini [System] regexp_default_engine = 1.
Эта переменная задает движок по умолчанию для RegExp.
При вызове regexp_init(0,pattern) вместо 0 будет подставлено это
значение. Это позволяет менять движок по умолчанию без изменения прикладных программ.
Добавлена переменная Crw32.ini [System] regexp_default_modifiers = rsg-imx.
Эта переменная задает модификаторы по умолчанию для RegExp.
При вызове regexp_init модификаторам будет присвоено это значение по умолчанию.
Это позволяет менять значение модификаторов по умолчанию без изменения прикладных программ.
Модификаторы влияют на работу алгоритмов поиска и замены RegExp.
Например, модификатор i включает регистро-независимый режим.
Добавлена переменная Crw32.ini [System] regexp_default_execmax = 0.
Эта переменная задает начальное значение предела (максимального числа)
итераций при поиске соответствий RegExp.Exec, так что значение
Exec будет ограничено этим пределом.
Значение 0 снимает ограничение числа итераций при поиске.
Добавлена переменная Crw32.ini [System] regexp_default_saveopt = 0.
Эта переменная задает начальный режим для RegExp.SaveOpt,
см. справку.
Добавлена переменная Crw32.ini [System] regexp_default_usesubst = 1.
Эта переменная задает начальный режим для RegExp.UseSubst,
который влияет на работу RegExp.Replace,
см. справку.
Добавлены переменные
Crw32.ini [System] ApplicationHintPause = 500,
Crw32.ini [System] ApplicationHintHidePause = 5000
Эти переменные влияют на всплывающие подсказки, задавая длительность
ожидания перед показом справки и длительность её работы.
Длинные подсказки могут исчезать раньше, чем их успеют прочесть.
Теперь это регулируется через файл инициализации.
В меню Инструменты добавлен RegExp Калькулятор.
Он реализован на том же
API,
который используется в DaqPascal и служит для облегчения
создания и использования регулярных выражений в прикладных программах.
При использовании RegExp важна возможность проверить их работу
на тех или иных тестах в калькуляторе, чтобы потом было меньше ошибок
в прикладных программах.
На этом можно предварительно считать работу по введению
регулярных выражений RegExp в пакет выполненной.
Со временем возможно развитие этой темы (например,
добавление новых движков), но пока и этого достаточно.
Главными достижениями данного выпуска являются:
устранение мелких ошибок,
добавление функции IsLexeme и связанных с ней констант,
увеличение допустимой длины строк текста программы до 241.
Этот выпуск сделан в продолжение работ по Конечным Автоматам.
arg:='nice_name';
if IsLexeme(arg,lex_name) then writeln('arg looks like a Name');
arg:='bad+name!';
if not IsLexeme(arg,lex_name) then writeln('arg is not a Name');
При реализации функции упор был сделан на скорости её работы.
По задумке, функция должна очень быстро проверять входную строку,
чтобы можно было её быстро классифицировать и обработать
в соответствии с определенным типом.
По факту, на CPU:i7-4700MQ-2.4GHz вызов функции IsLexeme(s,lex_Name)
занимает порядка 54+2.3*Length(s) ns. Например, для типичной длины
идентификатора 20 символов это порядка 100 ns.
Функция была разработана для применения в библиотеке Конечных Автоматов,
но может использоваться и в других целях.
В конфигурацию DEMO_TESTBENCH
добавлен тест (Test4) для проверки и иллюстрации работы IsLexeme.
Обновлена функция
ComOpen,
так что теперь в секции описания COM порта можно задавать
строку параметров PipeLine = ..., в которой присутствуют
переменные окружения (%variable%).
Например:
[SerialPort-COM1]
PipeLine = tcp port 123 client %ComputerName%
[]
Это дает возможность использовать переменные окружения
для конфигурирования портов.
Обновлена команда @SysInfo, чтобы её вызов был быстрым.
Это особенно важно при старте, т.е. эта команда выполняется одной из первых при запуске программы.
Причиной долгого (до 5-10 секунд) исполнения команды был вызов HostName(1), который обращается к сети
для получения полного сетевого имени компьютера. Теперь делается быстрый вызов HostName(0), который
просто возвращает имя компьютера (без сетевого суффикса).
Старое поведение доступно через @SysInfo --detail.
Обновлена функция
isoption,
так что теперь она верно распознает вызов
IsOption(arg,'-') или
IsOption(arg,'--').
В ограничениях DaqPascal
изменена максимальная длина буфера входной строки с 161 до 241 символов.
Использование длинных строк в текстах программ не рекомендуется, но в некоторых случаях допустимо.
Рекомендуется по-прежнему ограничивать длину строк программного кода 160 символами,
а строки до 240 символов использовать в исключительных случаях,
если это улучшает структуру кода.
Потребность в длинных строках кода возникла при разработке библиотеки для конечных автоматов.
Исправлена ошибка, связанная с консольным выводом в программах DaqPascal.
Было обнаружено, что при выводе больших текстов (более 32Kb) этот вывод "пропадал",
даже при большом значении размера FIFO программы (StdOutFifo), причем это происходило
без сообщений об ошибках.
Это было связано с тем, что у консольного окна тоже есть свой буфер FIFO, который имел
фиксированный размер. При этом вывод программы шел нормально (FIFO хватало), но при
передаче вывода от потока программы в поток графики FIFO консольного окна переполнялось.
Теперь FIFO консольного окна сделано динамическим: ему позволено наращивать размер
от начального (32Kb) до максимального (2*StdOutFifo).
Таким образом, размер FIFO консоли сам будет "подстраиваться" под вывод.
Для графического потока это вполне допустимо, т.к. он не является критическим
в смысле реального времени.
Теперь консольный вывод больших текстов в принципе должен идти нормально.
При этом остаются ограничения самой консоли (в текущей реализации это
не более 1024 строк истории с обрезанием длины строк в 256 символов).
Главными достижениями данного выпуска являются:
обновление функций ComOpen, ComClose, ComClear, ComCount, ComSpace, ComWrite, ComRead;
возможность перенаправлять порты ComXXX в каналы pipe_xxx.
Этот выпуск (первый в этом году) посвящен в основном функциям ComXXXX.
Цель изменений - получить возможность перенаправлять порты ComXXX в каналы pipe_xxx
(в основном для связи через TCP/IP порты).
Исправлена функция
pipe_init,
где было обнаружено неверное задание приоритета потока, обслуживающего канал.
Обновлены функции
ComOpen,
ComClose,
ComCount,
ComSpace,
ComWrite,
ComRead.
Добавление касается возможности использования для приемо-передачи
именованных каналов или TCP портов путем перенаправления
ввода-вывода в каналы pipe_xxx.
Теперь в секции описания COM порта можно задавать
строку параметров PipeLine = ..., в которой задаются параметры
канала связи (com port, pipe, tcp port)
для функции pipe_init.
Если это описание (PipeLine) присутствует,
то все перечисленные выше функции ComXXX работают
с каналами (pipe_xxx), а если нет - используется
старое описание и старая логика работы.
Например:
if ComOpen('[SerialPort-COM1]') then writeln('Port opened.'); ; Открытие порта
Конфигурация порта (в новом стиле):
[SerialPort-COM1] ; Разные варианты канала связи:
PipeLine = Com Port 1 Baudrate 9600 Parity NONE DataBits 8 StopBits 1 ; Обычный COM порт
PipeLine = Pipe DEMO Polling 4 Priority tpHighest ; Именованный канал DEMO (сервер)
PipeLine = Pipe .\DEMO Polling 4 Priority tpHighest ; Именованный канал DEMO (клиент)
PipeLine = Tcp Port 1234 Server 1 Polling 4 Priority tpHighest ; Сокет TCP:1234 (сервер)
PipeLine = Tcp Port 1234 Client localhost Polling 4 Priority tpHighest ; Сокет TCP:1234 (клиент)
Конфигурация порта (в старом стиле, через именованный канал):
[SerialPort-COM1] ; Именованный канал связи:
PipeName = DEMO ; Именованный канал DEMO (сервер)
PipeName = .\DEMO ; Именованный канал DEMO (клиент)
PipePolling = 1, tpHighest ; Период опроса и приоритет
TimeOut = 1000 ; Время ожидания
FifoSize = 16 ; Размер FIFO
[]
Конфигурация порта (в старом стиле, через обычный COM порт):
[SerialPort-COM1] ; Обычный COM порт
Port = COM1 ; Номер порта
BaudRate = 9600 ; Скорость связи
Parity = NONE ; Четность
DataBits = 8 ; Число бит данных
StopBits = 1 ; Число стоповых бит
[]
Новые возможности функций ComXXX позволяют (через указание PipeLine в секции описания порта)
прямо (без использования com0com/com2tcp или другого внешнего драйвера виртуального порта)
переадресовать драйверы, написанные для COM портов с помощью функций ComXXX,
в сетевые каналы (например, TCP/IP порты).
Это может использоваться в симуляторах или для "проброски" COM портов
через сеть Ethernet поверх протокола TCP/IP.
Также встречаются устройства, имеющие одинаковые протоколы для связи
через COM порт или TCP/IP.
В этом случае драйвер, написанный для COM порта, используется
без изменений и для TCP/IP.
25.12.2021
RefFind RefInfo WinSelectUnderClickSensor
Всех поздравляю с наступающим Новым Годом и Рождеством.
Главными достижениями данного выпуска являются:
обновление функций RefFind, RefInfo, WinSelectUnderClickSensor.
Этот выпуск (финальный в этом году) посвящен в основном мелким улучшениям и исправлениям замеченных ошибок.
Оптимизированы функции (по скорости выполнения)
RefFind,
RefInfo.
В функции
RefInfo
добавлены новые возможности для окон:
win:=RefFind('Window '+WindowName);
s:=RefInfo(win,'Bounds'); // Left Top Right Bottom
Вызов RefInfo(win,'Bounds') возвращает координаты окна
со ссылкой win, которую можно получить по имени (заголовку)
окна вызовом win:=RefFind('Window '+WindowName).
Координаты задаются относительно клиентской области,
см. ParamStr('AppClientBounds').
Обновлена функция
WinSelectUnderClickSensor(win,click,opt).
Теперь она корректирует координаты вызываемого окна так, чтобы оно не выходило за границы экрана (точнее, главного окна CRW-DAQ).
При реализации функции используются новые возможности RefInfo(win,'Bounds') (для чего они и были сделаны).
После обновления функции WinSelectUnderClickSensor обеспечена корректная работа UniHeater
в случае, когда вызываемая мнемосхема (UNIHEATER.SETTINGS) выходит за границы экрана.
Главными достижениями данного выпуска являются:
обновление функций FindNaiByName, FindNdiByName, FindNaoByName, FindNdoByName;
добавление типа TStatSum2D и функций TStatSum2D_Reset, TStatSum2D_Init, TStatSum2D_Add, TStatSum2D_Calculate;
исправленная версия UniHeater и DEMO_UNIHEATER.
Этот выпуск посвящен в основном улучшениям и исправлениям
в системе UniHeater и попутно возникшим в процессе этой работы вопросам.
Оптимизированы (с помощью хеш-таблиц) функции
FindNaiByName, FindNdiByName, FindNaoByName, FindNdoByName.
Это резко повысило производительность этих функций и существенно уменьшило объем их кода.
Увеличен PreProcessorTimeOut для конфигурации DEMO_UNIHEATER,
чтобы сценарий препроцессора успевал сгенерировать конфигурацию UniHeater
даже на слабых машинах (и при большом числе нагревателей).
Исправлены названия сенсоров в UniHeater.
Они были без префикса, что мешало совместно использовать
несколько подсистем UniHeater с разными префиксами на одной (общей) мнемосхеме.
Сейчас все сенсоры UniHeater имеют преффикс, что делает возможным совмещение
нескольких подсистем UniHeater в одном окне мнемосхемы.
Небольшие доработки в UniHeater.
Добавлен идентификатор сервера (SERVID).
Цвет часов (CLOCK) и идентификатора сервера (SERVID) зависит от типа конфигурации:
локальной или сетевой.
Оптимизированы (вычисляются исходя из числа нагревателей) размеры буферов FIFO в UniHeater.
В стандартную библиотеку добавлен тип
TStatSum2D в файле
_typ_StdLibrary.inc.
Он служит для статистических расчетов (для накопления статистических сумм).
Достоинством типа TStatSum2D и связанных с ним процедур является то, что можно накапливать
статистические данные (стат.суммы) без необходимости сохранения самих данных, т.к. стат.суммы
позволяют рассчитать основные статистические характеристики (математическое ожидание,
дисперсию, С.К.О., линейную регрессию, линейную корреляцию) без обращения к массиву данных.
Это позволяет выполнять статистическую обработку онлайн, по мере поступления данных,
без промежуточного накопления данных в больших массивах.
Оптимизированы (вычисляются с помощью стат.сумм) расчеты в UniHeater.
Для оптимизации использованы функции модуля _fun_StdStatSum.
Обновлена документация UniHeater.
Почти везде слово "скважность" заменено на "мощность",
т.к. (если быть точным) параметр QX - это скорее не скважность (отношение T1/T0),
а коэффициент заполнения (отношение T1/T), выраженный в процентах.
А фактически это и есть мощность в процентах от максимальной.
К тому же термин "мощность" будет понятнее конечным пользователям.
Обновлена документация DIM.
В руководстве по DIM добавлены примеры использования DIM в экспериментах CERN.
Обновлен редактор мнемосхем Origami.
В основном обновление посвящено исправлению ошибок.
Обновление предоставил А.Жирунов.
Добавлен файл документации crw-daq-ru-style-guide.pdf.
Это (пока еще) черновик, требующий исправлений и доработки, но (уже) полезный для ознакомления.
В нем даются рекомендации по стилю разработки и оформления текстов файлов конфигурации,
программного кода, интерфейса пользователя в пакете CRW-DAQ.
По результатам проведенной работы систему UniHeater можно считать (в первом приближении) завершенной.
Главными достижениями данного выпуска являются:
обновление функции paramstr;
обновление функции clickparams;
обновление редактора Origami;
добавление функций WinSelectUnderClickSensor, FindNaiByName, FindNdiByName, FindNaoByName, FindNdoByName;
добавление стандартного заголовичного файла _typ_StdLibrary и тип TTagRef;
добавление констант экранных координат приложения;
первая версия UniHeater и DEMO_UNIHEATER.
Этот выпуск посвящен в основном системе UniHeater
и попутно возникшим в процессе ее создания вопросам.
Обновлена функция ParamStr.
В нее добавлены параметры:
ParamStr('AppFormBounds') - границы (Left,Top,Right,Bottom) главного окна приложения,
ParamStr('AppClientBounds') - границы (Left,Top,Right,Bottom) клиентской области приложения,
т.е. клиентской области главного окна приложения CRW-DAQ, т.к.
это окно служит контейнером для остальных окон.
Необходимость этих параметров связана с тем, что функция ClickParams выдает абсолютные координаты (мыши, окна мнемосхемы и сенсора),
а в функциях WinDraw, WinSelect координаты окон задаются относительно клиентской области приложения.
Поэтому для пересчета координат нужно знать границы клиентской области приложения.
Напоминаем, что вызов ParamStr можно сделать в любой консоли шаблонной программы командой @paramstr ... .
Это позволяет разработчикам как узнавать системные параметры через консоль, так и использовать их в программах DaqPascal.
В системный калькулятор (связанный с окном Главной Консоли) добавлены константы экранных координат приложения:
@view screen обновляет список констант screen_xxx параметров экрана
@list cons печатает созданный список констант:
... (абсолютные экранные координаты приложения)
screen_appformleft левая координата главной формы приложения
screen_appformtop верхняя координата главной формы приложения
screen_appformright правая координата главной формы приложения
screen_appformbottom нижняя координата главной формы приложения
screen_appformwidth ширина координата главной формы приложения
screen_appformheight высота координата главной формы приложения
screen_appclientleft левая координата клиентской области приложения
screen_appclienttop верхняя координата клиентской области приложения
screen_appclientright правая координата клиентской области приложения
screen_appclientbottom нижняя координата клиентской области приложения
screen_appclientwidth ширина координата клиентской области приложения
screen_appclientheight высота координата клиентской области приложения
...
Отличие констант screen_appxxx состоит в том, что эти константы связаны
с окном приложения и зависят от его размера и положения на экране, в то время
как другие константы screen_xxx связаны с экраном или мониторами,
без привязки к окну приложения и не зависят от его положения.
Обновлена функция ClickParams.
В нее добавлены параметры:
ClickParams('AppFormBounds') - границы (Left,Top,Right,Bottom) главного окна приложения,
ClickParams('AppClientBounds') - границы (Left,Top,Right,Bottom) клиентской области приложения,
т.е. клиентской области главного окна приложения CRW-DAQ, т.к.
это окно служит контейнером для остальных окон.
Необходимость этих параметров связана с тем, что функция ClickParams выдает абсолютные координаты (мыши, окна мнемосхемы и сенсора),
а в функциях WinDraw, WinSelect координаты окон задаются относительно клиентской области приложения.
Поэтому для пересчета координат нужно знать границы клиентской области приложения.
В стандартную библиотеку добавлена функция
WinSelectUnderClickSensor(win,click,opt).
Она позволяет вызывать окно (мнемосхемы, кривой, таблицы) под нажатым сенсором.
Например:
if (ClickSensor='DEMO') then WinSelectUnderClickSensor('DEMO.WINDOW',ClickParams(''),'-Left,-Top');
В функции используются координаты клиентской области приложения (для чего они и были добавлены).
В стандартную библиотеку добавлен
заголовочный файл_typ_StdLibrary.inc.
В этом файле (будут) определены стандартные типы, часто используемые в прикладном ПО.
В настоящее время в нем определен тип TTagRef, как наиболее часто используемый
в прикладных программах.
В настоящее время включение _typ_StdLibrary.inc в шаблонные программы
является опциональным (необязательным), но рекомендуемым (на будущее).
Тип TTagRef
- запись, содержащая ссылку на тег (tag), а также ряд ассоциированных
(связанных) с тегом полей: номера кривых аналоговых/цифровых входов/выходов (nai,nao,ndi,ndo),
целочисленные ссылки (ref,crv,tid,pid,cid,key,lnk,obj) на связанные с тегом объекты,
а также вещественные данные (dat,val,tim),
которые могут использоваться для обработки или обновления тегов.
Тип TTagRef часто используется в прикладных программах потому,
что теги обычно существуют не сами по себе, а связаны с другими
объектами (входами/выходами, кривыми, окнами и т.д.).
В стандартную библиотеку внесен наиболее общий (полный) набор ассоциированных
с тегом данных из встречавшихся на практике.
Минусом такого множества полей может быть повышенное использование памяти.
При необходимости можно увеличить сегмент данных (Compiler.dtabmax)
через опции компилятора.
В стандартной библиотеке изменен шаблон для программ
template.pas.
В него добавлен заголовочный файл стандартных типов:
type
{------------------------------}{ Declare uses program types: }
{$I _typ_StdLibrary} { Include all Standard types, }
{------------------------------}{ And add User defined types: }
Рекомендуется при редактировании (старых) прикладных программ
вставлять этот шаблон (при этом локальные определения TTagRef
надо будет удалять).
Обновлен редактор мнемосхем Origami.
В основном обновление посвящено исправлению ошибок.
Обновление предоставил А.Жирунов.
В стандартную библиотеку добавлены функции
FindNaiByName(name),
FindNdiByName(name),
FindNaoByName(name),
FindNdoByName(name).
Эти функции находят номер аналогового/цифрового входа/выхода по имени кривой name.
Их рекомендуется вызывать при инициализации программы, а не в цикле опроса, т.к. поиск может занимать время.
Лучше найти номер, запомнить его и затем использовать в цикле опроса.
Функции поиска номера входа/выхода удобно использовать совместно с записью
TTagRef.
Например:
var DEMO : TTagRef; // Тип TTagRef объявлен в {$ _typ_StdLibrary}
...
DEMO.tag:=FindTag('DEMO'); // Инициализация тега по имени DEMO
DEMO.nai:=FindNaiByName(NameTag(DEMO.tag)); // Номер AnalogInput одноименной кривой
...
bNul(rSetTag(DEMO.tag,GetAi(DEMO.nai))); // В цикле опроса используем этот номер
Сделана первая версия новой подсистемы универсальных (унифицированных) нагревателей
UniHeater.
Это аналог старой подстистемы UniHeat, однако он разработан для распределенных систем.
В старой системе был фиксированный префикс имен (UH_), что не позволяло, например,
создавать (объединенные) системы с несколькими подсистемами нагревателей из-за конфликта имен.
В новой версии можно создавать (генерировать из шаблона) подсистемы с разными префиксами,
что позволяет объединять несколько подсистем нагревателей в одной конфигурации.
Это принципиально важно для распределенных систем, т.к. на главном компьютере
возможно объединение (по сети DIM) нескольких систем с разных серверов.
В новой версии есть значительные улучшения - например, есть набор статистики
(средняя мощность, температура и среднеквадратичное отклонение температуры
за указанный период, например, за последнюю минуту),
что позволяет облегчить настройку нагревателей и оперативно оценивать качество
стабилизации температуры.
Кроме того, релизована графическая программа
uniheater_make.lm9
для создания конфигураций UniHeater с нужным префиксом, числом каналов и т.д.
Сделана первая версия новой демонстрационной конфигурации для универсальных (унифицированных) нагревателей
DEMO_UNIHEATER.
Конфигурация позволяет не только демонстрировать и тестировать UniHeater,
но и создавать конфигурации (с разными префиксами) для прикладных систем.
Главными достижениями данного выпуска являются:
обновление сборки библиотеки "Конечных автоматов" SMI;
обновление значков (иконок) пакета.
Обновлена библиотека SMI++ от версии v56r1 до версии v57r2, актуальной на данный момент.
В проекты добавлены ресурсы ("иконки") для того, чтобы в списке процессов были легко заметны процессы SMI.
Библиотека собрана самостоятельно в Visual Studio 2005.
Обновлена конфигурация
DEMO_SMITEST,
в соответствии с обновлением библиотеки SMI.
Обновлена библиотека Resource/Icon значков (иконок) пакета.
Значки вида
в пакете по возможности заменены на
.
Постепенно будем уходить от упоминания текущей разрядности (на будущее).
В команде @run тоже добавилась
опция -e или -exp
или -expand или --expand,
которая позволяет использовать переменные окружения, например:
Расширение (подстановка) переменных окружения (expand environment variables) происходит
перед выполнением команды, поэтому переменные окружения будут подставлены даже при вызове программ,
которые сами (без использования командного процессора) этого делать не могут.
Исправлена незначительная ошибка в тестовой утилите
dim_benchmark.lm9.
Обновлена утилита CrwGo (тоже замена значков).
14.11.2021
DIM dimStat DEMO_DIM_PING Origami DieselPascal dpSystem.pas TextDiff
CRW_DAQ_SYS_CLASS CRW_DAQ_SYS_TITLE CRW_DAQ_SYS_HANDLE
Главными достижениями данного выпуска являются:
переменные окружения CRW_DAQ_SYS_CLASS,CRW_DAQ_SYS_TITLE,CRW_DAQ_SYS_HANDLE;
обновление редактора Origami;
обновление движка DieselPascal;
обновление утилит *.LM9;
обновление сборки DIM;
обновление утилиты dimStat;
обновление тестовой системы DEMO_DIM_PING.
Обновлена сборка DIM.
Небольшие правки в dimStat для совместимости с GCC.
Эта утилита (и вообще сборка DIM) проверена под ALT Linux Simply.
Сборка бинарников DIM под ALT Linux x64 включена в demodoc.
Обновлена тестовая система DEMO_DIM_PING.
Добавлены - среднее (PING_TIME_MEAN) и среднеквадратичное отклонение (PING_TIME_RMSD)
времени отклика за период накопления статистики (PING_STAT_PERIOD).
Добавлен генератор отчетов для облегчения тестирования и протоколирования.
Обновлен редактор мнемосхем Origami.
В основном обновление посвящено исправлению ошибок (стало намного лучше).
Обновление предоставил А.Жирунов.
Обновлен движок DieselPascal от версии 2.0.15 до версии 2.0.17.
Добавлены методы (TStrings.BeginUpdate/TStrings.EndUpdate),
ускоряющие вывод текстов в TMemo.
Это особенно важно для реализации эмуляторов консоли.
Обновлены библиотеки (dpSystem.pas)
и утилиты *.LM9 (числом 11 штук) с использованием новых функций.
Изменения коснулись процедур обработки исключений (BugReport) и обновления текстов
(MoveListToLoggerMemo, MoveLogEventsListToLoggerMemo, MoveBugReportListToLoggerMemo).
После применения указанных функций обновление окон - эмуляторов консоли значительно ускорилось
и стало практически незаметным для глаз (ранее при обновлении окна довольно заметно "моргали").
Зто ускорение происходит за счет того, что теперь при добавлении текста из нескольких строк
прорисовка делается один раз, а раньше каждая добавленная строка вызывала прорисовку.
Кроме того, в библиотеках DieselPascal и утилитах многие имена, содержащие Crw32, по возможности
заменены на CrwDaq (на будущее).
В сборку UnixUtils добавлена команда TextDiff для (визуального) сравнения файлов.
Утилита привлекла относительно маленьким размером и наличием исходных кодов на языке Object Pascal.
В сборке DemoDoc обновлен пакет FreeCommander в качестве дополнительного менеджера файлов.
Взята версия, используемая в CERN (PHOS).
В сборке основного рабочего файлового менеджера Q-Dir дабавлена ссылка на пакет TextDiff.
Теперь со сравнением файлов и каталогов не должно быть проблем.
В сервере DimSrv.exe исправлена ошибка,
заключающаяся в неверном (отличающемся от запрошенного) задании
приоритета процесса DimSrv.exe.
Теперь приоритет задается верно.
Введены новые переменные окружения:
CRW_DAQ_SYS_CLASS - строка имени класса основного окна окна пакета,
CRW_DAQ_SYS_TITLE - строка заголовка основного окна пакета,
CRW_DAQ_SYS_HANDLE - идентификатор основного окна пакета.
Эти переменные нужны для того, чтобы дочерние процессы знали (через наследование переменных окружения)
какое окно им надо искать, чтобы связаться с основным окном пакета (например, чтобы активировать его).
Класс окна является константой (TFormCrw32), а заголовок зависит от идентификатора процесса,
что гарантирует его уникальность (см. далее).
Заголовок пакета теперь задается при старте программы (а не в файле инициализации) и имеет вид
CRW-DAQ/PID@HOSTNAME, зависящий от идентификатора процесса (PID)
и имени компьютера (HOSTNAME), например, CRW-DAQ/1234@AK-W10X32-VM.
В предыдущих версиях имя окна было CRW32 #PID,
например, CRW32 #123.
Этот шаблон наименования имеет ряд недостатков.
Например, многие программы для работы с окнами ищут окна по признаку заданного начала имени окна.
В этом случае, например, названия CRW32 #123 и CRW32 #1234 будут неразличимы,
т.к. содержат в начале одинаковую часть строки. Потенциально это могло приводить к сбоям.
Новый шаблон имени заголовка был выбран из следующих соображений:
Нейтральное и более точное название CRW-DAQ теперь не указывает на разрядность (она может в будущем измениться).
Имя пакета, идентификатор процесса и имя компьютера обеспечивают достаточную уникальность имени окна.
Указанное имя хорошо приспособлено для функций поиска и активизации окон.
Новое имя не содержит пробелов, что удобно для анализа строк (по словам).
Новый заголовок более информативен и лучше подходит для идентификации окон, но смена шаблона имени
(в принципе) может задеть другие программы, использовавшие старый шаблон (это надо проверять).
В будущем программы должны ориентироваться на переменные окружения, а не на шаблон имени окна,
который может поменяться.
В командах @view, @note добавилась
опция -e или -exp
или -expand или --expand,
которая позволяет использовать переменные окружения, например:
@silent @view -e title FormCrw32 %CRW_DAQ_SYS_TITLE%
@silent @note -e Привет! Сеанс работы «%CRW_DAQ_SYS_TITLE%» начался.
03.11.2021
DIM dimStat dim.cmd dimgui.vbs dimStatGui.lm9 Crw32.Utils.lm9 GNU Programming Standards
Главными достижениями данного выпуска являются:
обновление сборки DIM;
добавление утилиты dimStat и dimStatGui;
обновление консольных утилит Crw32.Utils.lm9.
Этот выпуск посвящен в основном обновлению сборки DIM и добавлению утилиты dimStat.
В сборку DIM добавлена (созданная А.К.) утилита
dimStat
для сбора статистики, анализа трафика DIM.
Эта консольная утилита позволяет получать информацию о статусе DIM (работает ли DNS,
получить список сервисов, серверов, и клиентов).
Но главное назначение утилиты - получение статистики о частоте опросов (обновлений) сервисов,
трафика (байт в секунду) публикуемых данных и т.д.
Утилита dimStat дополняет штатный набор диагностических и отладочных средств DIM.
Она особенно полезна для больших систем (с большим числом серверов) и позволит повысить
эффективность отладки и диагностики сетей DIM.
К утилите есть краткое пояснение.
В сборку DIM добавлена (созданная А.К.) утилита
dimStatGui.lm9
- GUI оболочка для утилиты сбора статистики, анализа трафика DIM.
Работает как графическая надстройка для консольной утилиты dimStat.exe.
В сборке DIM отредактирована утилитаDIM Control GUI (Центр управления DIM).
В утилиту добавлены кнопки вызова dimStatGui и справочного файла index.htm.
Изменились файлы dim.cmd и dimgui.vbs.
В консольные утилиты Crw32.Utils.LM9 на закладке DAQ добавлена кнопка
DIM Stat GUI.
Обновлена документация DIM - dim_man_ru.pdf.
Добавлено краткое описание утилиты DIMSTAT.
Главными достижениями данного выпуска являются:
добавление новых опций и переработка команд @run, @env;
добавление полезной команды @getapppath;
добавление 2 констант и 5 новых функций для разбора командной строки и опций;
обновление утилит для файлового менеджера Q-Dir;
добавление многих команд в UnixUtils.
Этот выпуск посвящен в основном команде @run и утилитам UnixUtils.
А также тому, что возникло вокруг этого.
В сборку UnixUtils добавлена команда unix ask-input для пользовательского ввода.
> unix ask-input "Ask" "Your name:" "James Bond"
> James Bond
> unix ask-input --help - для справки
использование в скриптах:
for /f "delims=" %%i in ('unix ask-input "Ask" "Your name:" "James Bond"') do echo Hello, %%i.
Команда вызывает диалог (с заданным заголовком и текстом) для ввода строки (с заданным начальным значением)
и ждет подтверждения OK или отмены.
Если нажата кнопка Yes, возвращается статус успеха (0) и печатается введенная строка,
иначе возвращается статус ошибки (1).
Статус используется для условного выполнения команд с параметрами (например, с помощью операторов for, &&, ||).
Команда очень удобна для быстрой организации простых диалогов ввода данных в командных файлах.
В сборку UnixUtils добавлена команда unix ask-input-call для пользовательского ввода и выполнения команд.
> unix ask-input-call "Ask" "Your name:" "James Bond" cmd /c echo Hello @*
> James Bond
> unix ask-input-call --help - для справки
использование в скриптах:
unix ask-input-call "Ping" "HostName to ping:" "localhost" start "ping @*" ping -t @*
использование в Главной Консоли:
@run -sw7 unix ask-input-call "Ping" "HostName to ping:" "localhost" start "ping @*" ping -t @*
Команда вызывает диалог (с заданным заголовком и текстом) для ввода строки (с заданным начальным значением)
и ждет подтверждения OK или отмены.
В случае подтверждения выполняет указанную команду с заменой шаблона @* на введенную строку.
Команда очень удобна для быстрой организации простых диалогов ввода данных в командных файлах.
В сборку UnixUtils добавлена команда unix GetAppPath для поиска и выполнения приложений.
> unix getapppath firefox.exe chrome.exe iexplore.exe .html
> C:\Program Files\Mozilla Firefox\firefox.exe
> unix getapppath firefox.exe chrome.exe iexplore.exe .html --start c:\Crw32exe\Resource\Manual\crw-daq.htm
> "C:\Program Files\Mozilla Firefox\firefox.exe" c:\Crw32exe\Resource\Manual\crw-daq.htm (запуск)
> unix getapppath --help - для справки
использование в скриптах:
unix getapppath firefox.exe .html --start c:\Crw32exe\Resource\Manual\crw-daq.htm
использование в Главной Консоли:
@run -sw7 unix getapppath firefox.exe .html --start --show 3 c:\Crw32exe\Resource\Manual\crw-daq.htm
Команда ищет путь EXE-файла приложения, заданного в списке предпочтений.
Список предпочтений проходится по порядку (слева направо), в качестве результата
принимается первое подходящее описание (для которого файл найден).
По умолчанию выполняется просто печать полного пути EXE-файла найденного приложения.
C опцией --start или --run возможен запуск найденного приложения с заданными аргументами.
Опцией --show n можно задавать режим окна приложени при запуске.
Опцией --wait можно задавать режим ожидания завершения.
В списке предпочтений можно задавать:
Полное имя EXE-файла, например, %windir%\explorer.exe (переменные окружения разрешаются).
Базовое имя EXE-файла, например, explorer, для поиска в PATH/PATHEXT.
Короткое имя EXE-файла, например, firefox.exe, для поиска в PATH.
Короткое имя зарегистрированного в системе приложения, например, firefox.exe, для поиска в реестре.
Имя зарегистрированного в системе типа файла, например, htmlfile, для поиска в реестре.
Имя зарегистрированного в системе расширения файлов, например, .html, для поиска в реестре.
По умолчанию используются все методы поиска, но при необходимости можно уточнять метод поиска с помощью опций.
Поиск приложения основан на том, что при установке программ они регистрируются в системе,
помещая в реестре информацию о своем местонахождении, а также о типах файлов, которые они обрабатывают.
Поиск и запуск приложений на основе заданного списка приоритетов - довольно удобная вещь.
Теперь можно организовать вызов файлов (справки, документации и т.д.) так,
чтобы (обычно) запускалось "любимое" приложение, но если оно не найдено,
то искалось второе, третье, ..., и, наконец, приложение "по умолчанию".
Например, при вызове:
unix getapppath firefox.exe chrome.exe .html --start c:\Crw32exe\Resource\Manual\crw-daq.htm
сначала ищется firefox, при его отсутствии - chrome, при его отсутствии - используется
приложение по умолчанию для файлов *.html.
При этом файл все равно будет открыт - первым из найденных приложений.
В сборку UnixUtils добавлены команды
unix PhotoViewerC (консольная версия)
unix PhotoViewerW (графическая версия)
для вызова стандартного приложения Windows "Просмотр изображений".
Необходимость команд связана с тем, что "Просмотр изображений" реализован через вызов динамической библиотеки
rundll32.exe shimgvw.dll,ImageView_Fullscreen ..., что довольно громоздко и неудобно.
Лучше так:
В конфигурации программы Q-Dir задействованы новые утилиты.
А также добавлен ряд полезных программных утилит.
Во всех ДЕМО конфигурациях и в программе DaqCreator
обновлены (приведены к единому виду) файлы Simulation.bat.
Сборка UnixUtils серьезно переработана.
Изменения были внутреннего свойства (рефакторинг), они почти не коснулись внешнего поведения.
Тем не менее надо повнимательнее посмотреть, не сломалось ли что-нибудь.
Сделаны внутренние изменения в системе обработки исключений (процедура BugReport),
чтобы была возможность обрабатывать отдельные исключения как "безопасные",
для которых не производится запись в журнал и отображение всплывающего окна сообщения об ошибке.
Некоторые исключения (типа "файл не найден") являются вполне рядовыми случаями и не должны
отвлекать внимание операторов.
В Главную Консоль добавлена команда @getapppath, которая работает аналогично команде
unix getapppath.
Фактически это интеграция команды GetAppPath в состав ядра пакета.
Например:
В команду @run добавилась опция @run /wsh,
которая запускает приложение через COM объект WScript.Shell (как делает VBS).
Этот метод запуска имеет то преимущество, что может запускать зарегистрированные в реестре приложения,
даже если их нет в PATH (аналогично работает команда cmd start).
Например:
@run firefox.exe скорее всего не сработает, т.к. приложения нет в PATH
@run /wsh firefox.exe скорее всего сработает, если Firefox верно установлен
В команду @run добавилась опция @run -app "apptypes",
которая задает приложение, с помощью которого надо запускать файл.
Приложение задается на основании "списка предпочтений" apptypes.
В список для поиска могут входить имена EXE файлов, расширения и типы файлов.
Например:
В этом примере файл справки будет открыт одним из доступных браузеров, в порядке предпочтений.
В команду @env добавилась опция @env -app,
которая вызывает GetAppPath для поиска приложения и присваивает заданной
переменной окружения найденное приложение.
Например:
В данном примере переменной окружения HtmlBrowser будет присвоен
(а затем выведен на печать) полный путь одного из перечисленных приложений
(точнее - первого найденного в списке).
Сначала ищется firefox, затем chrome, затем iexplore,
а затем (как крайний случай) - браузер по умолчанию для файлов .html.
Переменную окружения затем можно использовать для запуска найденного приложения.
Новая опция дает возможность запуска приложений на основе списка приоритетов,
чтобы файлы и документы открывались в вышем "любимом" приложении,
но на худой случай (если оно не доступно) - открывались
в каком-нибудь доступном приложении.
В Главной Консоли существенно переработана обработка опций.
Вообще из практики известны такие виды опций:
/V короткие опции в стиле Windows
/VERBOSE длинные опции в стиле Windows
//V короткие опции в стиле WScript
//VERBOSE длинные опции в стиле WScript
-v короткие опции в стиле Linux
-verbose длинные опции в стиле Linux
--verbose длинные опции в стиле GNU
Обработка опций в кодах ранее делалась "по месту", разными способами. Это было нехорошо и некрасиво.
К тому же опции в стиле /Windows в других системах не поддерживаются, т.к. символ /
используется в качестве разделителя в именах файлов.
Теперь для разбора опций была сделана новая функция (IsOption), чтобы обрабатывать все опции одинаково.
При этом допускаются опции любого вида, но в новых кодах предпочтение надо отдавать опциям в стиле GNU/Linux.
Например:
@run /sw3 /cd %Temp% explorer.exe опции в старом стиле (будет работать как и раньше)
@run -sw3 -cd %Temp% explorer.exe опции в новом стиле (теперь это предпочтительнее)
С помощью новых средств (@env -app) в секции
Crw32.ini [System.StartupScript]
добавляется ряд переменных окружения для "приложений по умолчанию",
а также в секции Crw32.ini [@run]
определяются псевдонимы команды @run:
При этом конкретное приложение определяется на основании "списка предпочтений",
который определяет для каждого вида приложений возможные варианты в порядке приоритета.
Будет выбрано наиболее подходящее приложение из доступных в системе.
Кроме того, для некоторых часто используемых расширений (типов файлов) добавлены ассоциации:
Все это позволяет расширить возможности команды @run.
Теперь для открытия файлов и документов разного типа будут использоваться предпочитаемые приложения,
а не те, которые стоят в операционной системе по умолчанию.
Команда @run существенно переработана.
Более корректно обрабатываются имена файлов в кавычках.
Добавлены псевдонимы в секции
Crw32.ini [@run].
Псевдонимы (alias) начинаются с @ (например @LogViewer),
которые заменяются при выполнении на указанный файл (может содержать %переменные_окружения%).
Они отличаются тем, что не добавляют путь файла в переменную окружения CRW_DAQ_SYS_PATH.
То есть команда будет выполняться, но её каталог в пути поиска программ не включается.
Добавлены ассоциации в секции Crw32.ini [@run].
Ассоциации начинаются с . (например .html) и позволяют вызывать
нужный обработчик по расширению файла, минуя системные ассоциации,
что позволяет сделать прикладной код менее зависимым от настроек системы.
Они также не добавляют путь файла в переменную окружения CRW_DAQ_SYS_PATH.
То есть команда будет выполняться, но её каталог в пути поиска программ не включается.
Опции обрабатываются в новом стиле.
Меню Web переименовано в Ссылки.
В него добавлено много полезных ссылок, которые помогут ускорить работу прикладного программиста,
т.к. нужные средства всегда будут под рукой.
Кроме того, в меню Файл/Создать добавлен вызов DaqCreator и DaqConstructor.
Обновлена документация DIM.
Добавлены рекомендации по проектированию DIM серверов (с точки зрения производительности).
Добавлены соглашения о наименовании DIM серверов.
В новой редакции предлагается давать серверам имена вида DIM_TASK/СИСТЕМА/SERVER
с постоянным префиксом DIM_TASK.
Причина - надо отделить пространство имен служебных сервисов DIM от информационных.
Это позволяет легко организовывать экспорт всех данных сервера через мост DimBridge.
При этом ненужной публикации служебных данных не происходит.
В большом числе DEMO конфигураций (кроме относительно устаревших)
сделано наименование DIM серверов с префиксом DIM_TASK,
в согласии с новыми соглашениями о наименовании.
Изменена структура основного файла конфигурации Crw32.ini.
Теперь он ссылается на Resource\Crw32.Prime.ini,
в который включаются все остальные файлы конфигурации.
Причина - желание максимально облегчить основной конфигурационный файл
и вынести все сложные специфические конфигурации в каталог Resource.
В DaqPascal добавлена группа констант и функций для анализа и формирования командной строки,
содержащей кавычки и опции.
QuoteMark - константа, символ двойной кавычки (Quotation Mark по Unicode).
Apostrophe - константа, символ одинарной кавычки (Apostrophe по Unicode).
ExtractFirstParam - выделение первого аргумента строки (который может быть в кавычках).
SkipFirstParam - пропуск первого аргумента строки (который может быть в кавычках), возвращается остаток строки.
IsOption - проверка того, что аргумент является опцией (типа -help).
GetOptionValue - выделение из опции (типа --file=help.htm) значения (help.htm).
AnsiQuotedIfNeed - помещает строку аргумента в кавычки, если надо (если в ней есть пробелы).
В документации есть подробный пример, который иллюстрирует применение этих функций.
Пример рабочий, взят из DEMO_TESTBENCH.
Новые функции содержат практически все, что надо для разбора или формирования командной строки с параметрами,
заключенными в кавычки (если они содержат пробелы) и опциями (если нужны опции).
Следует, однако, заметить, что новые функции для анализа строк с кавычками
существенно сложнее (по внутренней реализации) и работают несколько медленнее,
чем простой разбор слов по старой схеме на основе WordCount/ExtractWord/SkipWords.
Поэтому там, где кавычки не используются, лучше использовать старые функции разбора слов.
В демо конфигурацию DEMO_TESTBENCH внесен пример использования
новых функций обработки командной строки, вызов по @test 3 в консоли устройства.
Обновлен редактор мнемосхем Origami.
Обновление предоставил А.Жирунов.
Главными достижениями данного выпуска являются:
добавление файлового менеджера Q-Dir;
добавление команд подтверждения и копирования/синхронизации в UnixUtils
обновление консольных утилит Crw32.Utils.lm9.
В инсталлятор runtime добавлена программа Q-Dir.
Это свободный (freeware) двухпанельный файловый менеджер (к сожалению, без исходных кодов).
Его достоинством является маленький размер (архив менее 700K),
портабельность (не требует установки, не пишется в реестре)
и работа под всеми версиями Windows.
Добавление файлового менеджера Q-Dir обусловлено тем, что на машинах с минимальной установкой
(когда ставится только runtime) работа крайне затрудняется из-за отсутствия файлового менеджера.
Штатный Проводник (explorer) проблему не решает, с ним трудно работать из-за низкой функциональности.
При этом возможность развернуть полную среду есть далеко не всегда.
Поэтому на такой случай нужен хотя бы минимальный файловый менеджер, который должен быть всегда доступен.
Небольшой по размеру Q-Dir прекрасно подходит на роль рабочего инструмента, который всегда под рукой.
Вызов файлового менеджера в Главной Консоли пакета можно делать так:
@run /cd .. Q-Dir прямой вызов Q-Dir
@run /cd .. FileManager вызов через псевдоним
Примечание: псевдонимы задаются в секции Crw32.ini [@run]
В приведенном примере опция /cd .. нужна для того, чтобы файловый менеджер
запускался в другом (родительском) каталоге и не блокировал рабочую папку пакета,
что (потенциально) может помешать при инсталляции новой версии пакета.
В меню Инструменты добавлена команда
Файловый Менеджер.
Она запускает команду @run /cd .. FileManager.
В консольные утилиты Crw32.Utils.LM9 на закладке Tools добавлена кнопка
Q-Dir File Manager.
Слегка модифицирована библиотека изображений в DieselPascal/External.
В Crw32.ini [System.StartupScript] теперь задается переменная окружения PROGRAMS_PORTABLE.
Она указывает на католог %SystemDrive%\Programs\Portable, где у нас будут располагаться
переносимые (portable) программы, т.е. программы, не требующие специального инсталлятора
и не регистрируемые в реестре.
Именно там будет расположена, например, программа Q-Dir.
Ссылка %PROGRAMS_PORTABLE%\SoftwareOK.com\Q-Dir\Q-Dir.exe должна работать в Главной Консоли.
В Crw32.ini [System.StartupScript] теперь задается переменная окружения ask-confirm-timeout=60.
Это время ожидания по умолчанию для команды unix ask-confirm в секундах.
Если за это время кнопка не нажата, диалог отменяется (нажимается Cancel).
В сборку UnixUtils добавлена команда unix system-shutdown-dialog.
Как нетрудно догадаться, команда вызывает диалог для завершения работы системы.
Эта команда может использоваться в прикладных системах для завершения работы,
особенно если обычная кнопка убрана с экрана (спрятана).
В сборку UnixUtils добавлена команда unix ask-confirm.
unix ask-confirm --timeout 60 "Подтверждение" "Хотите это сделать?" && cmd /c echo Это сделано.
Команда вызывает диалог Yes/No/Cancel и ждет подтверждения в течение timeout секунд.
Если нажата кнопка Yes, возвращается статус успеха (0), иначе возвращается статус ошибки (1).
Статус используется для условного выполнения команд (например, с помощью операторов &&, ||).
Команда очень удобна для быстрой организации простых диалогов подтверждения в командных файлах.
В сборку UnixUtils добавлена команда unix ask-confirm-call.
unix ask-confirm-call --timeout 60 "Подтверждение" "Хотите это сделать?" cmd /c echo Это сделано.
Эта команда выводит запрос unix ask-confirm и при подтверждении выполняет указанную команду с аргументами.
Она тоже может использоваться в командных файлах, но гораздо лучше приспособлена для вызова из Главной Консоли,
так как выполняется как один оператор (не надо организовывать проверку статуса и т.д.).
В сборку UnixUtils добавлены команды unix xcopy-update,
unix xcopy-overwrite, unix robocopy-update,
unix robocopy-mirror.
Это команды копирования, резервирования и синхронизации файлов и папок.
unix xcopy-update C:\Source\Data D:\Backup\Data - обновляет данные из папки Source в папку Backup
копируются только новые или измененные файлы
избыточные файлы из Backup не удаляются
unix xcopy-overwrite C:\Source\Data D:\Backup\Data - копирует данные из папки Source в папку Backup
копируются и перезаписываются все файлы
избыточные файлы из Backup не удаляются
unix robocopy-update C:\Source\Data D:\Backup\Data - обновляет данные из папки Source в папку Backup
копируются только новые или измененные файлы
избыточные файлы из Backup не удаляются
unix robocopy-mirror C:\Source\Data D:\Backup\Data - зеркалит данные из папки Source в папку Backup
копируются только новые или измененные файлы
избыточные файлы из Backup удаляются
Примечания: 1) Папки источника и приемника должны существовать (их надо создать заранее).
2) ROBOCOPY аналогична XCOPY, но надежнее в работе, а также имеет больше опций.
Приведенные команды копирования, резервирования и синхронизации можно использовать совместно с утилитами
unix ask-confirm, unix ask-confirm-call, чтобы подтверждать выполнение операций
(которые могут быть долгими и критичными с точки зрения сохранности данных).
Первоначально перечисленные команды создавались для интеграции в файловый менеджер Q-Dir,
но они представляют самостоятельный интерес и для прикладного программирования в пакете CRW-DAQ.
В сборку UnixUtils добавлена команда unix shell-appactivate.
unix shell-appactivate "CRW32 #123" && cmd /c echo Программа активирована.
Команда активирует программу с указанным заголовком в окне (если оно найдено).
Активация заключается в том, что окно программы вытаскивается наверх и получает фокус ввода.
Утилита работает аналогично команде unix setforegroundwindow,
но реализована на VBS и имеет ряд отличий в алгоритме поиска окна.
В меню Q-Dir добавлены ссылки на огромное число системных и служебных программ и папок,
чтобы сделать доступным их быстрый вызов из одного места.
Это превращает Q-Dir в мощный инсструмент для настройки и администрирования системы.
Меню программ находятся в файле настроек в секции Q-Dir.ini [Programs],
а папок - в секции Q-Dir.ini [Quick-Links].
Кроме того, для резервного копирования данных в меню Q-Dir сделаны разделы (Backup tools)
с вызовом (после запроса подтверждения) утилит резервирования
(xcopy-update, xcopy-overwrite, robocopy-update, robocopy-mirror).
Поскольку все команды в меню Q-Dir сделаны на основе (уже имеющихся на диске) системных программ
и (маленьких по размеру) скриптов, то Q-Dir предоставляет чрезвычайно компактный,
и в то же время довольно мощный инструментарий, вполне достаточный для настройки и технической поддержки
систем на машинах конечных пользователей, где работают прикладные системы измерений и управления.
Инструменты Origami, Kirigami, DIMgen логически объединены в один набор инструментов
DaqConstructor
и перенесены в общую папку
Resource/DaqSite/DaqConstructor.
Ссылка на DaqConstructor внесена в список TopList основного файла справки.
В консольные утилиты Crw32.Utils.LM9 на закладке Tools добавлена кнопка
DaqConstructor.
Обновлен редактор мнемосхем Origami.
Обновление предоставил А.Жирунов.
Добавлен генератор DIM сервисов DIMgen.
Обновление предоставил А.Жирунов.
20.09.2021
DEMO_DIM_PING dim_benchmark.lm9 &DimSrv
Главными достижениями данного выпуска являются:
обновление сервера &DimSrv;
обновление утилиты dim_benchmark.lm9;
добавление тестовой системы DEMO_DIM_PING.
Этот выпуск посвящен тестовой системе (DEMO_DIM_PING) для анализа производительности
и быстроты (времени отклика) работы сервера &DimSrv сетевой технологии DIM.
Целью было создание инструмента, позволяющего оценить свойства и границы применимости DIM
для создания распределенных систем управления.
Создана тестовая система DEMO_DIM_PING
для анализа производительности и быстроты (времени отклика) работы сервера &DimSrv
сетевой технологии DIM.
Тестовая система DEMO_DIM_PING работает следующим образом.
DIM клиент посылает DIM серверу одиночное или периодическое сообщение (ping)
с меткой времени и идентификатором клиента.
Сервер, получив этот пинг, формирует ответное сообщение заданного размера и посылает его клиенту.
Клиент, получив ответ, извлекает метку времени и вычисляет время отклика (pingtime), т.е. разницу времени
между посылкой пинга и получением ответа.
Измеренный pingtime отображается в виде графика и частотной гистограммы, чтобы оценить не только
величину, но и распределение времени отклика.
При этом измеряется частота пингов в секунду, объем передаваемых данных и нагрузка процессора (в данном процессе).
Имеется краткое описание.
Обновлена тестовая утилита dim_benchmark.lm9.
В неё добавлены (на закладке DIM_PING Benchmark) средства для тестирования производительности
сетевой технологии DIM и встроенного сервера &DimSrv с помощью тестовой системы
DEMO_DIM_PING.
С помощью этих средств можно сконфигурировать и запустить тестовую систему с заданным префиксом,
числом публикуемых сервисов и т.д.
Обновлен сервер &DimSrv.
В DimLib.pas проведена оптимизация блокировок, снижающая нагрузку на процесс DimSrv.exe
примерно в два раза при высокой частоте опросов.
В DimSrv.pas увеличены (в 4 раза) буферы памяти для возможности обслуживать системы большого размера.
В DimSrv.cfg увеличены (в 4 раза) буферы FIFO для возможности обслуживать системы
с большим потоком данных.
Увеличение буферов памяти сделано по результатам (предварительного) тестирования сервера &DimSrv
с помощью системы DEMO_DIM_PING.
Увеличение буферов "стоит" примерно 5.5MB памяти, что при современных объемах памяти признано оправданной
платой за увеличение производительности и пропускной способности сервера &DimSrv.
Главными достижениями данного выпуска являются:
обновление функции ParamStr;
обновление консольных утилит Crw32.Utils.lm9;
устранение ошибки реализации @daq compile ...;
увеличение максимального числа COM портов (MaxPortNum).
Обновлена функция ParamStr.
В нее добавлены параметры:
ParamStr('AnsiCodePage') Кодовая страница Windows (обычно 1251)
ParamStr('OemCodePage') Кодовая страница DOS (обычно 866)
ParamStr('System Screen Width') Ширина экрана, в пикселях
ParamStr('System Screen Height') Высота экрана, в пикселях
...и т.д. ... см. подробнее ParamStr('System Screen ...')
Напоминаем, что вызов ParamStr можно сделать в любой консоли шаблонной программы командой @paramstr ... .
Это позволяет разработчикам как узнавать системные параметры через консоль, так и использовать их в программах DaqPascal.
Н.Гурин обнаружил серьезную ошибку в реализации командах компиляции
@daq compile ... и @compile device ...,
которые используются для перезапуска серверов "на лету".
Она проявлялась в виде "мертвой блокировки" (deadlock) в случае вызова команды @daq compile &CronSrv.
В ходе "разбора полетов" было выяснено, что проблема возникает из-за использования при инициализации программы
CronSrv.pas вызова выражений типа eval('@system ...'), например, eval('@system ansicodepage').
Взаимная блокировка возникает из-за того, что команда @daq compile ... выполняется в критической
секции, так же как и вызов eval('@system ansicodepage').
Для устранения ошибки, во-первых, в коде сервера
CronSrv.pas
"проблемные" вызовы вида eval('@system AnsiCodePage')
заменены безопасными вызовами вида ParamStr('AnsiCodePage').
Во-вторых, коды команд @daq compile ... и @compile device ...
изменены (выведены из критической секции) так, чтобы принципиально исключить deadlock.
Сейчас проблема вроде бы устранена.
Добавлена тестовая утилита dim_benchmark.lm9.
Она предназначена для тестирования производительности сетевой технологии DIM.
Пока реализован тест для проверки "чистого" DIM (не интегрированного в пакет CRW-DAQ).
Этот тест использует "штатные" (входящие в дистрибутив DIM) утилиты benchServer, benchClient.
Для проверки интегрированного в пакет сервера &DimSrv требуются дополнительные усилия.
Вероятно, это будет сделано в ближайшее время.
Обновлена библиотека dpSysUtils.pas для DieselPascal.
Добавлены некоторые функции времени (msecnow и другие).
В консольные утилиты Crw32.Utils.LM9 на закладке DAQ добавлена кнопка DIM Benchmark
для вызова утилиты тестирования производительности сетевой технологии DIM.
В самой утилите Crw32.Utils.LM9 сделана процедура посылки сообщения без потери фокуса ввода (PostCommandToCrwDaq),
которая позволяет сократить число переключений между CRW-DAQ и утилитой Crw32.Utils.LM9,
что делает работу более удобной.
Раньше для всех команд использовалась процедура посылки сообщения с передачей фокуса ввода (SendCommandToCrwDaq),
которая всегда переключала фокус на CRW-DAQ, даже если в этом не было необходимости.
Теперь для большинства команд используется PostCommandToCrwDaq,
а вызовы SendCommandToCrwDaq сохранены только для команд, где это нужно по логике работы.
Обновлены также другие утилиты (CfgConfigurator.lm9, CrcConfigurator.lm9, DaqCreator.lm9,
TestPing.lm9, SmiGenGui.lm9, 01_Template_Utility.LM9).
В них тоже добавлена функция PostCommandToCrwDaq.
Устанена ошибка в команде @compile file.dpr компиляции проектов ObjectPascal.
Ошибка была в том, что не указывался каталог назначения компиляции, в результате чего компиляция происходила
во временный каталог (поди потом найти откомпилированный файл *.exe или *.dll).
Сейчас результат компиляции переносится в каталог файла проекта (*.dpr).
Кроме того, введены две команды @compile silent и @compile verbose
для отключения или включения режима подробной компиляции проектов *.dpr.
По умолчанию компиляция происходит молча (silent), при включении "многословного" режима (verbose)
при компиляции выдается подробная диагностика.
Проведена небольшая оптимизция службы Daq.Adams, которая обслуживает опрос всех ADAM-устройств.
Оптимизация сделана для того чтобы можно было увеличить максимальное число COM-портов
без потери производительности.
Максимальное число COM-портов увеличено с 64 до 250. Скорее всего, это окончательное значение.
27.08.2021
uart MaxPortNum
Главными достижениями данного выпуска являются:
оптимизация службы System.uart;
увеличение максимального числа COM портов (MaxPortNum).
Данный выпуск продолжает работы по виртуальным COM-портам -
com0com.
Работа с виртуальными портами может потребовать большего числа доступных COM-портов,
чем предусмотрено сейчас. Их число надо увеличить.
Проведена небольшая оптимизция службы System.uart, которая обслуживает опрос всех COM-портов.
Оптимизация сделана для того чтобы можно было увеличить максимальное число COM-портов
без потери производительности.
Максимальное число COM-портов увеличено с 32 до 64 (хватит пока?).
Это число можно увеличить до 255 изменением константы _UART.MaxPortNum,
которая задает максимальное число опрашиваемых COM-портов.
После изменения константы требуется перекомпиляция пакета.
Главными достижениями данного выпуска являются:
исправление ошибок в пакете com0com;
исправление WEB_MetaSetCookie;
обновление Origami и добавление Kirigami;
обновление консольных утилит Crw32.Utils.lm9;
довавление службы задач в сервере &CronSrv.
Данный выпуск продолжает работы по добавлению пакета для работы с виртуальными COM портами -
com0com.
Исправлено 2 ошибки в com0com.bat - запуск утилит setupg, setupc должен производиться
в каталоге установки com0com.
Исправлена ошибка в файле документации (там была использована внешняя ссылка вместо относительной).
Сделаны небольшие доработки в com0com.lm9.
Месяц (с 17.05 по 18.06) "выпал" из-за болезни.
Изменения в процедуре WEB_MetaSetCookie,
предложенные А.Жируновым в следующем сообщении:
Конструкция meta <http-equiv="Set-Cookie" content="*"> более не поддерживается браузерами с 2020-11-30 как устаревшая.
Современные браузеры ругаются на данный тег и блокируют их куки, обойти это можно только добавлением домена в исключения.
Чаще всего на современных сайтах куки посылают в заголовке (не в теге!) header документа, но оказалось,
что TinyWeb не имеет возможности генерировать и отправлять куки динамически в заголовке.
Потому пришлось задавать их средствами JavaScript, а так как куки шифруются, то на безопасность это не повлияет.
{
Set meta tag Set-Cookie Name=Value.
}
procedure WEB_MetaSetCookie(Name,Data:String);
begin
if Length(Name)>0 then
WEB_Reply('<script>document.cookie="'+Name+'='+Data+'";</script>');
end;
См. также https://learn.javascript.ru/cookie.
Спецификация HTML5 предлагает игнорировать конструкцию meta <http-equiv="Set-Cookie" content="*">,
поэтому от неё вреда вроде бы не будет. Для обратной совместимости её можно сохранить.
Поэтому в принятой реализации сохранены оба способа задания cookie.
Сделанные изменения касаются только прикладных систем, использующих сервер &WebSrv.
Обновлен редактор мнемосхем Origami.
Обновление предоставил А.Жирунов.
Добавлен редактор диалогов Kirigami.
Обновление предоставил А.Жирунов.
В консольные утилиты Crw32.Utils.LM9 на закладке DAQ добавлена кнопка Kirigami
для вызова редактора диалогов.
Также на закладке CRW добавлены кнопки List of.. Tasks, Hosts, Domains для получения списка задач,
серверов и доменов.
Обновлена библиотека DieselPascal\External.
Обновлен движок DieselPascal от версии 2.0.14 до версии 2.0.15.
Добавлена ДЕМО конфигурация
EGP_VACS
для управления вакуумной системой, которая заменила собой старую систему EGP_ACVS.
Обновление предоставил Н.Гурин.
Добавлена ДЕМО конфигурация
EGP_MZVS
для управления вакуумной системой микрозонда.
Обновление предоставил Н.Гурин.
Добавлена ДЕМО конфигурация
EGP_MAIN
для управления верхнего уровеня.
Обновление предоставил Н.Гурин.
Добавлена ДЕМО конфигурация
DEMO_OSM
с драйвером шагового двигателя серии OSM производства ООО «Онитекс».
Обновление предоставил Н.Гурин.
Добавлена ДЕМО конфигурация
DEMO_PID
с алгоритмом PID регулирования (новая версия).
Старая версия (пока) сохранена в каталоге DEMO_PID_OLD и (возможно) будет удалена в будущем,
после "обкатки" новой версии регулятора.
Обновление предоставил М.Ефремов.
Изменения в работе функции task_kill.
В предыдущей версии task_kill с консольными процессами методы 1 (WM_CLOSE), 2 (WM_QUIT) не работали.
Это связано с тем, что у консоли не срабатывала функция поиска окна, которому надо передавать сообщение.
Сейчас поиск окна консоли происходит по номеру процесса и имени класса окна (ConsoleWindowClass).
Теперь эти методы (вроде бы) должны работать корректно.
Для консольных окон метод 1 (WM_QUIT) эквивалентен нажатию CTRL-C или нажатию кнопки закрытия окна ("крестик").
Это "мягкий" способ завершения процесса, при котором процессу дается возможность завершиться нормальным образом,
выполнив предусмотренные процедуры перед выходом.
Напротив, метод 0 (TerminateProcess) является "жестким", когда процесс завершается принудительно,
без возможности выполнить предусмотренные процедуры перед выходом.
Рекомендуется завершать (консольные) процессы в два этапа - сначала методом 1 (WM_CLOSE)
в течение некоторого времени, а потом (для надежности) методом 0 (TerminateProcess).
То есть завершение процессов рекомендуется делать примерно так:
if task_wait(tid,0) then // Если процесс работает
if task_kill(tid,1,0,1000) then // Пробуем убить процесс "мягко" (через WM_CLOSE) в течение 1000 ms
Success('Kill(1) PID '+str(task_pid(tid))); // Если получилось, то пишем сообщение
if task_wait(tid,0) then // Если процесс все еще работает
if task_kill(tid,0,0,1000) then // Пробуем убить процесс "жестко" (через Terminate) в течение 1000 ms
Success('Kill(0) PID '+str(task_pid(tid))); // Если получилось, то пишем сообщение
При использовании метода завершения 1 (WM_CLOSE) следует иметь в виду код возврата.
Если консольная задача завершается через ^C (CTRL-C),
что эквивалентно посылке консольному окну WM_CLOSE,
то кодом возврата процесса будет
STATUS_CONTROL_C_EXIT = -1073741510; // Код завершения при CTRL-C = $C000013A
Также поправлены неточности в документации по функции task_kill.
Добавлена служба задач
в сервере &CronSrv.
Для этого обновлен программный код сервера
CronSrv.pas
(ключевые слова для поиска изменений - task_, tasker).
Служба задач позволяет запускать, завершать и контролировать задачи (процессы) по именам
через консольные команды @task_xxxx.
При этом служба задач может автоматически следить за работой процессов и (пере)запускать их в случае падения.
Таким образом, управление процессами можно проводить на уровне конфигурирования,
без написания программного кода на DaqPascal.
Есть пример конфигурирования задач.
Задачами также можно управлять из других программ путем посылки сообщений серверу &CronSrv
(см. процедуру Cron).
Обновлена демо конфигурация DEMO_CRON, чтобы проиллюстрировать
работу службы задач &CronSrv.
Конфигурирование службы задач - в файле
DEMO_CRON.CFG.
Служба задач завершает (пока) цикл работ по интеграции пакета com0com.
Теперь все необходимые для com0com процессы (com2tcp) можно запускать
через службу задач сервера &CronSrv, помещая их в секцию [&CronSrv.StartupScript].
Главными достижениями данного выпуска являются:
добавление утилиты lsps;
добавление пакета com0com для работы с виртуальными COM портами;
обновление консольных утилит Crw32.Utils.lm9.
Данный выпуск посвящен преимущественно добавлению пакета для работы с виртуальными COM портами -
com0com.
Сопутствующие утилиты добавлялись для достижения этой цели, хотя эти утилиты полезны и сами по себе.
В сборки UnixUtils и Runtime добавлена команда lsps.
Название можно считать комбинацией известных команд - ls (list) и ps (process status),
то есть совместно получается (list process status) - список процессов.
Команда lsps выводит список процессов с заданным PID, PPID и именем Name процесса
(имя процесса совпадает с коротким именем EXE файла).
Нулевое значение PID, PPID или пустое имя процесса означает любой процесс.
При выводе списка выводится: номер процесса PID, номер родительского процесса PPID,
приоритет процесса Pr, имя процесса Name и командная строка CommandLine,
если она доступна (системные процессы могут быть недоступными).
Например:
unix lsps вывод списка всех процессов
unix lsps 4501 вывод информации по процессу номер 4501
unix lsps 4501 && echo process exists проверка существования процесса с заданным номером
unix lsps 0 3715 вывод списка процессов порожденных процессом 3715
unix lsps 0 0 cmd.exe вывод всех процессов cmd.exe
@run unix lsps & pause вызов утилиты lsps из Главной Консоли
Пример вывода:
> unix lsps 0 0 cmd.exe
PID PPID Pr Name CommandLine
4552 4584 8 cmd.exe C:\WINDOWS\system32\cmd.exe /c unix lsps & pause
1392 3644 8 cmd.exe cmd /k call .cmdansicon --prompt & call ver & echo User «main» running in colorized console mode... &
2164 1116 8 cmd.exe C:\WINDOWS\system32\cmd.exe /Q /C lsps 0 0 cmd.exe
Утилита lsps была создана в ходе работ по добавлению пакета com0com,
но она полезна и сама по себе, например, для командных сценариев или проверки существования заданных процессов.
В сборке обновлены Firefox и LibreOffice.
В ходе создания утилиты lsps обновлена библиотека libsys.vbs, которая входит во все инсталляторы.
Поэтому обновились все инсталляторы.
В сборки UnixUtils и Crw32-Runtime добавлен пакет
com0com.
Виртуальные COM порты приобретают большую актуальность в связи с несколькими причинами:
Потребность проброски COM портов при использовании виртуальных машин, например, VirtualBox.
Потребность проброски COM портов через сеть Ethernet в некоторых распределенных системах.
Многие фирмы реализуют драйверы устройств USB или Etnernet в виде виртуальных COM портов.
Виртуальные COM порты позволяют создавать простые в использовании каналы связи между процессами (IPC).
Виртуальные COM порты позволяют создавать реалистичные симуляторы реальных устройств для отладки драйверов.
Большинство виртуальных COM портов - коммерческие, с закрытым кодом, что в зачастую неприемлемо.
Пакет com0com - один из немногих свободных пакетов с открытым исходным кодом под лицензией GPL.
Поэтому для включения в сборку пакета был выбран именно он.
Назначение пакета com0com - драйвер ядра и инструменты для работы с виртуальными COM портами.
Пакет содержит несколько компонентов, которые совместно решают задачу обеспечения
работы с виртуальными COM портами.
Драйвер ядра com0com.sys с сопутствующими файлами (*.inf) для реализации программного нуль-модема,
т.е. пары соединенных друг с другом виртуальных COM портов.
При этом данные, записанные в один порт, могут читаться из другого (парного) порта и наоборот.
Консольная утилита setupc.exe для создания и настройки виртуальных COM портов через консольные команды.
Графическая утилита setupg.exe для создания и настройки виртуальных COM портов через графическое окно диалога.
Консольная утилита com2tcp.exe для проброски виртуального COM порта в сеть TCP/IP или обратно.
Консольная утилита hub4com.exe для проброски виртуального COM порта с расширенными возможностями.
Специально созданная консольная утилита com0com.bat, облегчающая интеграцию com0com в пакет CRW-DAQ.
Специально созданная графическая утилита com0com.lm9, облегчающая интеграцию com0com в пакет CRW-DAQ.
Документация и исходные коды пакета com0com.
Утилита com0com.bat специально создана для работы с пакетом com0com
из Главной Консоли CRW-DAQ (а через неё - из программ DaqPascal).
Например:
@run /sw7 com0com --install вызов инсталлятора пакета com0com (в молчаливом режиме)
@run /hide com0com --setupg вызов графической утилиты для настройки виртуальных COM портов
@run /hide com0com --gui вызов графической утилиты для инсталляции и настройки пакета com0com
Утилита com0com.lm9 специально создана для удобной работы с пакетом com0com
через графическое окно диалога.
Фактически это графическая надстройка над утилитой com0com.bat, облегчающая её использование.
Например:
@run com0com.lm9 вызов графической утилиты для инсталляции и настройки пакета com0com
Следует заметить, что пакет com0com не инсталлируется "по умолчанию", т.к.
1) виртуальные порты нужны не всегда, и
2) при установке драйвера ядра требуется обязательное подтверждение пользователя,
что исключает возможность установки в "молчаливом" режиме.
По этой причине установка com0com должна производиться явно, например, через Консольные Утилиты,
где на закладке DAQ есть вызов com0com.
Работа с виртуальными портами производится примерно так.
Инсталлируется драйвер ядра, по умолчанию в каталог %ProgramFiles%\com0com.
При инсталляции пользователь должен подтвердить установку драйвера.
С помощью утилиты setupg создаются и настраиваются нуль-модемные пары виртуальных портов.
Пакет com0com позволяет создавать любое число нуль-модемных пар виртуальных портов.
При использовании нуль-модемной пары в качестве канала межпроцессной связи (IPC) две программы
подключаются к парным COM портам и передают друг другу данные.
Для проброски COM порта в сеть TCP/IP один конец виртуальной нуль-модемной пары
используется клиентской программой, а второй подключается к программе com2tcp,
которой в аргументах передаются все необходимые данные (номер и настройки COM порта,
имя сервера (для клиента), номер TCP порта подключения).
Программа com2tcp должна вызываться для каждого порта, при этом за работой каждой программы
надо следить и перезапускать её при необходимости.
Программа hub4com содержит расширенные возможности по сравнению с com2tcp,
например, возможность разветвления порта на несколько подключений.
Эти возможности используются в особых случаях.
Например:
1) Создается нуль-модемная пара портов COM3--COM4
2) К COM3 подключается программа (драйвер CRW-DAQ)
3) Запускается программа проброски порта, например:
com2tcp --baud 115200 --data 8 --stop 1 --parity no --ignore-dsr \\.\COM4 26001
4) По другую сторону указанного TCP порта (26001) подключается, например, преобразователь Ethernet--COM
5) К преобразователю Ethernet--COM подключается реальное устройство на COM порт
Драйвер com0com может создавать порты двух видов - нуль-модемные пары вида CNCA0--CNCB0 или
пары вида COM3--COM4.
Вид порта задается флажком "use Port class" в утилите setupg.
Порты первого вида отличаются именами от стандартных имен типа COM3,
поэтому их нельзя использовать во многих программах, ориентированных на эти имена (включая CRW-DAQ).
Зато их можно использовать в программе com2tcp для проброски портов в сеть TCP/IP.
Можно создать смешанную пару вида COM3--CNCB0, используя один конец (COM3) для программы,
а другой (CNCB0) - для проброски порта в сеть, чтобы четко различать назначение портов.
Виртуальные порты могут использоваться большим числом способов, которые можно комбинировать.
Например, вместо преобразователя Ethernet--COM можно использовать другой компьютер, на котором
работает другой экземпляр com2tcp для подключения к реальному COM-порту.
Все это делает пакет com0com весьма гибким и полезным инструментом.
Относительным недостатком com0com можно считать сложность его начального освоения,
т.к. виртуальные порты имеют множество настроек.
Работа по интеграции com0com в пакет CRW-DAQ будет закончена в следующих релизах.
Собственно, сам по себе пакет com0com уже готов к работе, но требуется еще автоматизировать
запуск и завершение процессов com2tcp для проброски портов.
В консольные утилиты Crw32.Utils.LM9 на закладке DAQ добавлена кнопка com0com Control
для вызова команды com0com.lm9, которая позволяет инсталлировать, настраивать и управлять работой
пакета com0com. Там содержится практически всё, что надо для работы, включая справочную информацию.
Главными достижениями данного выпуска являются:
добавление утилиты spvoice;
обновление Painter(v) и GuiLib;
добавление графического элемента Painter(v).GuiLib.SimpleBar;
появление у тегов атрибутов (color,param,timer);
добавление 2 констант и 7 функций DaqPascal;
начало разработки библиотеки SmiuiRtl для создания GUI
на основе технологии конечных автоматов SMI;
правка и обновление стандартных библиотек DaqPascal.
Данный выпуск посвящен преимущественно исправлению, обновлению и доработке
стандартных библиотек DaqPascal,
а также продолжению работ по конечным автоматам SMI.
Исправлена ошибка в диалоге "Вставить из шаблона...",
которая заключалась в неверных размерах полей группы "Параметры" при изменении размеров окна.
Теперь размеры полей корректируются автоматически.
Исправлена ошибка в
DIM_GuiClickInit,
приводившая (в старых прикладных программах) к отказу в доступе при вызове функции
GrantAccessDim.
В DaqPascal добавлена функция
HasFlags(i,m),
которая облегчают обработку операций с битовыми флагами, например:
if HasFlags(mode,3) then writeln('Режим mode имеет 0 или 1 бит');
if HasFlags(mode,mask) then ...
-- эквивалентно
if (iAnd(mode,mask)<>0) then ...
Вызов HasFlags(mode,mask) эквивалентен вызову (iAnd(mode,mask)<>0),
но выглядит намного понятнее и работает немного быстрее.
Рекомендуется использовать эту функцию в новых разработках.
В стандартной библиотеке во многих модулях задействована новая функция HasFlags.
В DaqPascal добавлены системные константы
TASK_REF_MIN,
TASK_REF_MAX,
которые задают допустимый диапазон номеров задач (tid) в функциях типа
task_run,
что позволяет корректно организовывать циклы по всем задачам.
Например:
for tid:=TASK_REF_MIN to TASK_REF_MAX do
if (task_ref(tid)<>0) then writeln('TASK ',tid,' has PID ',task_pid(tid));
В стандартную библиотеку добавлены функции
TextLineCount,
ExtractTextLine,
которые облегчают обработку небольших текстов, состоящих из строк, например:
buff:='Line1'+CRLF+'Line2'+CRLF;
for i:=0 to TextLineCount(buff,CRLF)-1 do begin
writeln('Line ',i,' = ',ExtractTextLine(i,buff,CRLF));
end;
Обновлен редактор мнемосхем Origami.
Обновление предоставил А.Жирунов.
В Главной Консоли добавлена команда @list tasks для просмотра списка задач (task),
запущенных с помощью функций task_run.
Например, это может выглядеть так:
@list tasks
Task PID Status Priority CmdLine
1 2792 Stopped Normal C:\Crw32exe\Resource\SmiSite\smi\bin\SMISM.EXE DEMO C:\DAQ32\DEMO_SMITEST_GUI\CONFIG\run_con.sobj -dns localhost -d 9 -t
2 1632 Running Normal C:\CRW32EXE\RESOURCE\DAQSITE\SMISERVER\SMIPROXY.EXE -obj DEMO::EVT_BUILDER -set READY/NUMBER_T(I)=1/NUMBER_P(I)=1 -dns localhost
3 5492 Running Normal C:\CRW32EXE\RESOURCE\DAQSITE\SMISERVER\SMIPROXY.EXE -obj DEMO::LOGGER -set NOT_LOGGING -dns localhost
4 5644 Running Normal C:\CRW32EXE\RESOURCE\DAQSITE\CRONSERVER\CRONGRD.EXE
5 540 Running Normal C:\CRW32EXE\RESOURCE\DAQSITE\SPEAKSERVER\SPEAKSRV.EXE
Task(s) found: 5
Команда полезна для отладочных целей, т.к. в ней видно все запущенные DAQ-системой процессы.
В набор консольных утилит (UnixUtils) добавлена команда spvoice
для речевого синтеза с помощью "движка" (программного интерфейса) SAPI5.
Небольшая справка.
Для реализации TTS (text to speech, перевод текста в речь)
используются программные интерфейсы SAPI (Speech API) разных версий.
Во времена Windows-2000/Xp использовался синтезатор речи версии SAPI4,
на нем и был сделан речевой сервер &SpeakSrv, встроенный в CRW-DAQ.
В Windows-7/8/10 появился синтезатор SAPI5, программно несовместимый с SAPI4.
Хотя библиотеки несовместимы, они могут сосуществовать вместе и параллельно работать на одном компьютере.
В ОС Windows, начиная с версии 7 и выше - по умолчанию установлена голосовая ситема SAPI5.
Голосовые системы SAPI4 и SAPI5 не замечают друг друга и могут работать на одном компьютере.
Однако программа должна выбирать, какой движок использовать, т.к. они имеют разный программный интерфейс.
Как было сказано, речевой сервер &SpeakSrv использует SAPI4 и не умеет использовать SAPI5.
Возможно, со временем &SpeakSrv тоже научится использовать SAPI5, но пока этого нет.
Новая команда spvoice использует SAPI5 и дает альтернативный путь для речевой генерации.
Это полезно, т.к. SAPI5 дает более высокое качество звука при генерации речи из текста.
В настоящее время SAPI5 можно использовать через вызов утилиты spvoice.
Например:
В окне консоли cmd:
unix spvoice --help - для получения справки
unix spvoice "Hello world." "I feel good." - речевое ссообщение с параметрами по умолчанию
unix spvoice --rate 2 --volume 80 "I can speak English." - речевое сообщение с явным заданием параметров
В окне Главной Консоли Crw:
@run /hide spvoice --rate -2 --volume 100 --voice 1 "Привет, мир." "Я могу говорить на Русском."
Параметры можно задавать также через XML теги TTS, например для выбора голоса можно задать:
@run /hide spvoice "<voice required='language=419;gender=female;age=adult'/>Привет, друг мой."
Здесь код языка language=409/419=English/Russian; пол gender=male/female; возраст age=adult/teen/child.
А в следующем примере задается высота тона звука (тембр голоса) pith в диапазоне -10..10:
@run /hide spvoice "<pitch absmiddle='5'/>Привет, друг мой."
В DaqPascal добавлены функции
GetTagColor(tag),
SetTagColor(tag,color),
GetTagParam(tag),
SetTagParam(tag,param),
GetTagTimer(tag),
SetTagTimer(tag,timer),
которые работают с пользовательскими атрибутами тега.
Атрибуты тега (color,param,timer) - это пользовательские данные,
которые могут применяться для хранения дополнительных локальных параметров,
ассоциированных (связанных) с тегом.
Доступ к атрибутам не зависит от типа данных тега.
Атрибуты могут служить для взаимодействия с графической системой
Painter.
Сценарий Painter может обращаться к атрибутам присоединенного к сенсору тега через функции
LinkedTagColor(),
LinkedTagParam(),
LinkedTagTimer(),
что позволяет передавать в графический сценарий пользовательские данные,
в дополнение к значению данных тега.
Например, прикладная программа может менять цвет фона числового поля за счет вызова SetTagColor
в прикладной программе и вызова LinkedTagColor() в сценарии рисования тега.
В стандартную библиотеку общепринятых графических элементов
(GuiLib)
добавлен элемент
SimpleBar.
Он отображает простой (simple) прямоугольник (bar) заданного цвета (glBarColor)
и служит для задания цветного фона для рисования на нем текста или других графических элементов.
Обновлена конфигурация
DEMO_SMITEST,
где задание цвета сенсоров для состояний логических объектов Конечного Автомата (FSM)
сделано с помощью новых функций Get/SetTagColor.
Этот способ проще, понятнее и быстрее метода посыылки сообщений через WinDraw, который использовался раньше.
Для извлечения цвета (c) в сценарии Painter используется примерно такой код:
Эта конструкция не только извлекает цвет LinkedTagColor(), но и задает цвет по умолчанию (clSilver),
если функция LinkedTagColor() вернула ноль (мы ведь не хотим увидеть черный сенсор).
Ноль при вызове LinkedTagColor() может возникнуть, например, в начале работы,
пока прикладная программа еще не выполнила инициализацию.
С учетом использования SimpleBar вызов выглядит так:
Начато создание стандартной библиотеки
SmiuiRtl,
которая будет использоваться для создания прикладных программ (GUI),
основанных на Конечных Автоматах (SMI).
Поскольку эта библиотека довольно большая и используется не всегда,
то она не включается в StdLibrary автоматически (неявно),
а должна включаться включаться явно, как описано в документации.
Библиотека пока в стадии разработки.
Главными достижениями данного выпуска являются:
доработка функции edit.
Данный выпуск посвящен преимущественно обновлению и доработке функции edit,
а также продолжению работ по конечным автоматам SMI.
Сделаны доработки в функции edit.
Теперь задавать положение диалога (@set Form.Left ..., @set Form.Top ...)
можно при вызове любого диалога edit.
Если точнее, изменения коснулись диалогов
Warning,
YesNo,
YesNoCancel,
Information,
Error,
FileOpenDialog.
Обновлена демо конфигурация DEMO_EDIT
для иллюстрации возможностей функции
edit.
Новый параметр конфигурации Crw32.ini [System] UseEditSettings (по умолчанию 1)
позволяет отключить (при значении 0) работу настройки параметров Edit('@set ...').
Этот параметр сделан для обратной ссовместимости, чтобы можно было вернуть старое поведение
диалогов Edit(..) (например, при возникновении каких-либо проблем).
В стандартную библиотеку добавлены константы
mr_OK,
mr_CANCEL, ...
(от слова modal result = "модальный результат"),
которые можно использовать для анализа результатов диалогов
edit.
// Если строка s выглядит как команда, послать её в свою консоль:
Старый стиль: if (StrFetch(s,1)='@') then DevSendCmd(devMySelf,s);
Новый стиль: if LooksLikeCommand(s) then DevSendCmdLocal(s);
Новый стиль ввыглядит более понятным и лаконичным.
Рекомендуется его использовать в новых проектах и (при случае) заменять в старых.
В документации есть хороший пример
создания меню (CLOSE) с обработкой подтверждений и команд для каждого пункта меню,
а также с заданием настроек (шрифта и позиции окна на экране).
Этот пример иллюстрирует использование перечисленных выше функций.
А вот пример для понимания общей структуры обработки редактирования:
procedure PollApplication;
begin
...
{
Edit handling...
}
if EditStateDone then begin
{
Warning dialog completion.
}
if EditTestResultName('Warning') then begin
if EditTestResultCode(mr_OK) then writeln('Warning: OK button pressed.');
if EditTestResultCode(mr_CANCEL) then writeln('Warning: Cancel pressed.');
EditReset;
end;
{
YesNo dialog completion.
}
if EditTestResultName('YesNo') then begin
if EditTestResultCode(mr_YES) then writeln('YesNo: YES button pressed.');
if EditTestResultCode(mr_NO) then writeln('YesNo: NO button pressed.');
EditReset;
end;
... etc ...
end;
if EditStateDone then begin
Problem('Unhandled Edit detected!');
EditReset;
end else
if EditStateError then begin
Problem('Edit error detected!');
EditReset;
end;
...
end;
Из приведенных примеров видно, что новые функции, по сравнению с прямым использованием функции edit,
значительно повышают ясность кода и улучшают его структуру.
Поэтому рекомендуется использовать эти функции в новых проектах,
а также постепенно заменять старый код в существующих проектах.
Модифицирован шаблон template.pas,
в который добавлен код нового стиля обработки редактирования (edit).
Обновлена утилита DaqCreator.
В шаблоне основной программы используется новая библиотека функций при создании диалогов (Tools, Close).
В стандартный обработчик консоли
DAQ-устройств добавлены команды:
@Tooltip (всплывающее окно сообщения),
@OpenConsole (открыть окно консоли устройства),
@BrowseHelp (открыть HTM справку из [DAQ] HelpFile),
которые теперь доступны всем программным устройствам, сделанным на основе шаблона в стандартной библиотеке.
Достоинство состоит в том, что консольные команды можно посылать в сообщениях или задавать в командах меню.
При этом устройства могут "перехватывать" команды, обрабатывая их по-своему.
В шаблоны редактирования в текстовом редакторе в разделе Daq_Pas добавлены шаблоны меню (Close,Tools),
которые рекомендуется использовать как образец для создания меню в новых проектах.
Также добавлены шаблоны для нестандартной обработки меню и для обработки CheckBoxList.
В Главной Консоле добавлена команда @list windows для чтения списка окон.
Например:
@list windows - список всех окон
@list windows 5201 - список окон процесса 5201
@list windows 0 #32770 - список окон класса #32770
@list windows 0 "" "Диспетчер задач" - список окон с заголовком "Диспетчер задач"
Команда списка окон - полезный вспомогательный инструмент для разработчиков.
Главными достижениями данного выпуска являются:
обновление библиотек и версии DieselPascal;
добавление функционала в функции edit.
Данный выпуск посвящен преимущественно обновлению и доработке
DieselPascal и его библиотек,
а также продолжению работ по конечным автоматам SMI.
Для этого (как ни странно) потребовалось доработать функцию edit,
чтобы можно было строить интерфейсы в стиле конечных автоматов.
Обновлен движок DieselPascal от версии 2.0.11 до версии 2.0.14.
В этом выпуске исправлены некоторые замеченные ошибки, добавлены некоторые свойства
визуальных объектов (Alignment,VerticalAlignment,BorderStyle).
Добавлены методы в интерфейсы TTreeView, TPopupMenu и ряда других классов.
Существенно доработана функция edit.
В ней добавлена возможность менять вид (шрифты) и положение/размер окна с помощью
параметров настройки (settings), которые задаются вызовом edit('@set ...').
Кроме того, заведено два пользовательских буфера:
cmd (command) для пользовательских команд: запись через edit('>...'), чтение через edit('?cmd n')
con (confirmation) для пользовательских подтверждений: запись через edit('!...'), чтение через edit('?con n')
Эти буферы задуманы для облегчения организации диалогов меню, чтобы было где хранить пользовательские команды
и строки для диалогов подтверждения, которые нужно выполнить в конце редактирования.
Например:
{
Инициировать диалог - меню выбора - по нажатию сенсора...
}
if IsSameText(ClickSensor,'MENULIST') then begin
bNul(Voice(sndClick));
if EditState=0 then begin
writeln('Demo MenuList.');
if pos('?',edit('(Выбор термопары')
+edit(' Задайте термопару')
+edit(' Термопара 1') + edit('>@termocouple 1') // Здесь задается текст
+edit(' Термопара 2') + edit('>@termocouple 2') // пунктов меню, а также
+edit(' Термопара 3') + edit('>@termocouple 3') // пользовательские команды
+edit('@set Panel.Font Name:PT_Mono\Size:12\Color:Maroon\Style:[Bold]')+edit('@set ListBox.Font Name:PT_Mono\Size:24\Color:Navy\Style:[Bold]')+edit('@set Form.Left '+ExtractWord(1,ClickParams('Bounds'))+' relative '+ClickParams('Window')+' PaintBox')+edit('@set Form.Top '+ExtractWord(4,ClickParams('Bounds'))+' relative '+ClickParams('Window')+' PaintBox')+edit('@set Form.Width 300')+edit('@set Form.Height 230')
//+edit('@set Form.Width 40 relative Desktop')+edit('@set Form.Height 50 relative Screen')
//+edit('@set Form.Width 50 relative '+ClickParams('Window'))+edit('@set Form.Height 50 relative '+ClickParams('Window'))
+edit(')MenuList MENU 2'))>0
then writeln('Error on edit MenuList!');
end else writeln('Cannot edit right now!');
end;
...
...
{редактирование завершено?}
if editstate=1 then begin // Если редактирование завершено
if IsSameText(edit('?ans 0'),'MENU_TC=1') // Если статус результата = 1 = OK
then n:=val(edit('?ans 1')) else n:=-1; // Узнать номер n выбранного пункта
s:=Trim(edit('?cmd '+Str(n))); // Извлечь пользовательскую команду s
if Pos('@',s)=1 then b:=devpostmsg(devname+' '+s+CRLF); // Если она есть, послать её в консоль
s:=edit(''); // Сброс редактора в исходное состояние
end;
Новые параметры значительно расширяют возможности функции edit и делают её удобнее.
Теперь можно менять тип, размер и цвет шрифтов списка, а также делать "привязку" окна диалога
к нажатому сенсору, что на практике очень удобно.
Примеры задания параметров:
edit('@set Panel.Font Name:PT_Mono\Size:12\Color:Red') - задание шрифта
edit('@set Form.Left 200') - указание абсолютной координаты на экране
edit('@set Form.Width 80 relative Screen') - ширина окна 80% относительно ширины экрана
edit('@set Form.Top 20 relative Desktop') - координата относительно Рабочего Стола (зависит от настроек Windows)
edit('@set Form.Left 30 relative DemoEdit PaintBox') - координата относительно окна с заголовком DemoEdit, элемента PaintBox
edit('@set Form.Width 40 relative *::FormCrw32') - ширина 40% относительно ширины главного окна пакета
edit('@set Form.Height 50 relative TFormCrw32::*') - высота 50% относительно высоты главного окна пакета
Подробное описание параметров
есть в документации по функции edit.
Обновлена демо конфигурация DEMO_EDIT
для иллюстрации возможностей функции
edit.
Добавлен параметр [DAQ]EditTagFont,
в котором указывается шрифт для редактирования тегов.
Этот шрифт при старте считывается в переменную
StdEditTagFont,
которая используется для задания шрифта при редактировании тегов.
Значение по умолчанию определено в включаемом (обычно) стандартном файле
Default/DAQ.cfg.
При необходимости шрифт можно заменить, задав новое значение переменной StdEditTagFont.
Восстановить стандартное значение фонта редактирования тегов можно вызовом
StdEditTagFont:=ReadIni('[DAQ] EditTagFont');.
Добавлены функции
StartEditTagStrEx,
StartEditTagEx,
а также обновлены функции
StartEditTagStr,
StartEditTag,
которые теперь дают возможность менять шрифт редактирования тегов (в переменной StdEditTagFont).
Расширенные (Ex = extended) версии функций также позволяют менять шрифт, размеры и координаты окна.
Например:
// Обычное редактирование
StartEditTag(tag,'Введите значение');
StartEditTagEx(tag,'Введите значение',''); // То же самое
// Редактирование с явным заданием шрифта через параметр
StartEditTagEx(tag,'Введите значение','@set StringGrid.Font Name:PT_Mono\Size:14\Color:Black\Style:[Bold]');
// Редактирование с явным заданием шрифта и координат через параметр
StartEditTagEx(tag,'Введите значение',
'@set StringGrid.Font Name:PT_Mono\Size:14\Color:Black\Style:[Bold]'+LineEnding+
'@set Form.Left 200 relative DemoEdit PaintBox'+LineEnding+
'@set Form.Top 10 relative DemoEdit PaintBox');
// Редактирование с заданием шрифта через переменную и восстановлением стандартного значения
StdEditTagFont:='Name:PT_Mono\Size:14\Color:Red\Style:[Bold]';
StartEditTag(tag,'Введите значение');
StdEditTagFont:=ReadIni('[DAQ] EditTagFont');
Новые возможности позволяют сделать редактирование тегов более удобным для оператора,
чтобы вводимый текст был крупнее и заметнее на экране.
Добавлена функция
SetFormUnderSensorLeftBottom,
которая вычисляет такие параметры вызова
StartEditTagEx,
чтобы окно редактирования поместилось прямо под нажатым сенсором, что удобно для пользователя.
Аргумент функции берется из вызова ClickParams(''),
откуда извлекается имя окна и координаты нажатого сенсора.
Например:
// Редактирование с указанием координат окна под сенсором и шрифта
StartEditTagEx(tag,'Введите значение',SetFormUnderSensorLeftBottom(ClickParams(''))
+'@set StringGrid.Font Name:PT_Mono\Size:14\Color:Black\Style:[Bold]');
Эта функция является вспомогательной и используется для облегчения работы с функциями редактирования.
По сложившейся практике имя устройства (DevName) очень часто совпадает с именем
связанного с ним окна мнемосхемы, кроме первого символа (амперсанда &).
В этом случае имя связанного окна можно получить вызовом Copy(DevName,2).
Это позволяет делать "привязку" различных диалогов к координатам окна,
например:
if EditState=0 then begin
if Pos('?',Edit('(Команда "Инструменты"... ')
+Edit(' Что выбираете:')
+Edit(' '+MenuToolsItem(0))
+Edit(' '+MenuToolsItem(1))
+Edit(' '+MenuToolsItem(2))
+Edit('@set ListBox.Font Size:14\Style:[Bold]')+Edit('@set Form.Left 800 relative '+Copy(DevName,2)+' PaintBox')+Edit('@set Form.Top 55 relative '+Copy(DevName,2)+' PaintBox')
+Edit(')MenuList MENU_'+NameTag(DOZA.MAIN.CMD.TOOLS.tag)))>0
then Warning('Error initializing MenuList!');
end else Warning('Cannot edit right now!');
Такой метод хорошо подходит для главной мнемосхемы, а также для окон настройки драйверов,
где обычно имя окна мнемосхемы совпадает (кроме амперсанда) с именем устройства.
Обновлены конфигурации
DEMO_DOZA,
DEMO_MAYAK,
DEMO_SMITEST,
DEMO_UNIHEAT
и библиотека UniHeat,
где редактирование тегов сделано с помощью функций StartEditTagEx и SetFormUnderSensorLeftBottom.
Теперь окно редактора тегов появляется под сенсором (раньше оно появлялось над ним).
Это довольно удобно, т.к. видно, какой тег редактируется и его текущее значение.
Эти конфигурации являются примером использования новых функций редактирования.
Эти параметры помогут вычислять координаты для позиционирования диалогов на экране
относительно окна или относительно основного поля мнемосхемы (PaintBox).
Обновлена утилита DaqCreator.LM9.
В шаблоне основной программы сделано изменение шрифта и позиционирование диалогов (Tools, Close).
Исправлена небольшая ошибка в формате вывода списка подключений мнемосхемы (по правой кнопке мыши).
Главными достижениями данного выпуска являются:
утилита SmiGenGui.lm9 для наблюдения и отладки SMI;
обновление библиотек и версии DieselPascal;
добавление библиотеки dpTask и dpColors.
Данный выпуск посвящен преимущественно обновлению и доработке
DieselPascal и его библиотек,
а также продолжению работ по конечным автоматам SMI.
Обновлен движок DieselPascal от версии 2.0.6 до версии 2.0.11.
Обновление связано с выходом новой версии Free Pascal 3.2.0 и Lazarus 2.10.
Кроме того, в новой версии улучшена поддержка работы с кодировками (OEM, ANSI, UTF8...).
Есть пример использования кодировок.
Добавлен модуль DieselPascal для работы с процессами
dpTask.pas.
Он позволяет работать с процессами через функции API,
аналогичные DaqPascal.
Добавлен пример, иллюстрирующий использование модуля dpTask для работы с процессами -
TestPing.lm9.
Он запускает программу ping для проверки сетевой связи и направляет консольный вывод в окно редактора.
Обновлен модуль DieselPascal - dpSysUtils, добавлен ряд полезных функций.
Разработана первая версия утилиты SmiGenGui.lm9
(название от SMI Generic QUI) для отображения и отладки конечных автоматов SMI,
созданная как альтернатива не очень удобной штатной утилиты Tcl/Tk SMI Generic GUI, входящей в SMI.
Утилита написана на языке DieselPascal и служит очередным шагом к реализации в пакете CRW-DAQ
поддержки конечных автоматов на основе технологии SMI.
Она также может служить прототипом для других графических утилит, работающих с интерфейсом SMI.
Обновлена демо конфигурация DEMO_SMITEST
для иллюстрации работы утилиты SmiGenGui.LM9.
Добавлен модуль DieselPascal для работы с именованными цветами
dpColors.pas.
Он позволяет работать с именами и кодами цветов,
аналогично вызову ParamStr('ColorName ..').
Обновлена утилита CrcConfigurator.LM9.
В ней удален внутренний модуль dpColors, т.к. теперь он доступен в общей библиотеке.
Обновлен редактор мнемосхем Origami.
Обновление предоставил А.Жирунов.
Главными достижениями данного выпуска являются:
обновление и документация сервера &SmiSrv;
редакторы мнемосхем CrcConfigurator и Origami;
обновление библиотеки SMI++.
Данный выпуск посвящен преимущественно обновлению и доработке
SMI.
Обновлена библиотека SMI++ от версии v51r3 до версии v56r1, актуальной на данный момент.
Библиотека собрана самостоятельно в Visual Studio 2005.
Создана первая пробная версия утилиты CrcConfigurator.LM9.
Это генератор и редактор мнемосхем на основе DieselPascal.
Утилиту предоставил Н.Гурин по шаблону, созданному А.Курякиным.
Создана первая пробная версия утилиты Origami.
Это генератор и редактор мнемосхем на основе HTML и JavaScript.
Утилиту предоставил А.Жирунов, который и предложил её идею.
Утилиты CrcConfigurator, Origami внесены в консольные утилиты Crw32.Utils.LM9.
Создан (точнее обновлен) и документирован сервер
&SmiSrv.
Это еще один шаг по интеграции SMI в пакет CRW-DAQ.
В будущем еще предстоит сделать графический интерфейс (GUI) для работы с конечными автоматами SMI.
Обновлена демо конфигурация DEMO_SMITEST для иллюстрации работы
сервера &SmiSrv.
Всех поздравляю с наступающим Новым Годом и Рождеством.
Главными достижениями данного выпуска являются:
обновление DieselPascal;
добавление библиотечных моделей данных dpGuiResMain, dpGuiResTools.
Данный выпуск посвящен преимущественно обновлению и доработке DieselPascal,
а также переработке утилит *.LM9, работающих с его помощью.
Был обновлен Diesel Pascal от версии 2.0.4 до версии 2.0.6.
Обновление было сделано по нашей просьбе и связано со следующей проблемой.
Внешние модули (External)
эффективно решили проблему хранения библиотечного программного кода, общего для всех программ *.LM9.
Однако в программах, помимо кода, присутствуют громоздкие списки изображений (ImageList),
которые для большинства утилит повторяются и занимают большую часть файлов *.LM9.
Для выноса ImageList во внешний модуль можно использовать модули данных (DataModule),
и это работало в RunTime, однако это не срабатывало в DesignTime,
т.к. на этапе разработки (design time) автоматической загрузки модулей не происхоло
и изображения ImageList были недоступны для Дизайнера, если они находялись во внешнем модуле.
Визуально это проявлялось в том, что при загрузке в Дизайнере вместо картинок
на кнопках BitBtn и других элементах наблюдалось пустое место - картинки не грузились,
хотя на этапе выполнения (run time) картинки могли изображаться нормально.
Для решения описанной проблемы необходимо было сделать механизм загрузки внешних модулей данных
на этапе разработки, чтобы сделать их доступными для Дизайнера.
Для этого было сделано следующее:
Вкладка Опции\Опции Проекта\Дополнительно переименована в Опции\Опции Проекта\Внешние модули.
Кроме поля Путь к папке с внешними модулями появился список
Автоматически создаваемые TDataModule (только в DesignTime).
В этот список помещаются имена модулей данных, которые надо автоматически загружать в DesignTime,
чтобы содержащиеся в них объекты стали доступными для Дизайнера.
При нажатии кнопки Добавить сканируется папка с внешними модулями (External)
и выбираются модули данных (TDataModule). Из них предлагается выбрать добавляемый в список модуль.
Дизайнер доработан так, что теперь помещенные в список модули данных автоматически загружаются
на этапе разработки DesignTime и находящиеся в модулях ресурсы доступны для Дизайнера.
Надо заметить, что проблема была решена частично.
Картинки из внешних модулей действительно загружаются нормально.
Однако в кнопках (например, BitBtn) не происходит автоматического назначения картинки,
если подключается Action с назначенной картинкой ImageList/ImageIndex.
Картинка появляется только если явно указать ImageList/ImageIndex в самой кнопке.
Это не страшно, хотя и неприятно, т.к. приводит к дублированию описаний картинок
ImageList/ImageIndex в объектах Action и BitBtn.
Тем не менее, это решает проблему хранения изображений во внешних модулях и поэтому рекомендуется к использованию.
Был создан модуль данных dpGuiResMain,
в который помещены списки изображений ImageListMain16x16, ImageListMain32x32,
содержащие большую (более 230) библиотеку изображений, используемых в пакете CRW-DAQ.
Эта библиотека нужна практически в любой утилите *.LM9, чтобы обеспечить
единство интерфейса пользователя - все утилиты выглядят похожими на основной пакет CRW-DAQ
за счет одинаковых картинок, обозначающих команды и действия.
Для использования библиотеки в каком-либо проекте надо
Задать расположение папки внешних модулей External в опциях проекта:
Опции\Опции Проекта\Внешние модули.
Обычно это ссылка на переменную окружения %DieselPascal_External%.
Включить модуль dpGuiResMain в список автозагрузки в опциях проекта:
Опции\Опции Проекта\Внешние модули.
Включить модуль в список uses ... , dpGuiResMain;
В главном файле проекта вызвать процедуру InitGuiResMain; до создания главной формы.
Это нужно сделать потому, что главная форма использует ресурсы модуля dpGuiResMain,
которые к моменту создания формы уже должны быть загружены.
Для изображений вместо ссылки ImageListMain32x32 используется
ссылка DataModuleGuiResMain.ImageListMain32x32.
Ссылка на изображение ImageList/ImageIndex должна явно прописываться
в каждой кнопке BitBtn, даже если она уже прописана в присоединенной Action.
Иначе картинка не будет доступна в DesignTime.
Был создан модуль данных dpGuiResTools,
в который помещены списки изображений ImageListTools32x32, ImageListTools48x48,
содержащие большую (более 80) библиотеку изображений, используемых в инструментах и программах Windows.
Эта библиотека может быть полезной во многих утилитах *.LM9, чтобы обеспечить
единство интерфейса пользователя - все утилиты выглядят похожими друг на друга
за счет одинаковых картинок, обозначающих команды и действия.
Модуль используется аналогично модулю dpGuiResMain.
Была переработана утилита Crw32.Utils.LM9
с использованием внешних библиотечных модулей dpGuiResMain, dpGuiResTools.
Это позволило сократить размер утилиты почти в 30 раз - c 4 MB до 140 KB.
При этом практически все изображения (кроме "иконки" основной программы и TrayIcon)
хранятся в списках изображений во внешних библиотечных модулях.
Была переработана шаблонная утилита Template_Utility.LM9
с использованием внешних библиотечных модулей dpGuiResMain, dpGuiResTools.
Это позволило сократить размер утилиты более чем в 100 раз - c 2.7 MB до 26 KB.
При этом практически все изображения (кроме "иконки" основной программы и TrayIcon)
хранятся в списках изображений во внешних библиотечных модулях.
Была переработана утилита DemoSinWaveControl.LM9
с использованием внешних библиотечных модулей dpGuiResMain, dpGuiResTools.
Это позволило сократить размер утилиты почти в 80 раз - c 2.8 MB до 35 KB.
При этом практически все изображения (кроме "иконки" основной программы и TrayIcon)
хранятся в списках изображений во внешних библиотечных модулях.
Была переработана утилита DaqCreator.LM9
с использованием внешних библиотечных модулей dpGuiResMain, dpGuiResTools.
Это позволило сократить размер утилиты более чем в 40 раз - c 2.8 MB до 65 KB.
При этом практически все изображения (кроме "иконки" основной программы и TrayIcon)
хранятся в списках изображений во внешних библиотечных модулях.
Была переработана утилита CfgConfigurator.LM9
с использованием внешних библиотечных модулей dpGuiResMain, dpGuiResTools.
Это позволило сократить размер утилиты более чем в 10 раз - c 2.9 MB до 210 KB.
При этом практически все изображения (кроме "иконки" основной программы и TrayIcon)
хранятся в списках изображений во внешних библиотечных модулях.
Таким образом, все имеющиеся в наличии утилиты *.LM9 переработаны
с использованием внешних библиотечных модулей dpGuiResMain, dpGuiResTools.
Это позволило сократить размер утилит в большое (от 10 до 100) число раз,
при этом имеющиеся и будущие утилиты, создаваемые из шаблонов,
будут компактными и не перегруженными громоздкими картинками.
В целом можно сделать вывод о значительном шаге в развитии DieselPascal и его библиотек,
который делает утилиты *.LM9 существенно более компактными и простыми.
Главными достижениями данного выпуска являются:
исправление ошибки в @reg -e, @run;
серьезные изменения в окнах таблиц Tab_Window;
добавлены функции rmin, rmax, imin, imax;
обновление драйвера ADAM, в котором исправлены ошибки
и добавлены параметры Reject50, FastPoll и RangeCodes.
Данный выпуск посвящен преимущественно исправлению ранее найденных ошибок и мелким доработкам,
в первую очередь в драйвере ADAM.
Также серьезные изменения произошли в таблицах Tab_Window для отображения кривых и тегов.
Исправлена ошибка в определении имени EXE файла по расширению, которая в некоторых
условиях выдавала неверный результат.
Ошибка влияла на работу команд @reg -e и @run,
из-за чего эти команды при некоторых условиях не срабатывали.
Теперь они должны работать верно.
Исправлена ошибка в драйвере ADAM,
из-за которой модуль 7033 выдавал ошибку при старте.
В драйвер ADAM добавлена поддержка
параметров Reject50 и FastPoll.
Параметр Reject50
применим ко всем модулям АЦП (7011, 7012, 7017, 7018, 7013, 7033),
кроме некоторых исключений (7015, 7019).
Параметр Reject50 включает фильтр, подавляющий помеху 50 Гц,
что может существенно снизить уровень шума, особенно в милливольтовых диапазонах.
Следует отметить, что в режиме FastPoll параметр Reject50 не работает.
Параметр FastPoll
применим модулям АЦП модификации F (7012F, 7017F).
Параметр FastPoll включает режим быстрого (fast) опроса,
частота которого зависит от типа модуля (100 Гц для 7012F, 60 Гц для 7017F).
Напоминаем, что это общая частота опроса, которая делится между подключенными каналами.
Кроме того, для ускорения опроса надо отключать Watchdog и оптимизировать настройку опроса устройств и потоков,
что достигается установкой InquiryPriod, DevicePolling и вызовом setclockres(..).
При правильном выборе параметров достигается частота опроса 7017F около 60 Гц.
Необходимо также учитывать, что при включении режима быстрого опроса снижается эффективная разрядность
(с 16 до 12 бит в модуле 7017F) и точность АЦП.
Например, для 7012F точность составляет 0.05 % в обычном и 0.25 % в быстром режиме.
Для 7017F точность составляет 0.1 % в обычном и 0.5 % в быстром режиме.
В драйвер ADAM добавлена поддержка
параметра RangeCodes для задания списка значений диапазонов каналов.
Параметр RangeCodes
применим модулям АЦП, имеющим функцию задания диапазонов для отдельных каналов (7015, 7019).
Обычно диапазон АЦП задается параметром RangeCode для всех каналов одновременно.
При наличии функции поканального задания диапазонов, можно задавать диапазон для отдельных каналов.
Диапазоны в этом случае задаются списком RangeCodes, а параметр RangeCode задает значения по умолчанию.
Например:
[DeviceList]
ADAM7019 = device adam ADAM-7019
[ADAM7019]
...
RangeCode = $08 ; код диапазона по умолчанию
RangeCodes = $00, $01, $02, $03, $04, $05, $08, $09 ; коды диапазонов для каждого канала
...
Если параметр RangeCodes отсутствует или содержит неполный список каналов,
то диапазоны каналов берутся из параметра RangeCode.
При открытии новых окон DAQ системы им теперь даются имена с указанием типа и номера окна:
DAQ.CURVE_WINDOW_1, DAQ.CURVE_WINDOW_2, ... для окон кривых или
DAQ.TAB_WINDOW_1, DAQ.TAB_WINDOW_2, ... для окон таблиц.
Это должно облегчить поиск окон в списке окон.
Раньше при открытии новых окон все они имели одинаковые имена, что затрудняло поиск нужного окна.
Сняты ограничения на размер таблицы.
Теперь в таблице может быть много кривых и тегов.
При большом числе кривых и тегов в окне появляется скроллер.
Текущее ограничение на число кривых и тегов - 4К, на ширину поля - 127.
Расширена поддержка форматов:
[Windows]
DemoTab = Tab_Window
[DemoTab]
...
Format = 11 4 f ; fixed 123456.7890 фиксированный формат
Format = 11 4 g ; general 1.235e5 генеральный (адаптивный)
Format = 11 4 e ; exponent +1.2345e+05 экспоненциальный (научный)
Расширена поддержка фонтов:
[Windows]
DemoTab = Tab_Window
[DemoTab]
...
Font = Name:PT_Mono\Color:Navy\Size:12\Style:[Bold]
То есть теперь фонты можно задавать так же как в мнемосхемах.
[Windows]
DemoTab = Tab_Window
[DemoTab]
...
CurveList = alpha, beta, gamma ; Список кривых для отображения
TagList = POWER_ON, POLL_RATE ; Список тегов для отображения
TagList = ERRORS, ... ; Список тегов для отображения
То есть теперь теги тоже можно отображать в таблицах, как и кривые.
Добавлено задание цветов таблицы (Colors = ...):
[Windows]
DemoTab = Tab_Window
[DemoTab]
...
Colors = Silver, White, Black ; Фон имен серый, фон значений белый, текст черный
То есть теперь можно задавать цветовое оформление таблиц.
По правой кнопке вызывается меню с командами настройки параметров - фонта, формата и цветов.
Новые возможности делают таблицы Tab_Window полезным инструментом,
который можно использовать не только для отладки, но и для создания интерфейсов пользователя.
В команде DAQ\Открыть окно добавлены новые возможности окон таблиц Tab_Window.
Теперь можно выбирать не только список кривых, но и список тегов для отображения.
Это особенно удобно для отладки приложений.
Новые возможности окон таблиц Tab_Window проиллюстрированы на конфигурации
DEMO_LM9.
В файле
demo_lm9_main_ctrl.cfg
имеется пример описания окна Tab_Window:
[Windows]
DEMO_LM9.PARAM.TAB = Tab_Window
[DEMO_LM9.PARAM.TAB]
Font = Name:PT_Mono\Color:Black\Size:14\Style:[Bold]
Format = 7 2 f
Colors = Default, White, Navy
TagList = SinWaveGenerate
CurveList = SinWaveAmplitude, SinWaveFrequency, SinWavePhase
CurveList = SinWaveNoise, SinWaveValue, CosWaveValue
[]
Обратите внимание - в описании @WinDraw|Options присутствуют только некоторые параметры,
там не должно быть других параметров (например, StatusBar, Width, Height),
иначе окно будет выглядеть неправильно.
В DaqPascal добавлены функции
rmin (синоним min),
rmax (синоним max),
imin (целочисленный аналог min),
imax (целочисленный аналог max).
Целочисленной версии функций мини-макса (imin, imax) давно не хватало, теперь они есть.
В стандартной библиотеке StdLib вызовы функций вида Round(max(..)), Round(min(..))
заменены на эквивалентные вызовы imin(..), imax(..).
Старые вызовы носили вынужденный характер, т.к. целочисленной версии мини-макса не было.
Новые вызовы делают код быстрее и понятнее.
Главными достижениями данного выпуска являются:
добавление функций Assertion, IsSectionName, IsEnvVarLink, ReadIniAlter,
msElapsedSinceMarker;
обновление утилит DaqCreator.lm9, CfgConfigurator.lm9;
добавление в дистрибутив библиотеки SMI++ для организации конечных автоматов (FSM);
добавление библиотеки SmiProxy для создания прокси серверов SMI/FSM;
добавление в дистрибутив пакета install-daqgroup-engines, включающего "движки" -
интерпретаторы DieselPascal, Tcl/Tk и Python.
В состав дистрибутива добавлен пакет "движков" install-daqgroup-engines
(от слова engine - "движок", мотор), включающий в свой состав несколько интерпретаторов языков:
DieselPascal - кроссплатформенный интерпретатор языка Pascal,
который был перенесен из пакета install-daqgroup-database.
Движок DieselPascal является составной частью пакета CRW-DAQ.
Бинарные файлы DieselPascal входят в crw32-runtime.
А здесь содержится полный набор файлов (включая исходники).
Tcl/Tk - кроссплатформенный интерпретатор языка TCL,
включающий в себя кроссплатформенную графическую библиотеку TK
позволяющую создавать графические интерфейсы.
Добавление движка Tcl/Tk связано с тем, что он используется в библиотеке SMI++.
Python - кроссплатформенный интерпретатор языка Python,
включающий в себя кроссплатформенную графическую библиотеку Tkinter
(на основе Tcl/Tk) позволяющую создавать графические интерфейсы.
Добавление Python связано с тем, что это очень популярный "движок" с большим набором библиотек.
Приведенные "движки" бывают нужны для исполнения скриптов, написанных на указанных языках.
Использование скриптов часто сокращает объем и трудоемкость кодирования, а также позволяет
использовать скрипты как "клей" для организации взаимодействия между разными пакетами и процессами.
В состав пакета "движков" включены также дополнительные программные библиотеки, статьи и книги.
Это позволяет изучать эти языки и эффективно заниматься разработкой прикладного ПО на них.
В состав дистрибутива добавлен пакет SMI++,
который реализует Конечную Машину Состояний (FSM = finite state machine).
Пакет расположен в папке Resource\SmiSite.
Технология FSM на основе библиотеки
SMI++
- большая тема, которая будет развиваться еще долго,
сейчас делаются только первые шаги в этом направлении.
Созданы интерфейсные модули на языке Pascal, необходимые для подключения для библиотеки SMI++
и создания прикладных программ, использующих FSM.
В папке smi_pasinter находится исходники.
В секции Crw32.ini [System] добавлены переменные окружения, нужные для работы DIM и SMI++.
Также в пути поиска PATH добавлены каталоги бинарных файлов DIM и SMI++.
[System]
SmiSite = Resource\SmiSite ; расположение SMI
DimSite = Resource\DimSite ; расположение DIM
DaqSite = Resource\DaqSite ; расположение стандартных библиотек DAQ
PathAddToTail = Resource\DimSite\dim\bin ; Add directory to tail of PATH environment
PathAddToTail = Resource\SmiSite\smi\bin ; Add directory to tail of PATH environment
Эти переменные и пути создают окружение, необходимое для запуска программ, использующих DIM и SMI++.
Создан скрипт для запуска ДЕМО примера SMIFSMsmi_test_run.cmd.
Для его запуска можно использовать такую команду:
Запустить ДЕМО для иллюстрации работы SMI FSM
@run Resource\SmiSite\smi_test_run\smi_test_run.cmd
smi_test_run.cmd
- содержит скрипт для запуска простого примера FSM.
Этот пример моделирует простой эксперимент, в котором можно управлять запуском измерений (RUN),
типом измерений (RUN_TYPE).
Журнал (LOGGER) событий и сборщик событий (EVT_BUILDER) моделируют измерительные подсистемы.
Автопилот (AUTOPILOT) организует цикл измерений.
Все исполняемые файлы входят в библиотеку SMI++, скрипт только вызывает их в нужном порядке.
По умолчанию запуск идет с DIM_DNS_NODE=localhost и с именем SMI домена DEMO.
Для работы примера должен быть установлен движок Tcl/Tk из пакета daqgroup-engines.
В стандартную библиотеку добавлена процедура
Assertion (утверждение).
Она удобна для проверки условий с выводом сообщений.
Например:
Assertion(FileExists(f),'FileName='+f);
это эквивалентно вызову
if FileExists(f)
then Success('FileName='+f)
else Trouble('FileName='+f);
но компактнее и исключает дублирование кода
В стандартную библиотеку добавлена функция
IsSectionName.
Она удобна для анализа текстов, разбитых на секции.
В стандартную библиотеку добавлена функция
IsEnvVarLink.
Она удобна для анализа текстов, содержащих ссылки на переменные окружения.
В стандартную библиотеку добавлена функция
ReadIniAlter.
Она удобна для чтения переменных окружения с ссылками на секции и на переменные окружения.
Например:
s:=ReadIniAlter('DnsNode',risModeDefault+risModeAlter);
При чтении файла
[&DeviceName]
DnsNode = [&DimSrv] DIM_DNS_NODE %DIM_DNS_NODE% localhost
сначала читается секция [&DimSrv] DIM_DNS_NODE
потом, если не удалось: %DIM_DNS_NODE%
потом, если не удалось: localhost
Таким образом, будет прочитано одно одно из значений альтернативных источников.
Создана библиотека
SmiProxy
для создания прокси-серверов SMI на языке DaqPascal.
Это первый шаг по интеграции SMI в пакет и CRW-DAQ.
Библиотека SmiProxy делает задачу написания прокси-сервера SMI довольно несложной процедурой.
При этом важно, что код прокси-сервера создается на привычном языке DaqPascal, что упрощает работу
прикладного программиста.
Создана демо конфигурация DEMO_SMITEST для иллюстрации работы
библиотеки SmiProxy.
В первом приближении библиотека SmiProxy готова.
Это важный шаг к интеграции технологии SMI в пакет.
В стандартную библиотеку добавлена функция
msElapsedSinceMarker.
Она удобна для организации "задержанных событий" после интересующего одиночного события.
Доработана утилита
Crw32.Utils.lm9.
В ней добавлены дополнительные кнопки для вызова утилит DIM и SMI.
Главными достижениями данного выпуска являются:
обновление DieselPascal;
доработка команды DaqGroup.cmd;
добавление в стандартную библиотеку команд @local, @remote;
доработка утилиты Crw32.Utils.lm9 и других утилит *.LM9.
Обновлен DieselPascal до версии 2.0.4.
В новой версии (А.Курякиным) добавлены дополнительные функции WinApi,
которые понадобились для реализации свертывания приложения в TrayIcon.
Доработана утилита
Crw32.Utils.lm9.
В ней добавлена возможность свертывания приложения в TrayIcon.
При старте приложение свертывается в "иконку" в "Области Уведомлений",
а также убирается из "Панели задач".
Это экономит место на экране, а также предотвращает непреднамеренное закрытие программы,
которое легко происходит при случайном нажатии мышкой в "Панели Задач".
Приложение развертывается при нажатии "иконки" в "Области Уведомлений".
По правой кнопке мыши появляется всплывающее меню, позволяющее управлять приложением.
При этом практически исключается случайное закрытие приложения по ошибке.
Аналогичным образом доработаны утилит
DaqCreator,
DaqConfigurator,
шаблон для создания утилит *.LM9
и пример утилиты DEMO_LM9.
Теперь все эти утилиты будут "прятаться" в Область Уведомлений (System Tray).
Переработана команда
DaqGroup.cmd.
Эта команда имеет важное значение, т.к. используется в стандартных ярлыках для (авто)запуска DAQ-системы.
Этот скрипт хоть и небольшой, но довольно сложный, т.к. запускает DAQ-систему под другим пользователем.
Большие сложности создают символы "экранирования", из-за которых скрипт получается довольно запутанным.
Было обнаружено, что этот скрипт срабатывает не всегда и (возможно) зависит от настроек системы.
Скрипт был полностью переработан с целью упростить код и повысить его надежность.
Будущее покажет, насколько это удалось.
В стандартный обработчик
StdIn_DefaultHandler
добавлены команды @Local и @Remote.
Команда @Remote выполняет команду, заданную в аргументе, удаленно,
т.е. пересылает её на удаленный DIM сервер для исполнения.
Пересылка делается вызовом
Dim_GuiConsoleSend(DevName,...)
т.е. через защищенную виртуальную графическую консоль.
Прием команды на стороне сервера выполняется вызовом
Dim_GuiConsoleRecv(DevName,...).
Команда @Local работает аналогично @Async,
просто пересылая аргумент в свою консоль.
Она сделана для удобства, как парная для команды @Remote.
04.10.2020
DIM @daq openconsole @daq openeditor
DaqConfigurator CfgConfigurator.lm9 Crw32.Utils.lm9
Главными достижениями данного выпуска являются:
обновление DIM;
доработка команды @daq;
создание утилиты CfgConfigurator.lm9;
доработка утилиты Crw32.Utils.lm9.
Целью данного выпуска было обновление версии DIM в составе пакета CRW-DAQ,
а также добавление утилиты DaqConfigurator.
Обновлен DIM до текущей версии 20.29.
В новой версии исправлены замеченные ошибки версии 20.27, высланные автору (Clara Gaspar).
Сборка исполняемых файлов выполнена самостоятельно с помощью компилятора MSVC 2005 SP1 (MS Visual Studio 8).
Расширена функциональность команды @daq в Главной Консоли:
Имевшиеся ранее команды:
@daq devsend &CronSrv @run cmd - посылка сообщения (@run cmd) устройству &CronSrv (синхронно)
@daq devpost &CronSrv @run cmd - посылка сообщения (@run cmd) устройству &CronSrv (в очередь)
@daq compile &DimSrv - компиляция (и перезапуск) устройства &DimSrv
Добавленные команды:
@daq openconsole &CronSrv - открыть консольное окно для устройства &CronSrv
@daq openeditor &DimSrv - открыть окно редактора кода для устройства &DimSrv
Эти команды позволяют управлять работой устройств DAQ-системы из Главной Консоли.
Выполнение команды @daq было оптимизировано по скорости интерпретации с помощью хеш-таблиц.
В UnixUtils и CrwToolkit добавлена команда junction для создания "точек подключения",
т.е. символических ссылок на папки.
В UnixUtils также добавлены команды autologon (задание входа под пользователем по умолчанию),
pipelist (список именованных каналов связи).
Добавлена новая группа утилит под общим названием "DAQ Конфигуратор" -
DaqConfigurator.
По замыслу, эта группа утилит будет служить средством автоматизации процесса разработки,
позволяя создавать прикладные системы с помощью генераторов кода для файлов разного формата
(конфигурационные файлы, файлы мнемосхем, программные коды).
В настоящее время реализована первая версия конфигуратора для CFG файлов конфигурации -
CfgConfigurator.lm9.
Пока утилиты работают в режиме "Copy/Paste", т.е. являются дополнением к текстовому редактору,
позволяя сгенерировать текст фрагмента конфигурационного файла по шаблону и затем вставить его в редактор.
Возможно, со временем утилиты "научатся" непосредственно редактировать конфигурационные файлы,
но пока это только замыслы.
Утилиты разработаны Н.Гуриным (по замыслу и заданию А.Курякина).
Обновлена утилита
Crw32.Utils.lm9.
Добавлены кнопки работы с DAQ устройствами (Compile, Edit, Console, DevSend, DevPost).
Добавлены кнопки настройки системы - Junc Prog32x64 (создание символических ссылок на программы);
Set AutoLogon (автоматический вход в систему под заданным пользователем).
Добавлена кнопка вызова DaqConfigurator.
Утилиты
DaqCreator,
DaqConfigurator
переведены из разряда "вспомогательных инструментов" в разряд "штатных средств".
В связи с этим они перенесены из папки Resource\Tools в папку Resource\DaqSite.
Теперь это будет их постоянное место, вместе с другими штатными средствами (библиотеками, серверами)
DAQ-системы.
Соответсвенно изменены пути в файлах, которые ссылались на эти утилиты.
В первом приближении задачу интеграции DieselPascal в пакет CRW-DAQ можно считать решенной,
а первый опыт использования DieselPascal - положительным.
Со временем набор утилит, работающих в DieselPascal, будет, вероятно, расширен.
25.09.2020
DIM DimInstaller.cmd Crw32.Utils.lm9 @run DaqCreator.lm9
Главными достижениями данного выпуска являются:
обновление DIM;
инсталлятор DimInstaller.cmd;
доработка команды @run;
создание утилиты DaqCreator.lm9;
доработка утилиты Crw32.Utils.lm9.
Целью данного обновления было обновление версии DIM в составе пакета CRW-DAQ.
Обновлен DIM до текущей версии 20.27.
Предыдущая версия 20.02 была рабочей с 2012 года и долго не обновлялась.
Одной из причин было то, что новые версии DIM "тянули" за собой зависимости от
новых DLL библиотек MS Visual C++, которые к иму же несколько раз менялись.
Изменение состава DLL библиотек влекло за собой изменение программного кода
хорошо отлаженного сервера DimSrv.pas, трогать который не хотелось.
А сейчас необходимость обновления DIM связана с тем, что мы вступаем в совместную
работу с другими институтами и должны предложить им для совместной работы самую свежую
версию DIM, а не старую версию, с которой мы долго работали в своем коллективе.
Обновление было не тривиальным. Если раньше бралась просто двоичная копия DIM
с сайта dim.web.cern.ch, то теперь было решено
самостоятельно "собрать" библиотеки DIM из исходных файлов.
Причины две - 1) хотелось убедиться, что мы владеем техникой сборки DIM и
2) хотелось избежать зависимостей от новых DLL библиотек MS Visual C++.
Вторая причина повлекла за собой выбор компилятора - MS Visual Studio 2005.
Эта версия использовалась для сборки старой версии DIM 20.02 и имеет те же
самые зависимости от DLL, поэтому для неё можно использовать те же библиотеки, что и раньше.
Это позволило сохранить неизменным код сервера DimSrv.pas, который ссылается
на эти библиотеки.
После установки компилятора MS Visual Studio 2005 (студия 8-й версии), а также
Java Standard Edition SDK 1.8.0.181 (нужна для сборки библиотек для Java)
была выполена сборка проекта
Visual/dimVS8.sln.
При сборке пришлось немного подредактировать файлы test_server.c,
webdid.c из-за того, что версии компилятора и компонивщика слегка отличаются.
Например, пришлось добавить определение #define snprintf _snprintf,
чтобы компоновщик смог найти функцию snprintf в DLL библиотеке.
Также надо отметить, что для сборки jdim.dll пришлось сделать следующее:
Добавить в системную среду окружения переменную JAVA_HOME,
которая указывает на каталог Java SDK.
Это можно сделать командой вида
В файле jdim.vcproj задать каталоги поиска
AdditionalIncludeDirectories="../dim;$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32".
После указанных манипуляций проект собирается без ошибок компиляции.
Теперь у нас будет работать DIM собственной сборки.
Кроме того, при сборке и отладке в файле dimbridge.cxx была обнаружена
явная ошибка, которая приводила к сбою запуска dimBridge.exe,
который у нас часто используется в рабочих системах.
Ошибка была исправлена самостоятельно, автору (Clara Gaspar) направлен отчет об ошибке.
Надеюсь, в следующем официальном выпуске DIM эта ошибка будет исправлена уже официально.
Создан сценарий DimInstaller.cmd для
инсталляции DIM в %CommonProgramFiles%.
Дело в том, что для избежания файловых конфликтов DIM копируется в каталог
%CommonProgramFiles%\CRW_DAQ\Resource\DimSite, чтобы общие программы
(такие как dns.exe) запускались из этого каталога и не блокировали
каталог Crw32exe.
При копировании надо проверять версию и целостность файлов, которые там уже есть
(с предыдущей инсталляции).
В общем, DimInstaller берет на себя задачу корректно скопировать DIM
в нужное место.
Вызов DimInstaller производится один раз (при инсталляции пакета).
Кроме того, при обновления версии DIM перед сборкой инсталлятора делается вызов
DimInstaller.cmd -m,
чтобы обновить контрольные суммы, используемые для контроля целостности файлов.
Обновлен инсталлятор crw32-runtime.
В него вставлен вызов сценария DimInstaller.cmd.
Теперь при инсталляции будет автоматически обновляться каталог DIM в %CommonProgramFiles%.
Доработана команда @run в Главной Консоли.
Команда @run по замыслу должна (подобно консоли cmd) определять
имя исполняемого файла по расширению файла (документа).
В процессе работы было замечено, что это срабатывает не всегда.
Были внесены поправки в процедуру поиска исполняемого файла по расширению.
Теперь это вроде бы должно работать правильно.
В частности, команда @run script.lm9 должна корректно запускать сценарий Diesel Pascal.
Утилита DaqCreator переведена на Diesel Pascal.
Это сокращает объем дистрибутива и унифицирует утилиты.
Утилиту разработал Н.Гурин.
В Главном Меню пакета добавлены изображения слева и пробелы справа от пункта меню
для улучшения визуального разделения пунктов меню.
Число пробелов устанавливается в переменной Crw32.ini [System] MenuRightSpaceWidth.
Главными достижениями данного выпуска являются:
команда @list specfolders;
функция paramstr('specfolder ...');
обновление библиотеки DieselPascal_External;
доработка утилиты Crw32.Utils.lm9.
Целью данного обновления являются продолжение работы
по интеграции DieselPascal в состав пакета CRW-DAQ.
Выпуск носит технический характер и в основном содержит мелкие исправления и доработки предыдущего выпуска.
Обновлен DieselPascal до версии 1.16.3.
В нем исправлены замеченные ошибки и добавлены новые возможности (например, процедурные переменные).
Обновлена библиотека Resource\DieselPascal\External.
Добавился модуль dpAntiZombie для автоматического завершения дочерних программ после завершения
работы пакета.
Добавление этого модуля позволило перенести часть шаблонного (общего для всех утилит) кода в библиотечные файлы,
что облегчит разработку и поддержку прикладных программ.
@list specfolders
CSIDL_DESKTOP=C:\Users\main\Desktop
CSIDL_PROGRAMS=C:\Users\main\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
...
@list specfolders system
C:\Windows\system32
Команда показывает "специальные папки" - известные системе папки,
типа каталога Windows\system32 и других папок, где располагаются файлы ОС и пользователей.
Добавлена функция ParamStr('specfolder ***'),
которая возвращает "специальные папки" - все одним списком или по имени.
Например:
S:=ParamStr('specfolder *'); // S = список каталогов
S:=ParamStr('specfolder system'); // S = C:\Windows\system32
На самом деле вызов ParamStr('specfolder ...') работает аналогично утилите unix getspecialfolderpath.
Надо также заметить, что в каждом програмном DAQ-устройстве (сделанному по шаблону) есть обработчик
собщения @paramstr, который встроен в стандартный обработчик "по умолчанию".
Поэтому в консоли устойств можно вызывать команду чтения специальных папок, например:
Знание "специальных папок" необходимо для того, чтобы находить нужные программам системные и пользовательские
файлы и каталоги.
Обновлен инсталлятор DieselPascal.
Теперь он поддерживает актуальность клиентской библиотеки fbclient.dll.
Дело в том, что СУБДFirebird имеет несколько версий,
и версия клиентской библиотеки должна соответствовать версии СУБД.
Сейчас клиентская библиотека копируется из каталога инсталляции Firebird, если она установлена.
Обновлен инсталлятор Firebird.
Было замечено, что инсталлятор отказывается работать, если в системе уже установлена другая версия Firebird.
Теперь инсталлятор проверяет и деинсталлирует предыдущую версию программы, прежде чем начать инсталляцию новой версии.
Главными достижениями данного выпуска являются:
добавление функций PosEx, LastPos, CountPos, NthPos, text_tostring;
добавление группы функций EasyIpc_XXX и LM9_XXX для работы с программами LM9;
улучшенная интеграция DieselPascal с пакетом CRW-DAQ;
добавление демонстрационной конфигурации DEMO_LM9 для иллюстрации работы с программами DieselPascal;
обновление библиотеки DieselPascal_External;
доработка утилиты Crw32.Utils.lm9.
Целью данного обновления являются продолжение работы
по интеграции DieselPascal в состав пакета CRW-DAQ.
По факту, начальный этап интеграции можно считать выполенным.
Есть работающие версии библиотек, демонстрационный пример как шаблон для создания прикладных программ.
Работы по интеграции будут продолжаться, но уже сейчас можно начинать использование DieselPascal
в прикладных задачах.
Обновлена библиотека Resource\DieselPascal\External.
Устранены замеченные ошибки, дополнен недостающий функционал.
Пока эта библиотека находится в активной стадии разработки,
поэтому документацией служат исходные коды и комментарии к ним.
Обновлена утилита
Crw32.Utils.lm9.
Теперь её функционал уже превышает исходную версию Crw32.Utils.ini.
Добавлены функции для работы со строками и текстом:
PosEx(Sub,Str,StartPos) - поиск вхождения подстроки в строке, начиная с StartPos.
LastPos(Sub,Str) - поиск последнего вхождения подстроки в строке.
CountPos(Sub,Str) - счетчик вхождений подстроки в строку.
NthPos(Sub,Str,n) - поиск n-го вхождения подстроки в строку.
Text_ToString(txt) - возвращает текст в виде длинной строки.
Эти функции позволяют итерационно обрабатывать длинные строки текста,
позволяя находить все вхождения подстроки (Sub) в строку (Str).
Тексты могут храниться в двух видах - в виде строкового буфера, т.е. длинной строки с разделителями
(LineEnding) или в виде текстового объекта
(text_new).
Текст в виде строкового буфера удобно хранить и передавать по линиям связи,
но при построчной обработке текстовый объект удобнее, т.к. позволяет быстро находить
и обрабатывать отдельные строки текста.
Поэтому довольно часто приходилось "перегонять" данные из строкового буфера в текстовый объект и наоборот.
Эти операции довольно трудоемки, хотелось бы минимизировать их использование.
Новые функции позволяют осуществлять сравнительно быстрое позиционирование строк в строковом буфере текста,
что позволяет во многоих случаях работать с буфером текста напрямую, без преобразования в текстовый объект.
Например:
procedure PrintLine(n:Integer;Line:String);
begin
Writeln(StrFmt('Line[%d] = ',n)+Line);
end;
procedure ProcessLines(Lines:String);
var i,p,n:Integer; Line:String;
begin
i:=0; p:=1; n:=0;
repeat
i:=PosEx(LineEnding,Lines,i+1);
if (i>0) then begin
Line:=Copy(Lines,p,i-p);
n:=n+1; PrintLine(n,Line);
p:=i+Length(LineEnding);
end else begin
if (p<=Length(Lines)) then begin
Line:=Copy(Lines,p,Length(Lines)-p+1);
n:=n+1; PrintLine(n,Line);
end;
end;
until (i<=0);
end;
Таким образом, новые функции позволяют серьезно ускорить обработку текстов,
что особенно важно для взаимодействия с программами DieselPascal по текстовому каналу связи IPC.
Обновлен модуль стандартной библиотеки StdDiesel,
содержащий большой набор функций для работы с Diesel Pascal и программами *.LM9.
Группа функций DieselPascalXXX
служит для поиска и идентификации исполняемых файлов DieselPascal.
Группа функций EasyIpc_XXX
служит для облегчения организации работы с каналами межпроцессной (IPC) связи
EasyIpc.
Группа функций LM9_XXX
служит для облегчения запуска и работы с программами LM9,
созданными и исполняемыми в среде DieselPascal.
Предполагается, что программы LM9 будут взаимодействовать с DAQ-программами
в реальном времени через каналы связи IPC.
Добавлена ДЕМО конфигурация DEMO_LM9, иллюстрирующая запуск прикладных
программ LM9, созданных в среде DieselPascal, и взаимодействие с ними в режиме online.
В данном случае в качестве иллюстрации взят простой генератор "синусовой волны" (SinWave).
Программа DemoSinWaveControl.lm9
запускается по кнопке (Control) из программы DaqPascal и реализует диалог для задания
параметров "волны" (частота, амплитуда, фаза, шум), а также генерирует и передает CosWaveValue.
Она взаимодействует с DAQ-программой в режиме online, позволяя наблюдать текущие значения
тегов, а также редактировать и менять их через графический интерфейс.
Данная конфигурация призвана служить прототипом для других, более сложных и содержательных прикладных программ.
Добавлена ДЕМО конфигурация DEMO_EGP/EGP_ISCS, подготовленная Н.Гуриным.
Эту прикладную систему отличает великолепная проработка графического интерфейса пользователя. Хорошая работа.
Главными достижениями данного выпуска являются:
добавление функций ExpEnv, CreateTempFile, StringReplace, AnsiQuotedStr, AnsiDeQuotedStr, AnsiSkipQuotedStr;
добавление набора EasyIpc_xxx функций в DaqPascal для организации простого взаимодействия между процессами;
обновление и улучшенная интеграция DieselPascal с пакетом CRW-DAQ;
библиотека DieselPascal_External;
доработка утилиты Crw32.Utils.lm9.
Целью данного обновления являются продолжение работы по интеграции DieselPascal в состав пакета CRW-DAQ.
В целом интеграция идет успешно, но пока она не завершена.
Поэтому данная версия является промежуточной.
Завершение интеграции планируется в ближайшее время.
Обновлен DieselPascal до версии 1.15.1.
В него добавлено много функций, разработанных (А.Курякиным) специально для интеграции с пакетом CRW-DAQ.
А также добавлены (А.Копниным) внешние (External) модули, что позволяет создать библиотеку программных модулей,
которыми будут пользоваться все прикладные программы DieselPascal.
Модули в языке DieselPascal делятся на внутренние (внутри файла *.lm9) и внешние.
Все внешние (по отношению к файлу *.lm9) модули должны располагаться в одном каталоге,
который задается в свойствах проекта.
Для ссылки на каталог внешних модулей допустимо использовать переменные окружения.
Предполагается, что все внешние модули программ, работающих в среде пакета CRW-DAQ,
будут расположены в каталоге %DieselPascal_External%.
Это каталог, в котором будут размещаться стандартные библиотеки, общие для всех программ DieselPascal.
Проекты *.lm9 должны ссылаться на него (в свойствах проекта) как на
%DieselPascal_External%.
Обновлена утилита
Crw32.Utils.lm9.
В ней теперь используются внешние модули (стандартные библиотеки) в каталоге %DieselPascal_External%.
Обновлена команда @daq - добавлены опции devpost, devpostmsg:
@daq devpost &Device Msg - послать сообщение Msg устройству &Device методом Post
@daq devpostmsg &Device Msg - послать сообщение Msg устройству &Device методом Post
Напомним, метод Post посылает сообщение без принудительного пробуждения устройства, т.е. ставит его в очередь.
Он применяется для снижения нагрузки при большом потоке событий.
Эти функции введены для улучшения переносимости кода с DieselPascal и с Free Pascal,
к которому мы постепенно движемся.
Добавлена новая группа функций, EasyIpc_xxx, для организации простого канала связи
между процессами - IPC (Inter Process Communication):
EasyIpc_Init - создание канала связи IPC.
EasyIpc_Free - удаление канала связи IPC.
EasyIpc_Poll - опрос канала связи IPC.
EasyIpc_Send - посылка текста в канал связи IPC.
EasyIpc_Recv - прием текста из канала связи IPC.
EasyIpc_Ctrl - запрос/установка параметров канала связи IPC.
Эта группа функций разработана специально для связи
программ DaqPascal с программами DieselPascal,
но может, разумеется, применяться и для других целей.
Функции имеют подробное описание, с примером. Читайте.
Эта группа функций нужна для выяснения расположения файлов DieselPascal по регистрации в системе.
Например:
s:=ParamStr('GetSystemAssocExe .lm9'); // Расположение DieselPascal CrossMachine.exe
s:=ParamStr('GetSystemFTypeExe VisualTech.DieselPascal.CrossMachine'); // Расположение DieselPascal CrossMachine.exe
s:=ParamStr('GetSystemFTypeExe VisualTech.DieselPascal.CrossDesigner'); // Расположение DieselPascal CrossDesigner.exe
Также добавлена функция
ParamStr('CreateGUID') - сгенерировать уникальный идентификатор GUID.
Эта функция нужна для генерации уникальных имен для временных файлов, каналов связи или других объектов,
нужных для вызова утилит DieselPascal из программ DaqPascal.
Например:
s:=ParamStr('CreateGUID'); // Сгенерирует что-то вроде {6B7826DD-B281-4BA9-B32F-AF78A24DEDA6}
s:=ParamStr('CreateGUID str'); // Сгенерирует что-то вроде {6B7826DD-B281-4BA9-B32F-AF78A24DEDA6}
s:=ParamStr('CreateGUID hex'); // Сгенерирует что-то вроде DD26786B81B2A94BB32FAF78A24DEDA6
s:=ExpEnv('%Temp%\demo.txt'); // Подстановка в строку переменных окружения, например, %Temp%.
s:=CreateTempFile('XXX.TMP'); // Создать временный файл с префиксом XXX и расширением .TMP.
s:=StringReplace(s,'1','2',3); // Заменяет строки в тексте
s:=AnsiQuotedStr(s,'"'); // Помещает строку в кавычки ("закавычивает").
s:=AnsiDeQuotedStr(s,'"'); // Удаляет кавычки из строки (выделяет первое "закавыченное" слово).
s:=AnsiSkipQuotedStr(s,'"'); // Возвращает остаток строки после "закавыченного" слова.
Функция CreateTempFile создает временный файл нулевой длины с заданным префиксом и расширением
и возвращает его имя. Применяется для создания файлов временных промежуточных данных.
После использования временные файлы надо удалять.
В стандартную библиотеку добавлен модуль StdDiesel,
содержащий функции для организации запуска, завершения и взаимодействия с программами DieselPascal.
Модуль находится в разработке и документирован частично.
Полная документация будет после завершения разработки.
В пакет добавлена переменная окружения CRW_DAQ_SYS_LANG,
содержащая информацию о языке интерфейса.
Это сделано для того чтобы дочерние программы DieselPascal могли узнать, на каком языке работает
их родительский процесс Crw32.exe и могли установить такой же язык интерфейса.
Добавлен шаблон утилиты DieselPascal в каталоге
Resource\DieselPascal\Templates.
Шаблон содержит заготовку утилиты DieselPascal для работы в составе пакета CRW-DAQ.
В шаблоне уже содержится код, нужный для большинства таких утилит.
В частности,
Запуск единственного экземпляра программы.
Обработка исключений с записью в журнал событий.
Посылка сообщений в главную консоль процесса Crw32.exe.
Автоматическое завершение программы при завершении процесса Crw32.exe.
Чтение передаваемых параметров из временного файла (опция --params).
Открытие канала связи IPC (опция --easyipc).
Шаблон еще не завершен (не успел), но уже вполне работоспособен.
01.07.2020
DieselPascal Crw32.Utils.lm9
Главными достижениями данного выпуска являются:
обновление DieselPascal,
доработка утилиты Crw32.Utils.lm9.
Обновлен DieselPascal.
В него добавлено большое число недостающих функций - как общего назначения,
так и специально созданных для работы в составе пакета CRW-DAQ.
В частности, добавлены функции для прямой связи с процессом Crw32.exe
путем посылки данных через сообщение WM_COPYDATA в Главную Консоль.
Разработка дополнительных функций велась в сотрудничестве с автором DieselPascal.
Накопленный опыт показал, что при необходимости можно вносить свои изменения в DieselPascal
самостоятельно и развивать его так, как нам нужно.
Это еще раз подтвердило правильность решения о включении DieselPasca в состав пакета.
Обновлена утилита
Crw32.Utils.lm9.
В ней проработаны механизмы взаимодействия с пакетом CRW-DAQ.
Обновленный набор функций DieselPascal позволил ускорить посылку сообщений
в консоль родительского процесса Crw32.exe.
Доработана библиотека модулей, которая будет входить в каждую клиентскую программу
DieselPascal, работающую в составе пакета.
Предполагается, что такие програмы будут запускаться из процесса Crw32.exe
и будут взаимодействовать с ним.
Передача данных из процесса Crw32.exe в клиентскую программу DieselPascal
происходит через переменные окружения и аргументы вызова.
Обратная связь осуществляется через посылку сообщений в Главную Консоль процесса Crw32.exe.
Библиотека содержит необходимые константы и функции, которые обеспечивают такое взаимодействие.
В утилиту также добавлено большое количество кнопок для вызова функций операционной системы.
Это делает утилиту полезным инструментом при работе в составе пакета.
Утилита Crw32.Utils.lm9 послужит прототипом для всех будущих клиентских программ.
На её основе будет разработан шаблон, из которого можно будет быстро создавать такие программы.
Надо только немного точнее проработать механизм обмена данными c DAQ-системой,
чтобы облегчить создание клиентских программ. Это будет сделано в ближайшее время.
23.06.2020
DieselPascal .lm9 Crw32.Utils.lm9
Главными достижениями данного выпуска являются:
добавление DieselPascal в crw32-runtime,
утилита Crw32.Utils.lm9.
На просторах Сети найден полезный продукт -
DieselPascal.
Это интерпретатор Pascal со своей средой быстрой графической разработки IDE.
Налажена связь с автором DieselPascal
(Юрий Копнин),
от него получены исходные коды как самого интерпретатора, так и всех используемых библиотек.
После того, как удалось самостоятельно "собрать" DieselPascal из исходных кодов,
было принято решение интегрировать DieselPascal в состав runtime пакета.
Отныне это часть среды исполнения.
Причины выбора DieselPascal:
Открытый код на Free Pascal, свободная лицензия. Возможность менять или расширять код.
Небольшой объем исполнительной части (8 МБ в архиве). "Чистота" кода с точки зрения VirusTotal.
И при всем этом - наличие среды IDE для быстрой разработки графических интерфейсов.
Возможность создания прикладных программ для работы с базами данных.
Кроссплатформенность (Win32/64,Linux32/64) без изменения кода.
DieselPascal привлекает своей относительной компактностью, возможностью быстрой разработки
небольших прикладных программ с графическим интерфейсом и доступом к базам данных.
Он, в силу своей невысокой скорости (интерпретатор все-таки), не является конкурентом DaqPascal
или Object Pascal, однако выглядит хорошим инструментом для создания прикладных графических утилит,
работающих в составе пакета.
Очень удобно, что независимо от объема и сложности программы DieselPascal,
она занимает ровно один файл (*.lm9), который одновременно является и исходным кодом,
и исполняемой программой (скриптом).
Поэтому не надо следить за большим числом библиотечных файлов и исходных кодов.
Для небольших прикладных программ это достоинство.
В инсталлятор install-daqgroup-crw32-runtime добавлен исполнительный набор (runtime)
DieselPascal, содержащий только программы и библиотеки.
Полный набор (с документацией и исходными кодами) будет храниться в install-daqgroup-database.
DieselPascal планируется активно использовать как в прикладных DAQ системах,
так и в внешних системных утилитах пакета.
При инсталляции DieselPascal устанавливает ассоциацию (связь, привязку)
с расширением .lm9.
Это стандартное расширение для программ DieselPascal.
Файловая ассоциация позволяет запускать программы DieselPascal
прямо из оболочки (Explorer, TotalCommander, ...)
или в консоли cmd /c call program.lm9
или с помощью grun -s program.lm9.
Запускаемой программе можно передавать аргументы, как обычно.
Фактически файлы .lm9 работают как исполняемые файлы.
Добавлена команда @reg для работы с реестром:
@reg
Syntax:
@reg -r key name - прочитать ключ реестра key, параметр name (key,name заданы в URL-кодировке)
@reg -f ftype - узнать командную строку, ассоциированную с типом файла ftype
@reg -a ext - узнать тип файла, ассоциированный с файловым расширением ext
@reg -e ext - узнать *.exe файл, ассоциированный с файловым расширением ext
Examples:
@reg -r HKLM\SOFTWARE\Microsoft\Windows+NT\CurrentVersion\Fonts PT+Mono+(TrueType)
@reg -f VisualTech.DieselPascal.CrossMachine
@reg -a .lm9
@reg -e .htm
Команда позволяет узнать, какой *.exe файл обрабатывает файлы с данным расширением или с данным типом.
А также можно прочитать параметр из реестра с данным ключем (путем) и именем.
Возвращаемое значение равно положительному числу (длине строки) или 0, если параметра нет.
Например, так можно проверять наличие установленных программ или шрифтов.
В стартовый скрипт Crw32.ini [System.StartupScript] добавлена команда:
@silent IsDieselPascalAvailable=@reg -a .lm9
Эта команда проверяет доступность DieselPascal (по файловой ассоциации .lm9)
и устанавливает переменную IsDieselPascalAvailable.
Это позволяет проверять доступность DieselPascal программах DaqPascal.
if eval('IsDieselPascalAvailable')=0
then Problem('DieselPascal is not available.')
else rNul(eval('@system @async @silent @run grun -s DemoProgram.lm9'));
Примечание: grun -s запускает программу через оболочку Shell, т.е. с учетом расширения
Сделана первая утилита на DieselPascal -
Crw32.Utils.lm9.
Эта команда заменяет встроенное меню "Инструменты\Консольные утилиты",
если доступен (установлен) DieselPasca, и в меню стоит "Инструменты\Внешние утилиты разрешены.".
Пакет запускает утилиту Crw32.Utils.lm9 через команду @run и она выполяется автономно.
Через унаследованные переменные окружения утилита имеет ссылку на родительский процесс Crw32.exe
и может с ним взаимодействовать. При выборе в списке команд интересующей команды, эта команда посылается
в консоль родительского пакета для выполнения. Утилита Crw32.Utils.lm9 автоматически завершается,
если родительский процесс прекратил работу.
Утилита Crw32.Utils.lm9 содержит полный набор библиотек и средств для взаимодействия с пакетом.
Эта утилита, помимо прикладного значения, может служить шаблоном для создания других утилит на языке
DieselPascal, работающих в составе пакета. В этой утилите уже собраны средства, необходимые для
взаимодействия с пакетом, DAQ системой и ОС.
Опыт создания утилиты на DieselPascal показал, что это - не игрушка, а вполне рабочий инструмент
для создания небольших прикладных программ с графическим интерфейсом, работающих в составе пакета.
С DieselPascal связаны далеко идущие планы, которые могут радикально изменить практику
прикладного программирования в пакете. Случится ли это - увидим со временем.
Главными достижениями данного выпуска являются:
константы TAG_REF_MIN, TAG_REF_MAX;
функция adjustlinebreaks;
оптимизация функций рисования для свернутых (спрятанных) окон;
команда @daq toplist для организации топ-листа отображаемых окон;
команда @list modules для вывода списка используемых DLL;
настройка топ-листа окон с помощью диалога и секции [DAQ];
инсталлятор install-daqgroup-database;
каталог общих библиотек Resource\Shared;
обновление команды @env и @daq;
обновление файла Crw32.ini.
Заведены константы
TAG_REF_MIN,
TAG_REF_MAX.
Они задают диапазон, в котором лежат ссылки на теги,
что позволяет организовывать циклы по всем тегам.
Например:
procedure PrintAllTags;
var tag:Integer;
begin
for tag:=TAG_REF_MIN to TAG_REF_MAX do
if typetag(tag)>0 then writeln(nametag(tag));
end;
Заведена функция adjustlinebreaks,
которая исправляет разделители строк, преобразуя их в CRLF.
Эта функция полезна для обработки текстов, поступающих по сети (например, HTTP)
или созданных в других системах (MAC, Linux), где приняты другие разделители строк.
Обновлена команда @env.
Добавились опции работы с переменной окружения PATH:
@env /c name - проверить, существует ли переменная окружения name@env /v PATH - исправить (validate) переменную PATH (список поиска)
@env /t PATH dir - добавить dir в конец (tail) переменной PATH@env /h PATH dir - добавить dir в начало (head) переменной PATH@env /d PATH dir - удалить (delete) dir из переменной PATH
например (из файла Crw32.ini):
@env /t PATH %CRW_DAQ_SYS_HOME_DIR%\Resource\Shared - включает в PATH каталог общих библиотек
@env /t PATH %CRW_DAQ_SYS_HOME_DIR% - включает в PATH домашний каталог пакета
Переменная окружения PATH содержит список каталогов - путей поиска программ и файлов.
Эти каталоги могут отсутствовать, или переменная может быть задана неверно.
Такое возможно, например, в результате инсталляции/деинсталляции программ,
которые вносят изменения в переменную PATH.
Команда исправления @env /v PATH исправляет список путей поиска,
удаляя из него несуществующие каталоги и исправляя формат списка.
Команды @env /h PATH dir, @env /t PATH dir
позволяют добавлять каталог dir в начало (head) или в конец (tail) списка
каталогов в переменной PATH.
Команда @env /d PATH dir удаляет каталог dir из списка
каталогов переменной PATH.
Перечисленные команды позволяют редактировать переменную PATH,
чтобы делать доступными для поиска файлов те или иные каталоги.
Это играет большую роль при вызове программ (например, командой @run),
т.к. дочерние процессы наследуют переменные окружения процесса, включая PATH.
Обновлена команда @list. Добавлена функция @list modules.
@list modules - выдает список модулей (EXE,DLL) текущего процесса
@list modules 321 - выдает список модулей (EXE,DLL) процесса номер 321
Команда @list modules позволяет узнать, какие библиотеки DLL
использует данный процесс. Это может помочь, например, если есть несколько
версий одноименных DLL в разных каталогах, и надо понять
- какую из них загрузил процесс.
Также помогает установить, от каких DLL библиотек зависит процесс.
Заведен каталог общих библиотек Resource\Shared,
в котором находятся *.DLL библиотеки, необходимые разным программам,
входящих в состав пакета.
Обновлен файл параметров Crw32.Param.ini, секция [System.StartupScript].
В этой секции в PATH включаются: каталог общих библиотек Resource\Shared
и домашний каталог пакета.
Благодаря этому общие библиотеки становятся доступны для поиска.
Это значит, что все запускаемые из среды пакета программы автоматически
будут иметь доступ к этим библиотекам.
Предпринята большая работа по оптимизации функций прорисовки,
т.е. минимизации рисования для уменьшения нагрузки CPU.
Это связано с тем, что в больших системах бывают десятки окон и сотни кривых.
Экран монитора в принципе не может вместить столько окон и графиков одновременно,
поэтому обычно большая часть окон бывает "свернута" или "спрятана".
При этом на обновление "свернутых" окон все же тратились ресурсы.
Для оптимизации сделано следующее.
Во-первых, в окнах кривых, таблиц и мнемосхем сделан (по возможности)
"обход" рисования для "свернутых" или "спрятанных" окон,
т.к. они все равно не видны на экране.
Обход рисования позволяет избежать ненужных затрат ресурсов процессора.
Во вторых, сделан полезный инструмент - "топ-лист" - для закрытия "лишних" окон.
Смысл инструмента в том, чтобы "свернуть" все окна заданного пользователем типа,
кроме небольшого числа недавно открытых окон, входящих в "топ-лист".
Команда @daq toplist Curve_Window 5 оставляет открытыми
только 5 недавно открытых окон с кривыми (Curve_Window),
а остальные окна "сворачиваются" и становятся невидимыми.
@daq toplist t1,n1,t2,n2,... - команда отображения топ-листа окон и сворачивания остальных окон
t1,t2, ... - тип окна: Curve_Window, Tab_Window, Circuit_Window, Spectr_Window
n1,n2, ... - число окон заданного типа в списке TopList
например:
@daq toplist Curve_Window 5 Tab_Window 4 Circuit_Window 7 Spectr_Window 3
При построении "топ-листа" учитываются только окна, имеющие кнопку "закрыть" или "свернуть".
Если окна не имеют этих кнопок, они всегда остаются на экране и не принимаются в расчет
при построении "топ-листа".
Это позволяет отделять окна, которые всегда нужны на экране (например, главная мнемосхема),
от других окон, которые открываются на время для посмотра определенных данных.
Команду @daq toplist ... можно использовать многими способами.
Можно вызывать её периодически, например, создав задание Cron.
Можно вызывать её по кнопке, чтобы закрывать лишние окна.
Топ-лист позволяет не только избежать излишней нагрузки процессора,
но и может сделать работу удобнее, т.к. множество одновременно открытых окон
только мешают сосредоточиться на решаемой в данный момент проблеме.
Ограничение числа одновременно открытых окон с помощью топ-листа
поможет сделать работу более быстрой и комфортной.
Для облегчения использования топ-листа окон в секции
[DAQ] заведены параметры:
[DAQ] ; Параметры топ-листа по умолчанию:
CurveTopListLimit = 0 ; Предел числа окон в топ-листе окон кривых
TableTopListLimit = 0 ; Предел числа окон в топ-листе окон таблиц
CircuitTopListLimit = 0 ; Предел числа окон в топ-листе окон мнемосхем
SpectrTopListLimit = 0 ; Предел числа окон в топ-листе окон спектров
DaqTopListPeriod = 5 ; Период опроса топ-листа окон DAQ системы, сек
По умолчанию топ-лист отключен (пределы имеют нулевое значение).
При указании в конфигурации DAQ отличных от нуля пределов, топ-лист включается в работу.
При этом система с заданным периодом опрашивает и корректирует список окон,
закрывая (сворачивая) лишние окна, не входящие в топ-лист.
В диалог "Операции с окнами DAQ" добавлена группа элементов:
для управления топ-листом окон в интерактивном режиме.
Для анализа работы пакета и диагностики затрат на рисование, в программе заведены счетчики
и сделан их вывод в консоль "Монитор ресурсов".
Также счетчики доступны через вызов
paramstr('DaqSysInfo name'),
где name - имя параметра, например:
paramstr('DaqSysInfo Tag.Count') счетчик всех тегов
paramstr('DaqSysInfo Curve.Count') счетчик всех кривых
paramstr('DaqSysInfo Sensor.Count') счетчик всех сенсоров
paramstr('DaqSysInfo Circuit_Window.TagEvalCall.Count') счетчик вызовов TagEval(v)
и так далее
Счетчики и (главное) их частота позволяют оценить, сколько и на что тратятся ресурсы при работе.
В консоли DAQ устройств добавлена обработка команды @paramstr
(в стандартной библиотеке StdIn_DefaultHandler).
Команда вызывает функцию ParamStr(arg) с переданным аргументом и печатает результат в консоли устройства.
Команда служит для информативной цели, в помощь разработчикам.
Например:
В дистрибутив добавлен новый инсталлятор install-daqgroup-database,
содержащий программы, библиотеки и документацию для работы с базами данных.
Это сделано "на перспективу" в связи с планами добавить в пакет поддержку работы с БД.
Предположительно ориентируемся на Firebird.
Главными достижениями данного выпуска являются:
добавление информации @sysinfo;
информация о кодовых страницах ansicodepage, oemcodepage,
добавление поддержки событий колесика мыши (Mouse Wheel) и
добавление констант (cw_MouseWheel, cw_MouseWheelDown, cw_MouseWheelUp),
увеличение допустимой длины строк текста программы до 161.
Добавлена дополнительная информация в команде @sysinfo.
Она касается версии OS, CPU и информации о языке, например:
@sysinfo
OS ver : WIN-NT 10.0.17763 - Windows 10 Enterprise LTSC 2019
...
CPU Info : Count:2, List:(0,1), Arch:x86, Level:6, Revision:3C03CPU 0 : Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz, GenuineIntel, x86 Family 6 Model 60 Stepping 3CPU 1 : Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz, GenuineIntel, x86 Family 6 Model 60 Stepping 3CPU Freq : 2394.535 MHz (eastimated), 2394 MHz (registry)
...
RS-232 : COM1,COM2
CodePage : ANSI CP1251, OEM CP866.Language : System=$419,RUS,Русский (Россия); User=$419,RUS,Русский (Россия).Locale : System=$419,RUS,Русский (Россия); User=$419,RUS,Русский (Россия).
User : main is elevated member of group(s) ADMINS,USERS
...
Добавленная информация выделена синим цветом.
В Главной Консоли добавлены константы с информацией о текущих кодовых страницах
ansicodepage, oemcodepage.
Например, для русскоязычной версии OS:
Знание кодовых страниц может быть полезно при вызове программ командой @run ...,
чтобы знать, в какой кодировке производится ввод-вывод.
Напомним, что для доступа к константам Главной Консоли в DaqPascal можно использовать вызовы
типа eval('@system ansicodepage') .
Константы кодовых страниц задаются и обновляются командой @view screen .
В сенсоры мнемосхем добавлены события обработки колесика мыши (Mouse Wheel).
Они возникают при прокрутке/нажатии/отпускании колесика мыши,
когда курсор находится в пределах сенсора.
В функции ClickParams('What')
соответственно добавились значения:
MouseWheel (поворот колесика),
MouseWheelDown (нажатие кнопки колесика),
MouseWheelUp (отпускание кнопки колесика).
В функции ClickParams('Wheel')
добавилось новое поле: Wheel (колесо), которое возвращает
приращение колесика мыши при его прокручивании: ClickParams('Wheel').
Приращение обычно кратно 120, а его знак зависит от направления вращения.
Добавлена переменная WHEEL_DELTA,
по умолчанию равная 120 (стандартное значение в Windows).
Это шаг приращения для обработки события MouseWheel.
Вызов ClickParams('Wheel')
возвращает приращение, кратное WHEEL_DELTA.
В функции ClickFilter
соответственно добавились новые маски:
64 (разрешение события MouseWheel),
128 (разрешение события MouseWheelDown),
256 (разрешение события MouseWheelUp).
По умолчанию события колесика запрещены,
поэтому их необходимо явно разрешить в программе.
Например:
i:=ClickFilter(0); // Прочитать значение фильтра
i:=iSetBitState(i,cw_MouseWheel,true); // Установить бит cw_MouseWheel
iNul(ClickFilter(i)); // Задать значение фильтра
В функции ClickAwaker
соответственно добавились новые маски:
64 (разрешение пробуждения по событию MouseWheel),
128 (разрешение пробуждения по событию MouseWheelDown),
256 (разрешение пробуждения по событию MouseWheelUp).
По умолчанию пробуждение по событиям колесика запрещены,
поэтому их необходимо явно разрешить в программе.
Разрешение и обработка событий колесика мыши позволит, например, создавать
управляемые оператором графические поля, в которых значения можно менять
не вводом чисел, а вращением колесика мыши.
В конфигурацию DEMO_PAINT_GUILIB
добавлен тест (Test Wheel) для проверки обработки событий колесика мыши.
Обработка события вращения колесика мыши в цикле обработки событий делается примерно так:
{
Handle user mouse/keyboard clicks...
}
if ClickWhat<>0 then
repeat
// Handle MouseDown/KeyDown
if (ClickWhat=cw_MouseDown) or (ClickWhat=cw_KeyDown) then begin
...Обработка обычных кликов...
end;
//
// Handle mouse wheel
//
if ClickWhat=cw_MouseWheel then begin // Если это событие колесика мыши
if ClickTag=tagWheelTestData then begin // Если это интересующий нас сенсор
i:=Round(Val(ClickParams('Wheel'))/WHEEL_DELTA); // Вычислить шаг приращения из ClickParams('Wheel')
if i<>0 then bNul(rAtomicTagOp(tagWheelTestData,'+',i)); // Применить это приращение к тегу
end;
end;
until (ClickRead=0);
Было замечно, что в мыши, где колесико играет роль средней кнопки мыши,
нажатия\отпускания колесика мыши не генерируют события MouseWheelDown\MouseWheelUp,
а распознаются как обычные клики MouseDown\MouseUp со средней кнопкой мыши
ClickButton=VK_MBUTTON.
Это по-своему логично.
Такое поведение необходимо учитывать при написании программ.
В ограничениях DaqPascal
изменена максимальная длина буфера входной строки с 121 до 161 символов.
Использование длинных строк в текстах программ не рекомендуется, но в некоторых случаях допустимо.
Рекомендуется по-прежнему ограничивать длину строк программного кода 120 символами,
а строки до 160 символов использовать в исключительных случаях,
если это улучшает структуру кода.
Обновлен генератор конфигураций DaqCreator от Н.Гурина.
01.05.2020
@font @if crw-daq-doc @tooltip --broker
Главными достижениями данного выпуска являются:
доработка команды Painter@font и @if,
усовершенствование (ускорение работы) команды @tooltip,
создание справочных файлов crw-daq-doc.
Открыт новый проект crw-daq-doc
по созданию документации пакета CRW-DAQ в "читабельном" формате PDF.
Документация будет расположена в каталоге Resource\Help\crw-daq-doc.
Документация будет "тематически" структурированной, т.е. на каждую большую тему
(например, описание языка DaqScript) будет свой PDF файл,
в котором будет собрана вся информация на эту тему.
Цель проекта - облегчение обучения новых специалистов (студентов) в плане
разработки прикладного ПО в пакете CRW-DAQ.
Сделан пункт меню "Справка\crw-daq-doc" для быстрого доступа к документации crw-daq-doc.
А также кнопка на панели инструментов.
Во время создания документации crw-daq-doc были замечены "лакуны" в реализации некоторых функций и команд.
Например, в Painter команде @font
присутствовал параметр @font height, но отсутствовал параметр @font size.
В ряде случаев удобнее задавать размер фонта (size) в пунктах (pt), а не высоту (height) в пикселях (px).
Это было исправлено:
@font height -13 -- задать высоту фонта в px
@font size 10 -- задать размер фонта в pt
По команде @if в Главной Консоли сделана справка (ранее она отсутствовала).
Кроме того, было сделано изменение (добавлено слово then) в синтаксисе этой команды:
@if cond cmd - старый стиль команды - работает, но считается устаревшим
@if cond then cmd - новый стиль команды - рекомендуется использовать теперь
Первый (старый) стиль копирует синтаксис команды if в командных файлах cmd.
Второй (новый) стиль похож на синтаксис оператора if ... then ... в скриптах DaqScript или программах DaqPascal.
Для совместимости работают оба стиля команды, но в будущем рекомендуется использовать новый, как более привычный.
Для увеличения скорости работы и снижения нагрузки CPU в системе FP-QUI "всплывающих уведомлений"
(tooltip notifier) в команду @tooltip в Главной Консоли добавлены новые возможности:
Включение/отключение режима Брокера:
@tooltip --broker start Пуск Брокера (посредника) системы уведомлений FP-QUI.
@tooltip --broker stop Стоп (отключение) Брокера системы уведомлений FP-QUI.
@tooltip --broker status Напечатать статус Брокера системы уведомлений FP-QUI.
В файле конфигурации Crw32.ini [System] добавлены такие параметры Брокера:
TooltipBroker = Resource\fpquibrk\fpquibrk.exe ; Брокер @tooltip для быстрого вызова FP-QUI
TooltipLogFile = Temp\@Tooltip.log ; Журнальный файл для вывода команды @tooltip
TooltipTimeOut = 200 ; Таймаут [мс] используемый для завершения Брокера
TooltipFifoSize = 64 ; Размер FIFO буфера команды @tooltip, [килоБайт]
TooltipPeriod = 30 ; Период [с] для проверки статуса Брокера @tooltip
В стартовом сценарии Crw32.ini [System.StartupScript] добавлена команда:
@silent @tooltip --broker start ; Запуск программы Брокера для команды @tooltip
Брокер (broker, посредник) в этом описании - это программа
fpquibrk.exe,
служащая для быстрой передачи сообщений системе всплывающих уведомлений FP-QUI.
Эта программа аналогична программе fpquitip.exe, только в отличие от неё
программа fpquibrk.exe не завершается после каждой передачи сообщения,
а остается в режиме online со связью через анонимный канал.
Вместо создания процесса для каждого передаваемого сообщения,
программа fpquibrk.exe загружается только один раз, а затем многократно
передает сообщения, поступающие через канал связи, в систему оповещения FP-QUI.
Это позволяет ускорить передачу сообщений и существенно сэкономить время CPU,
исключив создание новых процессов для каждой передачи сообщений.
Уменьшение числа запускаемых процессов особенно важно при наличии антивирусных программ,
т.к. антивирусы задерживают (иногда довольно существенно) запуск процессов для их проверки.
Такое решение проблемы позволяет кардинально ускорить работу системы "всплывающих" уведомлений
на основе команды @tooltip, но при этом не "перегружать" ядро пакета лишним кодом.
Основной код взаимодействия с системой FP-QUI работает в программе fpquibrk.exe,
а ядро пакета лишь запускает этот процесс и передает ему сообщения для обработки через канал.
Другим достоинством работы с Брокером является то, что все всплывающие уведомления
в этом случае журналируются в файле Temp\@Tooltip.log, что может помочь в случае
необходимости восстановить время и последовательность событий, например, при разборе
нештатных ситуаций.
При отключении Брокера команда @Tooltip работает по-старому, через вызов fpquitip.exe.
Работа команды @Tooltip с включенным Брокером может слегка отличаться от работы без него.
Различие в том, как обрабатывается подстановка переменных окружения, типа %UserName% или %PATH%.
В случае работы в старом стиле (через fpquitip.exe) подстановку переменных окружения
выполняет командный процессор CMD, т.к. вызов fpquitip.exe выполняется через него.
В случае работы в новом стиле (через Брокера) запуска командного процессора не происходит,
а подстановку переменных окружения выполняет сам Брокер (программа fpquibrk.exe).
Код Брокера максимально аккуратно моделирует работу командного процессора и в большинстве случаев
это должно работать одинаково, однако могут быть тонкие различия, к которым надо быть готовыми.
Например, Брокер делает подстановку специальных псевдо-переменных командного процессора
%CD%, %DATE%, %TIME%, %RANDOM%.
В то же время некоторые псевдо-переменные, такие как
%ERRORLEVEL%, %CMDEXTVERSION%, %CMDCMDLINE%
- не подставляются, т.к. они не имеют смысла для Брокера.
Поскольку работа команды @Tooltip может легко преключаться на режим с Брокером или без него,
прикладной программист сам может решать, какой режим использовать в конкретной системе.
По умолчанию запускается режим работы с Брокером.
Главными достижениями данного выпуска являются:
добавление команд DetectWindows, WindowsKey
добавление параметра UseKernelGetTickCount64,
оптимизация mSecNow.
Обновлены вспомогательные пакеты (netweb, mmedia, office, commander).
В commander добавлены утилиты настройки параметров Windows 10.
В репозитории Windows 10 Professional заменен на Windows 10 LTSC 2019,
имеющий длительный срок поддержки (до 2028).
Это наиболее подходящий дистрибутив для систем управления (небольшой объем, ничего лишнего).
Он, вероятно, станет основным на ближайшие 10 лет.
Также подготовлена виртуальная машина для быстрого развертывания.
Для Windows 10 LTSC 2019 подготовлен пакет вспомогательных утилит
для облегчения установки в режиме offline.
В пакет UnixUtils добавлены команды DetectWindows, WindowsKey:
unix windowskey - показать версию Windows и серийный номер
в диалоговом окне (GUI)
unix detectwindows - напечатать версию Windows в консоли
Windows 10 Enterprise LTSC 2019 -- Version 10.0.17763.107
unix detectwindows -v - напечатать версию Windows и все детали
ProductName : Windows 10 Enterprise LTSC 2019
ProductID : 00425-00000-00002-AA106
SerialKey : M7XTQ-FN8P6-TTKYV-9D4CC-J462D
EditionID : EnterpriseS
ReleaseId : 1809
CurrentVersion : 6.3
CurrentMajorVersionNumber : 10
CurrentMinorVersionNumber : 0
CurrentBuild : 17763
CurrentBuildNumber : 17763
UBR : 107
BuildBranch : rs5_release
BuildLab : 17763.rs5_release.180914-1434
BuildLabEx : 17763.1.x86fre.rs5_release.180914-1434
CurrentType : Multiprocessor Free
SoftwareType : System
InstallationType : Client
RegisteredOwner : main
SystemRoot : C:\Windows
Version : 10.0.17763.107
Как видно из примеров, команды показывают подробную информацию о версии Windows.
Некоторые параметры (например, серийный номер) нельзя получить стандартными средствами.
Команды реализованы на VBScript.
Серьезно изменена функция mSecNow (модуль _RTC.PAS) с учетом новых возможностей Windows 7/8/10.
Поскольку mSecNow является основной функцией измерения времени, стоит сказать об этом подробнее.
Старая версия mSecNow использует функцию GetTickCount, основанную на 32-битном счетчике,
который переполняется через (примерно) 49 дней.
Поэтому её приходится программно корректировать с учетом возможного переполнения счетчика.
Для корректной работы процедуры коррекции приходится блокировать поток, что несколько замедляет
работу функции, а также может серьезно замедлять работу прикладных программ из-за блокировки потоков.
Ведь mSecNow - одна из самых часто вызываемых функций.
Начиная c Windows 7 в системе появилась появилась функция GetTickCount64,
которая работает с 64-битным счетчиком.
Эта функция не переполняется и не содержит блокировки потоков, что дает ей преимущество.
Однако она недоступна на старых системах.
Поэтому эту новую функцию надо использовать условно, с учетом обратной совместимости.
Новая версия mSecNow использует функцию GetTickCount64, если она доступна
и разрешена флагом Crw32.ini [System] UseKernelGetTickCount64 = 1.
При недоступности функции GetTickCount64
или при флаге Crw32.ini [System] UseKernelGetTickCount64 = 0
используется старая версия.
Таким образом, mSecNow использует новые возможности Windows 7/8/10
при сохранении совместимости со старыми версиями Windows XP.
Используемой версией функции mSecNow управляет параметр Crw32.ini [System] UseKernelGetTickCount64:
Crw32.ini
[System]
UseKernelGetTickCount64 = 0 - использовать старую версию
UseKernelGetTickCount64 = 1 - использовать новую версию, если она поддерживается системой
Из приведенной таблицы следует, что старая версия mSecNow
тратит на свой вызов около 30 наносекунд,
а новая версия - около 15 наносекунд, т.е. вдвое меньше.
Кроме того, новая версия mSecNow не блокирует потоки,
что должно дополнительно снизить нагрузку на процессор,
особенно при большом числе работающих потоков.
Несмотря на и без того малое время вызова функции mSecNow,
повышение её эффективности очень важно, т.к. это одна из самых часто используемых функций,
на работе которой основано подавляющее большинство алгоритмов работы со временем.
Тест функций модуля RTC (realtime clocks) можно вызвать
командой Главной Консоли @TestBench RTC n,
где n - число итераций (по умолчанию 10000000).
Этот тест дает оценку времени вызова для основных функций измерения времени.
Логический параметр Crw32.ini [System] Check_RTC_Monotonicity = 0/1
управляет проверкой функций RTC на предмет монотонности измерений времени.
Если параметр разрешен (1), система периодически проверяет монотонность функций RTC
и фиксирует ошибку при её нарушениях. Счетчик ошибок виден в диалоге "Служба времени".
Нарушение монотонности говорит о серьезной ошибке в работе функций времени.
По умолчанию проверка разрешена.
05.02.2020
RFC Painter
Главными достижениями данного выпуска являются:
обновление библиотеки Painter,
добавление документов RFC.
Данный выпуск носит технический характер, в нем только фиксируются поправки в ранее созданном коде.
Всех поздравляю с наступившим Новым Годом и Рождеством.
Главными достижениями данного выпуска являются:
добавление библиотечной программы _TAG2CRV.PAS для синхронизации тегов и кривых,
добавление функций поддержки Unicode кодировки UTF8,
добавление документов ГОСТ.
Добавлена библиотечная программа _TAG2CRV.PAS,
смотри описание.
Программа _TAG2CRV.PAS выполняет периодическую (в цикле опроса) синхронизацию кривых и тегов,
то есть копирует зачения из тегов в кривые или из кривых в теги.
Кривые для копирования подключаются к аналогивым/цифровым входам/выходам, теги задаются либо в параметре
(tagAI#i, tagAO#i, tagDI#i, tagDO#i, где i - индекс подключения кривой),
либо берутся по имени соответствующей подключенной кривой.
Когда нужна программа _TAG2CRV.PAS?
Она нужна в случае, если необходимо поддерживать синхронность значений кривых и тегов.
Кривые и теги используются в разных модулях пакета по-разному для решения разных задач.
Например, сервер &DimSrv передает и принимает только теги, поэтому для приема и передачи
данных из кривых по сети их надо сначала записать в теги, а затем передавать эти теги.
А вот сервер &DatSrv, напротив, сохраняет только кривые, т.к. они, в отличие от тегов, имеют историю.
Поэтому для сохранения истории изменения тегов их надо копировать в кривые, и затем сохранять эти кривые.
Например, если есть теги состояния кнопок, историю изменения которых нужно сохранить в DAT файл,
то нужно сначала скопировать теги в одноименные кривые с помощью программы _TAG2CRV.PAS,
а затем сохранить эти кривые с помощью сервера &DatSrv.
Значительно расширена функция strconv для преобразования строк.
Теперь она, например, дает возможность преобразовывать строки в Unicode кодировку UTF8,
а также менять регистр, например:
s:=strconv('utf8-ansi','user string'); // Convert from UTF8 to ANSI code page
s:=strconv('ansi-utf8','user string'); // Convert from ANSI to UTF8 code page
s:=strconv('ansi-uppercase','String'); // Convert ANSI string to upper case
s:=strconv('ansi-lowercase','String'); // Convert ANSI string to lower case
Добавлена группа функций DaqPascal типа
utf8_xxx
для работы со строками Unicode в формате UTF8.
Кодировка UTF8 по факту является самым распространенным и переносимым форматом хранения и передачи
тестов Unicode, на неё ориентируется Internet/Web и Unix/Linux.
Большинство современных текстовых редакторов поддерживают UTF8.
Библиотека функций utf8_xxx позволяет обрабатывать строки UTF8 в DaqPascal, например,
для сохранения данных в файлы или передачи данных по сети.
function strconv(how,s:string):string - преобразует строку s методом how, включая UTF8
function utf8_encode_ansi(s:string):string - преобразует ANSI строку s в UTF8
function utf8_decode_ansi(s:string):string - преобразует UTF8 строку s в ANSI
function utf8_uppercase(s:string):string - преобразует UTF8 строку s в верхний регистр
function utf8_lowercase(s:string):string - преобразует UTF8 строку s в нижний регистр
function utf8_length(s:string):integer - возвращает символьную длину UTF8 строки s
function utf8_copy(s:string; i,n:integer):string - копирует фрагмент UTF8 строки s
function utf8_ord(s:string; i:integer):integer - возвращает код символа Unicode строки s
function utf8_chr(c:integer):string - возвращает UTF8 строку по коду символа Unicode
function utf8_bom:string - возвращает UTF8 маркер BOM (byte order mark)
Кодировка UTF8 является байт-ориентированной, она не меняет символы ASCII,
включая латинские буквы, цифры, пробелы, знаки пунктуации и управляющие символы.
Поэтому значительная часть обычных строковых функций, касающаяся анализа слов,
может работать и со строками UTF8.
Добавлена конфигурация test_utf8.cfg
с тестовым примером программы test_utf8.pas,
иллюстрирующей использование функций для работы со строками UTF8.
Добавлены документы (ГОСТ) в demodoc.
В частности, ГОСТ ИСО 8601-2001
описывает форматы представления даты и времени.
Устранены мелкие недочеты (касающиеся графического интерфейса) в Редакторе Калибровок.
15.12.2019
DEMO_DOZA _DIMRCV.PAS DaqLib.crc DaqLib.htm
Главными достижениями данного выпуска являются:
обновление DEMO_DOZA,
добавление программы _DIMRCV.PAS,
добавление библиотеки графических элементов DaqLib для интерпретатора Painter.
В сборке обновлен Commander от версии 8.52a до актуальной версии 9.22a.
Обновлено много инструментов, входящих в сборку, добавлены инструменты анализа окон и сообщений.
Добавлена программа
_DIMRCV.PAS,
которая является "универсальным приемником" данных, поступающих от DIM-сервера.
Эта программа используется на стороне DIM-клиента, если клиенту нужен только
прием данных в теги и кривые, а также передача простых консольных команд DIM-серверу
по защищенному каналу связи. Программа не ставит задачей полную реализацию клиента,
включающего обработку графических событий и т.д.
Она лишь принимает сообщения @DimTagUpdate и записывает принятые теги в одноименные
кривые, если они подключены к выходам (это нужно для записи данных в кривые на стороне клиента).
Также она может отсылать в консоль сервера команды с помощью команды @Remote
(для этого имена программных устройств и методы шифрования клиента и сервера должны совпадать).
Полезность программы _DIMRCV.PAS связана с тем, что во многих случаях удаленый клиент
не нуждается в полной функциональности, а лишь наблюдает данные DIM-сервера и посылает
простые команды, не требующие полнофункционального клиента.
Универсальный приемник позволяет минимизировать связи между клиентом и сервером,
заменив полномасштабную клиентскую программу этой универсальной "заглушкой".
Примером использования программы _DIMRCV.PAS является, например, DEMO_DOZA,
в которой вместе с конфигурацией генерируется файл импорта данных для использования
в удаленных клиентах.
Обновлена конфигурация
DEMO_DOZA
с драйверами устройств ДОЗА.
Модифицирован список DIM сервисов, убраны лишние файлы изображений,
которые теперь заменены на автоматически генерируемые файлы barbmp, ledbmp,
а также создана клиентская часть для упрощенного импорта данных от DIM-сервера.
При этом используется новая программа _DIMRCV.PAS.
Создана новая библиотека графических элементов
DaqLib
для интерпретатора
Painter.
Эта библиотека дополняет уже существующие библиотеки общепринятых графических элементов
(GuiLib)
и элементов на основе ГОСТ
(GostLib).
Также обновлена и слегка улучшена документация по Painter.
Главными достижениями данного выпуска являются:
команда @note,
ускорение и добавление команд в функцию windraw,
введение StartupDirectory,
изменение поведения @open и обработки аргументов командной строки,
утилиты gif2bmp, checkfilename,
устранение ошибок предыдущих версий.
Введен параметр Crw32.ini [System] StartupDirectory = ~~\. ,
который задает начальный каталог программы (это её домашний каталог),
устанавливаемый при старте Crw32.exe.
Раньше программа не меняла текущий каталог, сохраняя тот каталог, в котором изначально была запущена.
Это могло приводить к некоторым нежелательным эффектам, например,
1) блокировка каталога, откуда выполнялся запуск пакета,
2) неверное значение текущего каталога в наследуемых процессах, запускаемых из-под Crw32.exe.
Теперь пакет всегда работает в своем домашнем каталоге.
Это логично, поскольку все файловые ссылки в Главной Консоли
и так уже давно указываются относительно домашнего каталога программы.
Изменены правила обработки аргументов командной строки:
1) Если указан неполный файл (без расширения или пути), печатается ошибка. Раньше файл молча игнорировался.
2) Если указан несуществующий файл с полным именем (путем и расширением), печатается ошибка. Раньше был диалог.
3) Если указан существующий файл с полным именем, то, как и раньше, вызывается команда @open.
4) Если указан шаблон файла (*,?) или опция /d, то вызывается диалог @open.
Указанное поведение рассчитано на то, что пакет всегда работает в своем домашнем каталоге,
поэтому имена файлов всегда должны быть полными (с путем и расширением).
Изменено поведение команды @open, которая:
Теперь при задании файла, имеющего неполный (относительный) путь, печатает сообщение об ошибке Incomplete Path.
Раньше имя файла с неполным путем задавалось относительно текущего (т.е. случайного!) каталога.
Это было некорректно. Это было незаметно, т.к. обычно задавались абсолютные имена файлов.
Теперь при задании несуществующего (но определенного) файла печатает сообщение об ошибке File Not Found.
Раньше открывался диалог ввода имени файла, что порой было неожиданно и несвоевременно.
При задании маски (* или ?) файла или опции /d, как и раньше, открывает диалог ввода имени файла.
То есть:
@open c:\Daq32\demo\!test.cfg - запускает DAQ систему
@open /r c:\Daq32\demo\!test.cfg - запускает DAQ систему (/run)
@open /e c:\Daq32\demo\!test.cfg - редактирует DAQ систему (/edit)
@open c:\Daq32\demo\!xxxx.cfg - печатает сoобщение об ошибке: File Not Found
@open !test.cfg - печатает сoобщение об ошибке: Incomplete Path
@open c:\Daq32\demo\*.cfg - открывает диалог ввода имени файла
@open /d c:\Daq32\demo\!test.cfg - открывает диалог ввода имени файла (/dialog)
Новое поведение @open представляется более логичным и корректным.
Утилита gif2bmp.exe, которая преобразует файлы GIF в BMP, удалена и
заменена на gif2bmp.cmd, которая вызывает универсальную графическую утилиту
gm convert -compress None -colors 256 in.gif out.bmp.
Причина замены - плохая реакция некоторых антивирусов на файл gif2bmp.exe.
Раньше заменить его было нечем, но с включением в пакет универсальной утилиты gm его удалось заменить.
Вызов gm происходит чуть медленнее, но не существенно.
Зато решение универсальное и нет проблем с антивирусами.
Единственное примечание: в коде скриптов рекомендуется использовать call gif2bmp
(впрочем это касается любых вызовов программ в командных файлах).
Замена затрагивает, &PlotSrv, DEMO_GNUPLOT и некоторые Web-серверы.
Проверка после замены прошла успешно.
Добавилась утилита checkfilename, которая проверяет наличие файла
и исправляет имя файла, возвращая "истинное" имя файла, как он записан на диске:
В переменных окружения пакета присутсвуют различные имена
файлов и каталогов. Раньше они записывались в основном в верхнем регистре, например C:\CRW32EXE\CRW32.EXE.
Теперь они записываются в том виде, в котором существуют на диске, как в утилите checkfilename.
Переменная Crw32.ini [System] GetRealFilePathNameMode = 0 позволяет вернуть старое поведение.
Исправлена небольшая ошибка в версии 24.05.2019.
Она касается автономной версии установки crw32-runtime (т.е. при отсутствии UnixUtils).
В этом случае переменная окружения UnixUtils может быть не определена или может указывать на
отсутствующий каталог.
Это может привести к неверной установке некоторых переменных окружения CRW-DAQ
(например, CRW_DAQ_SYS_PATH), из-за чего некоторые (внешние) функции перестанут работать.
Теперь UnixRoot проверяется на старте и при необходимости (в случае отсутствия этой переменной
или каталога, на который она указывает) устанавливается в локальный каталог Resource\CrwToolkit.
Это гарантирует корректную работу основных утилит в случае автономной установки пакета.
В библиотеку GuiLib добавлены графические элементы:
Надо напомнить, что возможно комбинирование элементов,
например, SimpleCross и SimpleBorder дают квадратик с крестиком.
Это позволяет создавать из примитивов более сложные изображения сенсоров.
В вывод команды @sysinfo добавлен параметр CmdLine:,
содержащий командную строку, с которой была запущена программа.
Предприняты серьезные усилия для ускорения выполнения функции WinDraw за счет хеширования строк.
Это должно снизить нагрузку при большом объеме операций рисования.
В функции WinDraw добавились команды
Fast (для всех окон) и DrawSensor/UpdateSensor (только для окон мнемосхем).
Fast - команда, которая (если используется) всегда должна идти первой (после имени окна).
Она включает режим быстрого рисования, а еще точнее отключает полную прорисовку окна, которое делается обычно.
Это позволяет перерисовывать отдельные элементы окна, не вызывая избыточной перерисовки всего окна.
Команда Fast не имеет параметров и применима ко всем типам окон.
DrawSensor=s1,s2,.. - команда, которая рисует сенсоры с именами s1,s2 и т.д.
Её имеет смысл использовать совместно с режимом Fast, чтобы (пере)рисовать только интересующие сенсоры.
Например, если сенсоры зависят от переменной, которая меняется вызовом Eval.
Команда DrawSensor нужна, если сенсор использует Painter и не имеет подключенных данных (тег/кривая).
Если данные подключены, лучше использовать более быструю функцию UpdateSensor.
UpdateSensor=s1,s2,.. - команда, которая обновляет сенсоры с именами s1,s2 и т.д.
Её имеет смысл использовать совместно с режимом Fast, чтобы (пере)рисовать только интересующие сенсоры.
Например, если сенсоры зависят от переменной, которая меняется вызовом Eval.
Обновление происходит очень быстро, т.к. при этом рисования не происходит, а только устанавливается флаг обновления.
Рисование происходит позже, в общем цикле обновления сенсоров.
Например:
// Изменить надпись на осях без перерисовки окна:
b:=WinDraw('Demo.Plot|Fast|LegendX=Ось абсцисс');
// Задать переменную BorderColor и перерисовать только сенсор Border
b:=WinDraw('Demo.Ctrl|Fast|Eval=(BorderColor=clRed)|DrawSensor=Border');
// Задать переменную CrossColor и обновить только сенсор Cross (с подключенным тегом/кривой)
b:=WinDraw('Demo.Ctrl|Fast|Eval=(CrossColor=clRed)|UpdateSensor=Cross');
Необходимость изменения функции WinDraw продиктована практикой использования Painter.
Не хватало средств для частичной перерисовки элементов окна после изменений.
Теперь это стало возможным.
Обратите внимание, что при частичной (быстрой) прорисовке в режиме Fast надо точно знать,
что требуется перерисовывать (автоматически это не делается).
Если "зависимых" элементов очень много или они неизвестны, придется перерисовывать всё окно.
Всё сказанное о функции WinDraw распространяется на команду @WinDraw.
То есть команды Fast и DrawSensor можно использовать в скриптах, где есть @WinDraw.
Для оценки эффективности работы функции WinDraw
в конфигурацию DEMO_PAINT_GUILIB был добавлен @spam тест.
При введении в консоли &DemoGuiLib команды типа @spam 10
(с числом спам-пакетов за один квант времени) программа начинает генерировать "спам",
т.е. большое количество сообщений о прорисовке окна путем вызова типа такого:
WinDraw('Demo_GuiLib|Fast|Eval=(Border2Color=clLime)')).
При этом реальной прорисовки окна не происходит (поскольку используется режим Fast и команда Eval),
а происходит только передача ему сообщения и выполнение скрипта (Eval).
При этом в консоли ежесекундно отображается сообщение типа Spam Rate = 640
с числом пересылок команд в секунду.
В другом тесте кроме Eval в вызов добавляется DrawSensor, чтобы оценить вклад от рисования.
Тестирование показало, что:
График нагрузки CPU от частоты имеет "пороговый" характер, т.е. сначала ноль, потом резкий рост.
Повышение частоты спама значительно выше (в 2-3 раза) пороговой практически "вешает" процесс.
Пороговая частота зависит от версии OS и числа процессоров, используемых процессом.
Пороговая частота на одном процессоре ощутимо выше, чем на двух (нет конфликта потоков?).
Пороговая частота на Win10 ощутимо выше, чем на WinXP.
Приблизительная (очень грубо оцененная) таблица:
Пороговая частота,кГц:
Для WinDraw|Fast|Eval|UpdateSensor WinDraw|Fast|Eval|DrawSensor
OS/CPU | 1 | 2 OS/CPU | 1 | 2
-------|-----|----- -------|-----|-----
WinXP | 10 | 2.5 WinXP | 2 | 1.2
Win10 | 20 | ??? Win10 | 3.2 | ???
измерения производились в VirtualBox, результаты на "железе" могут отличаться
??? - значит измерение не проводилось
Вероятно, при повышении частоты "спама" начинается борьба потоков за доступ к общим переменным,
что и объясняет наблюдаемое поведение.
Также следует признать, что Win10 показывает более эффективную реализацию потоков,
чем WinXP (что было замечено и ранее).
Таким образом, можно констатировать, что метод WinDraw('WindowName|Fast|Eval=...'))
позволяет эффективно взаимодействовать с скриптами Painter, но общая частота пересылок
не должна превышать нескольких кГц.
При вызове команды скрипта с прорисовкой сенсоров
WinDraw('WindowName|Fast|Eval=...|DrawSensor=...'))
время также будет тратиться еще и на рисование сенсоров,
так что пороговая частота может существенно понижаться, в зависимости от сложности рисования сенсоров.
Поэтому по возможности лучше использовать UpdateSensor вместо DrawSensor.
Концепция пакета CRW-DAQ предполагает максимальное разделение функций измерения/управления (DAQ)
и отображения (GUI), т.i. они выполняются в разных потоках с разными приоритетами.
Новые возможности @WinDraw|Fast|Eval|DrawSensor дают дополнительные возможности для связывания
потоков управления и отображения.
Это полезно (в умеренном объеме), но этим не стоит злоупотреблять.
Не стоит вводить такие связи, пока в этом нет жесткой необходимости.
В Главную Консоль добавлена команда @note (заметка):
@note Сообщение - напечатает метку времени и сообщение, что-то вроде:
2019.11.01-15:20:30 => Сообщение
Команду @note можно использовать вместо @echo для печати сообщения о каком-то событии,
когда нужно зафиксировать время этого события.
По всей программе (по возможности) унифицированы форматы сообщений с меткой времени
(по шаблону @note), чтобы все подобные сообщения выглядели похоже.
Главными достижениями данного выпуска являются:
добавление графических элементов в библиотеку GuiLib,
добавление в сборку графического пакета GraphicsMagick,
добавление в сборку VNC клиент/сервера TightVNC.
В библиотеку GuiLib добавлены графические элементы:
GuiLib.SimpleBorder используется как аналог GuiLib.SimpleButton в тех случаях, когда
соответствующий элемент является ручным (не управляемым программно), т.е. не может быть нажат, как кнопка.
Элементы GuiLib.Cmd.xxx используются совместно с GuiLib.SimpleButton в кнопках
на панели инструментов для стандартных (часто используемых) команд.
Использование библиотечных графических элементов позволит унифицировать интерфейсы пользователя
в DAQ-системах, а также резко сократит число используемых файлов изображений.
Для иллюстрации работы новых элементов GuiLib также обновлена конфигурация
DEMO_MASS2.
Обновлен генератор конфигураций DaqCreator с учетом новых графических элементов.
Теперь новые конфигурации DAQ генерируются с полным набором кнопок на панели инструментов ToolBar
с использованием элементов GuiLib.
В сборку netweb добавлен VNC клиент/сервер TightVNC.
Достоинства TightVNC:
Удаленный клиент не "выбрасывает" локального оператора, в отличие от RDP.
Возможно подключение в режиме просмотра (View), без управления.
Есть режим масштабирования удаленного экрана под экран клиента.
Кроссплатформенность, возможность подключения Windows-Linux.
Возможно одновременное подключение множества VNC клиентов.
Малый размер (2 MB), высокая стабильность работы.
Маленький трафик (несколько kB/sec).
Недостатки TightVNC:
VNC работает медленнее, чем RDP.
Не поддерживается звук.
Несмотря на недостатки, достоинства VNC делают его хорошим инстументом
для удаленого управления там, где не требуется быстрая графика (видео) и звук.
Для большинства измерительных систем VNC является хорошей альтернативой RDP.
В сборки UnixUtils, CmdToolkit, CrwToolkit
добавлен мощный графический пакет
GraphicsMagick
или сокращенно
gm.
Этот кроссплатформенный пакет с открытым исходным кодом позволяет "рисовать" изображения
в файлы (bmp, png, gif, jpeg и т.д.) в пакетном режиме,
а также модифицировать и конвертировать файлы изображений в разных форматах.
Все операции выполняются в командной строке, т.е. доступны для автоматизации.
Например:
unix gm help - консольная справка
unix gm index - справочная документация в HTMLunix gm path - напечатать каталог расположения пакета
Размножить a.bmp в количестве 6 штук по 3 штуки в каждой строке, результат записать в b.bmp:
unix gm montage -background silver -tile 3 -geometry +0+0 a.bmp a.bmp a.bmp a.bmp a.bmp a.bmp b.bmp
Преобразовать b.bmp в 4-битный (16-цветный) формат (имя выходного файла совпадает с входным):
unix gm convert b.bmp -colors 16 b.bmp
Переобразовать файл формата ICO в файл BMP:
unix gm convert demo.ico demo.bmp
Нарисовать на изображении надпись 'gm Demo' фонтом 'PT Mono' размера 24pt.
Обратите внимание что указан файл фонта *.ttf, а координаты надписи - по левому нижнему углу текста.
unix gm convert demo.bmp -font %windir%\fonts\ptm55f.ttf -pointsize 24 -draw "text 10,50 'gm Demo'" -colors 16 result.bmp
Пакет
gm
хорошо известен в Сети и широко применяется для автоматической генерации изображений
на Web-сайтах (например, для авто-генерации миниатюр в фотоальбомах).
В пакете CRW-DAQ планируется применять команду gm для автоматической генерации и обработки
изображений для мнемосхем (в том числе в препроцессоре DAQ-конфигураций или в DaqCreator),
а также для динамической генерации изображений для Web-сервера.
В сборки UnixUtils, CmdToolkit, CrwToolkit добавлена полезная утилита FindFontFile:
FindFontFile - поиск имени файла по имени фонта
unix findfontfile "PT Mono" - напечатает C:\Windows\Fonts\PTM55F.ttf
unix findfontfile "arial bold italic" - напечатает C:\Windows\Fonts\arialbi.ttf
Использование в командных файлах:
for /f %%i in ('unix findfontfile "PT Mono"') do set ptmono=%%i
echo PT Mono font located in %ptmono%
Утилита FindFontFile сделана для использования совместно с gm,
т.к. программа gm использует имена файлов фонтов для рисования текста.
Главными достижениями данного выпуска являются:
обновление библиотек GostLib для Painter(v),
устранение проблемы с рисованием сенсоров на панели инструментов ToolBar,
добавление в свойства сенсоров параметров (ToolBarOpaque, ToolBarBorder, ToolBarSpace),
драйвер датчиков давления WIKA (DEMO_WIKA),
обновление генераторов для драйверов DEMO_DOZA, DEMO_MAYAK, DEMO_GENDC, DEMO_ZUPDC.
Устранена проблема с рисованием сенсоров на панели инструментов ToolBar.
Эта проблема не позволяла использовать графическую библиотеку Painter(v) для рисования сенсоров,
расположенных на панели инструментов, т.е. с параметром ToolBarKey = 1.
Теперь рисование сенсоров на панели инструментов должно работать так же, как и для обычных сенсоров,
в том числе можно использовать функции Painter(v).
Следует только помнить, что изображения на панели инструментов - квадратные, и рисовать там сенсоры
другой формы не стоит, они будут плохо смотреться.
Добавлены свойства сенсоров ToolBarOpaque, ToolBarBorder, ToolBarSpace:
Следующие свойства сенсоров работают, если включен флаг ToolBarKey = 1,
т.е. если сенсор находится на панели инструментов ToolBar окна-мнемосхемы.
ToolBarOpaque = 0..1 (по умолчанию 0) - отключает режим прозрачности для сенсоров,
т.е. сенсор будет рисоваться на непрозрачном (opaque) фоне.
ToolBarBorder = 0..1 (по умолчанию 1) - задает режим рисования рамки (border) вокруг сенсора,
когда сенсор расположен на панели инструментов.
ToolBarSpace = 0..8 (по умолчанию 2) - задает пустой промежуток (space) внутри кнопки вокруг
изображения сенсора, когда сенсор расположен на панели инструментов.
Например:
[SensorList]
Sensor = WIKA.MAIN.CMD.HELP
[WIKA.MAIN.CMD.HELP]
Pos = 850, 1000
Painter(v) = (glButtonBit=0)+(glButtonBevel=1)
Painter(v) = (glButtonMoveX=1)+(glButtonMoveY=1)
Painter(v) = [Painter(v).GuiLib.SimpleButton]
Tag#1 = 0, ..\Bitmaps\wika_main_cmd_help0.bmp
Tag#2 = 1, ..\Bitmaps\wika_main_cmd_help1.bmp
Hint = Вызов Справки.
ToolBarOpaque = 1 ; Режим непрозрачного фона
ToolBarBorder = 0 ; Рисовать сенсор без рамки
ToolBarSpace = 3 ; Промежуток 3 пикселя вокруг сенсора
ToolBarKey = 1 ; Поместить сенсор на панель инструментов ToolBar
[]
Добавление перечисленных параметров позволяет управлять внешним видом сенсоров на панели инструментов ToolBar.
Пример использования новых параметров приведен в описанной ниже конфигурации
DEMO_WIKA.
Обновлен модуль GostLib (разработки Н.Гурина)
для графической библиотеки Painter(v).
В библиотеку графических элементов добавились насосы и задвижки разных видов.
Добавлена конфигурация
DEMO_WIKA,
содержащая драйверы для работы с высокоточными датчиками давления WIKA D-10-P,
с интерфейсом RS-232.
Драйверы проверены на аппаратуре и содержат симулятор.
Обновлены конфигурации
DEMO_DOZA,
DEMO_MAYAK,
DEMO_GENDC,
DEMO_ZUPDC.
В них изменены скрипты для генерации конфигураций из таблиц.
Суть в том, что теперь можно задавать сложный префикс системы.
Ранее допускались только простые префиксы, например, ZUPDC.
Теперь генераторы могут создавать конфигурации с префиксом любой сложности, например, DEMO.TEST.ZUPDC.
Это требуется для включения систем в другие системы в качестве подсистем.
В этом случае им дается составной префикс, например, EGP.BEAM.ZUPDC.
Добавлена документация в справочник (HandBook),
на тему ЕСКД и стандартов RS-232.
Главными достижениями данного выпуска являются:
резервный режим работы (fallback mode) для сервера &DimSrv,
несколько новых функций для библиотеки DIM.
В стандартной конфигурации сервера DimSrv.cfg
добавился целочисленный (integer) системный тег:
[&DimSrv]
...
FallBackModeTag = &DimSrv.FallBackMode
[]
[TagList]
&DimSrv.FallBackMode = integer 0
[]
&DimSrv.FallBackMode - резервный режим работы для сервера &DimSrv (0/1)
Ненулевое значение этого тега будет использоваться для работы сервера DIM
в резервном режиме работы DIM-сервера, когда сеть "умерла" или недоступна.
В резервном режиме сообщения могут направляться в обход сервера
&DimSrv сразу в консоль устройств, чтобы графический
интерфейс мог работать и без сети DIM.
Также модифицирован сам сервер DimSrv.pas
и документация DimSrv.htm.
Добавлена также команда @FallBackMode
для задания значения этого тега через сообщения серверу &DimSrv.
В стандартную библиотеку введены:
Переменная DIM_GuiClickFallBackModeTag - тег (integer) резервного режима работы (fallback mode).
Первоначально этот тег нулевой. После вызова DIM_GuiClickInit() - это тег &DimSrv.FallBackMode.
В прикладной программе можно явно задать любой другой тег, если есть необходимость использовать
резервный режим работы DIM отдельно для каждого устройства.
Функция DIM_GuiClickInit() - изменила аргументы.
Теперь в качестве аргумента принимается не просто имя тега DIM_GuiClickTag, а разделенный пробелами список
имен тегов DIM_GuiClickTag, DIM_GuiClickFallBackModeTag. Это связано с введением резервного режима
DIM-сервера. Имя тега DIM_GuiClickFallBackModeTag необязательно, по умолчанию используется
тег с именем &DimSrv.FallBackMode.
Функция DIM_GuiClickAvail - вспомогательная для проверки инициализации тега DIM_GuiClickTag.
Функция DIM_GuiClickFallBackMode - вспомогательная для проверки режима работы DIM-сервера.
Функция DIM_GuiClickSendToServer - вспомогательная для обычного сетевого режима работы DIM-сервера.
Функция DIM_GuiClickSendLoopBack - вспомогательная для резервного режима работы DIM-сервера.
Функция DIM_GuiClickSend - изменила алгоритм работы.
Это основная функция посылки графических событий DIM-сервера.
Она использует для посылки графических событий:
либо вызов DIM_GuiClickSendToServer в обычном сетевом режиме (удаленного) DIM-сервера,
либо вызов DIM_GuiClickSendLoopBack в резервном режиме локального DIM-сервера.
В резервном режиме (fallback) посылка идет "обратной петлей" (loopback) в консоль локального сервера,
минуя сетевую приемо-передачу, что позволяет работать в условиях отсутствия DIM-сервера
или недоступности сети.
Функция GetStampOfTag - вычисляет "отпечаток" тега.
Она рекомендуется к использованию для обновления DIM-сервисов совместно с функцией ShouldRefresh.
Например:
if ShouldRefresh(upd1,GetStampOfTag(tag1,0))
+ShouldRefresh(upd2,GetStampOfTag(tag2,0))>0
then writeln('Пора обновить теги...')
"Отпечаток" тега это условное числовое значение, указывающее на то, изменился ли тег.
Для численных тегов это просто значение, а для строкового тега - это хэш (контрольная сумма).
Использование "отпечатка" позволяет унифицировать обновление тегов.
Модифицированная библиотека теперь поддерживает резервный режим работы DIM-сервера.
Если задать значение &DimSrv.FallBackMode = 1 , то DIM-сервер
начинает посылать графические события ("клики") в свою консоль, вместо того чтобы посылать их в сеть.
Это позволяет сохранить работоспособность графического интерфейса, написанного под DIM-сервер,
в случае недоступности сети.
Резервный режим работы также позволяет переносить код подсистем, написанных для распределенных систем
с DIM-сервером, в системы без DIM-сервера.
Если в системе отсутствует &DimSrv, то DAQ-устройства, использующие DIM-сервер,
автоматически переходят в резервный режим работы.
Единственное, о чем следует помнить - в конфигурацию все равно следует включать секцию [TrustedUsers]
с таблицей прав доступа, т.к. проверка прав доступа происходит в любом случае (и в рабочем, и резервном режиме).
В DAQ Pascal введены синонимы (альтернативные названия):
Функция _inf - синоним _plusinf (+бесконечность).
Она введена для краткости, т.е. _inf по аналогии с _nan, _nul и _nil.
Функция CreateTag - ищет существующий или создает новый тег.
Это синоним функции inittag, введенный по той причине, что эта функция DaqPascal оказалась
"перекрытой" процедурой InitTag из стандартной библиотеки и поэтому стала недоступной.
Она редко используется, но все же может пригодиться...
Для упрощения конфигурирования таблицы прав доступа DIM добавлены Default конфигурации (выделенные жирным):
[ConfigFileList] ; Default DAQ settings
ConfigFile = ~~\Resource\DaqSite\Default\DAQ.cfg ; Обычные настройки параметров DAQ
ConfigFile = ~~\Resource\DaqSite\Default\Integrity.cfg ; Обычные настройки проверки целостности
...
ConfigFile = ~~\Resource\DaqSite\Default\DimDnsLocal.cfg ; Настроить DIM DNS на LocalHost (т.е. DIM_DNS_NODE = . ).
ConfigFile = ~~\Resource\DaqSite\Default\DimAccessLocal.cfg ; Настроить DIM для локального доступа "ДЛЯ СЕРВЕРА"
ConfigFile = ~~\Resource\DaqSite\Default\DimAccessToAll.cfg ; Настроить DIM для удаленного доступа "ДЛЯ ВСЕХ"
[]
Таким образом, рекомендуется к любой конфигурации, работающей с DIM сервером,
подключать указанные Default конфигурации для унификации и упрощения конфигурирования.
При этом Default конфигурации (поскольку они содержат включаемые файлы) всегда записываются
к конец текста конфигурации, что дает возможность (при необходимости) переопределять параметры
Default конфигурации, поместив их в конфигурации явно. Например:
[ConfigFileList] ; Default DAQ settings
...
ConfigFile = ~~\Resource\DaqSite\Default\DimDnsLocal.cfg ; Настроить DIM DNS на LocalHost (т.е. DIM_DNS_NODE = . ).
[]
[&DimSrv]
DIM_DNS_NODE = demo-pc
[]
В данном случае сработает значение параметра DIM_DNS_NODE = demo-pc,
т.к. включение DimDnsLocal.cfg помещает содержимое в конец текста,
а конфигуратор считывает первое попавшееся значение.
Обновлена конфигурация DEMO_GENDC и
DEMO_ZUPDC с использованием новых функций
и исправлениями мелких неточностей.
Главными достижениями данного выпуска являются:
автономный вариант FP-QUI,
справочный файл readme.htm по составу дистрибутива,
добавление CheckBoxList в функцию edit,
добавление в Главную Консоль команд @pid find, @pid enum, @file exist,
@file size, @file kill, условного оператора @if.
Сделан автономный вариант системы уведомлений FP-QUI,
который может работать в составе минимальной инсталляции CRW-DAQ Runtime.
Этот автономный вариант реализован в виде install-daqgroup-crw32-notifier.exe,
который инсталлируется в Crw32exe сверху (после runtime и demodoc).
Работает это так:
1) Инсталлируем (именно в таком порядке):
install-daqgroup-crw32-runtime.exe - среда исполнения (обязательно)
install-daqgroup-crw32-demodoc.exe - ДЕМО,документация (опционально)
install-daqgroup-crw32-notifier.exe - система уведомлений (желательно)
2) Система уведомлений копируется в каталог
Crw32exe\Resource\CrwToolkit\add\fp-qui\
3) При запуске Crw32.exe выполняется скрипт:
[System.StartupScript]
@silent @env FPQUI_DIR=%CRW_DAQ_SYS_HOME_DIR%\Resource\CrwToolkit\add\fp-qui
@silent @env FPQUI_COREEXE=FP-QUICore.exe
@silent @env FPQUI_EXE=FP-QUI.exe
[]
который задает переменные окружения FPQUI_DIR, FPQUI_COREEXE, FPQUI_EXE.
4) Программы fpquitip.exe, fpquisend.exe модифицированы так, что они могут искать
расположение файлов пакета FP-QUI по этим переменным окружения, а не только в ProgramFiles.
Таким образом, если пакет FP-QUI не проинсталлирован в обычном месте, программы
fpquitip.exe, fpquisend.exe находят его в каталоге Crw32exe\Resource\CrwToolkit\add\fp-qui.
Таким образом, система оповещений FP-QUI должна работать как при нормальной инсталляции через
install-daqgroup-notifier.exe, которая устанавливает его в ProgramFiles,
так и при автономной инсталляции через install-daqgroup-crw32-notifier.exe,
которая "прячет" систему уведомлений внутри каталога Crw32exe.
Автономная инсталляция системы уведомлений через install-daqgroup-crw32-notifier.exe нужна,
если требуется установить пакет FP-QUI без внешних эффектов в виде записей в реестре или
файлов в системных каталогах (Windows, ProgramFiles).
Недостатком автономной инсталляции является то, что она может блокировать каталог Crw32exe,
поэтому для переустановки пакета надо сначала закрывать программу FP-QUI.
Сделан файл readme.htm, содержащий справку о составе дистрибутива.
Необходимость в этой справке связана с тем, что (в зависимости от требований) возможно
несколько вариантов установки пакета, и это требует пояснений.
В функции edit добавлен элемент CheckBoxList.
Он работает аналогично элементу SelectionList (выделение нужных пунктов из списка),
только вместо выделения цветом используются выделение флажками - галочками (CheckBox).
Обновлена конфигурация DEMO_GENDC
с использованием CheckBoxList для редактирования значений регистров.
В связи с введением автоматической генерации изображений barbmp, ledbmp была сильно сокращена
библиотека изображений Resource\DaqSite\StdLib\Bitmaps.
Оставлены изображения только двух цветов (silwer, white), чтобы иметь возможность определять размеры полей.
Остальные изображения будут генерироваться автоматически.
Добавлены следующие команды и опции в Главную Консоль:
Работа с процессами:@pid find cmd.exe - вернет PID первого найденного процесса cmd.exe@pid enum cmd.exe - вернет число процессов cmd.exe и напечатает их список
Работа с файлами:@file exist test.log - вернет 0/1 если файл test.log не/существует
@file size test.log - вернет размер файла test.log или -1 при ошибке
@file kill test.log - вернет 0/1 при не/успешном удалении файла test.log
Имена файлов отсчитываются от каталога пакета (%CRW_DAQ_SYS_HOME_DIR%).
Они могут также содержать переменные окружения (типа %ProgramFiles%).
Условное выполнение:@if cond expression - выполняет выражение expression при условии cond
Условие cond - это выражение, значение которого считается:
false - ложным, если результат равен 0 или NAN/INFtrue - истинным, если результат равет любому ненулевому числу
Использование этих функций и переменных позволяет выполнять действия
при выполнении условий, связанных с файлами или процессами, например:
fpqui_exist=@file exist %ProgramFiles%\FP-QUI\FP-QUICore.exe
@if ne(fpqui_exist,1) @echo Надо установить программу FP-QUI
Следует иметь в виду, что условный оператор @if не отображает сообщения об ошибках
при вычислении условия, поэтому при ошибках в формуле условия выражение будет
молча игнорироваться. Кроме того, после @if уже нельзя использовать @silent.
Его надо использовать до @if, например:
@silent dns_pid=@pid find dns.exe
@silent @if eq(dns_pid,0) @tooltip text "Процесс DNS.EXE не запущен."
Добавление указанных команд значительно расширяет возможности Главной Консоли,
особенно если учитывать, что сообщения в Главную Консоль могут формироваться программно
или считываться из конфигурационного файла.
Главными достижениями данного выпуска являются:
добавление драйверов (DEMO_GENDC) для источников TDK-Lambda Genesys,
добавление шаблона спецификации интерфейса DIM-сервера,
библиотека стандартизованных графических элементов GostLib (вентили, клапаны),
демо-конфигурации DEMO_PAINT_GOSTLIB, DEMO_MASS2 для иллюстрации библиотеки GostLib,
утилита barbmp, автоматическая генерация файлов изображений barbmp, ledbmp,
новые правила распознавания фонтов по псевдонимам, команда @fonts find.
Добавлена конфигурация DEMO_GENDC
для источников TDK-Lambda Genesys.
Она содержит полный набор современных средств (драйвер устройства, DIM-сервер,
активные мнемосхемы со скриптами, генератор конфигураций из таблиц)
и может служить хорошим примером и прототипом для создания новых систем.
В документацию DIM добавлен шаблон спецификации интерфейса DIM-сервера
dim_spec_sample_ru.pdf,
dim_spec_sample_ru.doc
который показывает, как примерно должен выглядеть документ, в котором описывается
(сетевой, программный) интерфейс DIM-сервера.
Такая спецификация нужна для того, чтобы разные независимые группы разработчиков
могли эффективно разделять задачи и обмениваться информацией по DIM-протоколу.
Собственно, спецификация интерфейса DIM-сервера - это то, что разработчики сервера
передают клиентам в качестве основного документа, необходимого для использования этого сервера.
Договорившись об этой спецификации, группы смогут эффективно взаимодействовать и обмениваться данными,
не погружаясь в несущественные для них подробности.
В документацию добавлены некоторые ГОСТ по ЕСКД,
касающиеся изображения газовой арматуры (вентили, клапаны, насосы и т.д.).
Конкретно это:
gost-2.785-70,
gost-2.785-96,
gost-2.721-74.
Использование ГОСТ позволит унифицировать
изображения сенсоров газовой арматуры на мнемосхемах.
В библиотеку графических элементов
Painter(v) добавлен
большой модуль GostLib,
который позволяет рисовать мнемосхемы, содержащие стандартизованные по ГОСТ/ЕСКД
изображения газовой арматуры (вентили, клапаны) - всего более двухсот типов элементов.
Элементы отличаются геометрией (проходные, угловые, трехходовые и т.д.), наличием концевиков,
типом привода (ручные, электромагнитные, пневматические и т.д.).
При этом элементы GostLib прекрасно сочетаются с элементами GuiLib,
например, можно использовать вентиль с кнопкой.
Пример описания сенсора с трехходовым вентилем с кнопкой:
[ConfigFileList] ; Include the Painter GUI Library ; Для доступа к библиотеке
ConfigFile = ~~\Resource\DaqSite\Default\Painter.crc ; Включаем Painter.crc
[]
...
...
[SensorList]
Sensor = Valve1 ; Создаем сенсор Valve1. Это будет трехходовой вентиль
[Valve1] ; с пневмоприводом и двумя концевиками
Pos = 10, 300 ; Задаем координаты сенсора
Painter(v) = (glButtonBit=0)+(glButtonBevel=2) ; Задаем параметры кнопки (не обязательно)
Painter(v) = (glValveOpenBit=2)+(glValveCloseBit=1) ; Задаем параметры вентиля (не обязательно)
Painter(v) = [Painter(v).GostLib.Valve.3WayUp.LimSwBoth.PneumaticOp] ; Включаем библиотечный сценарий GostLib
Painter(v) = [Painter(v).GuiLib.SimpleButton] ; Включаем библиотечный сценарий SimpleButton
Tag#1 = 0, ~~\Resource\DaqSite\StdLib\Bitmaps\ledbmp_2_20_4_silver_ptmono.bmp ; Задаем фоновое изображение
Hint = Valve1 - Трехходовой вентиль с пневмоприводом и кнопкой
[]
Библиотеку разработал Н.Гурин .
После (успешной) обкатки библиотеку рекомендуется использовать для реализации всех газовых мнемосхем
с целью унификации внешнего вида и поведения сенсоров в соответствии с ГОСТ.
Добавлена конфигурация DEMO_PAINT_GOSTLIB,
иллюстрирующаяя использование элементов GostLib.
Добавлена конфигурация DEMO_MASS2,
иллюстрирующаяя использование элементов GostLib.
Добавлена утилита barbmp
для генерации прямоугольных (bar) изображений (bmp)
для использования в качестве текстовых полей сенсоров.
Например:
unix barbmp 150 20 4 Aqua - сгенерировать файл barbmp_150_20_4_aqua.bmp
где
150 - Ширина прямоугольного изображения.
20 - Высота прямоугольного изображения.
4 - Глубина цвета 4 бит (т.е. 16 цветов).
Допустимые значения - [1,4,8,15,16,24].
aqua - Цвет, которым заполняется прямоугольник.
Допустимые цвета можно узнать вызовом:
barbmp --colors
Утилита barbmp позволяет создавать прямоугольные изображения разного цвета
и битности для сенсоров, в том числе в автоматическом режиме.
Например, можно генерировать необходимые изображения с помощью командных файлов.
В DAQ-систему добавлена автоматическая генерация недостающих BMP-файлов для сенсоров
на основе утилиты barbmp
для генерации прямоугольных (bar) изображений (bmp)
с заданными размерами (в пикселях) и цветом.
Правила генерации такие:
1) Генерация происходит в момент чтения CRC файла любой мнемосхемы.
2) Генерация не происходит, если требуемый BMP-файл уже существует.
4) Генерация касается выражений: Tag#n = x, FileName в конфигурации сенсоров.
5) Генерация BMP-файла происходит, если имя файла имеет вид dir\barbmp_w_h_d_c.bmp,
где dir - каталог где находится файл
barbmp - обязательный префикс имени файла
w - ширина прямоугольника в пикселях
h - высота прямоугольника в пикселях
d - глубина цвета (color depth) из набора [1,4,8,15,16,24]
c - цвет в виде числа или имени, типа red,green,blue,...
6) Если при чтении конфигурации сенсора BMP-файл не найден, посылается сообщение
@silent @integrity DAQ:CrcReadBmp:Failure FileName
которое записывается в журнал Temp\@IntegrityEvents.log и в Главную Консоль
7) Если при чтении конфигурации сенсора BMP-файл был сгенерирован, посылается сообщение
@silent @integrity DAQ:CrcReadBmp:Created FileName
которое записывается в журнал Temp\@IntegrityEvents.log и в Главную Консоль
Например, в следующем описании файл barbmp_32_30_4_silver.bmp
будет сгенерирован автоматически, если не будет найден при загрузке CRC-файла:
[SensorList]
Sensor = ThruWayValve1
[ThruWayValve1]
Pos = 10, 40
...
Tag#1 = 0, ~~\Resource\DaqSite\StdLib\Bitmaps\barbmp_32_30_4_silver.bmp
...
[]
Соглано этим правилам, существующие BMP-файлы будут просто загружены (как всегда),
а недостающие файлы barbmp_... будут сгенерированы при необходимости.
На производительность это не повлияет, т.к. генерация происходит только один раз.
Зато повышается удобство и гибкость - теперь можно указывать любые размеры полей для
рисования сенсоров, не заботясь об их создании.
Новое средство генерации BMP-файлов очень хорошо подходит для библиотек элементов
GuiLib, GostLib.
Фактически теперь можно рисовать кнопки, вентили и клапаны любого размера, если
указывать правильные имена файлов barbmp_...
В DAQ-систему добавлена также автоматическая генерация недостающих BMP-файлов для сенсоров
на основе утилиты ledbmp
для генерации изображений (bmp) прямоугольных текстовых полей (led)
с заданной шириной текста (в символах), именем и размером фонта (в пунктах) и цветом.
Правила генерации такие:
1) Генерация происходит в момент чтения CRC файла любой мнемосхемы.
2) Генерация не происходит, если требуемый BMP-файл уже существует.
4) Генерация касается выражений: Tag#n = x, FileName в конфигурации сенсоров.
5) Генерация BMP-файла происходит, если имя файла имеет вид dir\ledbmp_w_s_d_c_f.bmp,
где dir - каталог где находится файл
ledbmp - обязательный префикс имени файла
w - ширина текстового поля в символах
s - размер фонта в пунктах (pt)
d - глубина цвета (color depth) из набора [1,4,8,15,16,24]
c - цвет в виде числа или имени, типа red,green,blue,...
f - псевдоним фонта (имя фонта в нижнем регистре без пробелов)
6) Если при чтении конфигурации сенсора BMP-файл не найден, посылается сообщение
@silent @integrity DAQ:CrcReadBmp:Failure FileName
которое записывается в журнал Temp\@IntegrityEvents.log и в Главную Консоль
7) Если при чтении конфигурации сенсора BMP-файл был сгенерирован, посылается сообщение
@silent @integrity DAQ:CrcReadBmp:Created FileName
которое записывается в журнал Temp\@IntegrityEvents.log и в Главную Консоль
Например, в следующем описании файл ledbmp_8_10_4_silver_ptmono.bmp
будет сгенерирован автоматически, если не будет найден при загрузке CRC-файла:
[SensorList]
Sensor = Voltage
[Voltage]
Pos = 10, 40
...
LED = 7, 0, 0, %7.3f, Name:PT_Mono\Size:10\Style:[Bold]
Tag#1 = 0, ~~\Resource\DaqSite\StdLib\Bitmaps\ledbmp_8_10_4_silver_ptmono.bmp
...
[]
Соглано этим правилам, существующие BMP-файлы будут просто загружены (как всегда),
а недостающие файлы ledbmp_... будут сгенерированы при необходимости.
На производительность это не повлияет, т.к. генерация происходит только один раз.
Зато повышается удобство и гибкость - теперь можно указывать любые размеры полей для
рисования текстовых сенсоров, не заботясь об их создании.
Новое средство генерации BMP-файлов очень хорошо подходит для библиотек элементов
GuiLib, GostLib.
Фактически теперь можно рисовать тестовые поля и кнопки любого размера, если
указывать правильные имена файлов ledbmp_...
Использование утилит ledbmp
или barbmp
для BMP-файлов сенсоров определяется стоящей задачей.
Для рисования текстовых полей, на которых будут расположены надписи, больше подходит ledbmp,
т.к. их размер указывается в символах и пунктах для используемого фонта.
Использование ledbmp гарантирует, что надписи будут умещаться в заданном поле сенсора.
А вот для рисования чисто графических элементов (индикаторов, клапанов, вентилей, насосов и т.д.)
больше подходит barbmp, т.к. их размер задается в пикселях.
Правила автоматической генерации ledbmp, barbmp распространена также
на основной BMP-файл мнемосхемы [Circuit] GeneralMap.
Это позволяет, в принципе, генерировать вообще все изображения для мнемосхем автоматически.
Если, конечно, на них рисуются только стандартные элементы (текст, кнопки, вентили и т.д.).
Для упрощения конфигурирования имен фонтов вводятся такие правила интерпретации имен фонтов:
1)Регистр символов имени фонта не играет значения.
2)Пробелы и знаки подчеркивания «_» в имени фонта игнорируются.
3)Программа автоматически распознает имя фонта по псевдониму,
в котором из имени удалены пробелы или пробелы заменены на
знаки подчеркивания.
Это значит, что следующие имена фонтов будут эквивалентны:
PT Mono - оригинальное имя фонта
pt mono - псевдоним в нижнем регистре
pt_mono - псевдоним со знаком подчеркивания
ptmono - псевдоним с удаленными пробелами
Программа обеспечивает автоматическую замену псевдонимов на оригинальное имя фонта.
Эти правила работают в файлах конфигураций и при разборе сенсоров (LED).
Например, теперь можно использовать оба выражения:
LED = 0, 0, 0, *, Name:PT_Mono\Style:[Bold]\Size:20
LED = 0, 0, 0, *, Name:ptmono\Style:[Bold]\Size:20
Новые правила интерпретации имен фонтов связаны с тем, что в утилите ledbmp
используется псевдоним фонта, т.е. "обрезанное" имя фонта с удаленными пробелами.
Теперь программа автоматически находит нужный фонт по псевдониму.
В консольной команде @fonts добавлена опция find для поиска фонтов по псевдониму.
Псевдоним - это имя фонта без пробелов и без учета регистра символов.
Команда возвращает имя фонта, если оно известно системе.
Команда Напечатает
@fonts find ptmono PT Mono
@fonts find ptmonobold PT Mono
@fonts find couriernew Courier New
@fonts find missing Font «missing» is not found.
Новая опция позволяет проверить наличие интересующих фонтов в системе,
а также определять имя фонта по псевдониму.
Псевдонимы фонтов используются, например, в утилите ledbmp.
07.09.2019
mksecnow() cpu_start() cpu_clock() LED edit
Главными достижениями данного выпуска являются:
добавление функций интерпретатора DaqScript для измерения малых интервалов времени
(mksecnow(), cpu_start(), cpu_clock()),
добавление целочисленных форматов в LED сенсоры,
поправки в edit (элемент SelectionList).
В интерпретатор DaqScript добавлены функции для измерения малых интервалов времени в скриптах:
mksecnow() - число микросекунд, прошедших начиная со старта программы
cpu_start() - инициализирует счетчик тактов процессора
cpu_clock() - возвращает счетчик тактов процессора с момента инициализации
например:
mks=mksecnow()
cpu_start()
...
... тут какие-то интересующие пользователя вычисления
...
cpu=cpu_clock()
mks=mksecnow()-mks
echo Вычисления заняли %mks микросекунд, %cpu тактов процессора
Функция mksecnow() служит для измерения маленьких (микросекунды) интервалов реального времени.
Её полезно использовать для измерения производительности вычислительных алгоритмов,
а также для организации вычислений в реальном времени.
Надо учитывать, что сам вызов функции занимает 1-2 микросекунды.
Функции cpu_start(), cpu_clock() служат для оценки числа тактов процессора, требуемых
для проведения интересующих вычислений. Эта оценка является грубой и в ряде случаев неустойчивой.
Во-первых, в исследуемый расчет может "вклиниться" прерывание или переключение потоков.
Во-вторых, может происходить переключение процесоров в многоядерных или многопроцессорных системах.
Поэтому для проведения оценок рекомендуется делать "привязку" процесса к одному процессору, а также
рекомендуется закрывать лишние программы на время проведения оценки.
В спецификации формата сенсора LED раньше допускались только вещественные форматы
( %f, %g, %e ).
Теперь допускается также использовать целочисленные форматы
( %d, %u, %x ),
например:
[SensorList]
Sensor = demo
[demo]
Pos = 270, 90
LED = 3, 0, 0, $%2.2x, Name:PT_Mono\Size:10\Style:[Normal]
Tag#1 = 0, ~~\Resource\DaqSite\StdLib\Bitmaps\ledbmp_3_10_4_white_ptmono.bmp
Hint = Значение будет отображаться в шестнадцатеричном формате $xx.
[]
Разрешение целочисленных форматов расширяет возможности отображения данных в сенсорах,
позволяя, например, отображать значения регистров аппаратуры в шестнадцатиричном формате.
В функции edit изменения в элементе
SelectionList - введены два параметра, текущий пункт и начальный список выбранных пунктов
в виде битовой маски. Например:
if editstate=0 then begin
if pos('?',edit('(Выбор термопар')
+edit(' Задайте термопары')
+edit(' Термопара 1')
+edit(' Термопара 2')
+edit(' Термопара 3')
+edit(' Термопара 4')
+edit(' Термопара 5')
+edit(')SelectionList SEL 0 5'))>0
// Здесь 0 - текущий пункт, 5 - битовая маска выбранных пунктов
then writeln('Ошибка инициирования диалога!');
end else writeln('В настоящий момент редактирование недоступно!');
Введение параметров устраняет ту проблему, что раньше в элементе SelectionList нельзя было
задать начальное значение списка выбранных пунктов, что затрудняло его использование.
Элемент SelectionList может быть использован, например, для реактирования значений
регистров, состоящих из битов.
Обновлена конфигурация DEMO_EDIT,
с учетом внесенных поправок.
05.06.2019
NTC EVAL(V) _R4WIRE.PAS
Главными достижениями данного выпуска являются:
документация по NTP сенсорам, обновление инсталлятора,
программа _R4WIRE.PAS для расчета сопротивления в 4-проводной схеме,
введение в систему калибровки формульных калибровочных преобразований.
Добавлена документация по
NTC сенсорам (термисторам),
которые обычно описываются уравнением Стейнхарта.
TransformX = EVAL(V):LN(V):EXP(V):1E-100:1E100TransformY = EVAL(V):1/(V+273.15):1/V-273.15:-273:1E100где
EVAL(V) - признак формульного преобразования с аргументом V
LN(V) - прямое (линеаризующее) преобразование шкалы X
EXP(V) - обратное преобразование шкалы X
1E-100:1E100 - допустимые пределы шкалы X
1/(V+273.15) - прямое (линеаризующее) преобразование шкалы Y
1/V-273.15 - обратное преобразование шкалы Y
-273:1E100 - допустимые пределы шкалы Y
Приведенные в примере калибровочные преобразования задают
уравнение Стейнхарта,
которое используется для описания температурной зависимости сопротивления полупроводникового термистора.
Калибровочные преобразования позвлоляют линеаризовать задачу, то есть (путем замены переменных)
свести задачу к обычному полиному. В данном случае линеаризация задается с помощью явных формул.
См. также пример (уравнение Стейнхарта)
и пример файла калибровки.
Добавление формульных калибровочных преобразований первоначально было связано с необходимостью
введения калибровок для термисторов, которые описываются уравнением Стейнхарта.
Это уравнение легко линеаризуется (преобразуется в линейное) при введении несложных калибровочных
преобразований, заданных явными формулами.
Это можно было сделать частным порядком (забить формулы в код пакета), но более преспективным было
введение интерпретатора формул в описание калибровки, чтобы не надо было модифицировать код пакета
для каждой новой формулы.
Положительной стороной формульных калибровок является гибкость описания, позволяющая задавать
множество калибровочных преобразований (конечно, не слишком сложных), не внося изменений в код пакета.
Отрицательной стороной формульных калибровок является некоторое снижение скорости (за счет интерпретации формул).
Поэтому формульные калибровки должны использоваться для относительно медленных (до килогерца) каналов.
Обновлен код инсталлятора runtime, чтобы исключить копирование файлов в системные каталоги.
Задачей является получение инсталлятора runtime, пригодного для установки в условиях
ограниченных прав.
В библиотеку добавлена программа _R4WIRE.PAS,
служащая для расчета сопротивления в 4-проводной схеме (раньше аналогичная программа называлась RVST.PAS).
Эту программу рекомендуется использовать как стандартную расчетную программу для 4-проводной схемы
подключения резистивных датчиков температуры.
Ранее программа присутствовала в DEMO, но не входила в библиотеку.
24.05.2019
@env CrwToolkit CRWTOOLKIT_ROOT strfmt()
Главными достижениями данного выпуска являются:
модернизация инсталлятора с целью исключить зависимость runtime от внешних пакетов,
обновление команды @env,
функция форматирования strfmt().
Обновлена команда @env, в неё добавлена поддержка %переменных% окружения.
Например:
Команда позволяет установить переменные окружения процесса из скриптов и программ DaqPascal.
Установленные переменные окружения наследуются порожденными процессами,
что позволяет передавать им нужные параметры.
Предприняты усилия к устранению внешних зависимостей crw32-runtime.
Для этого сделано следующее:
Пакет CrwToolkit перенесен в каталог Resource\CrwToolkit,
находящийся внутри каталога Crw32exe.
Теперь он не инсталлируется как отдельный пакет, а входит в состав runtime.
В параметре Crw32.ini [System] CRWTOOLKIT_ROOT заведена ссылка Resource\CrwToolkit,
по которой устанавливается переменная окружения CRWTOOLKIT_ROOT, указывающая на расположение
пакета CrwToolkit.
В параметрах Crw32.ini [System] PathAddToHead, PathAddToTail добавляются пути
(переменная окружения PATH) для поиска программ - Resource\Shell.
Когда эти переменные установлены, программа unix становится доступной для всех дочерних
процессов через путь поиска PATH.
При запуске команд (например @run unix cmd ) команда unix находит
переменную CRWTOOLKIT_ROOT и устанавливает пути поиска так, чтобы сделать программы
пакета CrwToolkit доступными.
Поэтому все скрипты в порожденных процессах должны работать корректно.
В результате скрипты в составе runtime должны работать корректно
даже если пакет UnixUtils не был установлен.
В этом случае через вызов unix доступны те команды, которые входят в состав CrwToolkit.
Если же пакет UnixUtils установлен, то работает переменная окружения UnixRoot
и вызов unix делает доступным все программы этого пакета.
Таким образом, crw32-runtime должен работать с основным функционалом - даже в случае,
если ничего больше не установлено.
И должен работать с расширенным функционалом, если установлен пакет UnixUtils.
Инсталлятор crw32-runtime переделан с целью устранить все внешние ссылки.
Теперь инсталлятор практически полностью "замкнут" в своем каталоге,
ничего не копирует в реестр (кроме записи в Uninstall)
и ничего не записывает в системные каталоги.
Инсталлятор crw32-runtime ориентирован на то, чтобы пакет (вместе с прикладными системами)
мог работать при автономной инсталляции (без всего остального) и по возможности
не оставлял "следов" за пределами своего каталога.
Насколько это удалось - покажет практика.
В пакет CrwToolkit внесен дополнительный набор команд из пакета UnixUtils,
которые нужны в случае автономной работы.
Обновлен DAQ Creator и добавлен DEMO_TIR от Николая Гурина.
Введена новая функция DaqPascal:
StrFmt,
служащая для форматирования данных (чисел и строк).
Например:
////////////////////////////////////////////////////////
// StrFmt(f,p) - преобразование параметра p по формату f
// f - описание формата как в функции Format()
// p - имеет тип (string,char,integer,real)
////////////////////////////////////////////////////////
s:=StrFmt('maxint = %d',maxint); // Целое, десятичный формат
s:=StrFmt(' = $%8.8x',maxint); // Целое, шестнадцатеричный формат
s:=StrFmt('pi = %11.5f',pi); // Вещественное, фиксированный формат
s:=StrFmt('pi = %11.5e',pi); // Вещественное, экспоненциальный формат
s:=StrFmt('pi = %11.5g',pi); // Вещественное, автоматический формат
s:=StrFmt('pi = %11.8s','a string'); // Строковый формат
Подробнее см. описание функции Format() в Object Pascal
Функция будет полезна для формирования надписей/сообщений или данных для различных протоколов обмена данными.
Она заполняет существовавший до сих пор "пробел" в доступных способах форматирования,
позволяя использовать практически все доступные в языке Object Pascal форматы.
Отличие от функции Format() или sprintf() в том, что допускается лишь один параметр.
При необходимости форматировать сложные многопараметрические данные каждый параметр преобразуется
отдельным вызовом StrFmt() и затем "склеивается" вместе.
Чтобы оценить полезность новой функции, можно сравнить две реализации функции форматирования времени
GetDateTime в стандартной библиотеке:
{
Get string like 2006.09.21-00:12:30
}
Старая реализация
function GetDateTime(ms:Real):String;
var s:String;
begin
s:='';
s:=Str(ms2sec(ms))+s; while Length(s)<2 do s:='0'+s; s:=':'+s;
s:=Str(ms2min(ms))+s; while Length(s)<5 do s:='0'+s; s:=':'+s;
s:=Str(ms2hour(ms))+s; while Length(s)<8 do s:='0'+s; s:='-'+s;
s:=Str(ms2day(ms))+s; while Length(s)<11 do s:='0'+s; s:='.'+s;
s:=Str(ms2month(ms))+s; while Length(s)<14 do s:='0'+s; s:='.'+s;
s:=Str(ms2year(ms))+s; while Length(s)<19 do s:='0'+s;
GetDateTime:=s;
s:='';
end;
Новая реализация
function GetDateTime(ms:Real):String;
begin
GetDateTime:=StrFmt('%4.4d.',ms2year(ms))
+StrFmt('%2.2d.',ms2month(ms))
+StrFmt('%2.2d-',ms2day(ms))
+StrFmt('%2.2d:',ms2hour(ms))
+StrFmt('%2.2d:',ms2min(ms))
+StrFmt('%2.2d',ms2sec(ms));
end;
Как нетрудно заметить, новая реализация стала существенно проще и понятнее.
Надо отметить, что вызов простой функции преобразования Str(x) несколько быстрее,
чем форматного, например, StrFmt('%g',x).
Поэтому рекомендуется использовать простые вызовы Str() или StrFix() в обычных случаях,
когда форматирование не требуется, и использовать StrFmt() для более сложных случаев,
где форматирование действительно необходимо.
Обновлены функции стандартной библиотеки
GetDateTime,
ms2HttpTimeStr
которые теперь используют вызовы StrFmt.
Главными достижениями данного выпуска являются:
устранение ошибки сглаживания в библиотечных модулях mvtopu.pas, _mvtotc.pas,
введение функций getai_par, getao_par, getdi_par, getdo_par,
консольные утилиты cmdfocus, playwav, wbox, wbusy, wselect, wprompt,
включение компилятора PureBasic в сборку разработчика.
Обновлена конфигурация DEMO_SMOOTH,
в ней специально сделан генератор сигнала с разрывами (добавлена ступенька),
чтобы было легче изучать "переходные процессы" при сглаживании.
При помощи этой конфигурации был изучен вопрос со сглаживанием, в результате чего выяснилось, что:
Базовые функции сглаживания и функция getai() работают верно (вздох облегчения ☺).
Эти ошибки проявляются только в режиме "Smoothing+ Delay- History+",
т.е. при включении сглаживания и истории, но без введения задержки.
Было выяснено, что ошибка носит логический (а не случайный) характер,
т.е. сглаживание с историей без введения задержки логически некорректно.
В связи с этим при использовании сглаживания и истории задержка должна вводиться
принудительно, даже если она не была обозначена явно в параметре Delay.
Для вычисления задержки потребовалось введение функции getai_par, которая описана ниже.
Если точнее, задержка должна быть не менее текущей полуширины окна сглаживания.
Именно этот параметр потребовалось прочитать из конфигурации, для чего и введена новая функция.
Введены новые функции DaqPascal:
getai_par,
getao_par,
getdi_par,
getdo_par.
Эти функции позволяют прочитать параметры аналоговых/цифровых входов/выходов,
например, параметры сглаживания или округления.
Введение функций потребовалось для исправления ошибки со сглаживанием.
При помощи новых функций ошибки в библиотечных модулях
_MVTOPU.PAS,
_MVTOTC.PAS
были были исправлены.
Исправление заключается в введении задержки, равной, как минимум, полуширине окна сглаживания,
если выполняется сглаживание с историей.
При этом в новой версии повреждения данных при сглаживании не происходит.
Однако следует иметь в виду, что исправление может породить "побочные эффекты" в связи с
задержкой сглаженного сигнала.
Если требуется делать управление по сигналу без задержки, то для него надо
либо не использовать сглаживание, либо использовать сглаживание без истории.
В некоторых случаях это может повлечь за собой дублирование кривых.
Например, одна кривая будет "быстрой" (без задержки), но несглаженная либо сглаженная без истории.
А вторая будет "медленной" (с задержкой) и может содержать сглаживание с историей.
Рабочие конфигурации, которые ссылаются на библиотечную версию программ
~~\Resource\DaqSite\StdLib\DaqPas\_MVTOPU.PAS,
~~\Resource\DaqSite\StdLib\DaqPas\_MVTOTC.PAS
- в изменениях не нуждаются, т.к. библиотечные программы обновляется вместе с дистрибутивом.
Однако стоит проверить, не сказывается ли "побочный эффект" задержки, упомянутый выше,
на работе прикладной программы.
Также во многих (старых) конфигурациях использовались локальные копии этих программ.
В этом случае их нужно заменить - лучше всего ссылкой на библиотечные версии программ.
Несколько важных графических утилит (cmdfocus, playwav, wbox, wbusy,
wselect, wprompt), используемых в ряде работающих прикладных систем,
теперь включены в runtime.
Раньше они требовали обязательной установки unixutils,
теперь могут работать уже при установке runtime.
Утилиты написаны на языке PureBasic.
Исходные коды утилит (взятые с сайта horstmuc.de)
существенно переработаны, дополнены и включены в UnixUtils\add\src\pbtools.
Компилятор (легальная, официально купленная версия) языка PureBasic включена в пакет develop.
Также туда включены две книги (учебники), библиотеки и примеры, облегчающие освоение языка.
Компилятор PureBasic при небольшом объеме (менее 40 МБ) содержит полную среду разработки,
позволяющую создавать программы под Win32/64, Linux, MacOs.
Главными достижениями данного выпуска являются:
введение объектов потоков опроса Polling в DaqPascal,
новые возможности функций devsend, reffind, refinfo, enumerate, pipe_ctrl,
новая функция taglock для блокировки/разблокировки доступа других потоков к тегам,
введение атомарных операций с тегами iAtomicTagOp,
rAtomicTagOp,
изменение меню DAQ,
снятие ограничения на длину строк DaqPascal,
функция StringOfChar,
константы SizeOfBoolean, SizeOfChar, SizeOfInteger, SizeOfReal,
функции работы с буфером iGetDump, iSetDump, rGetDump, rSetDump.
enumerate - теперь может нумеровать потоки опроса Polling
reffind - теперь может находить потоки опроса Polling
refinfo - теперь поддерживает потоки опроса Polling
devsend - теперь может пробуждать каналы (pipe) и потоки (polling)
для досрочного пробуждения устройства, канала или потока
со ссылкой ref надо вызвать devsend(ref,'') с пустой строкой данных
Например:
p:=Enumerate(list,'Polling'); // Добавляет в список list имена потоков опроса Polling
ref:=RefFind('Polling System.Uart'); // Находит ссылку потока System.Uart, отвечающего за COM-порты
writeln(RefInfo(ref,'Type')); // Напечатает Polling
writeln(RefInfo(ref,'Name')); // Напечатает System.Uart
r:=devSend(ref,''); // Пробуждает поток System.Uart досрочно, чтобы ускорить обмен
pip:=pipe_init('com port 1'); // Открывает канал - в данном случае COM-порт COM1
r:=pipe_send(pip,'Data'); // Записывает в порт данные
r:=devSend(pip,''); // Пробуждает поток UART
Вызов devSend(ref,'') теперь служит общим способом досрочного пробуждения потока опроса
для устройства, задачи, потока, канала. Другие функции нужны для получения ссылки на соответствующий объект.
Таким образом, эти функции приобретают дополнительные возможности, позволяющие досрочно пробуждать
как системные потоки, так и потоки, связанные с задачами, каналами, портами, устройствами.
Это сделано специально для задач, где трубуется быстрая реакция на события в другом потоке.
Если, например, из прикладной программы досрочно пробудить поток COM-порта,
который имеет высокий приоритет, то он с высокой вероятностью сразу же вытеснит поток
прикладной программы и отошлет данные в порт, что ускорит процесс обмена данными.
Добавления в функции pipe_ctrl:
теперь можно менять некоторые настройки COM-порта, не закрывая его.
Например:
pid:=pipe_init('com port 1'); // Открыли порт COM1 со стандартными настройками
s:=pipe_ctrl(pid,'baudrate=19200'); // Задали скорость обмена
s:=pipe_ctrl(pid,'parity=MARK'); // Задали контроль четности
s:=pipe_ctrl(pid,'databits=8'); // Задали число бит данных
s:=pipe_ctrl(pid,'stopbits=1'); // Задали число стоповых бит
s:=pipe_ctrl(pid,'dcbflags=$4001'); // Задали флаги DCB
n:=pipe_send(pid,'data'); // Записали данные
r:=devsend(pid,''); // Пробудили поток UART
n:=sleep(10); // Немного подождали
s:=pipe_ctrl(pid,'parity=SPACE'); // Задали другой контроль четности
n:=pipe_send(pid,'data'); // Записали данные
... // И так далее
Раньше для изменения настроек COM-порта надо было закрывать его, а потом открывать заново,
что связано с гораздо большими затратами времени процессора и возможной потерей данных.
Изменение режима COM-порта в процессе работы может потребоваться для связи с некоторыми
специальными микроконтроллерными устройствами с нестандартной реализацией протокола обмена.
Изменения в меню DAQ: теперь оно разделено на разделы с подменю.
Высота меню была слишком большой, работать с ним было неудобно, т.к. оно выходило за пределы экрана.
Теперь меню небольшое по высоте, за счет выпадающего подменю.
Добавлена функция taglock для блокировки доступа к тегам из других потоков.
Блокировка применяется в особых случаях, когда надо выполнить атомарные (неделимые) операции
над одним или несколькими тегами, чтобы другие потоки не нарушили логику работы алгоритма.
Функцию всегда надо применять парными вызовами, кратковременно блокируя, а затем разблокируя доступ.
Например:
Если баланс блокировок-разблокировок нарушается, фиксируется фатальная ошибка в DAQ-программе.
Поэтому функцию надо использовать очень осторожно.
В стандартную библиотеку добавлены функции атомарных операций с тегами
iAtomicTagOp,
rAtomicTagOp,
в которых используется вызов taglock для временной блокировки доступа к тегам из других потоков.
Например:
b:=iAtomicTagOp(tag,'+',1); // Атомарный инкремент тега, то есть прибавления 1
b:=iAtomicTagOp(tag,'^',1); // Атомарная операция XOR 1, то есть инверсия 0-го бита
В описании функций подробно разъясняется, зачем были введены эти функции и какую проблему они решают.
Если коротко, атомарные операции позволяют разным потокам параллельно изменять значения тегов,
не создавая друг другу проблем.
Кроме того, атомарные операции позволяют потокам корректно осуществлять синхронизацию через общие теги.
Cтандартная библиотека обновлена с учетом атомарных операций с тегами.
В частности, обновлены функции
iSetTagBitState,
iSetTagBit,
iSetTagXor,
которые рекомендуются к использованию при обработке данных,
в частности, часто используются для обработки нажатий кнопок
или формирования цифровых сигналов из отдельных битов.
В коде прикладных программ рекомендуется в дальнейшем использовать iAtomicTagOp и rAtomicTagOp:
iAtomicTagOp(tag,'+',arg) вместо iSetTag(tag,iGetTag(tag)+arg)
iAtomicTagOp(tag,'-',arg) вместо iSetTag(tag,iGetTag(tag)-arg)
iAtomicTagOp(tag,'*',arg) вместо iSetTag(tag,iGetTag(tag)*arg)
iAtomicTagOp(tag,'/',arg) вместо iSetTag(tag,iGetTag(tag) div arg)
iAtomicTagOp(tag,'%',arg) вместо iSetTag(tag,iGetTag(tag) mod arg)
iAtomicTagOp(tag,'|',arg) вместо iSetTag(tag,iOr(iGetTag(tag),arg))
iAtomicTagOp(tag,'&',arg) вместо iSetTag(tag,iAnd(iGetTag(tag),arg))
iAtomicTagOp(tag,'^',arg) вместо iSetTag(tag,iXor(iGetTag(tag),arg))
... и так далее, а также
bNul(iSetTagXor(tag,XorMask)) вместо bNul(iSetTag(tag,iXor(iGetTag(tag),XorMask)))
это последнее выражение часто используется для включения кнопок (фактически - для инверсии
0-го бита тега кнопки) в процедух типа ClickBitXorLocal - функция iSetTagXor стандартной
библиотеки использует вызов iAtomicTagOp для безопасного изменения битов тега
Это будет не только надежнее, но и быстрее выполняться.
А также предотвратит возможность ошибок, связанных (дурным) с влиянием потоков друг на друга.
Такие ошибки возникают очень редко, но их очень трудно "отловить", поэтому лучше их сразу исключить.
Рекомендуется также постепенно заменить все конструкции указанного вида на атомарные операции в старом коде.
Эта работа не срочная, но желательная.
Серьезно переработана виртуальная машина DaqPascal.
Изменения связаны с обработкой исключений (ошибок) и строк (теперь строки могут быть длинными).
Исключения (ошибки времени исполнения) DaqPascal переведены в класс "серьезных".
Раньше эти ошибки принадлежали к классу "легких", для которых только печатается сообщение в Главной Консоли.
Теперь эти ошибки будут сохраняться в журнале (Temp\@OnException.log) и отображаться в виде всплывающего сообщения.
При этом подробно диагностируется информация об ошибке (где и что произошло).
Это может помочь при анализе ошибок.
Введена задержка (PostMortalSleepTime) после возникновения повторной ошибки времени исполнения DaqPascal.
По умолчанию она равна 30000 (30 секундам) и задается в секции устройства, либо секции [DAQ].
Суть в том, что после повторного серьезного сбоя программа "спит" заданное время, прежде чем начинать свою работу.
Задержка введена для того, чтобы при возникновении серии серьезных ошибок программа не перегружала систему
постоянными перезапусками.
Снято ограничение на длину строк DaqPascal.
Раньше строки не могли превышать 32*1024 = 32KB.
Теперь это ограничение снято. Максимальная длина строк задается так:
[Compiler.Options]
Compiler.slenmax = 1024*1024*2 ; Максимальная длина строк
[]
Секция [Compiler.Options] ищется в следующих местах:
1) В тексте программы (ProgramSource) - настройки данной программы
2) В файле текущей конфигурации DAQ - настройки данной DAQ конфигурации
3) В файле Crw32.ini - настройки всего пакета CRW-DAQ
По умолчанию теперь максимальная длина строк 1024*1024*2 = 2 МБ.
Максимальную длину строк можно было убрать совсем, однако было решено оставить предел на длину,
чтобы (на всякий случай) ограничить возможности прикладных программ по захвату памяти.
В настоящей версии максимальную длину можно менять от 32KB до 256 MB.
См. также опции компилятора.
Работа строковых функций DaqPascal существенно (в среднем примерно на 30%) ускорена.
Некоторые функции (pos, write, writeln) ускорены в 2-3 раза.
В функции paramstr появилась возможность узнать
текущие параметры компилятора:
paramstr('[Compiler.Options] Compiler.itabmax') - размер таблицы идентификаторов
paramstr('[Compiler.Options] Compiler.btabmax') - размер таблицы процедур
paramstr('[Compiler.Options] Compiler.atabmax') - размер таблицы массивов
paramstr('[Compiler.Options] Compiler.rtabmax') - размер таблицы констант
paramstr('[Compiler.Options] Compiler.dtabmax') - размер сегмента данных (стека)
paramstr('[Compiler.Options] Compiler.dtabmin') - минимальный размер свободного стека при старте
paramstr('[Compiler.Options] Compiler.stabmax') - размер таблицы строк
paramstr('[Compiler.Options] Compiler.stabmin') - минимальный размер свободных строк при старте
paramstr('[Compiler.Options] Compiler.slenmax') - размер (длина) строк
Это может потребоваться при реализации алгоритмов обработки, чтобы знать пределы допустимых параметров программы.
В DaqPascal добавлена строковая функция
StringOfChar(fill:Char; leng:Integer):String,
позволяющая быстро выделить строку, заполненную заданным символом fill, с заданной длиной leng.
Например, вызов writeln(StringOfChar('*',10));
напечатает строку '**********'.
Также обновлены функции (charstr, leftpad, rightpad, centerpad) стандартной библиотеки,
использующие заполнение строк - теперь они работают быстрее.
Эта функция пригодится как для форматирования строк, так и для выделения памяти под данные, хранимые
в строковом буфере.
В DaqPascal добавлены константы
SizeOfBoolean,
SizeOfChar,
SizeOfInteger,
SizeOfReal,
которые возвращают размер соответствующих типов.
Раньше эти константы были в стандартной библиотеке, теперь стали встроенными в компилятор.
Они полезны, например, для расчета размеров буферов, выделяемых для хранения данных.
procedure testDump;
var s:string; i,n:Integer; b:Boolean;
begin
n:=9;
writeln('testDump ',SizeOfBoolean,SizeOfChar,SizeOfInteger,SizeOfReal); // Размер типов
s:=StringOfChar(chr(0),SizeOfInteger*n); // Выделение памяти
for i:=0 to n-1 do b:=iSetDump(s,i*SizeOfInteger,i+1); // Запись в буфер
for i:=0 to n-1 do write(iGetDump(s,i*SizeOfInteger):5,', '); writeln; // Чтение из буфера
s:=StringOfChar(chr(0),SizeOfReal*n); // Выделение памяти
for i:=0 to n-1 do b:=rSetDump(s,i*SizeOfReal,i+1.0); // Запись в буфер
for i:=0 to n-1 do write(rGetDump(s,i*SizeOfReal):5:3,', '); writeln; // Чтение из буфера
end;
Введение длинных строк, а также быстрых и безопасных функций работы с буфером фактически
открывает возможность использовать длинные строки как динамические массивы данных.
Измерения (i7-4700MQ CPU @ 2.40GHz) показали для вызова xGet/SetDump примерно такой результат:
вызов rGetDump, rSetDump:
занимает около 210 циклов CPU
занимает около 88 наносекунд, что соответствует частоте 11 МГц
Этой производительности должно хватить для большинства прикладных задач управления.
Во всех DEMO конфигурациях сделана замена:
bNul(iSetTagXor(tag,XorMask)) вместо bNul(iSetTag(tag,iXor(iGetTag(tag),XorMask)))
Функция iSetTagXor стандартной библиотеки использует вызов iAtomicTagOp
для безопасного изменения битов тега, поэтому теперь код реализован более корректно.
Рекомендуется делать аналогичные замены в старом коде для всех систем при их очередном обновлении.
В процессе указанной замены программа проверялась на множестве конфигураций, ошибок не было замечено.
Снятие ограничения на длину строк и ускорение строковых функций потребовало глубокого изменения
кода всех строковых функций виртуальной машины DaqPascal.
С точки зрения структуры и дизайна этот код значительно улучшился, стал более ясным, оптимальным и переносимым,
что облегчит его сопровождение и модификацию в будущем.
Тем не менее, новая версия нуждается в серьезном тестировании,
т.к. изменения сделаны весьма существенные.
14.03.2019
DIM DIMTree
Главными достижениями данного выпуска являются:
доработка программы DIMTree.
Утилита DIMTree доработана и получила версию 2.1.6.
Исправлена ошибка с чувствительностью к регистру имен (имена DIM чувствительны к регистру символов).
Улучшено отображение - оно стало более "гладким", без "мигания" - за счет двойной буферизации (DoubleBuffered).
09.03.2019
DIM DIMTree unix pexports unix dimcfg unix findexe DEMO_DOZA
Главными достижениями данного выпуска являются:
доработка программы DIMTree (поддержка RPC),
утилиты unix dimcfg, unix findexe, unix pexports.
Утилита DIMTree доработана и получила версию 2.1.5.
Сделана поддержка RPC (remote procedure call), которая отсутствовала ранее.
RPC предоставляет сервис "удаленного вызова процедур", при этом (в отличие от обычных сервисов)
ответ на запрос получает только вызывающий клиент, а не все подключенные клиенты.
Предприняты дополнительные меры для повышения надежности и устранены найденные ошибки.
Улучшены возможности журналирования.
Несколько полезных утилит добавлено в UnixUtils,CmdToolkit,CrwToolkit:
unix pexports dim.dll - печатает список экспортируемых функций *.dll
полезная утилита для проверки наличия интересующих функций в *.dll
(список экспорта динамической библиотеки может зависеть от версии)
unix findexe prog - находит в PATH программу prog.exe, prog.bat, prog.cmd, ...
пути поиска берутся из PATH, а расширения файлов - из PATHEXT
служит для поиска/проверки наличия программ в командных файлах
unix dimcfg ... - утилита для конфигурирования DIM сервера в командных файлах
unix dimcfg dic_info XXX - напечатает объявление сервиса XXX типа DIC INFO
unix dimcfg dis_info XXX - напечатает объявление сервиса XXX типа DIS INFO
unix dimcfg dic_cmnd XXX - напечатает объявление сервиса XXX типа DIC CMND
unix dimcfg dis_cmnd XXX - напечатает объявление сервиса XXX типа DIS CMND, например:
[&DimSrv.ServiceList]
DIC_INFO:XXX = dic_info XXX
[DIC_INFO:XXX]
unix dimcfg tag a b c - напечатает объявление тегов
tag a
tag b
tag c
unix dimcfg devmsg ... - напечатает объявление сообщений
unix dimcfg devsend ... - напечатает объявление сообщений
unix dimcfg devpost ... - напечатает объявление сообщений
unix dimcfg devsendmsg . - напечатает объявление сообщений
unix dimcfg devpostmsg . - напечатает объявление сообщений,
например: unix dimcfg devpost "&DemoCtrl @UpdateTag=DEMO.TAG"
напечатает: devPost &DemoCtrl @UpdateTag=DEMO.TAG
unix dimcfg end или [] - напечатает конец секции:
[]
unix dimcfg section xxx - напечатает заголовок секции [xxx]
unix dimcfg -n или --new - разделяет инструкции, чтобы сократить число вызовов dimcfg
Например вызов:
unix dimcfg dis_info DEMO/ABC -n tag ABC -n devpost "&DemoCtrl @Update=ABC" -n end
напечатает:
[&DimSrv.ServiceList]
DIS_INFO:DEMO/ABC = dis_info DEMO/ABC
[DIS_INFO:DEMO/ABC]
tag ABC
devPost &DemoCtrl @Update=ABC
[]
Опция -n позволяет в одном вызове выполнять сразу много операторов, что сильно
сокращает время работы, т.к. вызов исполняемого файла - дорогостоящая операция.
Этот вызов в командных файлах можно сделать более понятным с помощью переносов:
unix dimcfg ^
-n dis_info DEMO/ABC ^
-n tag ABC ^
-n devpost "&DemoCtrl @Update=ABC" ^
-n end
При этом следует следить, чтобы знак переноса был последним символом в строке,
т.к. знак переноса фактически экранирует символ переноса строки. Если поставить
после ^ пробел, возникнет ошибка. Это трудно обнаружиимая ошибка, т.к. пробел
трудно заметить. Поэтому для командных файлов лучше всего использовать редактор,
в котором пробелы являются видимыми символами, например, Notepad++.
Пречисленные утилиты созданы для облегчения создания командных файлов, в том числе
для унификации командных файлов, генерирующих конфигурации с описанием DIM сервисов.
Использование утилиты unix dimcfg позволит сделать описание DIM сервисов
более компактным. Преимущества такие:
Меньше повторов громоздких имен сервисов. Правильные конструкции генерируются автоматически.
В конструкциях можно использовать "закавыченные строки", внутри которых допускаются практически
любые символы. При использовании штатной команды echo такой возможности нет. Символы
приходится "экранировать" с помощью символа ^, при этом возникает много неочевидных ошибок.
Дополнительная проверка синтаксиса на этапе генерации конфигурации.
Обновлена конфигурация DEMO_DOZA.
Генератор конфигурации doza_devices.cmd
переделан с использованием утилиты unix dimcfg.
Сравнивая старую и новую версию генератора, можно заметить, что объявление сервисов стало гораздо
компактнее и понятнее, исключены громоздкие конструкции с повторяющимися идентификаторами большой длины.
Фактически в объявлении имя сервиса встречается всего один раз, при этом нужные структуры создаются автоматически.
Кроме того, за счет кавычек удается исключить символы экранирования (типа ^&DimSrv).
Приведенный пример показывает перспективность данного подхода.
Обращаю внимание на то, что конфигурация довольно большого блока сервисов DIM делается одним вызовом
unix dimcfg c большим списком аргументов командной строки (благодаря опции -n и переносам строк).
Это позволяет сильно сократить время работы, т.к. вызов программы - довольно дорогостоящая операция.
Чем меньше вызовов программы, тем быстрее выполнение. Дешевле обработать много аргументов, чем много вызовов.
В реальных конфигурациях список параметров может включать сотни элементов и объемы в несколько килобайт.
02.03.2019
DIM DIMTree sourceforge.net
Главными достижениями данного выпуска являются:
доработка программы DIMTree (ускорение и надежность).
Утилита DIMTree доработана и получила версию 2.1.3.
Ускорена работа с большими объемами данных (подключение 22000 сервисов выполняется за 3-4 сек).
Предприняты дополнительные меры для повышения надежности и устранены найденные ошибки.
Улучшены возможности журналирования.
Утилита DIMTree выложена на сайте
sourceforge.net.
Это бесплатный хостинг для размещения исходников СПО.
На нем хранится огромное количество "исходников" свободных программ.
Вероятно, и другие части пакета (типа UnixUtils) со временем будут выложены там.
С автором DIM (Clara Gaspar) достигнута договоренность о том, что обновленная утилита
DIMTree будет включена в дистрибутив DIM.
20.02.2019
DIM &DimSrv DIMTree dim.cmd dimgui.cmd dimgui.vbs ReplaceStr
Главными достижениями данного выпуска являются:
обновление интерфейсных файлов и документации DIM;
обновление и оптимизация сервера &DimSrv;
добавление команды dim.cmd и "Центра управления DIM",
доработка программы DIMTree и библиотек DIM для Pascal;
обновление утилит, включая ReplaceStr.
Программный интерфейс DIM не обновлялся с 2005 года. Пришла пора это исправить.
Обновлены файлы дистрибутива и программного интерфейса DIM,
где добавлено более 30 новых функций. Добавлена документация и примеры.
Смотри Resource\DimSite\readme.htm.
Также доработана библиотека классов для облегчения создания
клиентов и серверов DIM.
Библиотеку иллюстрирует пример.
Эта библиотека также используется в программе DIMTree.exe.
В целом DIM подготовлен для тиражирования, чтобы можно было передавать его другим
участникам совместных работ для обеспечения связи с другими программами и пакетами.
Сервер &DimSrv обновлен и оптимизирован.
Обновление коснулось обработки ошибок и сбоев (например, при отключении DNS).
Теперь &DimSrv диагностирует эти ошибки и выводит их в Главную Консоль.
Режим вывода управляется командой @ReportFlags:
@ReportFlags 0 отключить вывод сообщений об ошибках
@ReportFlags 1 включить вывод сообщений об ошибках в консоль устройства
@ReportFlags 2 включить вывод сообщений об ошибках в Главную Консоль
@ReportFlags 3 включить вывод сообщений об ошибках в обе консоли
Кроме того, сообщения об ошибках в DIM системе теперь протоколируются в файлах
Temp\@IntegrityEvents.log и Temp\@DimEvents.log.
Типичные ошибки DIM - это ошибки и сбои связи,
отключение и подключение сервера имен DNS,
попытка повторного запуска уже работающего DIM-сервера и т.д.
Оптимизация &DimSrv заключалась в использовании хэш-таблиц для анализа команд,
поступающих в &DimSrv от процесса dimsrv.exe.
В старой версии анализ делался сравнением строк (это дольше).
В меню Инструменты добавлен пункт меню
Центр Управления DIM, который ссылается на новую команду
dim.cmd, расположенную к каталоге
Resource\DimSite\dim_cmd,
созданную специально для облегчения работы с DIM
и доступную также через команду @run:
@run dim gui Вызов диалога DIM Control Center
@run dim readme Открывает справку по DIM
@run dim copy Корирует каталог Resource\DimSite в %CommonProgramFiles%\CRW-DAQ\Resource\DimSite
@run dim dns state Проверяет и показывает статус DNS.EXE - running/stopped
@run dim dns status Проверяет и показывает статус DNS.EXE - running/stopped
@run dim dns open show Запускает сервер имен DNS.EXE и показывает окно
@run dim dns exec hide Запускает сервер имен DNS.EXE и скрывает окно
@run dim dns show Показывает окно сервера имен DNS.EXE
@run dim dns hide Скрывает окно сервера имен DNS.EXE
@run dim dns close Закрывает окно сервера имен DNS.EXE (мягкое завершение)
@run dim dns stop Закрывает окно сервера имен DNS.EXE (мягкое завершение)
@run dim dns kill Убивает процесс сервера имен DNS.EXE (жесткое завершение)
@run dim did exec Запускает отладочную утилиту DID.EXE
@run dim tree exec Запускает отладочную утилиту DIМTREE.EXE
@run dim ports add Запускает утилиту разрешения DIM портов в Windows Firewall
@run dim ports delete Запускает утилиту запрета DIM портов в Windows Firewall
@run dim ports show Печатает список разрешенных портов в Windows Firewall
Утилита dim.cmd служит для облегчения работы с системой DIM,
давая возможность запускать/завершать/показывать/прятать программу сервера имен DNS.EXE
и отладочных утилит DID.EXE, DIMTREE.EXE.
Для предотвращения файловых блокировок утилита dim.cmd копирует каталог Resource\DimSite
в %CommonProgramFiles%\CRW-DAQ\Resource\DimSite и запускает утилиты из этого каталога.
Утилита dim.cmd полезна еще и потому, что сервер имен DNS.EXE обычно запускается в скрытом окне.
Чтобы увидеть состояние этого процесса, скрытое окно надо уметь показывать и прятать обратно.
Утилита dim.cmd дает такие возможности.
Диалог DIM Control Center - это графическая надстройка над утилитой dim.cmd
(см. также код
dimgui.cmd и
dimgui.vbs),
которая позволяет работать с ней не через консоль, а через графический диалог с кнопками.
В диалоге также автоматически отображается состояние процесса DNS.EXE.
Это у нас первая утилита, реализованная через библиотеку WSO,
которая позволяет создавать графические приложения на языках
VisualBasicScript и JavaScript.
Библиотека WSO входит в состав пакета CrwToolkit,
который входит в состав Crw32Runtime и должна быть доступна всегда.
В сервере &DimSrv добавлена служба сервера имен dns.exe.
@dns.exe Запуск dns.exe, если он еще не запущен
Возвращает число работающих процессов dns.exe
@dns.exe Period Печатает период проверки(мс) процесса dns.exe
Нулевой период означает отключение проверок
@dns.exe Period 60000 Установка периодичности проверки (мс) dns.exe
При проверке, если dns.exe (еще) не запущен, он запускается
Задание периода проверки @dns.exe Period 60000 означает, что раз в минуту
будет выполяться команда dns.exe, которая будет проверять наличие процесса
dns.exe и запускать его, если он "упал".
Это гарантирует постоянную работу сервера имен dns.exe.
Примечание: dns.exe запускает программу только если в качестве DIM_DNS_NODE
установлен локальный компьютер (обычно - точка в конфигурации).
Это логично, т.к. если установлен другой сервер имен, то и локальный dns.exe просто не нужен.
Команда @dns.exe Period 60000 добавлена в стандартную конфигурацию
~~\Resource\DaqSite\Default\DimSrv.cfg.
Это значит, что по умолчанию сервер &DimSrv будет раз в минуту
присматривать за сервером имен dns.exe и запускать его, если он упал.
Это должно гарантировать отказоустойчивую работу DIM.
Утилита DIMTree доработана и получила версию 2.1.0.
Исправлены найденные ошибки и добавлены новые возможности в командных утилитах,
включая ReplaceStr.
В частности, в неё (а также во многие другие утилиты),
добавлена опция -- (отмена опций),
полезная для передачи аргументов, начинающихся с дефиса.
03.02.2019
DIM DIMTree ReplaceStr
Главными достижениями данного выпуска являются: полная переработка программы DIMTree,
обновление DIM и ReplaceStr.
Утилита DIMTree полностью переработана и получила версию 2.0.0.
Код утилиты переработан на 80-90% с целью удаления "мусора", повышения "читабельности" и ясности кода,
улучшения модульности, повышения уровня надежности программы и ускорения её работы.
Работа утилиты существенно (в десятки раз) ускорена.
Ранее некоторые операции (например, открытие сервисов) выполнялись очень долго (минуты),
если число сервисов велико (например, в конфигурации AliPhosCool их более 500).
Теперь это работает мгновенно (доли секунды).
В дополнение к давно разработанной интерфейсной DIM библиотеке
(_dim.pas)
разработаны новые библиотеки для облегчения создания
DIM-клиентов (_dimc.pas) и
DIM-серверов (_dims.pas).
Утилита DIMTree теперь реализована именно на этих библиотеках.
Наличие библиотек позволяет быстро создавать автономные клиентские или серверные программы,
использующие DIM для межпроцессного взаимодействия.
Сама утилита DIMTree может служить хорошим примером для создания таких автономных клиентов и серверов.
В утилиту добавлен встроенный тестовый DIM-сервер для тестирования и демонстрирования работы
DIM клиентов и серверов.
В общем, утилита DIMTree становится наиболее удобным отладочным инструментом для создания
DIM клиентов и серверов и распределенных систем управления.
Библиотека DIM обновлена с версии 19.31 до версии 20.2.
Это одна из последних "классических" 32-битных версий DIM, совместимых с Windows-XP.
В последующих версиях произошел переход на другую версию компилятора и библиотек Visual C++,
которые уже не работают в XP. Компиляция под старой версией компилятора возможна, но этим надо
специально заниматься (сейчас недосуг). Кроме того, в последующих версиях был добавлен Web-сервер
(WebDID), из-за которого объем библиотек DIM сильно раздулся (более чем в 3 раза).
По перечисленным причинам обновление до текущей версии (20.24) не производилось.
Пока будем работать с этой версией, а дальше будет видно.
Исправлены найденные ошибки и добавлены новые возможности в утилите ReplaceStr.
Всех поздравляю с наступающим Новым Годом и Рождеством.
Главными достижениями данного выпуска являются: получение исходных кодов и обновление DIMTree,
обновление unix.exe, добавление программы runvbsc.exe,
обновление и исправление найденных ошибок пакетов CrwToolkit, CmdToolkit, UnixUtils.
Сайт VirusTotal.com является самой известной комплексной антивирусной службой,
на которой файлы можно проверить с помощью большого числа (около 70) наиболее известных антивирусов.
Отсутствие предупреждений сайта VirusTotal.com гарантирует "антивирусную чистоту" проверенных
там программ, что весьма важно при использовании пакета на машинах с установленными СЗИ.
Было принято решение о том, что отныне все создаваемые или включаемые в пакет программы должны проходить
обязательную проверку на VirusTotal.com, чтобы со временем получить гарантированно "чистую" сборку,
которая может работать в составе любой СЗИ.
Что касается программ, которые были включены в пакет ранее, то они будут постепенно "вычищаться" (при наличии
исходного кода), либо заменяться на "чистые" аналоги, написанные на скриптовых языках (cmd,vbs,js,lua).
Утилита DIMTree давно (примерно с 2005 года) вошла в состав пакета CRW-DAQ
и является полезным инструментом при разработке распределенных систем на основе DIM.
Однако недавно было обнаружено, что эта утилита больше не входит в состав библиотеки DIM
последних версий.
Видимо, это произошло потому, что DIMTree является независимой разработкой,
на которую у авторов DIM нет исходных кодов.
Будущее утилиты DIMTree оказалось под вопросом.
В связи с этим была завязана переписка с автором, в результате которой
удалось получить исходные коды утилиты DIMTree от автора (Сергея Сергеева из Дубны).
Утилита была слегка модифицирована (добавлен манифест и информация о версии, проведена проверка
с помощью VirusTotal.com) и включена в состав пакета уже с исходными кодами.
Наличие исходных кодов снимает вопрос о будущем утилиты DIMTree.
Теперь она является неотъемлемой частью пакета CRW-DAQ.
Обновлена программа unix.exe с целью устранить замечания VirusTotal.com.
Теперь замечаний к программе нет, что гарантирует её "антивирусную чистоту".
Программа unix.exe является одной из ключевых компонентов пакета и должна быть
абсолютно "чистой" с точки зрения антивирусов, учитывая возможность работы при наличии СЗИ.
Создана программа runvbsc.exe, которая запускает одноименный vbs скрипт в консольном режиме.
Скрипт запускается с помощью программы cscript.exe, или, точнее, командной строки вида
cscript.exe //i //NoLogo file.vbs args, в которой передаются имя скрипта file.vbs и аргументы args.
Опции //i, //NoLogo задают режим вызова (интерактивный, без печати заголовка)
интерпретатора cscript.exe, являющегося штатным компонентом Windows.
Программа runvbsc.exe проверена на VirusTotal.com, замечений нет.
При использовании какого-либо скрипта (например, replacestr.vbs) программа runvbsc.exe копируется
в одноименный exe-файл (например replacestr.exe), в результате чего целевая программа (replacestr)
при выполнении запускает vbs скрипт.
Программа runvbsc.exe будет использоваться для постепенной замены "проблемных" с точки зрения
антивирусной чистоты программ на vbs скрипты, выполняющие те же функции.
Замена исполняемых файлов на скрипты должна обеспечить компактность и "антивирусную чистоту" пакета.
Антивирусная чистота обеспечивается тем что 1) программа runvbsc.exe чистая, 2) скрипты являются
штатным средством ОС и обычно не вызывают замечаний антивирусов.
Программы unix.exe и runvbsc.exe станут базовыми средствами, на которых будет строиться
дальнейшее развитие пакетов CrwToolkit, CmdToolkit, UnixUtils.
При тестировании предыдущей версии было обнаружено, что сделанная замена некоторых утилит (например replacestr.exe)
на командные файлы и скрипты (например replacestr.cmd + replacestr.vbs) приводит к появлению ошибок.
Это связано с тем, что командные файлы обрабатывает командный интерпретатор (cmd), который использует
специальные символы (& | < > ^ % ! и т.д.), обрабатываемые специальным образом.
Эта проблема устранена с помощью программы runvbsc.exe, которая описана выше.
А именно, проблемная программа (например replacestr.exe) замещается переименованной программой runvbsc.exe
со скриптом (replacestr.exe + replacestr.vbs).
В таком варианте вызов replacestr не приводит к запуску командного интерпретатора (cmd), а сразу вызывает
исполняемый файл replacestr.exe (переименованный runvbsc.exe), который вызывает скрипт replacestr.vbs.
По этой причине ошибок в интерпретации специальных символов не появляется.
Строка идентификации выдается в команде @SysInfo,
а также отображается в статусной строке, расположенной в нижней части главного окна CRW32.
Изменение строки идентификации связано с тем, что главный исполняемый файл Crw32.exe
изменяется значительно реже, чем сборка пакета, т.к. изменения в сборке могут касаться не только
основного файла, но и файлов конфигурации, утилит или библиотек.
Теперь строка идентификации выдает более точную информацию о версии программы и пакета.
Строка идентификации программы теперь также записывается в переменную окружения CRW_DAQ_SYS_VERSION.
Это нужно для того, чтобы дочерние процессы или команды могли узнавать версию пакета во время исполнения.
Добавлены демо конфигурации
DEMO_EGP и
DEMO_UFL.
Подготовил Н.Гурин.
Утилита cltimer заменена на скриптовый (vbs) аналог.
Она служит для измерения времени выполнения команд и используется во многих командных файлах:
unix cltimer -start - старт таймера
call command ... - выполнение команд
unix cltimer -stop - печать времени, прошедшего после старта
Теперь cltimer входит в пакеты CrwToolkit, CmdToolkit, UnixUtils.
08.12.2018
UnixUtils CmdToolkit CrwToolkit
Главными достижениями данного выпуска являются: реструктуризация дистрибутива,
пакет CrwToolkit, обновление пакетов CmdToolkit, UnixUtils.
Немного истории и теории.
Для работы пакета CRW-DAQ кроме самого исполняемого файла Crw32.exe необходимы многочисленные утилиты
(как правило, командной строки), которые выполняют рутинную работу по взаимодействию с операционной системой.
Утилиты отличаются тем, что каждая из них выполняется как отдельный процесс (что хорошо с точки зрения отказоустойчивости)
и выполняет четко определенные и строго ограниченные задачи.
Например, проверку контрольных сумм (контроль целостности) выполняют утилиты checksum.exe, textmetadata.exe.
Утилиты решают задачи оперирования с файлами, процессами, взаимодействия с другими программами, например, пакетом ROOT.
Первоначально утилиты существовали в виде виде файлов (exe,cmd,bat), размещенные в каталоге пакета (Resource).
Однако со временем стало ясно, что это неудобно.
Пакетов может быть установлено несколько экземпляров.
Где будут расположены утилиты, заранее неизвестно, что затрудняло их использование в прикладных системах.
Объем среды исполнения (Runtime) пакета сильно возрастал.
Однако отказываться от утилит не хотелось, т.к. они облегчают создание прикладных систем (в разы!).
Все эти соображения привели к созданию пакета UnixUtils - утилит в стиле Unix,
куда были перенесены большинство утилит (при этом объем пакета Crw32Runtime сильно сократился).
Пакет UnixUtils реализован как отдельный продукт со своим инсталлятором и имеет (сейчас) объем около 100 МБ.
Он устанавливается в папку %ProgramFiles%\UnixUtils и регистрируется в реестре Windows.
Доступ к возможностям пакета дается с помощью одной команды unix.exe, помещаемой в каталог Windows.
Например, unix replacestr - вызов утилиты замены строки в тексте.
Пакет UnixUtils оказался весьма полезным и удобным.
Однако у него (при работе в наших условиях) обнаружился ряд недостатков:
Сравнительно большой объем, избыточный для Runtime.
Позиционирование как отдельный продукт вызывает вопросы с точки зрения формальных разрешений.
Ряд программ, входящих в пакет UnixUtils, вызывает вопросы VirusTotal.com,
то есть распознается рядом антивирусов как потенциально опасное ПО.
Это, конечно, ложные предупреждения, но они могут привести к отказу в разрешении
на установку пакета UnixUtils на машинах пользователей.
Все эти проблемы не играют роли на машинах разработчиков, но могут осложнить установку ПО
и работу на машинах конечных пользователей.
При этом и в самом пакете, и в прикладных системах есть много зависимостей от утилит пакета UnixUtils.
По перечисленным причинам возникла потребность выделить из пакета UnixUtils небольшую часть,
которая будет устанавливаться на компьютеры пользователей в составе среды исполнения Runtime.
Для этого было сделано два пакета: CmdToolkit и CrwToolkit.
При этом оба пакета являются частью ("выжимкой") из пакета UnixUtils, куда помещаются только самые
необходимые утилиты, которые должны присутствовать в Runtime.
Пакет CmdToolkit содержит "выжимку" (небольшую часть) пакета UnixUtils, в основном реализованную
в виде командных файлов (cmd,bat,vbs,lua), откуда и взялось название пакета.
Пакет CmdToolkit реализован как отдельный продукт со своим инсталлятором и имеет (сейчас) объем около 5 МБ.
Он устанавливается в папку %ProgramFiles%\CmdToolkit и регистрируется в реестре Windows.
Доступ к возможностям пакета дается с помощью той же самой команды unix.exe, помещаемой в каталог Windows.
Кроме того, CmdToolkit содержит "цветную консоль" (через библиотеку ANSICON), что удобно для работы.
Предполагается, что CmdToolkit устанавливается в составе Runtime вместо или вместе c UnixUtils.
При совместной установке эти пакеты не мешают, а лишь дополняют друг друга.
Однако, поскольку CmdToolkit является отдельным пакетом (виден в реестре) и тоже содержит некоторую
избыточность (фонты, цветную консоль), было решено сделать еще одну "выжимку".
Пакет CrwToolkit содержит "выжимку" (некоторую часть) пакета CmdToolkit, строго необходимую для
установки на компьютеры пользователей в составе среды исполнения Runtime.
Пакет CrwToolkit реализован как часть Crw32Runtime и имеет объем около 3 МБ.
Он позиционируется как неотъемлемая часть (библиотека в составе пакета) CRW-DAQ и входит в основной дистрибутив пакета.
Пакет CrwToolkit не позиционируется как автономный продукт, и не регистрируется в реестре, чтобы не было вопросов.
Утилиты, входящие в этот пакет, будут проходить особо тщательный отбор, чтобы избежать каких-либо проблем с антивирусами.
Он устанавливается в папку %ProgramFiles%\CrwToolkit.
Доступ к возможностям пакета дается с помощью той же самой команды unix.exe, помещаемой в каталог Windows.
Предполагается, что CrwToolkit устанавливается в составе Crw32Runtime вместо или вместе c пакетами CmdToolkit, UnixUtils.
При совместной установке эти пакеты не мешают, а лишь дополняют друг друга.
Команда unix.exe, входящая в пакеты UnixUtils, CmdToolkit, CrwToolkit,
и помещаемая при инсталляции в каталог Windows, теперь работает таким образом.
При вызове unix cmd arg ... она проверяет наличие пакета UnixUtils, затем
CmdToolkit и CrwToolkit.
Если один из этих пакетов найден, то его каталоги добавляются в пути поиска (PATH).
Затем вызывается требуемая команда cmd arg ....
Таким образом, команда будет искаться в одном из пакетов, смотря какой из них установлен.
На машинах разработчиков устанавлявается наксимальный набор UnixUtils, на машинах
пользователей устанавливается сокращенный набор CmdToolkit (при возможности)
и CrwToolkit (всегда).
Таким образом, на компьютере, где установлен пакет CRW-DAQ, обязетельно будет присутствовать
команда unix с (хотя бы) минимальным набором необходимых утилит.
Поэтому все командные скрипты могут рассчитывать на то, что команда unix cmd arg ...
будет работать в любом случае (для команд, входящих в CrwToolkit).
Наличие единого механизма доступа к утилитам помогает избежать сложных процедур поиска расположения утилит.
Сделанная реструктуризация дистрибутива и введение встроенного пакета CrwToolkit,
входящего в состав Crw32Runtime, призвана решить следующие задачи:
Минимизировать объем Crw32Runtime с сохранением необходимых возможностей.
Очистить пакет Crw32Runtime от программ, которые не любят антивирусы.
Сделать Crw32Runtime автономным, чтобы на машинах конечных пользователей прикладные системы
могли работать без установки дополнительных утилит.
Несколько утилит, входящих в UnixUtils, CmdToolkit, CrwToolkit, переведены из
формата исполняемых файлов (exe) в формат командных файлов (cmd,vbs,lua).
Это мотивировано несколькими соображениями.
Командные файлы компактны, доступны в исходных кодах (и поэтому их легче поддерживать и развивать).
Они не вызывают проблем с антивирусами (т.к. используют штатные командные интерпретаторы).
Есть и недостатки - снижение скорости работы, зависимость от интерпрератора
(теоретически командные интерпретаторы могут быть отключены).
Однако в большинстве задач скорость работы утилит не критична, а командные интерпретаторы доступны
(если их специально не отключали).
Среди утилит, которые подверглись переработке, есть довольно важные, например,
replacestr - замена строк в тексте, messagebox - диалог сообщения,
inputbox - диалог ввода текста, и ряд других.
С точки зрения использования ничего не изменилось - например, команда unix replacestr
работает как прежде, т.к. команда unix сама отыскивает нужный файл (exe,bat,cmd,vbs,lua).
Однако в ряде скриптов, где были явно прописаны имена утилит с расширениями (например, replacestr.exe),
возникнут проблемы, которые решаются заменой на имена без расширений.
К сожалению, придется потерпеть некоторые временные неудобства, связанные с этими мелкими поправками.
Целый ряд утилит, входящих в UnixUtils, которые раньше копировались в каталог Windows, теперь оттуда убраны.
Это сделано для того, чтобы не "засорять" системный каталог и не создавать лишних поводов для конфликтов
с администраторами на машинах конечных пользователей
(в этом смысле чем меньше файлов будет копироваться в системный каталог, тем лучше).
В частности, это касается утилит replacestr, sleep и ряда других.
Теперь в системном каталоге остаются только самые незаменимые утилиты, необходимые для работы инсталляторов
- архиваторы (7z,gzip,arj), команды старта/завершения (.cmdautorun.cmd и т.д.),
"запускалки" (grun,saferun,admirun) и нотификатор (fpquitip,fpquisend).
Со временем и их, возможно, там не будет.
В идеале в системном каталоге Windows должна остаться только одна команда unix,
через которую будет выполняться доступ ко всем остальным утилитам пакета UnixUtils.
Во всяком случае, в системном каталоге должны остаться только самые необходимые программы.
Для прикладных систем это означает, что некоторые командные скрипты, в которых использовался прямой вызов
команд (например, sleep 1), перестанут работать, т.к. они будут недоступны в PATH.
Решение состоит в том, чтобы использовать вызов через команду unix, например, unix sleep 1.
К сожалению, придется потерпеть некоторые временные неудобства, связанные с этими мелкими поправками.
Идет борьба за "чистоту" дистрибутива.
Работа над пакетами CmdToolkit, CrwToolkit будет продолжаться (в фоновом режиме),
с целью получить "чистый" и компактный Crw32Runtime для установки на машины конечных пользователей.
Для этого, в частности, некоторые исполняемые файлы (exe) будут постепенно заменяться на командные (cmd,vbs,lua),
которые не вызывают проблем с антивирусами (т.к. используют штатные командные интерпретаторы).
Это долговременная работа, которая может занять годы.
Но делать её необходимо.
При разработке прикладных систем следует добиваться того, чтобы прикладные конфигурации сохраняли
свои функции при установке только одного Crw32Runtime (и CrwToolkit в его составе).
Пока это в полной мере недостижимо, т.к. некоторые конфигурации используют возможности UnixUtils,
которых нет в составе CrwToolkit.
Однако по мере доработки пакета CrwToolkit эта проблема исчезнет.
Главными достижениями данного выпуска являются: обновление DEMO_DOZA, утилита DimPorts.cmd,
поддержка мостов (DimBridge) в сервере &DimSrv.
В целом выпуск посвящен доработке сервера &DimSrv для создания распределенных систем с GUI.
Обновлена конфигурация DEMO_DOZA (вариант c DIM-сервером).
Устранены мелкие недочеты, найденные при тестировании.
Для корректной работы &DimSrv в Firewall необходимо выполнить разрешение TCP-портов, связанных с DIM.
Это можно сделать вручную, но это долго и неудобно.
Для автоматизации настройки портов сделана утилита DimPorts.cmd.
Она доступна в меню "Инструменты\Консольные утилиты", а также в Главной Консоли
и в консоли &DimSrv:
В консоли &DimSrv:
@DimPorts add enable - разрешить DIM-порты TCP 2505,5100..5108
@DimPorts delete - удалить разрешения для DIM-портов
@DimPorts show - показать разрешения Firewall
В Главной Консоли:
@run cmd /c Resource\DaqSite\DimServer\DimPorts.cmd add enable
@run cmd /c Resource\DaqSite\DimServer\DimPorts.cmd delete
@run cmd /c Resource\DaqSite\DimServer\DimPorts.cmd show
При работе c &DimSrv часто требуется запускать DIM-мосты
DimBridge.exe.
Раньше это делалось вручную в каждой DIM-конфигурации, что было неудобно и громоздко.
Теперь &DimSrv-сервер сам позволяет запускать до 32 процессов -мостов
DimBridge.exe
и следить за их работой, выполняя перезапуск "упавших" процессов при необходимости.
Запуск DIM-мостов осуществляется с помощью команд в секции [&DimSrv.StartupScript],
например:
[&DimSrv.StartupScript]
@StatPeriod 60000
@DimBridge Period 60000
@IfComputerName egp-mzbs @DimBridge egp-mzbs.dep0404.ru simply.dep0404.ru EGP/MZBS/*
@IfComputerName egp-main @DimBridge simply.dep0404.ru egp-main.dep0404.ru EGP/MZBS/*
[]
@StatPeriod задает период обновления статистики
@DimBridge Period задает период проверки/перезапуска процессов DimBridge.exe
@IfComputerName выполняет команду при совпадении имени компьютера с шаблоном
@DimBridge source target services экспортирует сервисы services из компьютера source в target
egp-mzbs, simply, EGP/MZBS/* источник (source), приемник (target), маска данных (services)
Сервисы (services) задаются по маске (префикс*), имена компьютеров (source,target) - это источник и приемник данных,
которые желательно задавать в полном виде (с доменным именем), т.е. simply.dep0404.ru вместо simply.
Причина, по которой рекомендуется использовать мосты DimBridge, состоит в следующем.
При создании распределенных DIM-систем было принято решение делать графический интерфейс (GUI)
распределенных клиент-серверных систем с помощью DIM всегда, без исключений на локальный интерфейс.
Это значит, что сервер отсылает графические события ("клики") в DIM-сеть и затем принимает их
на общих основаниях, как будто бы они пришли из сети.
То есть серверный процесс работает как DIM-клиент по отношению к самому себе, и получает локальные
графические события так же, как события от любого другого удаленного клиента.
Такой подход имеет то преимущество, что в нем минимизируется количество программного кода - не надо отдельно
создавать локальный и удаленный интерфейс (а это удвоило бы объем кода и увеличило бы вероятность ошибок).
Кроме того, при отладке есть уверенность в том, что если GUI отлажен локально,
то он точно так же будет работать удаленно.
В этом методе разработки GUI есть только один недостаток - если сервер имен (DNS,
заданный в DIM_DNS_NODE) недоступен, то локальный интерфейс перестает работать, как и удаленные.
Сервер имен DNS может оказаться недоступным, например, из-за проблем с сетью или из-за отключения
центрального компьютера, на котором запущен DNS.
Если распределенная система управления состоит из локальных компьютеров, которые могут запускаться
независимо друг от друга (что является распространенное практикой), то желательно добиться того,
чтобы работоспособность локального GUI не зависела от состояния сети или центрального DNS.
Для этого делается следующее. На каждом из работающих компьютеров, входящих в сеть DIM,
запускается свой локальный DNS, для чего надо указать DIM_DNS_NODE = .
(это значение по умолчанию в стандартной конфигурации
~~\Resource\DaqSite\Default\DimSrv.cfg).
Сервер и локально запущенные клиенты используют DIM_DNS_NODE = . для ссылки на локальный DNS.
Локальный DNS доступен всегда, даже при отсутствии сети, поэтому локальный интерфейс, а также
локально запущенные клиенты будут работать гарантированно.
Для связи с другими компьютерами используется мосты DimBridge, которые экспортируют сервисы
с одного DNS на другой.
Для сохранения централизованной структуры DIM-сети мосты могут наводиться между компьютерами
не попарно (для этого надо было бы "прописать" каждую пару, что не очень удобно), а через центральный
компьютер.
Например, в рассмотренном выше примере данные EGP/MZBS/* экспортируются
с измерительного сервера egp-mzbs на центральный сервер simply,
а клиент импортирует эти данные с центрального сервера simply на клиентскую машину egp-main.
Этот метод тоже имеет свои недостатки (удвоение трафика данных), однако он является более отказоустойчивым
по отношению к возможным сбоям в сети, поэтому рекомендуется к использованию (во всяком случае, при
умеренном трафике данных).
В команде @Run добавлены опции /SW0../SW10 для задания оконного режима запуска.
Главными достижениями данного выпуска являются:
обновление &DimSrv, улучшение обработки событий в потоках Polling,
новые функции clickwhat, clickread, clickwrite, clickwrote, clickfilter, clickawaker
позволяющие расширить возможности обработки пользовательского ввода (фильтр событий, цикл событий, симуляция событий),
новые функции обработки строк strfetch, cookiescan,
большая группа функций DIM_xxx для разработки распределенных систем,
которая очень существенно упрощает создание сетевых распределенных систем на основе DIM
и демонстационная система DEMO_DOZA, иллюстрирующая построение распределенных DIM систем
с графическим интерфейсом.
Устранены мелкие недочеты - при обработке команд @dns.exe, @did.exe, @dimtree.exe
необоснованно генерировались ошибки.
Кроме команды devmsg для рассылки клиентам обновлений добавились команды
devsend, devpost, devsendmsg, devpostmsg, что позволит добиваться
снижения нагрузки процессора или уменьшения времени обработки (см. предыдущие новости).
Улучшена обработка событий в потоках Polling.
Напомним, что опрос программных устройств задается так:
[DeviceList]
MyDevice = device software program
[MyDevice]
InquiryPeriod = aPeriod ; Задает номинальный период опроса (при отсутствии событий)
DevicePolling = aDelay, aPriority ; Задает период пробуждения и приоритет потока опроса
При этом номинальный период опроса aPeriod квантуется (величиной 10 или 15 ms).
Значение aPeriod=0 означает "вызывать программу всегда, т.е. при любом пробуждении потока".
Поток активизируется (пробуждается от сна) с периодом aDelay, либо досрочно по событию (devSend, ClickButton).
Выполнение программы после пробуждения происходит не всегда, оно происходит или по таймеру опроса (aPeriod),
или по событиям (до сего дня - devSend, ClickButton).
Если период опроса aPeriod (с учетом квантования) > периода пробуждения aDelay,
то пробудившийся поток может пробудиться вхолостую, если период опроса еще не подошел, а событий для обработки нет.
Правда, при холостом пробуждении все же происходит сброс сторожевого таймера и накопление статистики.
Однако холостое пробуждение все же является избыточным и в нем не видно большого смысла.
Теперь к событиям, влияющим на исполнение программы, добавлено событие (StdIn.Count>0),
т.е. наличие данных в консоли ввода. На практике это значит, что теперь есть смысл задавать aPeriod > aDelay.
При этом, хотя выполнение программы в среднем будет происходить реже пробуждения, однако при поступлении данных в консоль
выполнение программы будет запускаться с частотой пробуждения потока, если поток событий велик.
Это ситуация, характерная для серверов (&DimSrv, &CronSrv, ...).
Например, в характерном случае
[&DimSrv]
InquiryPeriod = 1 ; Задает номинальный период опроса 10 или 15 ms (из-за квантования!)
DevicePolling = 1, tpHighest ; Задает период пробуждения 1 ms и высокий приоритет потока опроса
При малом числе событий программа будет выполняться с периодом 10 или 15 ms (из-за квантования!),
а поток будет часто пробуждаться вхолостую (с периодом до 1 ms, если задан SetClockRes(1)).
Однако при наличии большого числа событий, когда клиенты шлют много посылок devPost,
консоль ввода почти всегда будет заполнена данными и выполнение программы будет происходить при каждом пробуждении.
В общем, идет оттачивание потоковой модели системы...
В DAQ Pascal добавлены новые функции для организации цикла опроса пользовательских событий:
ClickWhat,
ClickRead,
ClickWrite,
ClickWrote,
ClickFilter,
ClickAwaker.
Функции позволяют организовать цикл опроса событий (а не только обработку по одному событию за вызов),
обрабатывать разные типы событий (движение мыши, нажатие и отпускание кнопок и клавиш),
а также фильтровать события (по типу) и симулировать их (используется для удаленных клиент-серверных систем).
Функции достаточно подробно описаны в документации, поэтому читайте приведенные выше ссылки.
Также полезно ознакомиться с принципом обработки
и рекомендациями по обработке событий.
Здесь приведу только такой пример:
f:=ClickFilter(63); // При инициализации задаем фильтр событий
a:=ClickAwaker(63); // а также флаги "пробуждения по событию"
... // В данном случае разрешаем все события
procedure HandleClicks; // Процедура обработки пользовательских событий
begin // Вызывается в цикле опроса ApplicationPoll
if ClickWhat<>0 then // Что-то случилось?
repeat // Начинаем цикл обработки событий...
if ClickWhat=cw_MouseDown then begin // Нажатие кнопки мыши?
if ClickButton=VK_LBUTTON then begin // Нажатие левой кнопки?
if ClickSensor='DEMO' then ... // Выполняем обработку нажатия сенсора
... // И так далее
end; //
end; //
if ClickWhat=3 then begin // Движение мыши?
writeln('Mouse move to: '+ClickParams('Where')); // Печатаем координаты мыши
... // И так далее
end;
until ClickRead=0; // Читаем следующие события, пока они есть
end;
Следует отметить, что (из соображений совместимости) все старые программы работают по-старому,
т.е обрабатывают по одному событию за вызов и принимают только нажатия кнопок
(отпускание кнопок и движение мыши игнорируется).
Для обработки в новом стиле надо задать фильтр событий и организовать цикл опроса событий, как показано
в приведенном выше примере.
Обработка пользовательского ввода, конечно, несколько усложняется, однако теперь есть возможность
обрабатывать разные типы событий (а не только нажатия кнопок) и выбирать из очереди все события
(а не только по одному за вызов).
Кроме того, новая возможность - симуляция событий - позволяет существенно упростить создание
распределенных сетевых систем.
Симуляция событий позволяет обрабатывать "искусственные" события (например, удаленные события, полученные по сети)
так же, как обрабатываются "естественные" (локальные) события от клавиатуры и мыши.
Обновлена демо конфигурация DEMO_PAINT_GUILIB.
В ней продемонстрированы новые функции обработки событий, описанные выше.
Можно посмотреть, как выглядит рабочий код цикла обработки событий и анализа событий по типам.
Открыв окно консоли и монитора ресурсов, можно наблюдать, как на обработку событий влияют
фильтр событий ClickFilter и флаги пробуждения ClickAwaker.
Примечание: фильтр событий ClickFilter и флаги пробуждения ClickAwaker в данной версии
не внесены в конфигурационный файл и изначально имеют обычное значение "по умолчанию".
Включение в конфигурацию пока нецелесообразно, т.к. большинство программ скорее всего будет
по-прежнему использовать обычный режим обработки.
Если обработка отличается от обычной, программа должна при старте сама изменить эти параметры.
В стандартную библиотеку заведены константы для кодов функции ClickWhat
и некоторые коды виртуальных клавиш
для функции ClickButton.
Эти константы позволят сделать код анализа пользовательского ввода более читабельным и понятным.
Наиболее часто будут использоваться константы
cw_MouseDown и
VK_LBUTTON
Модифицирован шаблон template.pas,
в который добавлен код нового стиля обработки пользовательского ввода (процедура GUIHandler),
а также код для обработки диалогов редактирования (функцией edit).
Предыдущий шаблон cохранен под именем
template2.pas.
Код шаблона задает образец, по которому следует создавать прикладные программы.
В DAQ Pascal и стандартную библиотеку заведены очень полезные функции общего назначения,
позволяющие увеличить надежность, скорость и безопасность программ:
strfetch,
cookiescan,
TextVarScan.
Стандартная библиотека модифицирована с учетом новых функций с целью повышения надежности.
Стандартные сервера тоже модифицированы с использованием новых функций (особенно strFetch).
В стандартную библиотеку заведена новая команда @DimGuiClick,
которая служит для поддержки распределенных систем на основе DIM сервера.
Она принимает от сервера &DimSrv данные об удаленном пользовательском событии
и записывает их в локальную очередь событий.
Записанные события можно обрабатывать с помощью тех же функций, что и обычные события.
Для различения локальных и удаленных событий служат функции ClickIsLocal, ClickIsRemote.
При этом для анализа события используются одни и те же функции (типа ClickButton).
Команда @DimGuiClick становится доступной после вызова функции
DIM_GuiClickInit.
Даны рекомендации,
помогающие в создании распределенных DIM-систем.
Задача создания библиотеки для упрощения создания распределенных систем выглядит решенной, в первом приближении.
Процедура создания распределенных систем все еще остается существенно сложнее локальных, но эти сложности, как представляется,
носят уже логический характер, т.к. надо тщательно продумывать, где (на сервере или клиенте) и что будет выполняться.
Все библиотечные функции для реализации распределенных систем готовы.
Обновлена конфигурация DEMO_DOZA (вариант c DIM-сервером).
Это образцовый вариант распределенной системы с DIM сервером, который предлагается использовать
как работающий шаблон для других распределенных систем, а также драйверов ModBus.
Эта конфигурация не перегружена большим числом DIM тегов (их там всего несколько),
однако основные возможности DIM сервера используются.
На этом примере можно изучать новые возможности DIM и принципы построения распределенных систем
с графическим интерфейсом.
Конфигурация использует локальный DIM DNS ( т.е. DIM_DNS_NODE=. ).
Это значит, что при запуске сервера и клиента на одной машине всё должно работать сразу.
А при запуске клиента на удаленной машине надо указать в качестве
DIM_DNS_NODE компьютер сервера.
31.10.2018
@testbench time-diff time-sync ping-scan
Главными достижениями данного выпуска являются:
команды @testbench, time-diff, time-sync, ping-scan,
оценки эффективности работы потоков различного типа,
добавление общей частоты потоков в Монитор Ресурсов.
В окно консоли Монитор Ресурсов в самом низу добавлена строка All Polling Threads.
Там отображается суммарная нагрузка и частота всех контролируемых потоков опроса (TPolling),
которые есть в программе. Кроме них есть еще основной поток и могут быть другие служебные потоки,
но загрузка и частота по ним обычно пренебрежимо мала.
Суммарную частоту опроса потоков опроса особенно полезно видеть при анализе работы потоков системы.
Тесты показали, что нагрузка процессора остается низкой при суммарной частоте потоков до 200 кГц
(конкретная цифра зависит от процессора).
При более высоких суммарных частотах накладные расходы на переключение потоков
становятся все более заметными и быстро растут с повышением частоты.
Для тестирования и демонстрации работы потоков опроса (TPolling) добавлена команда @testbench:
Тест ping-pong создает два потока опроса (TPolling), которые с максимально возможной
скоростью передают управление друг другу.
Тест используется для анализа накладных расходов на переключение потоков и на управление ими.
Объект опроса потоков (TPolling) отличается от "чистого" потока (TThread)
дополнительным сервисом - обработкой асинхронных событий, ведением статистики,
наличием программного сторожевого таймера (watchdog) и т.д.
Объекты опроса потоков (TPolling) составляют основу потоковой модели CRW-DAQ,
поэтому так интересны оценки её производительности.
Тест multi-polling создает много рабочих потоков (TPolling),
которые ничего содержательного не делают (имеют пустую процедуру обработки),
однако содержат всю служебную инфраструктуру, включая ведение статистики, сторожевой таймер и т.д.
Тест используется для анализа накладных расходов на создание и поддержание работы
большого числа потоков и управление ими.
Для тестирования и демонстрации работы потоков добавлена также тестовая программа
pingpong.exe, в которой два потока с максимально возможной
скоростью передают управление друг другу.
Программа используется для анализа накладных расходов на переключение потоков и на управление ими.
В данной программе (в отличие от команды @testbench ping-pong) работа потоков (TThread)
происходит "вчистую", без накладных расходов на ведение статистики, работу сторожевого таймера (watchdog) и т.д.
Тестирование различных вариантов потоков показало примерно такие (очень грубые) оценки
(CPU i3,2GHz,2Core,4Threads):
Context Switch (lat_ctx) - 4000 kHz, 0.25 mks "Чистые" затраты на переключение потоков без синхронизации
ping-pong.exe - 415 kHz, 2.5 mks "Чистые" затраты на переключение потоков с синхронизацией
@testbench ping-pong - 282 kHz, 3.5 mks Затраты на переключение потоков с синхронизацией и сервисом (статистика,watchdog)
@testbench multi-polling - 250 kHz, 4 mks 500 потоков (TPolling) с частотой 500 Hz и с сервисом (статистика,watchdog)
DEMO_TESTSEND devSend - 63 kHz, 16 mks Затраты на переключение и работу потоков DaqPascal с передачей сообщений
Тестирование позволяет сделать следующие выводы:
Время (lat_ctx, latency of context switch) на "чистое" переключение контекста потоков,
расчитанное по разнице времени выполнения одинаковых действий в однопоточном цикле
и в режиме частого пререключения контекста составляет около 0.25 мкс (250 нс).
Это существенно меньше времени операций синхронизации (ожидание события,
досрочное пробуждение потока по событию и т.д.).
Операции синхронизации (ожидание событий, досрочное пробуждение,
принудительное переключение контекста потоков) отнимают около 1 мкс,
что существенно больше времени переключения контекста самого по себе.
1 мкс - это типичное (минимальное) время для любого системного вызова Windows.
Такое (относительно) большое время связано с переходом в защищенный режим ядра и возврат в режим пользователя.
Однако, с другой стороны, использования операций синхронизации избежать нельзя,
т.к. синхронизация потоков необходима для реализации логики работы системы.
Можно только минимизировать число операций синхронизации.
Синхронизация потоков включает минимум две операции синхронизации (т.е. 2 системных вызова)
- ожидание события (приемник) и возбуждение события (передатчик).
Отсюда и возникает наблюдаемое значение около 2.5 мкс.
Сервис потоков опроса (TPolling), связанный с ведением статистики, сторожевым таймером и т.д.,
имеет ощутимые, но сравнительно небольшие дополнительные расходы (3.5 против 2.5 мкс).
При большом числе потоков (500 потоков с частотой 500 Hz) накладные расходы
остаются не таком же уровне (порядка 4 мкс на переключение).
Цикл опроса программ DaqPascal, связанный с посылкой, получением и обработкой сообщений,
стоит сравнительно дорого (16 против 4 мкс).
Это расходы на пробуждение потока, вызов DaqPascal, чтение и анализ потока ввода (StdIn) и т.д.
Поэтому злоупотреблять синхронными сообщениями (devSend) не стоит, т.к. это увеличивает
частоту операций синхронизации и переключения потоков.
Большие потоки данных лучше обрабатывать через неблокирующие сообщения (devPost), кривые и теги.
На этом вопрос оценки производительности многопоточной модели (пока) закрыт.
Эти оценки имеют значение при планировании и разработке архитектуры систем
(сколько потоков делать, как они будут взаимодействовать).
Важным вопросом при работе распределенных сетевых систем управления является синхронизация часов
на разных компьютерах.
Для синхронизации часов используется протокол NTP (net time protocol).
При наличии сети Internet синхронизация ведется по часам специальных NTP-серверов,
например, pool.ntp.org.
В локальной сети без Internet в качестве NTP-сервера должен работать один из компьютеров,
с которым будут синхронизоваться остальные NTP-клиенты.
При наличии домена NTP-сервером обычно становится сервер домена.
При работе в рабочих группах NTP-сервером назначается одна из машин (которая постоянно доступна).
Так или иначе, Служба Времени Windows по имени W32Time должна быть специальным образом
сконфигурирована, причем по разному для NTP-клиентов и локального NTP-сервера.
Кроме того, на NTP-сервере должен быть сконфигурирован также Firewall,
т.к. NTP-серверу надо разрешить входящие сообщения на порт UDP:123
для работы службы NTP.
Необходимы также средства диагностики для оценки разницы времен на разных компьютерах.
Вопреки ожиданиям, удобных графических средств настройки службы времени в Windows найти не удалось.
Правда, служба времени автоматически как-то настраивается при работе в домене,
но и там для изменения настроек приходится использовать консоль.
Стандартный диалог "Синхронизации времени по Internet" мало что дает,
т.к. там фактически периодически (обычно раз в неделю) делается принудительная переустановка времени,
вроде такой:
net time \\server узнать время по часам server
net time \\server /set задать время по часам server
При этом время меняется "скачком", а это нехорошо для систем управления.
Служба Времени Windows как и любая другая реализация NTP умеет синхронизировать часы "плавно",
без скачков, за счет изменения расчетной частоты тактов, однако для её настройки есть только консольные утилиты:
w32time - имя службы времени
w32tm - настройка службы времени
net start w32time - для запуска службы времени
net stop w32time - для остановки службы времени
sc - для настройки сервиса w32time
netsh - для настройки Windows firewall
Причем синтакис команд довольно сложный.
Стало ясно, что надо сделать командные файлы, упрощающие настройку NTP.
Для конфигурирования и диагностики NTP-клиентов и NTP-сервера сделаны следующие командные утилиты,
вошедшие в сборки UnixUtils, CmdToolkit, Commander и Crw32-runtime:
time-diff - утилита для оценки разницы локального времени и часов NTP-сервера
tyme-diff - вызов справки
time-diff ru.pool.ntp.org - посмотреть разницу времени с часами сервера ru.pool.ntp.org
time-diff ru.pool.ntp.org? - то же самое, но с вызовом диалога для задания имени сервера
см. Типичный вывод команды time-diff:time-sync - утилита для настройки синхронизации NTP-клиентов и NTP-сервера
tyme-sync - вызов справки
time-sync ru.pool.ntp.org - перезапустить службу времени и синхронизировать NTP-клиент
с удаленным NTP-сервером (ru.pool.ntp.org)
time-sync time.dep0404.ru -r -l - переустановить (-r = reset) службу времени и синхронизировать NTP-клиент
с локально расположенным (-l = local) NTP-сервером (time.dep0404.ru)
time-sync time.dep0404.ru? -r -l - то же самое, но с вызовом диалога для задания имени сервера
time-sync ru.pool.ntp.org -r -s - переустановить службу времени и синхронизировать локальный NTP-сервер
(-s = server) с удаленным Internet-сервером (ru.pool.ntp.org)
time-sync time.dep0404.ru -f -l - синхронизировать NTP-клиент с локальным сервером (time.dep0404.ru)
принудительно (-f = force), без запроса подтверждения операции
Опции команды time-diff:
? - знак ? в конце имени сервера вызывает диалог для задания имени сервера
-r - reset - полная переустановка службы времени, при которой производится
сброс всех настроек службы времени в стандартные начальные значения
-l - local - указанный NTP-сервер расположен в локальной сети
-s - server - компьютер будет сконфигурирован как локальный NTP-сервер,
по которому смогут синхронизоваться другие компьютеры в локальной сети
-f - force - подавляет диалог запроса подтверждения операции синхронизации
см. Типичный вывод команды time-sync:
Команда time-sync выполняется довольно долго (около минуты) и перезапускает/переустанавливает
службу времени, синхронизирует локальное время с временем сервера, настраивает службу времени
и приводит подробную информацию о настройках службы времени, а также при необходимости
настраивает Firewall. В конце выдается оценка разницы локального времени и сервера.
Если настройка time-sync прошла успешно, корректировать часы больше не придется,
т.к. служба времени будет периодически плавно, без рывков подстраивать часы так, чтобы
локальное время было синхронизовано с NTP-сервером как можно точнее.
Останется только периодически проверять вызовом time-diff "уход" локальных часов от часов сервера.
Это надо периодически делать, т.к. при разнице часов более 5 минут (300 сек) синхронизация
"срывается" и клиент более не синхронизуется с сервером.
В этом случае надо повторить time-sync синхронизацию вручную.
Для удобства настройки сетевых систем управления команды синхронизации времени добавлены в
Инструменты\Консольные утилиты пакета Crw32, а также в сетевые инструменты Commander.
Главными достижениями данного выпуска являются:
асинхронные сообщения (post) для снижения нагрузки процессора,
функции devPost,
devPostMsg,
devSendMsg,
демо конфигурация DEMO_TESTSEND,
исправление мелких недочетов, добавление новых стандартных консольных команд.
Этот выпуск, кроме устранения мелких недочетов, целиком посвящен механизму обмена сообщениями, одному из базовых средств DAQ-системы.
Мотивом послужило наблюдение резкого возрастания нагрузки процессора в некоторых ситуациях, связанных с интенсивным обменом сообщениями.
Предложен способ решения этой проблемы (функции devPost, devPostMsg, devPostCmd), описанные ниже.
Даны рекомендации по применению функций обмена сообщениями исходя из стоящих задач (минимизация времени задержки или нагрузки процессора).
Устранен недочет в реализации команды @silent, связанный с некорректной обработкой повторных команд @silent.
Например,
@silent @silent @run cmd
Такие повторения @silent могут возникать при пакетной обработке команд, когда аргументом команды служит
другая команда (например, при обработке правил в команде @integrity).
Раньше такие повторения вызывали ошибку.
Теперь повторение любого числа @silent рассматривается как один @silent и все работает корректно.
Устранен недочет в реализации окна Консоль Монитора Ресурсов, связанный с форматом частоты опроса потоков Poll/s.
При большой частоте опроса потоков таблица "ломалась" из-за длинных чисел. Устранено изменением формата вывода частоты.
Добавлена функция devPost,
аналогичная функции devSend,
однако отличающаяся способом синхронизации.
Функция devSend(dev,msg) помещает сообщение msg в очередь сообщений устройства-приемника dev,
а затем выполняет синхронизацию, т.е. "пробуждает" устройство dev для скорейшей обработки посланного сообщения.
"Пробуждение" означает, что поток устройства-приемника переходит в состояние активности (готовности к немедленному исполнению)
и помещается в очередь планировщика задач. Его исполнение начинается "досрочно", даже если время опроса по таймеру еще не пришло.
Синхронизация сокращает до минимума время задержки между посылкой сообщения устройством-источником и его обработкой устройством-приемником.
Если, например, приемник имеет более высокий приоритет, чем источник, то он при "пробуждении" немедленно "вытесняет" поток источника
и выполняет обработку буквально через несколько микросекунд (время переключения контекста и вызова обработчика).
Это можно использовать для синхронизации и управления потоками - например, при посылке пустого сообщения данные не передаются,
но досрочное "пробуждение" приемника происходит.
Таким образом, синхронизация уменьшает задержку обработки сообщения за счет досрочного "пробуждения" приемника.
Однако при этом возникает риск чрезмерного повышения частоты переключения контекста потоков
и возрастания нагрузки процессора.
Эта ситуация может возникать, если сообщения посылаются очень часто.
Тест (см. далее) показывает, что частота переключения потоков при интенсивном обмене сообщениями
может достигать десятков и даже сотен килоГерц, а нагрузка процессора может вырасти до 100%.
Однако минимизировать время задержки требуется отнюдь не всегда - иногда важнее снизить нагрузку.
В некоторых случаях требуется передача большого числа сообщений, однако задержка их обработки не критична,
и обработка может выполняться в обычном режиме - по таймеру.
Для этих случаев и создана функция devPost.
Функция devPost(dev,msg) помещает сообщение msg в очередь сообщений устройства-приемника dev асинхронно,
т.е. не выполняет синхронизацию и не "пробуждает" устройство dev.
Это значит, что сообщения будут накапливаться в буфере приемника, пока не придет ожидаемое время обработки по таймеру.
Устройство-приемник продолжает выполнение в обычном режиме, без досрочного пробуждения.
При этом эффекта увеличения частоты переключения потоков и нагрузки процессора не происходит.
Снижение нагрузки достигается ценой буферизации и возможного увеличения задержки между посылкой сообщения источником и его обработкой приемником.
Выбор того, какую функцию использовать, зависит от поставленной задачи.
Если для задачи критичным параметром является время задержки обработки сообщения, то следует использовать devSend.
Например, если сообщение управляет исполнительным физическим устройством через драйвер,
то лучше использовать devSend для ускорения срабатывания устройства.
Если время задержки не критично и допустима обычная обработка сообщений по таймеру, то следует использовать devPost,
так как это снижает частоту переключения потоков и уменьшает нагрузку процессора.
Например, при прорисовке окон (@winDraw, @winShow и т.д.) лучше использовать devPost,
т.к. задержка тут несущественна, а снижение нагрузки вполне уместно.
Добавлена функция devPostMsg,
аналогичная функции devPost,
только устройство передается по имени, а не по ссылке.
Добавлена функция devSendMsg,
аналогичная функции devSend,
только устройство передается по имени, а не по ссылке.
Эта функция является синонимом старой функции devMsg,
которая считается устаревшей, но сохранена для совместимости старых кодов.
В новых программах рекомендуется заменять DevMsg на DevSendMsg или DevPostMsg, в зависимости от задачи.
А еще лучше заменять на DevSend или DevPost (но это требует изменения кода с заменой имен устройств на ссылки).
Новая демо конфигурация DEMO_TESTSEND
(см. справку)
создана для иллюстрации и тестирования работы сообщений devMsg, devSend, devPost, devSendMsg, devPostMsg.
Она содержит два устройства (&TEST_SEND1, &TEST_SEND2),
которые, при включении тестирования консольной командой @Test n m,
начинают "игру в пинг-понг", т.е. непрерывно посылают друг другу сообщения
(точнее, в каждом кванте времени посылается пакет из m сообщений).
Частоту потоков и нагрузку процессора можно наблюдать через Окна\Консоль Монитора Ресурсов,
а также командой @CpuProfiler в консоли устройств &TEST_SEND1, &TEST_SEND2.
При посылке сообщений методом devSend (тест 1,2) или devMsg (тест 3,4) или devSendMsg (тест 7,8) происходит резкое возрастание частоты
переключения потоков до десятков килоГерц, а нагрузка процессора возрастает вплоть до 100 %.
Рост нагрузки возникает даже в том случае, если данные вообще не передаются (тест 1,3,7), а происходит только синхронизация,
при этом всё время процессора уходит на переключение потоков туда-сюда (с частотой десятки килоГерц).
Почему это возникает?
При использовании синхронных сообщений при каждой посылке сообщения приемник сообщения "пробуждается"
и сразу же посылает ответное сообщение, в свою очередь "пробуждающее" источник.
Такой непрерывный процесс взаимной посылки сообщений с "пробуждением" друг друга и приводит
к неожиданному (на первый взгляд) результату - резкому повышению частоты опроса потоков,
которые, только успев отослать сообщение и "заснуть", тут же снова "пробуждаются" ответным сообщением.
При посылке сообщений методом devPost (тест 5,6) или devPostMsg (тест 9,10)
никакого роста частоты переключения потоков не происходит,
а нагрузка процессора определяется потоком данных и остается низкой, пока объем данных невелик.
Это связано с тем, что при посылке асинхронных сообщений "пробуждения" приемника не происходит
и он выполняется в своем обычном режиме (по таймеру).
В стандартную библиотеку StdLibrary добавлена сервисная функция
devPostCmd, в дополнение к имеющейся функции
devSendCmd.
Эти функции удобны тем, что проверяют ссылку устройства и автоматически добавляют CRLF в конце команды,
а также фиксируют ошибку при сбое передачи данных.
Они применяются для удобства при посылке команд серверам или драйверам.
В стандартную библиотеку StdLibrary добавлена функция
DIM_Post, в дополнение к имеющейся функции
DIM_Send.
Кроме того, функция DIM_UpdateTag
теперь использует DIM_Post вместо DIM_Send для снижения нагрузки.
Функции используются для обмена данными через DIM-сервер.
К имеющимся стандартным консольным командам @DevMsg, @DevSend добавлены стандартные команды
@DevPost, @DevPostMsg, @DevSendMsg, соответствующие новым функциям обмена сообщениями.
Шпаргалка по функциям посылки сообщений:
| Функция | реализация | синхронизация | оптимальна | CRLF в конце | устройство | Рекомендуется для |
|-----------------------|----------------------------|------------|----------------|------------|--------------------------|
| devSend(dev,'msg') | DAQ Pascal | синхронно | по времени | надо добавлять | по ссылке | сообщений драйверам |
| devPost(dev,'msg') | DAQ Pascal | асинхронно | по CPU | надо добавлять | по ссылке | сообщений серверам |
| devMsg('dev msg') | DAQ Pascal | синхронно | по времени | надо добавлять | по имени | считается устаревшей |
| devSendMsg('dev msg') | DAQ Pascal | синхронно | по времени | надо добавлять | по имени | анализа CFG/INI/консоли |
| devPostMsg('dev msg') | DAQ Pascal | асинхронно | по CPU | надо добавлять | по имени | анализа CFG/INI/консоли |
| devSendCmd(dev,'msg') | StdLibrary | синхронно | по времени | автоматически | по ссылке | посылки команд драйверам |
| devPostCmd(dev,'msg') | StdLibrary | асинхронно | по CPU | автоматически | по ссылке | посылки команд серверам |
----------------------------------------------------------------------------------------------------------------------------
Стандартные сообщения: @DevMsg @DevSend @DevPost @DevSendMsg @DevPostMsg - работают как одноименные функции
В стандартных библиотеках часть вызовов @DevMsg, @DevSend заменена на вызовы @DevPost, @DevPostMsg.
Это сделано в тех случаях, где это показалось уместным для снижения нагрузки процессора, например:
- при обработке RunStartupScript, RunFinallyScript - чтобы сократить нагрузку при старте/остановке,
- при вызове функций Cron, DIM_UpdateTag (так как серверы &CronSrv, &DimSrv и так обычно
работают на высоких скоростях и их незачем дополнительно ускорять),
- при обработке команды @Async.
Другие вызовы пока оставлены как есть, от них вроде бы пока не ожидается проблем ввиду малого трафика.
В стандартных серверах
( &CronSrv, &DimSrv, &WebSrv, &PlotSrv, &OpcCln,
&VkbdSrv, UniVent, UniHeat )
произведена замена вызовов @DevMsg, @DevSend
на вызовы @DevPost, @DevSendMsg, @DevPostMsg - там, где это показалось уместным
по логике решаемых задач, для снижения нагрузки процессора.
Главными достижениями данного выпуска являются: увеличение длины идентификаторов DaqPascal,
улучшение обработки исключений, добавление средств отладки сценариев Painter(v),
исправление мелких ошибок и недочетов, добавление новых стандартных консольных команд.
Максимальная длина идентификаторов DaqPascal увеличена до 40.
Это должно снять проблему использования длинных имен переменных, которая порой всё еще возникала в прикладном программировании.
Значимого увеличения расходов памяти и времени компиляции из-за увеличения длины имен не замечено.
Устранены некоторые погрешности в обработке исключений.
Если точнее, убран избыточный вывод всплывающих диагностических сообщений в случае "безвредных" исключений.
Например, при отмене ввода DAT файла. Сообщения в консоль сохранены.
Устранены некоторые погрешности в цветах фонтов для сенсоров мнемосхем.
Раньше цвет фонтов сенсоров после загрузки всегда был черный, и менялся на заданный в поле LED только при обновлении тегов.
Теперь это исправлено.
Кроме того, теперь при подключении кривых цвет фонта не берется из кривой, а сохраняется таким, как задано в конфигурации.
Эти изменения призваны сделать вид сенсоров более предсказуемым.
Устранены некоторые погрешности в диалоге DAQ\Работа с окнами DAQ.
Там некорректно работали средства задания периодов обновления окон (графиков, таблиц, мнемосхем, спектров).
Задание периодов обновления, например, полезно для отладки сценариев Painter.
Во время отладки сценариев можно задавать большой период обновления мнемосхем,
чтобы избежать избыточного объема вывода в отладочный файл (см. ниже).
Добавлены программные средства отладки для сценариев Painter(v).
Отладочный вывод позволяет узнать имя окна, имя сенсора и местоположение ошибки, где она возникает.
Для управления отладочным выводом при ошибках сценариев сделана новая функция
SetDebugFlags(f),
которая задает битовые флаги отладки, см. описание функции.
Вызов функции делается однократно в начале секции [Circuit.StartupScript],
чтобы включить отладочный вывод как можно раньше.
Отладочный вывод происходит только при ошибках и делается в Главную Консоль, и/или в отладочный файл Temp\Debug.out.
Отладочный вывод надо временно включать при обнаружении ошибок сценариев, а затем после успешной отладки отключать,
чтобы избежать ненужного после отладки вывода в консоль и журнальный файл.
Также на время отладки полезно увеличить период обновления окон мнемосхем через диалог "DAQ\Работа с окнами DAQ",
чтобы снизить скорость потока сообщений об ошибках (если они есть).
Добавлены интерактивные средства отладки для сценариев Painter(v).
В меню "Вид\Отладка Painter" добавлены инструменты, позволяющие изменять флаги отладочного вывода
аналогично функции SetDebugFlags, только через диалог, а также вызывать утилиты для анализа работы
сценариев Painter (просмотр и слежение за файлом Temp\Debug.out, просмотр текущего состояния переменных Painter).
Обновлен библиотечный OPC-клиент &OpcCln.
Предприняты большие усилия по повышению его производительности в связи с тем,
что скоро ожидается его использование в разрабатываемых системах.
Соответственно обновлена ДЕМО конфигурация DEMO_OPC.
Добавлено много утилит в меню Инструменты\Консольные команды.
Например, теперь там есть команды задания приоритета процесса (PriorityClass), его привязки к процессорам (CPU Affinity),
частоты опроса потоков (setclockres) и другие полезные в работе команды.
Конечно, все эти команды в принципе можно набирать в консоли вручную, но это требует времени,
а кроме того, названия и синтаксис команд быстро забываются и их приходится каждый раз вспоминать.
Поэтому наиболее часто используемые команды полезно иметь под рукой в готовом виде.
Особенно следует отметить команды:
--Install Open With Menu : @run Resource\Crw32.Owmenu.cmd
--Uninstall Open With Menu : @run Resource\Crw32.Owmenu.cmd --uninstall
Эти команды добавляют в контекстное меню пункт "Open with C:\Crw2exe\Crw32.exe" для файлов .cfg;.crc;.cal;.dpr.
Это дает быстрый и удобный доступ к пакету в процессе разработки.
@Async cmd - Execute command cmd asynchronously.
@Speak s - Speak text s with speech engine.
@Voice s - Play sound s with wave sound player.
@DevMsg &d s - Send message s to device &d.
@DevSend &d s - Send message s to device &d.
@WinHide w - Hide window w.
@WinShow w - Show window w.
@WinDraw w|o - Draw window w with options o.
@WinSelect w - Show and select window w.
@SilentEval n - 0/1=verbose/silent @SysEval evaluation mode.
@SysEval ex - Evaluate expression ex globally, i.e. @Eval @System @Async ex.
@LoadIni - load params from INI file.
@SaveIni - save params to INI file.
Это значит, что теперь все эти команды будут доступны в консоли любой прикладной программы,
выполненной по шаблону template.pas,
который использует библиотеку StdLibrary.
Новыми в списке являются только две команды (@SysEval, @SilentEval), добавленные для удобства.
Перечисленные команды добавлены потому, что они часто используются в практике и многократно дублируются в прикладных программах.
Можно постепенно "вычищать" обработку этих команд из старого кода, т.к. теперь они реализованы на уровне библиотеки.
В новом коде теперь можно сократить число обрабатываемых команд, т.к. обработка стандартных команд уже есть.
Это сократит объем кода и уменьшит вероятность ошибок.
Добавление команд никак не должно сказаться на производительности, т.к. для обработки команд теперь используется
быстрый алгоритм анализа команд, основанный на хеш-таблицах.
Следует отметить, что добавление команд в библиотеку никак не скажется на работе созданных ранее программ,
т.к. стандартный обработчик вызывается в самом конце, когда все пользовательские команды уже обработаны.
Если в программе уже есть обработчик команды, то команда будет перехвачена и не дойдет до стандартного обработчика.
Например, реакция на команду @LoadIni может потребовать дополнительных операций после загрузки параметров,
в этом случае необходимо перехватывать команду и сделать её обработку по-своему.
Консольные команды, внесенные в стандартный обработчик, частично "вычищены" из библиотек и кода ДЕМО-конфигураций,
в частности, UniHeat, DEMO_UNIHEAT, DEMO_LINCORR, DEMO_OPC.
24.09.2018
GuiLib DEMO_PAINT_GUILIB _NBSP
Главными достижениями данного выпуска являются: обновление библиотеки GuiLib.
Обновлена библиотека GuiLib.
По предложению Н.Гурина улучшен дизайн элементов CheckBox и RadioButton.
Теперь они не обязаны иметь квадратные сенсоры, а могут иметь любые размеры,
и в свободном месте (справа от кнопки) на них можно делать надписи,
которые к тому же могут меняться в зависимости от состояния тега.
При этом вид самих кнопок CheckBox и RadioButton не зависит от отношения сторон сенсора - они всегда остаются квадратными.
Новый дизайн также позволяет использовать для фона библиотечные изображения ledbmp,
что снижает объем и число изображений в прикладных системах.
Для форматирования сообщений в библиотеку StdLib добавлен символ _NBSP = chr(160).
Это символ (UNICODE U+00A0: NO-BREAK SPACE) "неразрывного пробела", который можно использовать там, где в слове или фразе должен стоять пробел,
но восприниматься оно должно как одно слово (в том числе при выделении и анализе слов).
Другими словами, "неразрывный пробел" отображается как пробел, но считается "значимым символом" (не пробельным).
В частности, он может использоваться для маркировки начала или конца фразы, содержащей пробелы в начале или конце.
Такие фразы не подвергнутся обрезанию при прохождении фильтров, удаляющих незначащие пробелы, т.к. _NBSP является значащим символом.
В URL-кодировке, которая часто используется в CRC-файлах, "неразрывный пробел" обозначается символом %A0.
Например, если нужно напечатать на сенсоре фразу, содержащую пробелы в начале или конце фразы,
то возникает проблема фильтрации - при чтении конфигурации незначащие пробелы в начале и конце фразы удаляются.
Удаление пробелов приводит к смещению положения надписи (т.к. она центрируется в поле сенсора).
Неразрывный пробел позволяет избежать этой проблемы:
[SensorList]
Sensor = DEMO
[DEMO]
Pos = 10 10
Tag#1 = 0, ~~\Resource\DaqSite\StdLib\Bitmaps\ledbmp_4_10_4_silver_ptmono.bmp %A0+1
Hint = Надпись « 1» с двумя пробелами впереди
[]
Наличие двух пробелов впереди слова приведет к тому, что надпись « 1» будет находиться в сенсоре справа, а не в центре.
Использование неразрывного пробела позволяет правильно форматировать элементы CheckBox и RadioButton с надписями.
Точнее, в надпись надо вставлять пробелы впереди, чтобы надпись была смещена и не налезала на изображение кнопки.
Обновлена демо конфигурация DEMO_PAINT_GUILIB.
В ней продемонстрированы новые возможности библиотеки GuiLib, а также использование "неразрывного пробела".
Главными достижениями данного выпуска являются: дополнение и уточнение
средств поддержки многомониторных систем, включая константы
screen_monitornumber, screen_monitorprimary, screen_colordepth,
screen_worktop, screen_workleft,
screen_workwidth, screen_workheight,
screen_monitor0worktop, screen_monitor0workleft,
screen_monitor0workwidth, screen_monitor0workheight,
screen_monitor0flags, обработка событий WM_QUERYENDSESSION, WM_ENDSESSION
для корректного завершения работы программы,
обработка события WM_DISPLAYCHANGE для корректной смены разрешения экрана.
Уточнены (по документации и эмпирически) константы геометрии экрана, добавлены новые.
В результате получается примерно следующее:
@view screen создает список констант screen_xxx и возвращает число мониторов
@list cons печатает созданный список констант:
(в этом примере в системе два FullHD монитора, расположены горизонтально, основной монитор справа)
screen_colordepth = 32 цветовое разрешение экрана, бит/пиксель
screen_desktopheight = 1080 высота Рабочего Стола (виртуального экрана, включая все мониторы)
screen_desktopleft = -1920 левый край Рабочего Стола (виртуального экрана, включая все мониторы)
screen_desktoptop = 0 верхний край Рабочего Стола (виртуального экрана, включая все мониторы)
screen_desktopwidth = 3840 ширина Рабочего Стола (виртуального экрана, включая все мониторы)
screen_height = 1080 ширина основного экрана на основном (primary) мониторе
screen_monitor0flags = 0 флаги 0-го монитора (0-й бит указывает на primary монитор)
screen_monitor0height = 1080 высота 0-го монитора (в данном случае дополнительного)
screen_monitor0left = -1920 левый край 0-го монитора (в данном случае дополнительного)
screen_monitor0top = 0 верхний край 0-го монитора (в данном случае дополнительного)
screen_monitor0width = 1920 ширина 0-го монитора (в данном случае дополнительного)
screen_monitor0workheight = 1040 высота Рабочей Области (без Панели Задач) 0-го монитора
screen_monitor0workleft = -1920 левый край Рабочей Области (без Панели Задач) 0-го монитора
screen_monitor0worktop = 0 верхний край Рабочей Области (без Панели Задач) 0-го монитора
screen_monitor0workwidth = 1920 ширина Рабочей Области (без Панели Задач) 0-го монитора
screen_monitor1flags = 1 флаги 1-го монитора (0-й бит указывает на primary монитор)
screen_monitor1height = 1080 высота 1-го монитора (в данном случае основного)
screen_monitor1left = 0 левый край 1-го монитора (в данном случае основного)
screen_monitor1top = 0 верхний край 1-го монитора (в данном случае основного)
screen_monitor1width = 1920 ширина 1-го монитора (в данном случае основного)
screen_monitor1workheight = 1040 высота Рабочей Области (без Панели Задач) 1-го монитора
screen_monitor1workleft = 0 левый край Рабочей Области (без Панели Задач) 1-го монитора
screen_monitor1worktop = 0 верхний край Рабочей Области (без Панели Задач) 1-го монитора
screen_monitor1workwidth = 1920 ширина Рабочей Области (без Панели Задач) 1-го монитора
screen_monitorcount = 2 число мониторов; мониторы нумеруются в диапазоне 0..screen_monitorcount-1
screen_monitornumber = 0 номер текущего монитора программы в момент вызова @view screen
screen_monitorprimary = 1 номер основного (primary) монитора
screen_pixelsperinch = 96 разрешение экрана, пиксель/дюйм
screen_width = 1920 ширина основного экрана на основном (primary) мониторе
screen_workheight = 1040 высота Рабочей Области (без Панели Задач) основного экрана
screen_workleft = 0 левый край Рабочей Области (без Панели Задач) основного экрана
screen_worktop = 0 верхний край Рабочей Области (без Панели Задач) основного экрана
screen_workwidth = 1920 ширина Рабочей Области (без Панели Задач) основного экрана
systemdefaultuilanguage = 1049 идентификатор языка графического интерфейса операционной системы
userdefaultuilanguage = 1049 идентификатор языка графического интерфейса текущего пользователя
threaduilanguage = 1049 идентификатор языка графического интерфейса текущего процесса
systemdefaultlcid = 1049 идентификатор основной локали операционной системы
userdefaultlcid = 1049 идентификатор основной локали текущего пользователя
threadlocale = 1049 идентификатор локали текущего процесса
Идентификаторы языка интерфейса (UILanguage) связаны с тем, на каком языке выводятся надписи в GUI
Идентификаторы локали (lcid = locale identifier) определяяют язык и формат ввода-вывода,
задаваемый в Контрольной Панели\Язык и региональные стандарты
Для русского языка эти константы равны $419 = 1049
Примечания:
В системе может быть несколько (0..screen_monitorcount-1) мониторов (monitor0, monitor1, ...),
из которых один (номер screen_monitorprimary) является основным (primary) монитором
и ассоциируется с основным экраном (screen), всегда имеющим координаты (left,top)=(0,0).
При этом монитор номер screen_monitornumber указывает на текущий
(в момент вызова @view screen) монитор программы.
Каждый монитор имеет координаты/размеры (left, top, width, height)
и флаги (flags), при этом 0-й бит флагов маркирует основной primary монитор.
Основной экран (на основном мониторе), как и каждый монитор, имеет Рабочую Область (work),
из которой исключается служебная область - Панель Задач (taskbar), Главное Меню, Область Уведомлений (tray).
Окна работающих программ расположены именно в рабочих областях основного экрана и дополнительных мониторов.
Рабочие области могут (но не обязаны) совпадать с размерами мониторов.
Рабочий Стол (desktop), или виртуальный экран, объединяет (включает в себя) все мониторы.
Примеры расположения окон программы:
Нормализовать окно программы:
@view norm FormCrw32
Расположить программу во всей Рабочей Области основного экрана:
@view pos FormCrw32 %screen_workleft %screen_worktop %screen_workwidth %screen_workheight
Расположить программу во всей Рабочей Области 0-го монитора:
@view pos FormCrw32 %screen_monitor0workleft %screen_monitor0worktop %screen_monitor0workwidth %screen_monitor0workheight
Расположить программу в левой половине Рабочей Области 1-го монитора:
@view pos FormCrw32 %screen_monitor1workleft %screen_monitor1worktop %screen_monitor1workwidth/2 %screen_monitor1workheight
Расположить программу в правой половине Рабочей Области 1-го монитора:
@view pos FormCrw32 %screen_monitor1workleft+%screen_monitor1workwidth/2 %screen_monitor1worktop %screen_monitor1workwidth/2 %screen_monitor1workheight
При анализе работы программы обнаружено, что при смене разрешения экрана на некоторых системах
(например Win-7x32rus) происходит сбой отображения ("кракозябры" в меню из-за изменения фонтов).
Чтобы избежать этого, добавлена реакция на событие изменение разрешения экрана:
Обработчик события (кроме печати в Главную Консоль) посылает сообщение
@silent @integrity WIN32:WM_DISPLAYCHANGED w h c
с параметрами новой ширины (w), высоты (h) и цветового разрешения (с) экрана.
В секцию ~~\Crw32.ini [@integrity.DefaultRules]
добавлено правило для события WIN32:WM_DISPLAYCHANGE,
которое (пере)устанавливает фонты меню.
Это правило срабатывает при изменении разрешения экрана, если не загружена конфигурация DAQ.
В секцию ~~\Resource\DaqSite\Default\Integrity.cfg [@integrity.DefaultRules]
добавлено правило для события WIN32:WM_DISPLAYCHANGE,
которое (пере)устанавливает фонты меню.
Это правило срабатывает при изменении разрешения экрана, если загружена конфигурация DAQ
и в нее включена стандартная конфигурация ~~\Resource\DaqSite\Default\Integrity.cfg.
Сделана попытка обеспечить корректное завершение работы программы при завершении сессии Windows.
В предыдущих версиях при завершении Windows через кнопку Start или команду shutdown
программа принудительно (аварийно) завершалась, и это завершение никак нельзя было отличить от аварийного
завершения по ошибке.
В новой версии сделана попытка реализовать корректное завершение DAQ-системы и затем Crw32.exe.
При завершении сеанса Windows отправляет всем программам (окнам) два сообщения:
сначала WM_QUERYENDSESSION для уведомления и подтверждения возможности завершения сеанса,
а затем WM_ENDSESSION для принудительного завершения всех процессов.
Заметим, что в обычных условиях при попытке завершения программы Crw32.exe выдается предупреждение
и завершение процесса отвергается, если DAQ-система в это время работает.
Это предохраняет работу DAQ-системы от случайного непреднамеренного завершения работы.
Получение сообщения WM_QUERYENDSESSION означает, что операционная система готовится к завершению сессии,
и поэтому надо немедленно, без всяких условий, завершить работу DAQ-системы.
Поэтому обработчик сообщения WM_QUERYENDSESSION завершает (принудительно) работу DAQ-системы,
если она запущена, и посылает в Главную Консоль команду
@silent @integrity WIN32:WM_QUERYENDSESSION
для уведомления об этом событии.
Получение сообщения WM_ENDSESSION означает, что сессия уже находится в фазе завершения, поэтому
процесс должен в ближайшее время (не более 5 секунд) завершиться.
Поэтому обработчик сообщения WM_ENDSESSION завершает (принудительно) работу программы,
и посылает в Главную Консоль команду
@silent @integrity WIN32:WM_ENDSESSION
для уведомления об этом событии.
При обработке сообщения WM_ENDSESSION пользователю выдается окно уведомления о завершении работы программы,
а самой программе на проведение операций завершения работы дается время (в миллисекундах), взятое из параметра
Crw32.ini [System] EndingSessionDelay.
Таким образом, при завершении работы через кнопку Windows\Start или через команду shutdown
программа должна завершаться корректно, а в журнальном файле Temp\@IntegrityEvents.log
должна остаться запись типа такой:
Файл Temp\@IntegrityEvents.log:
...
2018.09.13-20:53:28=> enter.daq C:\CRW32EXE\DEMO\DEMO_PAINT_GUILIB\DEMOPAINT.CFG
2018.09.13-20:53:28=> Загружены правила Resource\DaqSite\Default\Integrity.cfg [@integrity.DefaultRules]
2018.09.13-20:53:51=> WIN32:WM_QUERYENDSESSION $0 $0
2018.09.13-20:53:51=> Загружены правила Crw32.ini [@integrity.DefaultRules]
2018.09.13-20:53:51=> leave.daq C:\CRW32EXE\DEMO\DEMO_PAINT_GUILIB\DEMOPAINT.CFG
2018.09.13-20:53:51=> WIN32:WM_ENDSESSION $1 $0
Второй параметр WIN32:WM_QUERYENDSESSION определяется способом завершения сессии:
$0 shutdown или reboot
$80000000 user logoff
Следует заметить, что алгоритм завершения работы программ при завершении сессии Windows
зависит также от настроек операционной системы.
Например, при определенных настройках Windows программы могут завершаться принудительно,
без предварительного уведомления, может меняться время ожидания завершения и т.д.
В этом случае сообщения WM_QUERYENDSESSION, WM_ENDSESSION, возможно, не будут корректно обрабатываться.
Поэтому, чтобы завершение работы программы было корректным, надо также убедиться,
что операционная система настроена правильно.
Добавлены параметры, влияющие на поведение программы при завершении сессии Windows.
Crw32.ini [System] ProcessShutdownLevel
Этот параметр меняется в диапазоне $100..$3FF (значение по умолчанию $280) и задает уровень завершения процесса
в списке процессов при завершении сессии Windows, при этом завершение процессов идет от высокого уровня
к более низким. Значение $3FF означает что процесс будет завершаться одним из первых.
Crw32.ini [System] ProcessShutdownForce
Включает принудительное завершение DAQ-системы при получении сообщения WM_QUERYENDSESSION.
Главными достижениями данного выпуска являются:
средства поддержки многомониторных систем, включая
добавление в интерпретатор Главной Консоли
констант processid, screen_width, screen_height,
screen_desktopwidth, screen_desktopheight, screen_desktopleft, screen_desktoptop,
screen_monitorcount, screen_monitor0top, screen_monitor0left,
screen_monitor0width, screen_monitor0height, ...
и команд @view title, @view pos, @view move, @view screen,
служащих для поддержки многомониторных систем и/или запуска пакета в заданном положении экрана.
В чем проблема работы в много-мониторных системах?
Проблема в том, что программа всегда запускается на основном (главном) мониторе (monitor0).
Если мониторов несколько, а запускать программу надо на другом (не основном) мониторе,
то главное окно программы надо после запуска переместить на другой монитор,
задав ему новые координаты, соответствующие нужному монитору.
Для этого надо иметь средства
Задания положения и размера окна,
Определения параметров экрана (размер виртуального экрана, число мониторов, координаты каждого монитора на виртуальном экране),
Однозначной идентификации разных экземпляров окон программы Crw32.exe (нужно в случае работы с главным окном из внешних программ).
Данный выпуск ставит задачей решение перечисленных задач.
В интерпретатор DaqScript добавлена константа ProcessId с идентификатором текущего процесса (PID).
Эта константа дублирует функцию getpid() и служит для подстановки значения PID в командах, например:
@echo pid=%ProcessId напечатает что-то вроде: pid=9805
Напоминаем, что выражение %xxx в командах DaqScript означает подстановку
значения переменной или константы xxx в виде строки.
Константа ProcessId добавлена для идентификации окон, как показано ниже.
В интерпретатор Главной Консоли добавлены команды @view title, @view pos, @view move
служащие для работы с окнами (формами), включая основную форму с именем FormCrw32.
Здесь имеются в виду внутренние имена окон/форм, под которыми они известны программе и которые не совпадают с заголовками окон.
Список имен окон/форм можно увидеть командой @view list.
Команда @View Title F T задает форме с именем F заголовок T (в виде строки).
Команда @View Pos F Left Top Width Height задает форме с именем F
положение Left,Top и размер Width,Height.
При указании положения/размера можно использовать вычисляемые выражения и подстановки переменных/констант интерпретатора Главной Консоли.
При этом начальное положение формы сохраняется в константах view_pos_left, view_pos_top, view_pos_width, view_pos_height.
Если какой-либо параметр изменять не требуется, то для сохранения исходного значения соответствующего параметра нужно в качестве нового значения поставить звездочку *.
Команда @View Move F Left Top Width Height задает форме с именем F
смещение положения Left,Top и изменение размера Width,Height.
При указании положения/размера можно использовать вычисляемые выражения и подстановки переменных/констант интерпретатора Главной Консоли.
При этом начальное положение формы сохраняется в константах view_pos_left, view_pos_top, view_pos_width, view_pos_height.
Если какой-либо параметр изменять не требуется, то для сохранения исходного значения соответствующего параметра нужно в качестве нового значения поставить звездочку *.
Например:
@view title FormCrw32 CRW32 #%ProcessId задает заголовок главного окна Crw32.exe
используя PID, например: CRW32 #9805
@view pos FormCrw32 100 200 800 600 задает положение/размер окна Crw32:
Left=100, Top=200, Width=800, Height=600
для сохранения текущего положения/размера надо задать *
@view pos FormCrw32 * * 800 600 задать размер главного окна 800x600 не изменяя положения
минимальный размер FormCrw32 равен 740x560
@view pos FormCrw32 прочитать положение/размер окна (не меняя их) в константы
view_pos_left, view_pos_top, view_pos_width, view_pos_height
@view move FormCrw32 10 20 30 40 переместить/расширить окно FormCrw32:
Left+=10, Top+=20, Width+=30, Height+=40
если положение/размер не надо менять, задается *
@view move FormCrw32 10 * 100 * сдвинуть окно на 10 и расширить на 100 по горизонтали
не меняя положения/размера по вертикали
@view pos FormCrw32 %screen_width/4 %screen_height/4 %screen_width/2 %screen_height/2
расположить окно в полэкрана в центре экрана
Примечания:
1) Имя главного окна Crw32.exe в команде @view равно FormCrw32
2) Минимальный размер окна FormCrw32 в данной версии программы равен 740x560
3) Начальное положение/размер окна (формы) при каждом вызове команд @view pos, @view move
сохраняется в константах view_pos_left, view_pos_top, view_pos_width, view_pos_height
4) В параметрах положения (@view pos, @view move) можно использовать выражения и подстановки констант экрана,
например: @view pos FormCrw32 %screen_width/4 %screen_height/4 %screen_width/2 %screen_height/2
следует обратить внимание на необходимость подстановки значения
(%screen_width вместо screen_width), чтобы выражение сработало
Команда
@silent @view title FormCrw32 CRW32 #%ProcessId
добавлена в Crw32.ini [System.StartupScript].
Это значит, что главное окно Crw32.exe будет иметь имя типа CRW32 #PID с номером процесса PID.
Это позволит отличать одно окно Crw32.exe от другого в списке процессов и обращаться к ним по именам.
Дочерние процессы, запущенные из пакета, наследуют PID через переменную окружения CRW_DAQ_SYS_EXE_PID.
Это позволит дочерним процессам находить окно программы и взаимодействовать с ним.
Включение идентификатора процесса в имя окна гарантирует его уникальность.
В интерпретатор DaqScript добавлена команда @view screen для чтения параметров экрана.
Например:
@view screen создает список констант screen_xxx и возвращает число мониторов
@list cons печатает созданный список констант:
screen_desktopheight = 1013 высота Рабочего Стола
screen_desktopleft = 0 левый край Рабочего Стола
screen_desktoptop = 0 верхний край Рабочего Стола
screen_desktopwidth = 1871 ширина Рабочего Стола
screen_height = 1013 высота экрана
screen_monitor0height = 1013 высота 0-го (главного) монитора
screen_monitor0left = 0 левый край 0-го (главного) монитора
screen_monitor0top = 0 верхний край 0-го (главного) монитора
screen_monitor0width = 1871 ширина 0-го (главного) монитора
screen_monitorcount = 1 число мониторов
screen_pixelsperinch = 96 разрешение монитора пиксель/дюйм
screen_width = 1871 ширина экрана
Команда
@silent @view screen
добавлена в Crw32.ini [System.StartupScript].
Это значит, что параметры экрана считываются при старте программы и будут доступны в константах screen_xxx,
перечисленных выше.
Это позволяет создавать скрипты, использующие параметры экрана для работы с окнами.
Сделана реакция на сообщение WM_DISPLAYCHANGE, которое посылается системой при изменении разрешения экрана.
При изменении размера экрана будет печататься сообщение в Главной Консоли с указанием нового разрешения экрана,
а также в Главную Консоль будет посылаться команда
@silent @view screen
для обновления констант screen_xxx.
Таким образом будет гарантирована актуальность этих констант при изменении разрешения экрана.
Новые команды интерпретатора DaqScript позволяют организовать работу программы в много-мониторных системах,
а также в системах, где требуется задавать фиксированное расположение одного или несколькох экземпляров Crw32.exe на экране.
При запуске конфигураций можно, например, задавать команды перемещения главного окна, типа такого:
[&CronSrv.StartupScript] ; скрипт для 2-мониторной системы 1920x1080, второй экран внизу
@Eval @System @Async @Silent @View norm FormCrw32 ; нормализовать главное окно Crw32.exe
@Eval @System @Async @Silent @View pos FormCrw32 0 1080 960 1080 ; перенести на второй (нижний) экран, заняв левую половину 2-го экрана
@Eval @System @Async @Silent @View max FormCrw32 ; максимизировать окно (если надо)
[]
Заметим, что в команде можно также использовать выражение вроде такого:
Этот фрагмент задает при старте системы размер (4/5 экрана) и положение (по центру экрана) для главного окна программы.
Для много-мониторных систем надо задавать координаты, соответствующие нужному экрану, используя экранные константы.
С помощью команды @IfComputerName можно задавать разные экранные режимы при работе на разных компьютерах,
если предполагается запускать пакет на машинах с разными мониторами.
Вызов AdmiLink по правой кнопке мыши. Сильно упрощает создание ярлыков.
Доработка инсталлятора.
Доработка интерфейса.
В пакет CmdToolkit перенесена часть функций UnixUtils,
добавлена минимальная конфигурация LUA, позволяющая создавать скрипты для Win32.
Это работа на перспективу, т.к. с пакетом CmdToolkit связаны большие планы на будущее развитие.
В частности, AdmiLink теперь входит в CmdToolkit и удален из других пакетов
кроме RunTime.
Добавлены полезные утилиты в пакеты CmdToolkit, UnixUtils:
AdmiLaunch.exe, HandleOpenWithMenu.cmd, Start-*.cmd.
AdmiLaunch -e cmd
--Вызвать cmd с повышением прав (As Administrator) с запросом пароля
call .CmdToolkit -c HandleOpenWithMenu -i Notepad -c Notepad.exe -e ".txt;.ini" -p "Open with Notepad..."
-- Добавляет в контекстное меню пункт "Open with Notepad..."
call .CmdToolkit -c Start-Firefox demo.htm
-- Стартует Firefox (отыскивает его расположение и вызывает)
и т.д.
call .CmdToolkit -l - просмотр всех утилит, для большинства которых доступен --help
Минимальные изменения в основном пакете Crw32:
он просто скомпилирован с обновленными библиотеками (_uac.pas,_task.pas),
а также добавлены картинки (AdmiLink,UAC) в библиотеку изображений.
Библиотеки были отредактированы для новой версии AdmiLink.
Обновлена демо конфигурация DEMO_MERA,
с драйвером вакуумметра МЕРАДАТ-ВИТ19ИТ1. Драйвер проверен на реальной аппаратуре.
Благодарность Николаю Гурину.
Главными достижениями данного выпуска являются:
обновление Commander,
реструктуризация дистрибутива,
новый пакет CmdToolkit,
цветная консоль ANSICON,
обновление библиотеки GuiLib,
обновление демо DEMO_PAINT_GUILIB.
Проведена модернизация сборки Commander: сделана более удобная среда для разработчиков.
Панель инструментов теперь содержит выпадающие кнопки, сгруппированные по разным темам.
Пакет CRW-DAQ теперь имеет полноценный инсталлятор: он регистрируется в реестре Windows\Uninstall
и виден в (де)инсталляторе Windows (Панель управления/Программы/Программы и компоненты).
Поскольку может быть несколько инсталляций пакета, пакет записывает себя под именем,
в котором содержится его путь, например:
CRW-DAQ in C:\Crw32exe
CRW-DAQ in D:\Crw32exe
Каждый экземпляр пакета рассматривается как отдельный продукт.
Инсталлятор Crw32-DemoDoc не создает свой раздел (он ставится поверх существующего),
но при инсталляции он обновляет оценку размера дистрибутива (см.ниже).
Проведена модернизация дистрибутива в целях обеспечения совместимости с (де)инсталлятором Windows
(Панель управления/Программы/Программы и компоненты).
Теперь в разделах инсталляции основных наших программ (Crw32, Commander, UnixUtils,
CmdToolkit) указываются: Издатель (Publisher) DaqGroupTeam, Комментарий (Comments),
Версия (DisplayVersion), равная дате создания пакета, и Размер (EstimatedSize),
равный размеру файлов в каталоге инсталляции.
Эти параметры видны в окне Программы и компоненты, что облегчает управление программными пакетами.
Проведена модернизация дистрибутива в целях обеспечения совместимости с новыми и старыми версиями Windows:
теперь многие пакеты имеют разные версии в зависимости от версии Windows.
Это касается, например: LibreOffice, FireFox, Chrome, AdobeReader.
Написаны инсталляционные скрипты, которые сами определяют какую версию надо ставить.
Добавлены также скрипты для запуска приложений вне зависимости от версии системы
(пути меняются, поэтому необходим поиск по ключевым признакам).
Всё проверялось на Windows-XP/7/10-32/64.
Проведена серьезная реструктуризация дистрибутива: добавлен новый пакет
CmdToolkit
(можно перевести как "командный инструментарий").
В него вынесены из других частей дистрибутива командные утилиты, связанные с консолью CMD,
(то есть полезные командные файлы *.bat, *.cmd), а также различные утилиты,
ориентированные на консоль CMD и/или оболочку (Shell, Explorer).
Например, теперь CmdAutoRun, CmdOpen, HashCheck стали частью пакета CmdToolkit.
Также добавлен пакет поддержки цветной консоли ANSICON, описанный ниже.
Одной из причин выделения пакета CmdToolkit стало желание уменьшить основной дистрибутив crw32-runtime,
путем перемещения посторонних утилит в другой пакет.
Другой причиной стало желание сократить исторически сложившееся дублирование компонентов в разных частях дистрибутива.
Например, библиотека системных скриптов CmdAutoRun содержалась сразу в трех пакетах
(UnixUtils, crw32-runtime, Commander), что затрудняло обновление и поддержку пакетов.
Предполагается, что пакет CmdToolkit будет сравнительно маленьким (несколько мегабайт)
и будет содержать минимальный набор самых полезных консольных программ и сценариев CMD,
необходимых для обеспечения работы измерительных систем и системного администрирования.
Предполагается также, что пакет CmdToolkit будет практически обязательным для установки,
и что он должен ставиться на чистую машину в первую очередь, чтобы нужные инструменты всегда были под рукой.
Установка тяжеловесных пакетов не всегда возможна и порой не целесообразна,
поэтому хотелось бы иметь легкий инструментарий, содержащий необходимый минимум.
Обновлена системная библиотека CmdAutoRun (теперь ставшаю частью пакета CmdToolkit).
Теперь она обеспечивает разный промпт (приглашение командной строки) в зависимости от прав пользователя:
cmd.exe Заходим в консоль
[C:\Crw32exe]$ Это промпт пользователя
[C:\Crw32exe]# Это промпт администратора
В пакет CmdToolkit добавлена библиотека ANSICON и утилита .cmdansicon,
которая обеспечивает цветную консоль.
Пример сеанса CMD:
cmd заходим в cmd
call .cmdansicon -h цветная справка
call .cmdansicon -t показать таблицу цветов
call .cmdansicon --prompt установить цветной промпт (приглашение командной строки)
call .cmdansicon --prompt --reset вернуть стандартный промпт
... и самое главное:
call .cmdansicon -p "Цветная печать: " -c e -p "Желтый " -c b -p "Синий " -c c -p "Красный" -n
exit
Выглядит это примерно так:
В будущем также возможно создание информационных окошек и инструментов на базе цветной консоли.
Они возможно войдут в CmdToolkit.
Обновлена библиотека GuiLib.
Добавлен элемент от Николая Гурина Painter(v).GuiLib.ProgressBar для отображения "прогресса".
Обновлена демо конфигурация DEMO_PAINT_GUILIB,
для иллюстрирации функций Painter(v)
и библиотеки GuiLib.
Добавлены элементы Painter(v).GuiLib.ProgressBar.
Добавлен пример DEMO_E440, который содержит драйвер карты E440.
Для конфигурирования надо отредактировать файл E440_CTRL.CMD, и затем запустить его.
Карта аналогична E140.
Главными достижениями данного выпуска являются: расширение библиотеки хеш-функций (включая CRC-8/16/32),
калькулятор CRC, обновление стандартной библиотеки, драйвер источника питания INTEK.
Обновлена демо конфигурация DEMO_PID.
Обновленная версия послужит основой для UniPid.
Добавлена демо конфигурация DEMO_INTEK.
Она содержит драйвер высоковольтного источника питания с протоколом MODBUS.
Добавлен калькулятор CRC.
Он может вычислять котрольные суммы по нескольким десяткам вариантов алгоритма CRC-8/16/32.
См. также тут и там.
Обновлена библиотека _hash.pas.
В неё добавлено много (более 40) новых алгоритмов хеширования, включая контрольные суммы CRC-8/16/32, MODBUS/LRC, MODBUS/CRC, HART, DCON и т.д.
Это значит, что теперь контрольные суммы для многих протоколов (MODBUS/ASCII, MODBUS/RTU, HART и т.д.) можно вычислять
с помощью функции hashindexof.
Библиотека будет пополняться по мере необходимости.
Обновлена функция paramstr, в которой добавлены параметры
HasherCode (кодовый номер хеш-функции по имени алгоритма),
HasherName (имя хеш-функции по номеру):
// Вычислить контрольную сумму MODBUS/RTU
hid:=iValDef(ParamStr('HasherCode Crc16Modbus'),-1); // получить код хеш-функции CRC-16/MODBUS по имени
if hid<0 then Trouble('Алгоритм не найден'); // проверить допустимость кода хеш-функции
checksum:=HashIndexOf(data,0,hid); // вычислить контрольную сумму
// Получить список имен хеш-функций
i:=0;
while (i<256) do begin
s:=ParamStr('HasherName '+Str(i));
if s='' then i:=256 else writeln(i:3,' ',s);
i:=i+1;
end;
// Некоторые имена алгоритмов для индексирования и расчета контрольных сумм:
Имя Назначение Комментарий
RS индексирование строк основной алгоритм для индексирования
RS_W2 индексирование строк основной вариант для длинных строк
RS_W4 индексирование строк основной вариант для длинных строк
SDBM индексирование строк запасной вариант для индексирования
SDBM_W2 индексирование строк запасной вариант для длинных строк
Crc16Modbus MODBUS/RTU основная версия
ModbusCrc MODBUS/RTU другая реализация
ModbusLrc MODBUS/ASCII
HART HART protocol
Crc32Mpeg2 CRC-32/MPEG-2
Новая библиотека хеш-функций для расчета контрольных сумм позволит облегчить поддержку многих протоколов
обмена данными, в которых встречается расчет контрольных сумм.
Для тестирования производительности новой версии функций была выполнена следующая процедура,
расчитывающая контрольную сумму MODBUS/RTU по новому и старому алгоритму:
procedure NetBench; // Тест скорости расчета modbus_calc_crc
const testdata='123456789'; var ms:Real; i,n,m,h:integer;
begin
n:=1000000; // задаем число итераций
m:=hid_NetModbusCrc; // сохраняем код хеш-функции
ms:=msecnow; for i:=1 to n do h:=modbus_calc_crc(testdata); ms:=msecnow-ms;
writeln('CRC new '+StrFix(n/ms/1000,1,3)+' Mops');
hid_NetModbusCrc:=-1; // задаем старый алгоритм расчета контрольной суммы
ms:=msecnow; for i:=1 to n do h:=modbus_calc_crc(testdata); ms:=msecnow-ms;
writeln('CRC old '+StrFix(n/ms/1000,1,3)+' Mops');
hid_NetModbusCrc:=m; // возвращаем код хеш-функции
end;
Результат (для процессора Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz):
CRC new 2.062 Mops
CRC old 0.184 Mops
Как видно из результата, расчет по новому алгоритму (с использованием библиотеки хеширования)
более чем в 10 раз быстрее, чем по старому.
Переключение между старым и новым алгоритмом происходит с помощью переменных
hid_NetModbusLrc,
hid_NetModbusСrc,
которым при старте присваивается значение:
Для возврата к старому алгоритму надо присвоить этим переменным значения -1.
Возможность возврата к старому программному коду сделана из соображений сохранения обратной совместимости
и для сохранения полезного старого программного кода, который может быть использован для новых разработок.
03.02.2018
DEMO_DMCS SCPI DJVU-Spec _COLORS.PAS ParamStr
Главными достижениями данного выпуска являются: обновление сборки,
модуль для работы с цветами по именам, изменение описания фонтов,
драйвер источника питания Sorensen SGI с протоколом SCPI.
Выполнено обновление сборки, обновлены commander (добавлена программа DJVU-spec для перевода PDF в DJVU),
office (OpenOffice, LibreOffice), netweb (Firefox), mmedia (Adobe Flash, KLCodekPack),
devel (обновлен FreePascal, Lazarus).
Обновлена система UniHeat.
Исправлены мелкие ошибки, слегка улучшен интерфейс пользователя.
Добавлен модуль _COLORS.PAS,
для работы с цветами по именам в программах Object Pascal (Delphi).
Цвета описаны тут.
Таблица имен такая же как используется в Painter(v).
В описании фонтов теперь можно использовать имена цветов и имена кодовых страниц вместо их кодов.
Например:
[StandardFont]
CharSet = RUSSIAN ; кодировка фонта ANSI=0,DEFAULT=1,RUSSIAN=204,OEM=255
Color = Black ; цвет фонта
Height = -13 ; высота фонта
Name = PT Mono ; название фонта
Pitch = Fixed ; ширина символов фонта Default/Fixed/Variable
Style = [] ; [Bold, Italic, Underline, StrikeOut]
[]
Таблица допустимых имен цветов - такая же как используется в Painter(v),
см. тут, только без префикса cl.
Допустимые имена кодировок см. тут,
только без суффикса _CHARSET.
Реально, вероятно, будут использоваться кодировки:
RUSSIAN (русская),
ANSI (английская),
DEFAULT (системная по умолчанию),
OEM (ДОС).
Использование имен цветов и кодировок вместо кодов сделает конфигурации более "читабельными".
В описании фонтов теперь можно использовать размеры шрифтов (Size) в пунктах (pt)
вместо базовой высоты шрифтов (Height) в пикселях (px). Обратите внимание, что
размер задается положительным числом, а высота - отрицательным (такие договоренности в Delphi,
почему - не знаю).
Например:
[StandardFont]
CharSet = RUSSIAN ; кодировка фонта ANSI=0,DEFAULT=1,RUSSIAN=204,OEM=255
Color = Black ; цвет фонта
Size = 10 ; размер фонта 10 pt
; Height = -13 ; соответствует базовой высоте фонта -13 px
Name = PT Mono ; название фонта
Pitch = Fixed ; ширина символов фонта Default/Fixed/Variable
Style = [] ; [Bold, Italic, Underline, StrikeOut]
[]
Зависимость высоты и размера фонта дается формулами:
Height = - ( Size * PPI / 72 )
Size = - ( Height * 72 / PPI )
PPI = Pixels Per Inch - вертикальное разрешение экрана, точек на дюйм.
В пакете всегда используется стандартное разрешение = 96 PPI.
Название Height ("базовая высота шрифта") не должно обманывать - реальная высота текста
отличается от базовой. Например, для фонта PT_Mono с высотой -13 реальная высота
текста будет 15 px. Таким образом, базовая высота шрифта задает некоторую характерную
величину размера большинства символов, которая несколько меньше реальной высоты текста.
Увеличение реальной высоты шрифта получается за счет вертикальных "пробелов" между символами
и "хвостиков", которые есть у некоторых символов.
Надо сказать, что указание базовой высоты шрифта в пикселях для мнемосхем все же предпочтительнее,
т.к. более "переносимо", в смысле пиксельного размера шрифтов, которые "вписываются" в сенсоры
с фиксированным пиксельным размером.
Указание размера шрифта в пунктах более подходит для документов, где более важен реальный
(не в пикселях, а в дюймах или сантиметрах) размер символов.
Однако во всех редакторах размер шрифтов указывается именно в пунктах, поэтому работать с ним удобнее.
При работе со стандартным разрешением 96 PPI проблем быть не должно,
а вот при работе с нестандартным значением PPI могут возникнуть проблемы.
В пакете для расчета размеров фонтов всегда (независимо от разрешения экрана) используется
стандартное разрешение 96 PPI.
Это сделано потому, что мнемосхемы имеют фиксированный пиксельный размер,
а значит фонты тоже должны быть заданы в привязке к пикселям.
В описании сенсоров - полей вывода LED = ... теперь допускается прямое описание фонтов.
Теперь описание фонта - это либо ссылка на секцию в квадратных скобках [...], либо прямое описание фонта.
Прямое описание фонта может быть сокращенным (см. правила описания ниже).
Таким образом, имеем такие формы описания:
1) Секционное описание фонта:
LED = 7, 3, 0, %7.3g, [LedFont]
...
[LedFont]
CharSet = RUSSIAN ; кодировка фонта ANSI=0,DEFAULT=1,RUSSIAN=204,OEM=255
Color = Black ; цвет фонта
Height = -13 ; высота фонта, px
; Size = 10 ; или размер, pt
Name = PT Mono ; название фонта
Pitch = Fixed ; ширина символов фонта Default/Fixed/Variable
Style = [Bold] ; [Bold, Italic, Underline, StrikeOut]
[]
2) Прямое полное описание фонта:
LED = 7, 3, 0, %7.3g, Charset:Russian\Color:Black\Size:10\Name:PT_Mono\Pitch:Fixed\Style:[Bold]\
3) Прямое сокращенное описание фонта:
LED = 7, 3, 0, %7.3g, Size:16\Style:[Bold]\
Если описание фонта НЕ заключено в квадратные скобки [...], то это описание интерпретируется
как прямое описание используемого для отображения фонта.
Описание фонта в этом случае имеет примерно такой вид:
LED = 7, 3, 0, %7.3g, Charset:Russian\Color:Black\Size:10\Name:PT_Mono\Pitch:Fixed\Style:[]\
Строка описания фонта интерпретируется следующим образом:
За основу берется стандартный фонт Crw32.ini [StandardFont]:
[StandardFont]
CharSet = RUSSIAN ; кодировка фонта ANSI=0,DEFAULT=1,RUSSIAN=204,OEM=255
Color = Black ; цвет фонта
Height = -13 ; высота фонта
Name = PT Mono ; название фонта
Pitch = Fixed ; ширина символов фонта Default/Fixed/Variable
Style = [] ; [Bold, Italic, Underline, StrikeOut]
[]
Это эквивалентно строке описания:
CharSet:RUSSIAN\Color:Black\Height:-13\Name:PT_Mono\Pitch:Fixed\Style:[]\
В строке описания производится замена символов:
«_» - на «» (пробел)
«\» - на «CRLF» (разделитель строк)
«/» - на «CRLF» (разделитель строк)
«|» - на «CRLF» (разделитель строк)
«:» - на « = » (знак равенства)
В результате получается текст, интерпретируемый аналогично тексту секции с описанием фонта.
В описании могут быть заданы не все параметры (сокращенное описание).
В этом случае пропущенные параметры берутся из стандартного фонта.
LED = 7, 3, 0, %7.3g, Size:16\Style:[Bold]\ - сокращенное описание фонта
Использование прямого и сокращенного описания фонта позволяет обойтись
без дополнительных секций описания фонтов при сохранении сравнительной компактности описания.
Подробнее см. описание формата *.CRC.
Обновлена демо конфигурация DEMO_MCA_SCAN.
Обновленная версия включает исправление ошибок и новый тип АЦП.
Добавлена демо конфигурация DEMO_DMCS.
Она включает в себя драйвер источника питания SORENSEN SGI DC,
который работает по протоколу SCPI
(Standard Commands for Programmable Instruments).
Этот протокол, стандартизованный в 1999, применяется в целом ряде лабораторных измерительных приборов,
типа источников питания, осциллографов, генераторов, мультиметров и т.д.
Данный драйвер может служить хорошим прототипом для других устройств с
протоколом SCPI.
Для иллюстрации применения прямого описания фонтов
см. dmcs_main_ctrl.crc.
Этот файл специально сделан с прямым описанием фонтов, так что секций с описаниями фонтов там вообще нет.
paramstr('ColorCode Red') = $0000FF // код цвета по имени, $1FFFFFF при отсутствии имени в базе
paramstr('ColorName $0000FF') = Red // имя цвета по коду, либо числовое представление $GGBBRR
paramstr('CharsetCode Russian') = 204 // кодовая страница символов по имени
paramstr('CharsetName 204') = RUSSIAN // имя по кодовой странице символов
paramstr('PitchCode Default') = 0 // код ширины фонта по имени
paramstr('PitchName 0') = Default // имя ширины фонта по коду
27.12.2017
ledbmp
Это финальная версия - 2017.
Всех поздравляю с наступающим Новым Годом и Рождеством.
Главными достижениями данного выпуска являются: утилита ledbmp.exe,
унификация графических полей (LED).
Давно хотелось унифицировать изображения (bmp) для числовых полей (LED).
Имевшиеся в библиотеке
Resource\DaqSite\StdLib\Bitmaps
числовые поля часто использовались, но на самом деле они не очень для этого подходят, т.к.
имеют ограниченный диапазон по цветам, размерам шрифтов, ширине текста, а также ряд явных ошибок.
Генерировались они вручную, т.е. во многом случайно, что и послужило причиной этих ошибок.
Так, например, поле _LED07C.BMP имеет высоту 14 px (пикселей),
хотя рассчитано на фонт PT Mono размером 10 pt, имеющий высоту 15 px,
из-за чего некоторые символы (например [] скобки) обрезаются снизу.
Стало ясно, что для системного решения проблемы нужен генератор, который расчитывает и создает
растровые изображения для числовых полей по заданным параметрам - ширине текста,
размеру фонта, цвету, имени фонта и т.д.
Такая утилита была создана и получила название ledbmp.
Создана утилита ledbmp,
которая добавлена в UnixUtils, а также Resource\Shell\.
Она служит для пакетного создания растровых изображений для числовых полей по заданным параметрам.
Имеется краткая справка.
Используется она так:
ledbmp --help - справка
ledbmp --colors - распечатать таблицу цветов
ledbmp 7 10 8 Aqua "PT Mono" - создать поле под 7 символов, шрифт "PT Mono" 10 pt, 8 bit, цвет Aqua
- результат записывается в файл ledbmp_7_10_8_aqua_ptmono.bmp
ledbmp 7 10 8 Red -oredled.bmp - создать поле под 7 символов, шрифт "PT Mono" 10 pt, 8 bit, цвет Red
- результат записать в файл redled.bmp
ledbmp w s d c f - общий синтаксис вызова
w - ширина текста, символов
s - размер шрифта, pt
d - глубина цвета, 1,2,4,8,15,16,24 бит
c - цвет изображения - число $BBGGRR или имя, см. ledbmp --colors
f - имя фонта которым будет отображаться поле
параметр w обязателен, остальные параметры по умолчанию равны:
s=10 pt, d=24 bit, c=White, f="PT Mono"
в результате работы утилиты генерируется файл ledbmp_w_s_d_c_f.bmp
например ledbmp_7_10_24_white_ptmono.bmp
при генерации имени файла цвет по возможности переводится в имя цвета
по таблице ledbmp --colors
кроме переречисленного утилита имеет расширенный синтаксис вызова
с многочисленными опциями, см. справку
По заданным в командной строке параметрам команда unix ledbmp генерирует растровое изображение,
размеры которого рассчитываются по заданному фонту (по умолчанию PT Mono),
подходящее для отображения числового поля с заданной шириной текста.
Утилита дает возможность генерировать изображения полей в любом количестве и без досадных ошибок.
Для полей рекомендуется использовать основную 16-цветную палитру, используемую в 4-битных изображениях:
Black ,
Maroon ,
Green ,
Olive ,
Navy ,
Purple ,
Teal ,
Gray - тёмная палитра
White .
Red ,
Lime ,
Yellow ,
Blue ,
Fuchsia ,
Aqua ,
Silver - светлая палитра
Остальные цвета тут. Они требуют более высокого цветового разрешения.
В библиотеку Resource\DaqSite\StdLib\Bitmaps
добавлен пакетный генератор полей
и созданная с его помощью библиотека наиболее часто используемых числовых полей
с шириной (1 .. 31), размерами фонтов (8 .. 28), 4 бит, цвета светлой палитры, фонт "PT Mono".
При использовании библиотеки следует учесть, что
ledbmp выдает точные размеры поля для заданной ширины текста и размера фонта.
Однако внешний вид полей улучшается, если справа и слева оставить свободное пространство в полсимвола,
чтобы одно поле четко отделялось от другого в случае их плотного расположения.
Поэтому рекомендуется брать поле на 1 символ больше, чем формат числового поля.
Например, для отображения поля LED = 7, 0, 0, %7.0f рекомендуется использовать
поле ~~\Resource\DaqSite\StdLib\Bitmaps\ledbmp_8_10_4_silver_ptmono.bmp.
Во всех случаях, когда требуется другое цветовое разрешение, другие размеры поля и т.д.
настоятельно рекомендуется генерировать поля вызовом unix ledbmp,
что устранит возможные ошибки и разночтения с числовыми полями.
Обновлена демо конфигурация DEMO_MAYAK.
Обновленная версия использует новую библиотеку полей, сгенерированных утилитой ledbmp.
Это пример использования этой библиотеки.
Главными достижениями данного выпуска являются: ускорение загрузки конфигурационных файлов в 4 - 5 раз,
увеличение длины идентификаторов DAQ Pascal до 20 символов.
Предприняты меры для ускорения загрузки конфигурационных файлов.
Для начала был проведен анализ задержек загрузки конфигурационных файлов.
Как выяснилось, основной вклад в задержку вносит проверка актуальности кеш-буферов конфигурационных файлов.
При чтении конфигурационных файлов их содержимое кешируется (сохраняется в памяти), чтобы избежать многократной
загрузки одних и тех же файлов.
Чтобы убедиться в актуальности файловых кешей, при каждом обращении к ReadIni проверялась
дата, размер и атрибуты файлов.
С учетом того, что в конфигурационных файлах содержатся вложенные файлы (через секцию [ConfigFileList]),
проверять приходилось довольно много файлов.
Как выяснилось, операции проверки даты, атрибутов и размеров файлов являются дорогостоящими,
и на эти проверки уходило около 60-80% времени загрузки.
Проблема была решена путем двойного кеширования и введения так называемого времени удержания кеша (config cache holding time),
то есть времени (по умолчанию принятого 100 мс), в течение которого кеш конфигурационных файлов сохраняет актуальность.
Кеш первого уровня хранит тексты читаемых секций, кеш второго уровня хранит тексты читаемых конфигурационных файлов.
Сначала делается попытка взять данные из кеша первого уровня, потом из второго, а потом уже - прочитать с диска.
Двойной кеш необходим потому, что секция (например, [DeviceList]) может содержаться сразу в нескольких файлах.
Возможна ситуация, когда одни файлы изменились, а другие нет, тогда секция "собирается" из всех кешированных файлов,
некоторые из которых могут браться готовыми из кеша, а другие (измененные) - перезагружаться.
Работает это так.
При чтении конфигураций (т.е. при обращении к ReadIni) проверяется наличие в кеше первого уровня
уже загруженной копии текста интересующей секции и время последнего обновления этого кеша.
Если кеш первого уровня еще актуален, то есть с момента последнего обновления прошло менее
ConfigCacheHoldingTime, то возвращается сохраненный в кеше первого уровня текст секции.
Это очень быстрая операция, т.к. кеш реализован через быстрые хеш-таблицы.
Если же кеш первого уровня потерял актуальность, то есть с момента его последнего обновления прошло
более ConfigCacheHoldingTime, то инициируется проверка актуальности данных в файловом кеше второго уровня.
При этом проверяется дата, размер и атрибуты файлов конфигураций, и при необходимости идет перезагрузка кешей.
Если файл конфигурации изменился, кеш второго уровня для данного файла перезагружается,
затем идет чтение секции из кеша второго уровня и обновление кеша первого уровня.
В результате частота проверки дат и атрибутов файлов ограничивается временем удержания кеша ConfigCacheHoldingTime,
что резко снижает загрузку процессора и снижает время загрузки конфигураций.
Ускорение возникает потому, что при чтении конфигураций данные в чаще всего берутся из кеш-буферов первого уровня
с помощью быстрых хеш-таблиц, и только изредка происходит обновление файловых кеш-буферов и еще реже - чтение файлов.
Для оперативного управления кешированием конфигурационных файлов введены также консольные команды:
@memory cfgcachehold - прочитать время удержания кеша ConfigCacheHoldingTime, мс
@memory cfgcachehold 100 - задать время удержания кеша ConfigCacheHoldingTime, мс
@memory cfgcachehash - прочитать метод хеширования кеш-буферов, 0..39, см. _hash.pas
@memory cfgcachehash 1 - задать номер метода хеширования кеш-буферов и инициализировать кеш
Эти команды позволяют управлять кешированием и хешированием в процессе работы.
Начальные настройки кеша и хеша задаются в секции [System.StartupScript].
Предельный размер кеш-буферов по умолчанию увеличен с 4 до 32 MB.
Управляется переменной Crw32.ini [System] ConfigCacheLimit,
а также командой @memory cfgcachelim.
Недостаточный объем кеша может замедлить загрузку больших конфигураций.
Современные компьютеры имеют достаточно большой объем памяти и экономия тут не очень нужна.
Для освобождения памяти после загрузки DAQ-конфигурации можно использовать команду
Для оценки результатов оптимизации загрузки конфигураций можно привести такую таблицу,
составленную при загрузке довольно большой конфигурации (DEMO_FAHT) с различных источников:
Конфигурация | Время загрузки, сек | Версия | Комментарий
-------------+---------------------+---------+--------------------------
!FAHT.CFG | 85 | Старая | Загрузка с локального HDD
!FAHT.CFG | 12 | Новая | Загрузка с локального HDD
!FAHT.CFG | 130 | Старая | Загрузка с сетевого диска
!FAHT.CFG | 25 | Новая | Загрузка с сетевого диска
-------------+---------------------+---------+--------------------------
Как видно, ускорение составляет до 5 - 7 раз.
Загрузка с сетевого диска всё равно идет медленнее, чем с диска, но времена загрузки
даже в этом случае получаются вполне приемлемыми.
Следует иметь в виду, что реализованное "кеширование с временем удержания" может иметь побочные эффекты.
Они связаны с тем, что при таком кешировании теряется возможность модификации конфигураций в процессе их загрузки.
Допустим, если при загрузке программа генерирует конфигурационный файл, который тут же загружается,
то при использовании кеширования такой метод работать не будет - точнее, потребует введения задержек для обновления кеша.
В старой версии это бы сработало, потому что актуальность файлового кеша проверялась при каждом вызове ReadIni.
При использовании кеша с удержанием актуальность кеша проверяется гораздо реже, что дает ускорение работы,
но и задержку обновления.
В принципе, у нас этот подход (модификация в процессе загрузки) по-моему, нигде пока не использовался,
но такой эффект надо иметь в виду.
Если по-каким-то причинам "кеширование с временем удержания" надо отключить, достаточно задать
переменную Crw32.ini [System] ConfigCacheHoldingTime = 0
или выполнить команду:
@memory cfgcachehold 0
При этом удержание кеша будет отключено и всё будет работать как раньше, то есть медленно, но с возможностью
модифицирования конфигурации в процессе её загрузки.
Для анализа работы кеша добавлена команда:
@memory cfgcacheshot - краткая сводка по кешу (Config Cache Snapshot)
@memory cfgcacheshot 0 - краткая сводка по кешу (Config Cache Snapshot)
@memory cfgcacheshot 1 - более подробная сводка по кешу (список секций и файлов)
@memory cfgcacheshot 2 - самая подробная сводка по кешу (полный текст, работает очень долго)
Эта команда позволяет увидеть имена секций и файлов, загруженных в кеш и статус их актуальности.
Длина идентификаторов DaqPascal увеличена с 16 до 20 символов.
Это связано с ростом объема библиотек и появлением в них более длинных идентификаторов.
Например, некоторые идентификаторы библиотеки NetLibrary уже превышают 16 символов.
При переходе на новую версию могут (хотя это маловероятно) возникнуть мелкие проблемы.
Так, были случаи, когда в прикладных программах использовались длинные идентификаторы с ошибками,
которые были не заметны из-за обрезания концов имен.
В принципе, ничто не мешает увеличить максимальную длину идентификатора ещё больше, но при этом возрастет
потребление памяти под таблицу идентификаторов и увеличивается время компиляции.
Поэтому будем увеличивать максимальную длину только по мере необходимости.
Главными достижениями данного выпуска являются: обновление библиотеки хеш-функций
_HASH.PAS, анализ качества и скорости работы хеш-функций,
выбор для работы основной хеш-функции, оптимизация хеш-таблиц и интерпретатора,
улучшение механизма обработки исключений через команду @OnException,
а также средства идентификации версий пакета.
Обновлена сборка СПО программ, в частности обновлены 7z, LibreOffice, Firefox, CodekPack.
Обновлена и расширена библиотека хеш-функций _HASH.PAS.
Проведена большая работа (см. hashbench.htm)
по анализу качества и производительности работы хеш-функций.
Хеш-функции проклассифицированы для использования в различных приложениях
(например, при работе с короткими и длинными ключами рекомендуется использовать разные функции).
По результатам выработано решение о том, какую хеш-функцию использовать в пакете в качестве основной
для работы интерпретатора и для индексации строк.
В качестве хеш-функции по умолчанию выбрана функция Hash32_RS (автор - Robert Sedgwicks),
которая показала хорошие результаты во всех проведенных тестах при относительно высокой скорости работы.
Независимые тесты (см. здесь) также показывают
хорошее качество этой функции на большинстве тестов.
В то же время функция простая и легко реализуемая.
Другие библиотеки хеширования см. здесь.
Сделана возможность выбора в качестве рабочей хеш-функции интерпретатора DaqScript
любую из библиотеки хеш-функций (управляется переменной [System] EvaluatorHasher).
Сделана возможность выбора в качестве рабочей хеш-функции для хеш-таблиц
любую из библиотеки хеш-функций (управляется переменной [System] THashListHasher).
Обновлена функция hashlist_init,
в которой теперь можно выбирать функцию хеширования - любую из библиотеки хеш-функций.
Проведена дополнительная оптимизация работы интерпретатора DaqScript и хеш-таблиц.
В рамках принятой модели данных (хеширование и двоичный поиск в отсортированном списке)
по всей видимости, достигнут потолок по производительности.
Изменен механизм обработки исключений (Exception).
Раньше в случае исключений просто печаталось сообщение в Главной Консоли.
Теперь обработка усложнилась. Прежде всего, выделены новые классы исключений:
ENiceException - "безопасное" программное исключение, с подробной диагностикой,
но без окна предупреждения и без журналирования (т.е. записи в журнальный файл).
Служит для "некритичных" ошибок, не представляющих серьезной угрозы.
Например, если не найден нужный, но не критически важный файл.
ESoftException - "безопасное" программное исключение, с менее подробной диагностикой,
без окна предупреждения и без журналирования (т.е. записи в журнальный файл).
Служит для "заранее предусмотренных" ошибок, не представляющих угрозы.
Например, если пользователь ввел недопустимые для работы параметры.
Вычисления прерываются, но ничего страшного, можно повторить ввод.
EEchoException - "безопасное" программное исключение, с минимальной диагностикой,
без окна предупреждения и без журналирования (т.е. записи в журнальный файл).
Служит для "частых заранее предусмотренных" ошибок, не представляющих угрозы.
Например, ошибка компиляции программы DaqPascal - обычное дело.
Подробная диагностика не нужна, достаточно краткого сообщения (Echo).
Все выше перечисленные "безопасные" исключения генерируются программно в процессе обработки данных.
Они возникают в каком-то смысле "планомерно", "предсказуемо", и не представляют какой-либо угрозы.
Поэтому для них достаточной реакцией является консольный вывод разной степени подробности.
Все прочие исключения считаются "вредными" и "небезопасными".
Они теперь журналируются (т.е. записываются в журнальный файл
Temp\@OnException.log
) и вызывают всплывающее окно предупреждения.
Логика работы примерно такая.
При возникновении аппаратного или программного исключения оно перехватывается и классифицируется
как "безопасное" или "небезопасное".
Для "безопасных" исключений делается только консольный вывод в Главной Консоли разной степени подробности.
Для "небезопасных" исключений кроме этого в консоль посылается команда @Silent @OnException Msg с сообщением Msg.
Затем посылается команда @Silent @OnException --info Inf с дополнительной информацией Inf об ошибке.
Обработчик команды @OnException в настоящей версии посылает в консоль команду
@Silent @Integrity @OnException Msg и @Silent @Integrity @OnExceptionInfo Inf.
Это сделано для того, чтобы была возможность обработки исключений через общий механизм правил
@Integrity --rule @OnException ... и @Integrity --rule @OnExceptionInfo ....
В файле Crw32.ini в секции [@Integrity.DefaultRules]
заданы такие правила, которые выводят сообщение в журнальный файл Temp\@OnException.log
и открывают сообщение во всплывающем окне @Tooltip.
Таким образом, теперь исключения журналируются и оповещаются в удобном для оператора виде.
Работу нового механизма можно проверить вызовом:
@OnException --raise Comment text Тестовое программное исключение
@OnException --raise EAccessViolation Аппаратное исключение "нарушение защиты памяти"
@OnException --raise EDivByZero Аппаратное исключение "целочисленное деление на ноль"
@OnException --raise ENiceException Программное исключение, не вызывающее всплывающего окна
@OnException --raise ESoftException Программное исключение, без всплывающего окна и подробностей
@OnException --raise EEchoException Программное исключение без подробной диагностической информации
Новый способ обработки исключений поможет выловить оставшиеся в пакете ошибки и поможет лучше диагностировать
проблемы при их возникновении. Например, при чтении специально (для тестов) поврежденного файла
Demo\DEMO_DATA\FAIL.CRW будет сгенерировано исключение с диагностикой типа
Exception «EReadError» in Crw32.exe PID 4744 EReadError in Crw32.exe at 00013BE3 «Stream read error»
При появлении "небезопасных" исключений в журнал заносится адрес ошибки.
По адресу ошибки с некоторой точностью можно установить модуль и строку исходного кода, где возникла ошибка.
Для этого надо использовать файл Resource\Crw32.map.txt.
Обработка исключений затронула очень много файлов (т.к. почти везде используется обработка исключений),
поэтому в ближайшее время надо очень хорошо "обкатать" эту версию на предмет возможных ошибок.
Ошибок быть, конечно, не должно, но всё бывает в нашей жизни...
Для проверки работы системы обработки исключений сделаны тестовые плагины (библиотеки DLL).
TEST_EACCESSVIOLATION.DPR
- генерирует исключения EAccessViolation (нарушение защиты памяти)
TEST_EDIVBYZERO.DPR
- генерирует исключения EDivByZero (целочисленное деление на ноль).
Эти примеры позволяют проверить устойчивость системы к сбоям.
Обновлена библиотека NetModbus.
В ней добавлены зарегистрированные консольные команды
cmd_NetModbusPoll (для @Modbus.Poll), cmd_NetModbusReply (для @Modbus.Reply),
cmd_NetModbusTimeout (для @Modbus.Timeout), cmd_NetModbusRefuse (для @Modbus.Refuse).
Их можно использовать в обработчиках команд:
if (cmdid=cmd_NetModbusPoll) then begin
...
end else
...
Соответственно обновлен сервер &ModbusProxy
и демо конфигурация DEMO_MAYAK.
Обновление делалось в рамках перехода на новый стиль обработки консольных команд.
Эта работа будет продолжена, пока все сервера не будут переделаны на новый лад.
Обновлена утилита DAQ Creator от Н.Гурина.
Исправлены замеченные ошибки. Обновлен стиль обработки консольных команд.
В связи с аттестациями и прочими нововведениями актуальность приобрел вопрос идентификации версий пакета,
т.к. в документах на аттестацию должны быть указаны контрольные суммы для конкретной версии пакета.
То есть нужен идентификатор версии. Вообще-то версия программы в пакете давно есть (в ресурсах EXE файла),
но удобного доступа к этой информации не было. Теперь он появился.
В статусной строке теперь написано что-то вроде CRW-DAQ ver 20171207 ....
Число идентифицирует дату выпуска данной версии, которая одновременно служит и для идентификации версии.
Различные версии программы будут различаться в первую очередь этим номером - датой выпуска,
который одновременно будет служить идентификатором версий.
В команду @SysInfo добавлена опция --file-version для получения информации о версии EXE файла.
Главными достижениями данного выпуска являются: обновление GuiLib,
обновление и доработка инсталляторов, возможность распаковки исходного кода инсталляторов,
создание библиотеки _HL.PAS хеш-таблиц HashList,
ускорение функции findtag, создание библиотеки DaqPascal-функций
hashlist_xxx
для прикладного программирования, а также ускорение обработки консольных команд с помощью функций
GotCommandId и
RegisterStdInCmd,
а также обновление сервера &CronSrv и &ModbusProxy с использованием хеш-таблиц
для повышения производительности обработки консольных команд.
Обновлены все инсталляторы (т.к. обновлена библиотека инсталляционных сценариев).
Скорректирована обработка ошибок инсталляции, сделана возможность просмотра журналов инсталлятора.
Добавлена возможность распаковки исходного кода всех инсталляторов.
Например:
install-daqgroup-crw32-runtime.exe /SOURCE /S /D=C:\DaqGroupToolsSource\install-daqgroup-crw32-runtime
install-daqgroup-crw32-runtime.exe /EXTRACT /S /D=C:\DaqGroupToolsSource\install-daqgroup-crw32-runtime
Обе команды распаковывают исходный код инсталлятора в указанный каталог в "тихом" режиме (silent).
Также добавлен командный файл
install-daqgroup-extractall.cmd
Этот командный файл, расположенный в Resource\Shell, служит для распаковки всех инсталляторов в каталог
%ProgramFiles%\DaqGroupToolsSource\. Файл надо скопировать в каталог, где расположены все инсталляторы
и запускать в этом каталоге.
Возможность распаковки исходного кода инсталляторов делает ненужным отдельное хранение архивов
с исходным кодом и дает возможность развернуть среду разработки с помощью тех же инсталляторов,
которые используются для рабочей инсталляции целевого продукта.
Исправлена обработка ошибок в инсталляторах.
Из-за недоработок в инсталляционных библиотеках при запуске сценариев (командных файлов CMD)
всегда возвращался успешный статус, даже если сценарий вернул код ошибки.
Теперь это исправлено и код возврата анализируется корректно: если сценарий CMD возвращает ненулевой код,
то инсталлятор фиксирует ошибку.
После исправления обработки ошибок в инсталляторах выяснилось, что большое число инсталляционных сценариев
(CMD) при инсталляции выдает неверный код (раньше это было незаметно).
В связи с этим было исправлено большое число (более 100) инсталляционныых сценариев,
которые теперь возвращают верный результат, т.е. успешный код возврата (0)
в случае если инсталляция прошла успешно, или код ошибки (1) при сбое инсталляции.
Успешность инсталляции проверяется по наличию записи в реестре, в разделе Uninstall,
т.е. считается, что если ожидаемая запись появилась, то все (должно быть) в порядке.
В инсталлятор добавлена кнопка Log на всплывающем сообщении, по которой можно посмотреть журналы инсталляции.
Обновлена версия nnCron. Старая версия не работала под Win7/8/10, теперь работает корректно.
Служба nnCron позволяет запускать программы по расписанию с требуемыми правами доступа
и играет важную роль как средство для автоматизации и самообслуживания операционной системы.
Например, для периодической чистки дисков и копирования данных.
Обновлена программа unix.exe и пакет UnixUtils, куда, в частности,
добавлена программа SSH клиента PuTTY.
Обновлены утилиты grun, specrun, saferun. Теперь они вызывают меньше нареканий от VirusTotal.
В сборку Commander добавлена программа Text Replacer для замены текста в пакетном режиме.
В библиотеку GuiLib
добавлены элементы RadioButton и CheckBox. Оба элемента рисуются на квадратной картинке.
CheckBox отображает состояние отдельных битов тега данных (независимые кнопки), а
RadioButton отображает состояние выбора одной из альтернатив (зависимые кнопки).
Предполагается, что тег данных связывается с группой элементов CheckBox или RadioButton,
которые совместно отображают его состояние.
В DemoDoc добавлена утилита DAQ Creator от Н.Гурина.
Служит для создания шаблона новой DAQ системы.
Ссылка на эту утилиту добавлена в меню "Инструменты\Консольные утилиты...".
Имеется help.
Создана библиотека _HL.PAS,
содержащая хеш-таблицу или хешированный список THashList для быстрой индексации строк.
HashList служит для создания ассоциативных массивов, т.е. массивов, в которых в качестве индекса
используется не целое число, а произвольная строка.
Хеширование позволяет оперировать с такими массивами с высокой скоростью, практически не зависящей от размера массива.
Имеется краткое описание того, что такое хеш-таблицы.
С помощью хеш-таблиц ускорена работа функции findtag.
Эта функция используется для инициализации тегов, а также для поиска ссылок тегов по имени в ряде серверов.
Например, сервер &DimSrv использует findtag для обработки консольных сообщений.
Ускорение работы функции findtag непосредственно влияет на повышение производительности этих серверов.
Проведено тестирование ускорения работы функции findtag помощью хеш-таблиц.
Тестирование проводилось на конфигурации DEMO_UNIHEAT с 32 нагревателями (чтобы в конфигурации было достаточно много тегов).
Запускался тестовый фрагмент:
if GotCommand(Data,cmd,arg) then begin
{
@test
}
if IsSameText(cmd,'@test') then begin
r:=msecnow; n:=100000; for n:=1 to n do tag:=FindTag('DatSrv.Gate');
r:=msecnow-r; Success(NameTag(tag)+' '+Str(1000*r/n)+' mks/op findtag');
Data:='';
end else
....
По результатам измерения, старая версия программы выполняла вызов FindTag('DatSrv.Gate') за 360 mks,
а новая версия - за 6 mks, т.е. ускорение составляет 60 раз.
Причем эта разница результатов будет только усиливаться по мере роста размера конфигурации (числа тегов),
т.к. в старой версии программы использовался линейный поиск, эффективность которого напрямую зависит от
размера массива, т.е. числа тегов в системе.
В новой версии поиск не только осуществляется быстро, но и практически не зависит от размера массива тегов.
Это весьма существенный результат.
Добавлена группа функций hashlist_xxx
для работы с хеш-таблицами в DaqPascal.
Хеш-таблицы весьма полезны в случае работы с любыми объектами, имеющими имена, например, с файлами, кривыми,
окнами, тегами, устройствами, секциями конфигурационных файлов, консольными командами и т.д.
Обычно такие данные хранятся в списках, но в этом случае возникает проблема быстрого поиска элементов
списка по имени. Эту задачу и решает хеш-таблица. Она позволяет осуществлять быстрый поиск элементов
по строковым ключам (именам) со скоростью, практически не зависящей от размера массива.
Сделаны средства для существенного ускорения обработки консольных команд с помощью функций
GotCommandId и
RegisterStdInCmd.
Эти функции основаны на хеш-таблицах и дают значительное ускорение обработки консольных команд,
особенно при большом трафике и большом количестве обрабатываемых команд.
Назовем это новым хеш-стилем обработки консольных команд.
Это работает примерно так:
program Demo;
...
var
...
cmd_Demo : Integer; { Command @Demo } // Заводим целочисленную переменную под команду
...
procedure InitApplication;
begin
...
cmd_Demo:=RegisterStdInCmd('@Demo','@Demo - Run Demo command'); // Регистрируем команду в списке консольных команд
... // При регистрации задаем комментарий для @Help
end;
...
procedure StdIn_Processor(var Data:String);
var cmd,arg:String; cmdid:Integer;
begin
...
if GotCommandId(Data,cmd,arg,cmdid) then begin // Получаем команду cmd c идентификатором cmdid
{
@Demo ...
}
if (cmdid = cmd_Demo) then begin // Сравниваем команду с этим идентификатором
... // Обрабатываем, если совпало
end else
...
end;
...
end;
...
end.
Для каждой команды заводится целочисленная переменная cmd_XXX.
С помощью функции RegisterStdInCmd эта команда регистрируется при инициализации программы.
В цикле опроса с помощью функции GotCommandId, использующей хеш-таблицу команд,
вычисляется идентификатор cmdid поступившей
команды и сравнивается с зарегистрированной командой. При совпадении выполняется обработка.
Программы обработки консольного ввода, построенные по такой схеме, выполняются существенно быстрее,
чем программы, построенные на вызове функции GotCommand и последующем сравнении строк
функцией IsSameText(cmd,..).
Модифицирован шаблон template.pas,
в котором показано использование нового стиля обработки консольных команд. Старый шаблон охранен под именем
template1.pas.
Обновлен сервер CronSrv.pas
и ModbusProxy.pas,
в которых обработка консольных команд переведена на новый стиль с использованием хеш-таблиц,
что дает существенное ускорение обработки консольных команд.
Это весьма существенно, т.к. например,cервер &CronSrv содержит более 50 команд,
а сервер &ModbusProxy - около 30.
Другие серверы со временем тоже планируется обновить.
Рекомендуется использовать новый хеш-стиль обработки консольных команд во всех новых системах.
А старые системы - по возможности обновлять в новом хеш-стиле.
Разумеется, старый стиль обработки консольных команд на основе GotCommand/IsSameText
по-прежнему работает и будет поддерживаться, но ввиду соображений эффективности от него постепенно надо уходить.
Интереса ради проведен анализ скоростных характеристик различных операций, связанных с обработкой консольных команд.
Для тестирования использовалась конфигурация DEMO_UNIHEAT на 32 нагревателя, включающая 836 тегов.
В неё была вставлена процедура, осуществлющая измерение времени различных операций DaqPascal:
procedure HashBenchmark(MaxIter:Integer);
var ms:Real; i,n,tag,hl:Integer; name:string;
begin
hl:=HashList_Init(0);
for tag:=1 to 10000 do if typetag(tag)>0 then bNul(HashList_SetLink(hl,nametag(tag),tag));
Success('Count = '+Str(HashList_Count(hl)));
n:=MaxIter; ms:=msecnow;
for i:=1 to n do tag:=HashList_GetLink(hl,'DatSrv.Gate');
ms:=msecnow-ms; Success(NameTag(tag)+' '+Str(1000*ms/n)+' mks/op');
name:=nametag(tag); n:=MaxIter; ms:=msecnow;
for i:=1 to n do if IsSameText(name,'DatSrv.Gate') then;
//for i:=1 to n do if name='DatSrv.Gate' then;
//for i:=1 to n do if tag=i then;
ms:=msecnow-ms; Success(NameTag(tag)+' '+Str(1000*ms/n)+' mks/op'); name:='';
bNul(HashList_Free(hl));
end;
...
HashBenchmark(5000000); // Использовалось 5 миллионов итераций
По результатам тестирования на машине Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz получаются такие результаты:
Сравнение целых чисел (типа if (cmdid = cmd_XXX) then .. ) занимает около 28 ns.
Простое сравнение строк (типа if (cmd = '@demo') then .. ) занимает около 78 ns.
Регистронезависимое сравнение строк (типа if IsSameText(cmd,'@demo') then .. ) занимает около 580 ns.
Извлечение значения хеш-таблицы (типа cmdid:=HashList_GetLink(hid,cmd); ) занимает около 580 ns.
Как и ожидалось, операция сравнения целых чисел существенно (примерно в 3 раза) быстрее простого сравнения строк
и более чем в 20 раз быстрее регистронезависимого сравнения строк с помощью IsSameText.
Неожиданностью оказалось то, что извлечение значения хеш-таблицы HashList_GetLink,
на котором основана функция GotCommandId, по затратам сопоставимо с вызовом IsSameText.
Это говорит о высокой эффективности хеш-таблиц, ведь для извлечения значения требовался поиск в таблице из 836 элементов.
По результатам тестирования можно сделать вывод, что использование хеш-таблиц "окупается" даже в случае
обработки одной команды, т.к. извлечение значения из хеш-таблицы по ключу занимает примерно столько же времени,
сколько регистронезависимое сравнение строк.
При большом числе команд эффективность обработки растет пропорционально числу команд в цикле обработки
и может дать выигрыш в десятки раз. Возьмем конкретный пример - пусть сервер &CronSrv,
имеющий более 50 команд, обрабатывает 1000 сообщений в секунду. Тогда затраты времени составят
0.58*50*1000 = 29000 mks в секунду, что соответствует загрузке 3%. При переводе на хеш-таблицу
затраты процессорного времени снизятся более чем в 20 раз, т.к. дорогостоящие операции сравнения
строк IsSameText заменятся на высокоэффективное сравнение целых чисел, которое быстрее как минимум в 20 раз.
Это особенно важно при большом числе команд и высоком трафике консольных сообщений.
Разумеется, в сделанном расчете учитывается только время интерпретации, т.е. поиска команды для исполнения,
а не время исполнения самой команды. Следует также сказать, что сделанные оценки являются грубыми, прикидочными.
Вывод простой - хеш-таблицы дают чрезвычайно эффективный инструмент для обработки строковых данных,
который рекомендуется активно использовать в прикладных программах.
01.11.2017
TinyWeb Painter HashCheck CmdOpen tee
Главными достижениями данного выпуска являются:
обновление сервера TinyWeb и ряда других утилит,
анализ, оптимизация и доработка интерпретатора Painter.
Обновлены: Web сервер tiny.exe, расширения оболочки HashCheck, CmdOpen,
утилита tee.exe, архив Dcc32Sfx.exe заменен на Dcc32Bin.7z + Dcc32Bin.cmd.
Это продолжение работы по "очистке" дистрибутива от утилит с "плохой кармой" (которых не любят антивирусы).
Старые версии вызывали предупреждения VirusTotal.com, новые версии предупреждений не вызывают.
Замечено, что антивирусы не любят самораспаковывающиеся архивы и некоторые инсталляторы, так что в некоторых
случаях вместо инсталлятора (EXE) лучше использовать архив (ZIP) и сценарий (CMD) для его распаковки.
Удалены утилиты: nircmd.exe, hidexe.exe - из-за нареканий VirusTotal.com.
Все ссылки на эти утилиты в прикладных системах должны быть заменены:
Команда Заменяется на
hidexe ... grun -h ...
nircmd setprocesspriority ... unix setprocesspriority ...
nircmd win show title ... unix showwindow ...
nircmd win hide title ... unix hidewindow ...
nircmd win close title ... unix closewindow ...
nircmd win activate title ... unix setforegroundwindow ...
nircmd win setsize title ... unix resizewindow ...
и так далее
Примечание:
Для совместимости старых конфигураций часть команд nircmd.exe была упакована
в безопасную "заглушку" nircmd.cmd, поэтому старые конфигурации должны работать
корректно, например: unix nircmdc setprocesspriority VSPEmulator.exe high
работает как прежде.
Замена утилит связана с желанием очистить дистрибутив от программ с плохой репутацией на VirusTotal.com.
Выполнена дополнительная (в самых очевидных случаях) оптимизация интерпретатора DaqScript и Painter.
Дальнейшая оптимизация признана (пока) нецелесообразной, т.к. требует больших изменений в коде интерпретатора,
ухудшающих модульность, переносимость и читабельность, давая при этом несущественный выигрыш в несколько процентов.
Как говорится, "овчинка выделки не стоит".
Проведен анализ скорости работы интерпретатора Painter.
Для этого была скомпилирована специальная версия программы с заглушенными (временно отключенными)
функциями собственно рисования, при сохранении общей структуры функций интерпретатора.
Затем был сгенерирован ДЕМО пример DEMO_PAINT_BENCH,
в котором рисование простой кнопки (SimpleButton) выполняется 10000 раз.
Фиксируется время выполнения рисования и вычисляется среднее время выполнения скрипта SimpleButton.
Результат оказался таким. При реальном рисовании кнопка рисуется за 65.7 мкс (микросекунд).
При отключении функций рисования кнопка "рисуется" (интерпретируется) за 12.5 мкс.
Из этого слудует, что выполнение сценария Painter занимает около 20% от общего времени рисования.
По сути это значит, что сценарии Painter вносят лишь незначительное замедление в работу графики
по сравнению с откомпилированным вариантом, т.к. основное время тратится не на интерпретацию формул,
а на выполнение самого рисования. Это подтверждает целесообразность использования "умных сенсоров".
Добавлено еще несколько функций интерпретатора Painter:
На данный момент в интерпретаторе Painter реализован достаточно большой набор графических функций,
что дает большие возможности для рисования практически чего угодно на сенсорах.
Пока что эта тема (расширение интерпретатора Painter) закрыта.
В планах ожидается накопление элементов графической библиотеки GuiLib,
чтобы сделать использование графических функций простым и понятным.
Обновлена демо конфигурация DEMO_PAINT.
Туда добавлены иллюстрирации новых функций Painter(v).
В целях ускорения загрузки конфигураций изменен механизм журналирования при чтении ReadIni.
Раньше делался отладочный вывод непосредственно в отладочный файл ReadIni.log,
теперь вывод буферизован через поток System.DebugOut[2].
Буферизация должна ускорить загрузку за счет сокращения числа операций открытия/закрытия файлов.
Добавлена переменная Crw32.ini [System] ReadIniLogFifo для управления размерами FIFO.
Главными достижениями данного выпуска являются: оптимизация интерпретатора DaqScript,
завершение работы с умными сенсорами Painter(v) и создание первой версии библиотеки графических
элементов GuiLib, которая будет пополняться по мере возможности и необходимости.
Уточняю, что "умными сенсорами" мы будем называть сенсоры,
содержащие формулы TagEval(v), LedEval(v) или сценарии Painter(v).
Умные сенсоры отличаются от простых сенсоров более сложным видом и поведением,
который обеспечивают формулы и сценарии,
см. подробнее тут.
В связи с возросшей (из-за умных сенсоров) ролью интерпретатора DaqScript проведена его оптимизация.
Существенно уменьшено потребление памяти, примерно в 2 раза увеличена производительность.
Введено хэширование (управляется переменной [System] EvaluatorHasher).
За счет этого скорость выполнения скриптов теперь слабо зависит от числа переменных в адресном пространстве.
Например, выполнение обработки (Macro "Арифметика") для кривой в 1000000 точек занимает около 5200 мс
при малом числе переменных и возрастает до 6200 мс (на 20%) при искусственном введении 100000 переменных.
В предыдущей версии рост в аналогичной ситуации составлял примерно 2 раза (с 10000 до 20000 мс), то есть был существенно больше.
Полученный результат говорит о высокой скорости индексации (хеширования) строк, т.к. при исполнении переменные ищутся
в списке по строковому ключу (по имени). Хеширование позволяет быть уверенным, что скорость исполнения
скриптов мало зависит от их объема и количества используемых переменных.
В интерпретатор DaqScript добавлены дополнительные константы.
minshortint = -128 - минимальное значение shortint
maxshortint = 127 - максимальное значение shortint
maxbyte = 255 - максимальное значение byte
minsmallint = -32768 - минимальное значение smallint
maxsmallint = 32767 - максимальное значение smallint
maxword = 65535 - максимальное значение word
minlongint = -2147483648 - минимальное значение longint
maxlongint = 2147483647 - максимальное значение longint
minint = -2147483648 - минимальное значение int
maxint = 2147483647 - максимальное значение int
maxdword = 4294967295 - максимальное значение DWORD
maxlongword = 4294967295 - максимальное значение longword
minsingle = 1.5E-45 - минимальное значение single положительное отличное от нуля
maxsingle = 3.4E38 - максимальное значение single
mindouble = 4.94065645841247E-324 - минимальное значение double положительное отличное от нуля
maxdouble = 1.7E308 - максимальное значение double
Эти константы полезны для операций с числами.
Проведено тестирование производительности интерпретатора DaqScript.
Программа тестирования:
program testee; {$APPTYPE CONSOLE} {$I _sysdef}
uses ShareMem,SysUtils,Windows,Math,_alloc,_str,_pio,_fio,_rtc,_ee;
function ExpressionEvaluatorBenchmark(n:Integer=1000000):LongString;
var ee:TExpressionEvaluator; expr:LongString; i:Integer; ms:Double;
begin
Result:='Expression Evaluator Benchmark:'+CRLF;
expr:='gt(v,alarm1)+gt(v,alarm2)';
ee:=NewExpressionEvaluator;
try
ms:=mSecNow;
for i:=0 to n-1 do begin
ee.SetValue('alarm1',0.5);
ee.SetValue('alarm2',0.7);
ee.SetValue('v',frac(ms*0.01));
if ee.EvaluateLine(PChar(expr))<>0 then break;
end;
ms:=mSecNow-ms;
Result:=Result+Format('Expression = %s',[expr])+CRLF;
Result:=Result+Format('Total loop = %d',[i])+CRLF;
Result:=Result+Format('Total time = %g ms',[ms])+CRLF;
Result:=Result+Format('Oper. time = %3g mks/op',[ms*1000/n])+CRLF;
finally
Kill(ee);
end;
end;
begin
write(ExpressionEvaluatorBenchmark);
end.
Результат на процессоре Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz:
Expression Evaluator Benchmark:
Expression = gt(v,alarm1)+gt(v,alarm2)
Total loop = 1000000
Total time = 718 ms
Oper. time = 0.718 mks/op
По результатам тестирования на компьютере Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz,
типичная формула gt(v,alarm1)+gt(v,alarm2) вычисляется в среднем за 720 ns.
Грубо говоря, каждая формула интерпретируется за микросекунду.
Эту оценку можно использовать для грубой оценки производительности "умных сенсоров".
Например, если имеется мнемосхема из 100 сенсоров, которые обновляются 10 раз в секунду
и содержат сценарий из 10 строк, то их вычисление займет 100*10*10 мкс = 10 мс в секунду,
что соответствует загрузке 1%.
Реально сенсоры обновляются существенно реже, поэтому загрузка будет еще ниже.
Исходя из этой грубой оценки производительности использование "умных сенсоров" вполне приемлемо,
однако использовать их все же следует по необходимости,
т.е когда обычные (не содержащие формул) сенсоры не могут решить поставленную задачу.
Сделано описание функций Painter(v).
Ссылка на описание внесена в Top List.
Заложена основа для создания простой в использовании библиотеки графических сценариев
GuiLib
для интерпретатора Painter(v).
Библиотека будет содержать стандартные объекты GUI - кнопки, индикаторы и т.д.
В настоящее время доступен один объект - SimpleButton (простая кнопка).
Другие объекты будут создаваться постепенно, по мере необходимости.
Пример использования:
[ConfigFileList] ; Include the Painter GUI Library
ConfigFile = ~~\Resource\DaqSite\Default\Painter.crc
[]
...
[SensorList]
Sensor = Button1 ; Simple button example
[Button1]
Pos = 10 150 ; Set button position
LED = 0, 0, 0, *, [BigButtonFont] ; Set button font
Tag#1 = 0, ButtonBar.bmp, Button1 ; Set button bitmap and title
Painter(v) = (glButtonBit=0)+(glButtonBevel=3) ; Set button Bit and Bevel thickness
Painter(v) = (glButtonMoveX=2)+(glButtonMoveY=2) ; Set button text move to show press state
Painter(v) = [Painter(v).GuiLib.SimpleButton] ; Include GUI library script of SimpleButton
Hint = Button1
[]
Чтобы использовать библиотеку, надо для начала включить её в *.CRC файл,
включив ссылку [ConfigFileList] ConfigFile = ~~\Resource\DaqSite\Default\Painter.crc.
Затем в сенсоре желательно указать параметры кнопки
glButtonBit (номер бита состояния кнопки включен/выключен),
glButtonBevel (толщина линий фаски кнопки),
glButtonMoveX и glButtonMoveY (смещение надписи при нажатии кнопки).
Если параметры не указывать, принимаются некоторые разумные значения по умолчанию.
После этого надо включить сам сценарий рисования кнопки указанием секции [Painter(v).GuiLib.SimpleButton].
Подробнее см. Painter.htm.
Под сценарии TagEval(v), LedEval(v), Painter(v) заведены счетчики ошибок,
так что при ошибках выполнения этих сценариев будет выдана диагностика по системе DAQ.
К сожалению, источник ошибок не фиксируется, т.е. нельзя узнать, какой именно сенсор генерирует ошибки.
Поэтому источники ошибок лучше выяснять сразу по мере создания конфигурации.
s:=ClickParams('CrcFile'); - имя CRC файла из которого загружен сенсор
s:=ClickParams('Section'); - имя секции из которой загружен сенсор
s:=ClickParams('Bookmark'); - тег изображения (идентификатор текущей картинки)
s:=ClickParams('LedValue'); - строка циферблата (надпись, если указано значение LED>0)
s:=ClickParams('LedEval(v)'); - пустая строка или формула LedEval(v), если она задана
s:=ClickParams('TagEval(v)'); - пустая строка или формула TagEval(v), если она задана
s:=ClickParams('Painter(v)'); - пустая строка или имя секции, если есть сценарий Painter(v)
Эти дополнительные параметры могут использоваться при обработке нажатий сенсоров.
Вызов ClickParams('Painter(v)') возвращает вместо текста сценария имя секции,
потому что сам текст сценария может быть довольно большим.
При необходимости нужная информация считывается из CRC файла.
Обновлена демо конфигурация DEMO_PAINT.
Туда добавлены иллюстрирации использования библиотеки Painter(v).GuiLib.
Главным достижением данного выпуска являются умные сенсоры в окнах мнемосхем.
Это сенсоры, которые содержат формулу TagEval(v) для расчета тега изображения (идентификатора фоновой картинки),
формулу LedEval(v) для расчета циферблата (цифровой надписи) или пользовательский сценарий Painter(v)
для рисования сенсора.
Умные сенсоры позволяют, например, создавать поля, меняющие фон в зависимости от значения тега,
или сенсоры, которые содержат динамические изображения типа стрелочных приборов, индикаторов прогресса и т.д.
Умные сенсоры выводят графику пакета на качественно новый уровень.
Если кратко, то:
TagEval(v) - задает формулу для расчета тега изображения (идентификатора фоновой картинки) сенсора.
LedEval(v) - задает формулу для расчета циферблата (отображаемой надписи) сенсора.
Painter(v) - задает сценарий для рисования чего угодно на сенсоре.
Подробности - ниже.
В умные сенсоры добавлена возможность вычислять циферблат (LED), т.е. цифровую надпись по заданной формуле.
Параметр
LedEval(v) = e
Задает выражение e (т.е. формулу) для вычисления отображаемого циферблата (цифровой надписи) по значению переменной v.
В качестве формулы подойдет любое выражение на языке DaqScript, которое можно проверить, например, в Главной Консоли.
При этом переменная v обозначает текущее значение связанной с сенсором переменной (Linked tag/curve).
Задание формулы позволяет гибко управлять отображением числовых (в виде надписи) значений кривых/тегов.
Например, при задании LedEval(v)=Log(10,v)*20 сенсор будет отображать числовое значение (надпись) связанной переменной в децибеллах.
Не следует путать формулы LedEval(v) и TagEval(v).
Формула LedEval(v)=... задает вычисляемое значение ДЛЯ НАДПИСИ на сенсоре и
задается только при ненулевом значении LED = ... (т.е. если используется циферблат).
Формула TagEval(v)=... задает вычисляемое значение ДЛЯ ИДЕТНИФИКАТОРА КАРТИНКИ сенсора.
Обе формулы можно использовать совместно, что позволяет, например, создавать числовые поля с переменным фоном,
зависящим от значения присоединенного тега/кривой, т.е. совместить числовые поля с индикатором уровня.
Например:
; Пример показывает, как отобразить параметр с переменным фоном
; В поле отображается значение в децибеллах, а цвет изображения
; зеленый/желтый/красный в зависимости от значения переменной v
[SensorList]
Sensor = Decibels
[Decibels] ; Сенсор отображает сигнал в децибеллах
Pos = 255 85
Tag = 0
LED = 7, 0, 2, %7.2f, [LedFont] ; Set uses LED format and font
LedEval(v) = log(10,v)*20 ; Convert LED value to decibels
TagEval(v) = gt(v,100)+gt(v,1000) ; Evaluate picture tag to paint:
Tag#1 = 0, ~~\Resource\DaqSite\StdLib\Bitmaps\_LED07L.BMP ; Lime background if v<100
Tag#2 = 1, ~~\Resource\DaqSite\StdLib\Bitmaps\_LED07Y.BMP ; Yellow background if v>100
Tag#3 = 2, ~~\Resource\DaqSite\StdLib\Bitmaps\_LED07R.BMP ; Red background if v>1000
В окна мнемосхем добавлен стартовый сценарий [Circuit] StartupScript = ....
Этот скрипт выполняется при загрузке мнемосхемы и позволяет задать начальные значения переменных
интерпретатора Painter(v), связанного с окном мнемосхемы и выполняющего вычисление сенсоров
при задании формул LedEval(v), TagEval(v) и Painter(v).
Это позволяет параметризовать формулы расчета отображаемых значений.
Параметр
StartupScript = s
может содержать ссылку на секцию (обычно [Circuit.StartupScript]) или очередную строку скрипта (строк может быть много).
Например:
[Circuit]
GeneralMap = ..\Bitmaps\demo_ctrl.bmp
Hint = Контрольная панель DEMO
StartupScript = [Circuit.StartupScript]
[]
[ConfigFileList] ; Включить стандартную инициализацию
ConfigFile = ~~\Resource\DaqSite\Default\Painter.crc
[]
[Circuit.StartupScript] ; Добавить свою инициализацию переменных
alarm1=100
alarm2=200
[]
[SensorList]
Sensor = Demo
[Demo]
Pos = 10, 10
LED = 7, 0, 3, %7.3f, [LedFont]
TagEval(v) = gt(v,alarm1)+gt(v,alarm2) ; Formula for ground picture
Tag#1 = 0, ..\BITMAPS\LED07L.BMP ; Lime ground if v < alarm1
Tag#2 = 1, ..\BITMAPS\LED07Y.BMP ; Yellow ground if v > alarm1
Tag#3 = 2, ..\BITMAPS\LED07R.BMP ; Red ground if v > alarm2
[]
В функции WinDraw добавилась команда Eval
для задания в окне мнемосхемы параметров интерпретатора, выполняющего вычисления
LedEval(v), TagEval(v) и Painter(v).
Эта функция позволяет динамически изменять параметры, используемые при расчете LedEval(v), TagEval(v) и Painter(v).
Например:
// Пример показывает, как изменить параметры alarm1, alarm2
// используемые в предыдущем примере из программы DaqPascal
b:=windraw('DEMO.CTRL|Eval=(alarm1=200)'); // Задать новое значение alarm1=200
b:=windraw('DEMO.CTRL|Eval=(alarm2=300)'); // Задать новое значение alarm2=300
b:=windraw('DEMO.CTRL|Eval=(alarm1=200)+(alarm2=300)'); // Задать оба параметра
// В данном случае для присвоения сразу нескольких переменных (a,b,c,d)
// можно использовать выражения в скобках по типу (a=1)+(b=2)+(c=3)+(d=4)
// Это позволяет сократить число вызовов при задании нескольких параметров
Функция выполняется путем посылки сообщения указанному окну.
При использовании этой функции следует минимизировать число вызовов, чтобы избежать "спама", т.е. избыточного потока сообщений.
Предполагается, что параметры (в данном случае alarm1, alarm2) меняются редко и сообщения посылаются
только после действительного изменения их значений.
Новая команда позволяет динамически управлять поведением "умных сенсоров".
Например, если сенсор меняет фон при превышении порогового значения, то можно изменять этот порог.
Например, если пользователь отредактировал пороговый уровень, окну мнемосхемы следует послать сигнал об изменении порога.
В умные сенсоры добавлена возможность выполнять сценарий (скрипт на языке DaqScript) для рисования на сенсоре.
Параметр
Painter(v) = s
Задает имя секции s для сценария, который будет рисовать на поле сенсора по значению переменной v.
Рисование происходит на фоне изображения сенсора (картинки).
Подробности можно найти в примере DEMO_PAINT.
Пример:
[Circuit]
Name = DemoPaint ; Set window name
GeneralMap = .\DemoPaint.bmp ; Set background picture
StartupScript = [Circuit.StartupScript] ; Set startup script section
[]
[ConfigFileList] ; Include standard definitions
ConfigFile = ~~\Resource\DaqSite\Default\Painter.crc
[]
[Circuit.StartupScript] ; Run on startup
alarm1=30 ; Set alarm1 level
alarm2=60 ; Set alarm2 level
[]
[SensorList]
Sensor = Led1
[Led1] ; Display with variable background
Pos = 10, 10 ; Set sensor position
LED = 7, 0, 3, %7.3f, [LedFont] ; Set display format
TagEval(v) = gt(v,alarm1)+gt(v,alarm2) ; Background depends on v
Tag#1 = 0, ~~\Resource\DaqSite\StdLib\Bitmaps\_LED07C.BMP ; Background if v <= alarm1
Tag#2 = 1, ~~\Resource\DaqSite\StdLib\Bitmaps\_LED07Y.BMP ; Background if alarm1 < v <= alarm2
Tag#3 = 2, ~~\Resource\DaqSite\StdLib\Bitmaps\_LED07R.BMP ; Background if v > alarm2
[]
[SensorList]
Sensor = Bar1
[Bar1] ; Sensor with script painting
Pos = 10 40 ; Set sensor position
Tag#1 = 0, BAR.BMP ; Set background picture
Painter(v) = [Bar1.Painter(v)] ; Set script to paint sensor
[]
[Bar1.Painter(v)] ; Draw a line script
sw=sensorWidth() ; Get sensor width
sh=sensorHeight() ; Get sensor height
x1=2 ; Calculate coordinates of line
y1=sh-2-v*(sh-4)/100 ;
x2=sw-2 ;
y2=y1 ;
color=clAqua*le(v,alarm1)+clYellow*gt(v,alarm1)*le(v,alarm2)+clRed*gt(v,alarm2) ; Calculate color to draw
setPen(color,psSolid,pmCopy,4)+drawLine(x1,y1,x2,y2) ; Set pen style and draw a line
setBrush(clWhite,bsClear) ; Set brush style for text
fh=-round(1.33*16) ; Find height of font 16 pt
@font charset 204 ; Set font Charset Russian
@font style 1 ; Set font Style Bold
@font color %clBlue ; Set font Color
@font height %fh ; Set font Height
@font name Courier New ; Set font Name
tw=@textwidth %7.3f%v ; Get text width
th=@textheight %7.3f%v ; Get text height
setCursor(sw/2-tw/2,max(5,min(y2+2-(th+4)*gt(y2,sh/2),sh-th-5))) ; Set text cursor
@print %7.3f%v ; Print v value with format %7.3f
[]
Краткий перечень функций Painter(v):
Sensor Painter routines
sensorwidth() - get sensor width
sensorheight() - get sensor height
linkedvalue() - linked tag/curve value, must be equal to v
linkedcurve() - linked curve reference
linkedtag() - linked tag reference
bookmark() - sensor bookmark, i.e. current picture tag
ledwidth() - LED field width
leddigit() - LED digits after dot
setcursor(x,y) - set text cursor position
setpen(pencolor,penstyle,penmode,penwidth) - set pen style to draw lines
setbrush(brushcolor,brushstyle) - set brush style to fill bars
drawpoint(x1,y1,pointcolor,pointstyle) - draw a point with given marker
drawline(x1,y1,x2,y2) - draw a line with current pen
drawarrow(x1,y1,x2,y2,d1,d2) - draw a line with arraw ends d1,d2
drawbar(x1,y1,x2,y2) - draw a bar (filled rectangle)
drawellipse(x1,y1,x2,y2) - draw a filled ellipse
drawpie(x1,y1,x2,y2,x3,y3,x4,y4) - draw a filled ellipse pie
@print msg - draw a text (msg) at cursor
@textwidth msg - return text width
@textheight msg - return text height
@font charset/color/height/name/pitch/style value - assign value to font property like @font name PT Mono
where:
color=[R,G,B]=[clBlack,clMaroon,clGreen,clOlive,clNavy,clPurple,clTeal,clGray,clSilver,clRed,clLime,clYellow,clBlue,clFuchsia,clAqua,clLtGray,clDkGray,clWhite]
penstyle=[0..6]=[psSolid,psDash,psDot,psDashDot,psDashDotDot,psClear,psInsideFrame]
penmode=[0..15]=[pmBlack,pmWhite,pmNop,pmNot,pmCopy,pmNotCopy,pmMergePenNot,pmMaskPenNot,pmMergeNotPen,pmMaskNotPen,pmMerge,pmNotMerge,pmMask,pmNotMask,pmXor,pmNotXor]
penwidth=line width
barcolor=color of bar filling
barstyle=[0..7]=[bsSolid,bsClear,bsHorizontal,bsVertical,bsFDiagonal,bsBDiagonal,bsCross,bsDiagCross]
charset=[ANSI_CHARSET, DEFAULT_CHARSET, SYMBOL_CHARSET, MAC_CHARSET, SHIFTJIS_CHARSET, HANGEUL_CHARSET,
JOHAB_CHARSET, GB2312_CHARSET, CHINESEBIG5_CHARSET, GREEK_CHARSET, TURKISH_CHARSET, HEBREW_CHARSET,
ARABIC_CHARSET, BALTIC_CHARSET, RUSSIAN_CHARSET, THAI_CHARSET, EASTEUROPE_CHARSET, OEM_CHARSET]
font style=[0..15]=4 bits [fsBold,fsItalic,fsUnderline,fsStrikeOut]
font pitch=[0..2]=[fpDefault,fpVariable,fpFixed]
Более подробное описание функций можно найти в примере DEMO_PAINT.
Создана демо конфигурация DEMO_PAINT.
Эта конфигурация иллюстрирует все новые возможности "умных сенсоров".
Справку DemoPaint.htm можно также считать
краткой документацией по программированию "умных сенсоров".
Обновлена демо конфигурация DEMO_MAYAK.
Обновленная версия проверена на аппаратуре и является рабочей.
В ней также используются новые возможности умных сенсоров.
29.09.2017
DEMO_PROMETHEUS DEMO_SPVZK DEMO_OSM
Обновлены сборки сторонних программ (office,mmedia).
В сборку office добавлен DJVU Virtual Printer и DJVU Solo (редактор DjVu).
Для унификации интерфейсов GUI предлагается полностью перейти на семейство фонтов PT,
то есть использовать в новых разрабатываемых системах только PT шрифты.
Это дает такие преимущества:
1) Фонты PT встроены в пакет CRW-DAQ и доступны всегда, независимо от установки других пакетов.
2) Фонты PT являются наиболее читабельными в смысле различения похожих символов.
3) Фонты PT свободны для распространения и доступны под Windows\Linux.
Таблица рекомендуемых замен фонтов:
Старый фонт
Заменить на ...
FixedSys
PT Mono Bold
Liberation Mono
PT Mono
Courier
PT Mono
Courier New
PT Mono
Liberation Serif
PT Astra Serif
Times New Roman
PT Astra Serif
Arial
PT Sans
Arial Narrow
PT Sans Narrow
Arial Black
PT Mono Bold
Tahoma
PT Astra Sans
Verdana
PT Sans
В мнемосхемы добавлены умные сенсоры.
Это значит, что теперь у каждого сенсора появилась возможность не просто отображать значение связанной кривой\тега,
но можно также вычислять отображаемое значение по заданной формуле.
Параметр
TagEval(v) = e
Задает выражение e (т.е. формулу) для вычисления отображаемого значения тега изображения (идентификатора картинки) по значению переменной v.
В качастве формулы подойдет любое выражение на языке DaqScript, которое можно проверить, например, в Главной Консоли.
При этом переменная v обозначает текущее значение связанной с сенсором переменной (Linked tag/curve).
Задание формулы позволяет гибко управлять отображением значений кривых/тегов.
Например, при задании TagEval(v)=isBit(v,0) сенсор будет отображать состояние нулевого бита связанной переменной.
Этот параметр не обязателен, по умолчанию принимается пустое выражение, что эквивалентно заданию формулы TagEval(v)=v.
Пример:
; Пример показывает, как отобразить статусный регистр в виде отдельных битов
[SensorList]
Sensor = StateBit0
[StateBit0] ; Сенсор отображает 0-й бит статуса
Pos = 255 85
Tag = 0
TagEval(v) = isbit(v,0)
Tag#1 = 0, ~~\Resource\DaqSite\StdLib\Bitmaps\_smallcheck0.BMP
Tag#2 = 1, ~~\Resource\DaqSite\StdLib\Bitmaps\_smallcheck1.BMP
[SensorList]
Sensor = StateBit1
[StateBit1] ; Сенсор отображает 1-й бит статуса
Pos = 255 105
Tag = 0
TagEval(v) = isbit(v,1)
Tag#1 = 0, ~~\Resource\DaqSite\StdLib\Bitmaps\_smallcheck0.BMP
Tag#2 = 1, ~~\Resource\DaqSite\StdLib\Bitmaps\_smallcheck1.BMP
; Обратите внимание, что тег статусного регистра State связан
; с несколькими сенсорами, которые отображают его по-разному.
[Windows]
DemoCircuit = Circuit_Window
[DemoCircuit]
Circuit = .\Demo.crc
Link sensor StateBit0 with tag State device &Demo
Link sensor StateBit1 with tag State device &Demo
Использование умных сенсоров позволяет минимизировать число тегов и объем прикладного кода,
т.к. теперь для отображения, например, отдельных битов данных нет необходимости вводить промежуточные теги,
как приходилось делать раньше.
Однако теперь при использовании умных сенсоров следует внимательнее анализировать нажатия сенсоров,
поскольку тег может быть привязан к нескольким разным сенсорам. Поэтому при анализе ClickButton надо
учитывать не только значение связанного тега ClickTag, но и имя сенсора ClickSensor.
В соответствии с новыми возможностями умных сенсоров сделаны изменения в функции
clickparams.
В ней добавлены поля TagEval(v) (формула для вычисления идентификатора изображения),
LedValue (формула для вычисления циферблата, т.е. цифровой надписи), BookMark (идентификатор текущего изображения).
Добавление этих полей связано с тем, что у умных сенсоров текущее отображаемое значение
(надпись или идентификатор картинки) могут отличаться от значения связанной с сенсором тега/кривой.
Обновлена демо конфигурация DEMO_EDIT для иллюстрации умных сенсоров.
Создана демо конфигурация DEMO_MAYAK с драйвером радиометра БДГБ-14И производства ПО МАЯК.
Драйвер работает по протоколу MODBUS и пока еще находится в разработке, т.к. написан по документации (не проверялся на аппаратуре).
Однако даже незавершенный драйвер может служить примером активного использования умных сенсоров.
Использование умных сенсоров особенно удобно для отображения аппаратных данных, например отдельных битов аппаратурных регистров.
В этом случае один тег или кривая подключается к нескольким сенсорам, каждый из которых отображает состояние отдельного бита или группы битов.
Требуется лишь указать правильную формулу для расчета состояния сенсора.
Например, в демо конфигурации используются такие формулы:
Выражение отражает состояние... и выдает значение...
TagEval(v) = isbit(v,8) бита 8 0..1 (проверяет наличие 8-го бита)
TagEval(v) = bitand(v,255) битов 0..7 0..255 (выделяет 8 младших битов данных)
TagEval(v) = bitand(v/2,3) битов 1..2 0..3 (сдвигает на 1 разряд и выделяет 2 бита)
TagEval(v) = bitand(v/256,15) битов 8..11 0..15 (сдвигает на 8 разрядов и выделяет 4 бита)
TagEval(v) = bitand(v/4096,15) битов 12..15 0..15 (сдвигает на 12 разрядов и выделяет 4 бита)
TagEval(v) = eq(255,bitand(v,255)) битов 0..7 0..1 (проверяет быты 0..7 на равенство 255)
Как видно из примеров, использование умных сенсоров позволяет отображать состояние регистров аппаратуры
без введения большого числа промежуточных тегов, как приходилось делать раньше.
18.08.2017
DEMO_OSM getpid getppid cpu_count pidaffinity
Обновлены сборки сторонних программ (netweb,office,mmedia).
Обновлена демонстрационная конфигурация DEMO_OSM.
Это драйвер для контроллера шагового двигателя Онитекс OSM42-RA.
При тестировании на виртуальной машине с двумя логическими процессорами было замечено,
что потоки драйвера дают ненормально высокую загрузку процессора. Вероятно, это связяно
с конкуренцией потоков за общие ресурсы.
Этот эффект исчезает, если установить привязку процесса (CPU affinity).
Поэтому в конфигурацию был добавлен параметр UseCpuAffinity,
который устанавливает привязку процесса к процессору с указанным номером (1..32).
Если номер процессора больше числа процессоров, привязка делается к последнему по номеру процессору.
Для установки привязки процессора используется функция
pidaffinity.
Данный пример может служить образцом для других систем, в которых по тем или иным причинам требуется
привязка процессоров. Например, для обеспечения "реального времени" или для балансировки нагрузки на
процессоры.
В интерпретатор DAQ Script добавлено несколько функций:
getpid() возвращает идентификатор текущего процесса
getppid() возвращает идентификатор родительского процесса
cpu_count() возвращает число процессоров
pifaffinity(p,m) задает для процесса p маску привязки процессоров m
возвращает битовую маску привязки процессоров
p=0 означает текущий процесс
m=0 используется для чтения маски
pifaffinity(0,0) прочитать маску текущего процесса, не меняя её
pifaffinity(0,1) привязать текущий процесс к процессору CPU 0
Введенные функции в частности доступны в [&CronSrv.StartupScript],
что позволяет задавать при инициализации привязку процесса к процессорам.
; Данный пример привязывает текущий процесс к первому по номеру процессору:
[&CronSrv.StartupScript]
pidaffinity(getpid(),1)
[]
; Данный пример привязывает текущий процесс к последнему по номеру процессору:
[&CronSrv.StartupScript]
pidaffinity(getpid(),2^(cpu_count()-1))
[]
; Данный пример привязывает текущий процесс ко всем процессорам системы,
; то есть фактически отменяет привязку:
[&CronSrv.StartupScript]
pidaffinity(getpid(),2^cpu_count()-1)
[]
Новые функции позволяют избежать написания кода на DAQ Pascal, управляющего привязкой процессоров,
сосредоточив его в секциях [&CronSrv.StartupScript], [&CronSrv.FinallyScript],
что упрощает разработку и конфигурирование DAQ-систем.
Введенные функции были сразу добавлены в конфигурацию DEMO_OSM,
в качестве примера.
На системе DEMO_OSM были протестированы временные характеристики каналов
связи Modbus RTU при различных вариантах подключения:
Вариант | Poll/s | I/O,ms | GapTime,ms
-------------+--------+--------+-----------
native win32 | 32 | 10 | 15
vbox+com | 30 | 16 | 10
vbox+ser2net | 20 | 32 | 10
-------------------------------------------
native win32 - вариант подключения к реальной системе Windows со штатными COM портами
vbox+com - вариант Windows под VirtualBox c проброской (до 4) COM портов штатными средствами VirtualBox
vbox+ser2net - вариант Windows под VirtualBox c проброской (до 32) COM портов средствами ser2net
Poll/s - число опросов в секунду (на один порт)
I/O,ms - время выполнения транзакции, мс
GapTime,ms - время междукадровой паузы, мс
Согласно тестам, максимально достижимая частота опроса виртуальной системы (vbox+com)
мало отличается от реальной системы Windows (native win32) и составляет около 30 Гц,
а частота опроса многопортовой виртуальной системы (vbox+ser2net) несколько ниже (около 20 Гц).
Тесты показали, что снижение времени междукадровой паузы (GapTime) приводит к появлению сбоев (Timeout).
Это связано с тем, что по стандарту Modbus RTU не предусмотрено управляющих символов,
а для разделения сообщений вместо них используется пауза.
В таблице указана минимальная междукадровая пауза, при которой опрос идет устойчиво.
Введение паузы снижает максимальную частоту опроса даже при использовании реальной системы Windows,
поэтому разница между реальной и виртуальной системой становится мало значимой.
Спецификация ("MODBUS over serial line specification and implementation guide V1.02",
раздел "2.5.1.1 MODBUS Message RTU Framing") говорит о том,
что междукадровая пауза (inter-frame delay) должна составлять не менее 3.5 символов,
а также дает рекомендацию делать её не менее 1.75 мс.
Видимо, реальная межкадровая пауза, которую реализуют производители, еще выше.
Вот что пишут на форуме asutpforum.ru
на тему "Предельная скорость линии ModBUS-RTU":
Со стандартным Modbus RTU все просто. Изначально были скорости до 19200 и 38400 бод.
Увеличивать скорости можно хоть до 10 Мбит, но пресловутые задержки 1.75 мс вместо 3.5 символов делают это бессмысленным.
Т.к. уже на скорости 230400 бод задержка 1.75 мс соответствует аж 36 символам, т.е. паузы больше чем пакеты.
Однако для высокопроизводительных процессоров никто не запрещает положить на эти ограничения
и использовать задержки 3.5 символа на высоких скоростях.
В итоге скорость такого Modbus RTU может быть очень высокой, главное чтобы все устройства в сети могли работать с такими задержками.
Если бы товарищи из modbus.org просто вписали бы в свой документ такую возможность
и обозвали бы такой Modbus например Modbus HS RTU (типа High Speed), то могли бы дать Modbus RTU вторую жизнь.
А в итоге ставку сделали на Modbus TCP.
P.S. А с другой стороны, о чем я? По факту ведь большинство Modbus слейвов в том числе именитых брендов
и до 1.75 мс ой как далеко,тупят по 10-70 мс. Итого чаще 10 опросов в секунду добиться в большинстве случаев нереально.
Именно от этого к Modbus RTU такое отношение выработалось.
P.P.S. По моему опыту 460800 бод и 1000 транзакций (запрос/ответ) в секунду для Modbus RTU (без ограничений 1.75 мс)
совершенно не проблема. Некоторые и на мегабитах работают.
Учитывая полученный опыт, при программировании &ModbusProxy следует быть очень внимательным
к выбору времени междукадровой паузы (GapTime), снижение которой может привести к сбоям связи,
а увеличение - к снижению частоты опроса.
Ситуация осложняется еще и тем, что выбор времени междукадровой паузы надо делать так, чтобы работали все
подключенные устройства, то есть ориентируясь на худшее из подключенных к данному порту устройств.
В реальной практике использования Modbus RTU оказывается, что из-за больших междукадровых пауз
полезное время передачи оказывается существенно меньше, чем эти паузы.
Тем не менее уменьшать паузы нельзя, иначе будут ошибки.
В результате скорость Modbus RTU оказывается существенно ниже теоретической для данного значения baud rate.
Следует отметить, что реально достигнутые скорости опроса (30 Гц) существенно ниже скоростей,
достижимых для устройств ADAM (около 200 Гц), что в ряде случаев может ограничивать применимость
протокола Modbus RTU в системах, требующих быстрого опроса.
28.06.2017
DEMO_MCA_SCAN
Обновлены сборки сторонних программ (netweb,office,mmedia).
Добавлены функции
DIM_GuiStdinSend,
DIM_GuiStdinRecv.
Они служат для передачи и приема консольных команд (сообщений) через защищенный механизм сенсорных "кликов".
Это облегчает создание интерфейсов DIM.
Обновлены сборки сторонних программ (netweb,office,mmedia).
Данная версия в основном продолжает темы 1)контроля целостности и 2)системы оповещений.
Исправлена ошибка в инсталляторе, из-за которой не обновлялись некоторые файлы в системном каталоге.
В Daq Pascal добавлена функция getpid,
которая возвращает идентификатор (номер) текущего процесса.
Эта функция полезна для организации межпроцессного взаимодействия с другими процессами.
Например, при организации сообщений @tooltip с кнопками можно организовать передачу команд
в консоль Crw32 по кнопке через send2crwdaq -p pid -c command.
Поправлены мелкие (не критические) погрешности предыдущей версии, связанные с Tooltip.
В стандартную библиотеку добавлена процедура ShowTooltip.
Она аналогична UnixTooltipNotifier,
но работает через команду @Tooltip (в том числе содержит антиспам).
Функция UnixTooltipNotifier сохранена для совместимости, но теперь считается устаревшей.
Обновлены UniHeat и DEMO_UNIHEAT.
В них задействованы возможности ShowTooltip для отображения справки.
Добавлена демо конфигурация DEMO_TRAMP2 от Н.Гурина с мелкими поправками.
Обновлена утилита TextMetaData. Изменения связаны с оптимизацией.
В первоначальной версии файл считывался в память целиком и затем обрабатывался в памяти.
Этот метод хорошо работает при небольшом размере файлов.
При обработке больших файлов (например, DAT) это может приводить к переполнению памяти.
В новой версии обработка ведется по мере чтения файлов, с небольшой загрузкой по памяти.
Внешний интерфейс утилиты не изменился.
Добавлена проверка контрольных сумм DAT файлов при чтении (Файл\Открыть).
Проверка контрольных сумм DAT файлов делается не прямым вызовом
FileCheckMetaData в теле программы, а через общий механизм правил @Integrity.
Это работает так:
1) При чтении файла в консоль посылается команда:
@silent @integrity load.dat filename.dat
2) В правилах @integrity есть правило обработки события load.dat
которое вызывает проверку @integrity --check данного файла:
@integrity --rule load.dat @silent @integrity --check $*
3) По результатам проверки генерируется команда @integrity, которая
содержит результат проверки, например:
@integrity MISSING:[MetaData]:@CheckSum filename.dat
4) В правилах @integrity есть правило обработки события MISSING:[MetaData]:@CheckSum,
по которому выдается необходимое сообщение.
5) Правила создаются динамически либо загружаются из INI файла, что придает
обработке событий контроля целостности большую гибкость.
Таким образом, вся проверка целостности производится средствами команды @integrity,
а клиентский программный код только инициирует проверку целостности.
Это позволяет гибко управлять обработкой событий контроля целостности.
Проверка контрольных сумм @integrity --check ... файлов и
добавление контрольных сумм @integrity --add ... в файл сделаны асинхронными операциями,
которые выделяются в отдельный поток @Integrity и исполняются параллельно, в фоновом режиме.
Это связано с тем, что проверка больших файлов может длиться довольно долго (зависит от размера файла).
Нельзя блокировать консоль на это неопределенное время.
Побочным эффектом может быть:
1) временная блокировка проверяемых файлов, пока происходит расчет контрольных сумм,
2) срабатывание сторожевого таймера Watchdog, если файл проверяется дольше 5 секунд.
Добавлена опция в команду @polling, которая открывает окно "Консоль Монитора Ресурсов"
и задает опции мониторирования:
@polling monitor - открывает "Консоль Монитора Ресурсов" с текущими опциями
@polling monitor * - открывает "Консоль Монитора Ресурсов" с опциями по умолчанию
@polling monitor -1 - открывает "Консоль Монитора Ресурсов" с опциями по максимуму
@polling monitor m - открывает "Консоль Монитора Ресурсов" с опциями m:
- 1: показывать счетчики объектов (objects)
- 2: показывать счетчики памяти (memorys)
- 4: показывать счетчики ссылок (handles)
- 8: показывать счетчики потоков (threads)
Новая опция введена для того, чтобы контролировать число потоков,
так как в большой системе бывает необходимо контролировать число потоков,
чтобы диагностировать возможные неполадки.
Опции монитора m введены потому что счетчики потоков - дорогостоящая операция,
требующая около 2% CPU, что вносит погрешность в измерение счетчиков загрузки.
Поэтому по умолчанию ссчетчики потоков отключены.
Для их активизации используется команда @polling monitor -1.
Добавлена опция в команду @tooltip, которая позволяет использовать всплывающие окна
вместо окон "Сторожевой таймер" и "Служба системного времени":
@tooltip --prefer 0 - все работает по старому
@tooltip --prefer 1 - сообщениям @tooltip отдается предпочтение перед диалогами
- "Сторожевой таймер" и "Служба системного времени"
@tooltip --prefer 1 срабатывает, если установлен пакет FP-QUI.
Начальное значение считывается из Crw32.ini [System.StartupScript].
Данная опция приводит к тому, что вместо окон "Сторожевой таймер" и "Служба системного времени"
генерируются всплывающие окна с сообщениями и кнопками. Это удобнее, т.к. всплывающие окна менее назойливы
и не мешают работе, в то же время давая возможность открыть диалоги в старом стиле.
Сделан сервер &DatSrv.
Раньше у нас этот сервер включался в виде программы
_DATSAVE.PAS,
которую надо было конфигурировать вручную.
Кроме того, имя сервера сохранения данных было непостоянным и менялось от системы к системе.
Теперь имя сервера &DatSrv фиксировано.
Кроме того, теперь для включения этого сервера достаточно вставить в [ConfigFileList] файл
Заметим, что все старые возможности использования программы _DATSAVE.PAS сохраняются.
Это может быть необходимым, например, если надо иметь несколько групп DAT файлов с разными префиксами.
В этом случае вдобавок к обычному &DatSrv серверу добавляются другие экземпляры программы с другими именами.
В сервер &DatSrv добавлен код контроля целостности данных.
А именно, при смене суток, а также при завершении сеанса работы вызывается команда
@Integrity --add filename.dat, которая подсчитывает контрольную сумму DAT файла.
Таким образом, контроль целостности теперь распространяется и на DAT файлы, то есть все препятствия
для аттестации, связанные с контролем целостности файлов, теперь устранены.
Для сохранения обратной совместимости программа _DATSAVE.PAS на старых системах работает по-старому.
Для активизации новых возможностей программы _DATSAVE.PAS и сервера &DatSrv надо либо
использовать включение шаблонного файла ConfigFile = ~~\Resource\DaqSite\DatServer\DatSrv.cfg,
либо добавить в существующую конфигурацию параметр IntegrityMode:
[&DatSrv]
IntegrityMode = 0 ; отключить контроль целостности (по умолчанию)
IntegrityMode = 1 ; включить КЦ через команду @Integrity --add
IntegrityMode = 2 ; включить КЦ через команду @run /hide textmetadata --add
IntegrityMode = 3 ; включить КЦ через прямой вызов textmetadata --add
[]
Демо конфигурация DEMO_UNIHEAT обновлена с учетом нового сервера &DatSrv.
Её можно использовать как пример (образец) использования и конфигурирования &DatSrv.
Для облегчения конфигурирования стандартных серверов заведены файлы-сcылки:
Которые ссылаются на соответствующие стандартные серверы и включают их в конфигурацию.
Остается только задать дополнительные параметры серверов, поместив их в соответствующие секции.
Оповещения о загрузке/сохранении INI файлов также переведены на @Tooltip,
чтобы избежать навязчивых диалогов.
Заведены резервные сайты для размещения дистрибутива:
crw-daq.su и
зеркало.
27.03.2017
FP-QUI tooltip-notifier fpquitip
Данный релиз полностью посвящен системе всплывающих оповещений FP-QUI.
Важность этой системы связана с тем, что она является, например, основным средством оповещения
о нарушении целостности данных, о наличии серьезных сбоев работы программы и т.д.
Поскольку система "продвинутая" и позволяет не только привлекать внимание оператора через текст, звук,
картинки и анимацию, но также и позволяет получать обратную реакцию (через кнопки с командами),
то система оповещения становится важным инструментом в работе пакета.
Создан автономный инсталлятор install-daqgroup-notifier.exe, ставший частью дистрибутива.
Он инсталлирует пакет FP-QUI в стандартном месте (%ProgramFiles%\FP-QUI)
и регистрирует программу в реестре. Также он помещает в системный каталог (%SystemRoot%)
утилиты fpquitip.exe, fpquisend.exe (см. ниже), которые позволяют получить доступ
к возможностям FP-QUI из любого места.
Хотя система оповещения остается частью пакета UnixUtils (там все исходники), она также может работать
без установки UnixUtils, если её установить автономно. Это позволяет использовать пакет FP-QUI
как совместно с UnixUtils, так и без него. Это важно, учтитывая большой размер UnixUtils
и возможность ситуаций когда его установить по ряду причин нельзя.
Создана утилита fpquitip.exe, которая дает доступ к возможностям пакета FP-QUI.
Эта утилита является (по возможности) точным аналогом tooltip-notifier, но выполяется
существенно быстрее, так как сделана в виде EXE файла (написанного на Object Pascal).
После инсталляции install-daqgroup-notifier.exe следующие вызовы эквивалентны:
unix tooltip-notifier - работает если проинсталлирован пакет UnixUtils
unix fpquitip - работает если проинсталлирован пакет UnixUtils
fpquitip - работает если проинсталлирован пакет FP-QUI
Команда tooltip-notifier модифицирована таким образом, что в случае инсталляции пакета FP-QUI
она передает управление команде fpquitip.exe для ускорения работы. Если эта команда не найдена
(то есть пакет FP-QUI не установлен), то все выполняется по-старому.
Вызов unix tooltip-notifier теперь выполняется лишь немногим медленнее вызова fpquitip.exe
(при условии что пакет FP-QUI установлен).
Таким образом сохраняется обратная совместимость и при этом приобретается более высокая скорость.
Команда tooltip-notifier остается в силе (и будет сохранена для совместимости), но в новых проектах
рекомендуется использовать fpquitip.
Команда @tooltip Главной Консоли модифицирована так, что она должна работать как в случае установки
FP-QUI, так и в случае установки UnixUtils. То есть ищется файл fpquitip.exe, либо
файл unix.exe при его отсутствии. И соответственно вызывается
cmd /c fpquitip - при установленном FP-QUI
unix tooltip-notifier - при установленном UnixUtils
То есть система оповещения сделана более надежной и менее зависимой от окружения.
Можно поставить небольшие по объему пакеты (runtime+notifier) - и система оповещения должна работать.
Многочисленные дополнения в команде tooltip-notifier (и соответственно fpquitip).
В первую очередь изменения касаются "динамически обновляемых окон",
то есть окон, которые не создаются каждый раз при поступлении сообщений,
а обновляют свое содержимое. Поскольку окна существуют глобально, в другом
процессе, то для идентификации окон используются "глобальные идентификаторы" - GUID.
В качестве GUID можно использовать любую уникальную в рамках данного сеанса строку,
однако для обеспечения гарантрованной уникальности рекомендуется генерировать для каждого
типа сообщений глобально уникальные строки командой
unix getguid
Каждый вызов getguid возвращает новую уникальную строку - идентификатор,
которая никогда не повторяется. Например, {DB2EE970-A4FA-440F-AEEB-1CCAEC898999}.
Полученный идентификатор можно использовать в качестве параметра GUID для однозначной идентификации окон.
В команду tooltip-notifier добавлены следующие опции:
unix tooltip-notifier guid G - Вывод динамически обновляемого окна с идентификатором G.
- Название GUID происходит от global unique identifier, т.е.
- глобально уникальный идентификатор. GUID используется для
- идентификации окон сообщений, чтобы можно было различать их.
- Идентифицировать окна необходимо в случае динамического
- обновления окна, когда окно не создается вновь, а обновляет
- содержимое уже существующего окна.
unix tooltip-notifier delete G - Удаляет окно с идентификатором GUID.
- Удалять GUID надо после завершения работы с сообщениями данного
- типа, чтобы очистить память, занятую под GUID. При большом числе
- различных сообщений с разными GUID список идентификаторов может
- замедлить работу системы. Во избежание этого GUID надо удалять.
unix tooltip-notifier sure C - Это короткий синоним флага createIfNotVisible. Переводится как
- "уверен". То есть при "sure 1" можно быть уверенным, что окно
- будет показано на экране. При "sure 0" такой уверенности нет,
- так как окно может не существовать.
unix tooltip-notifier createIfNotVisible С - Задает флаг C = 0/1 = "создать окно, если оно не существует".
- Этот флаг используется только совместно с GUID. По умолчанию
- при указании GUID флаг равен 1, то есть если задан GUID, то
- окно создается всегда. Однако можно отменить автоматическое
- создание окна. Например, если выдается ряд однотипных сообщений
- с разным приоритетом, может закрыть окно, и новое окно с тем же
- значением GUID не будет отображаться, если в сообщении указан
- нулевой флаг.
unix tooltip-notifier run "cmd arg" - Выполнить команду "cmd arg" при получении сообщения и после
- отображения окна с сообщением. Если окно не отображается из-за
- флага GUID + createIfNotVisible, то команда не выполняется.
unix tooltip-notifier progress p - Отображает полосу прогресса с процентами исполнения от 0 до 100.
- Полоса прогресса используется совместно с GUID, чтобы можно было
- динамически обновлять состояние, используя идентификатор GUID.
unix tooltip-notifier xml "<..>" - Добавляет к сообщению XML выражение.
unix tooltip-notifier --demo - демо с использованием различных возможностей системы оповещения.
Вот пример, в котором показывается прогресс некоторой операции
(предполагается, что вызовы делаются по завершении очередного шага):
Обратите внимание, что при помощи sure 0 разрешается закрытие окна прогресса щелчком мыши.
При этом новые сообщения появляться не будут, пока процесс не дойдет до 100%.
Последнее сообщение при 100% появится обязательно, т.к. для него действует значение по умолчанию sure 1.
В систему оповещения добавлена библиотека анимаций для стандартных наборов (preset).
Посмотреть работу библиотеки можно командой
unix tooltip-notifier --demo
или
fpquitip --demo
Сообщения при загрузке и завершении работы, а также проверки целостности приведены в соответсвие с новыми
возможностями системы оповещения. Если точнее, поправлены командные файлы
Crw32.Logon.cmd,
Crw32.Verify.cmd,
Daq32.Verify.cmd).
При этом с помощью специального командного файла
(tooltip.cmd)
обеспечивается минимизация зависимостей.
То есть сначала проверяется, установлен ли пакет FP-QUI, затем пакет UnixUtils,
а при их отсутствии сообщение выдается с помощью команды msg.
Таким образом сообщение будет выдано - тем или иным доступным способом.
Командный файл tooltip.cmd доступен в консольной команде @run:
@run /hide tooltip text "Hello world" preset stdTooltip delay 15000
При этом, как уже было сказано, команда tooltip гарантирует появление какого-то сообщения
и выбирает наиболее подходящий способ его отображения (через команды fpquitip,
unix tooltip-notifier или msg).
Сводная таблица команд оповещения
--------------------------------------------------------------------------------------
| Команда | Вызывается из | Выдает | Требует установки |
------------------------|-------------------------------------------------------------
| fpquitip | cmd/bat файлов | tooltip | FP-QUI |
| unix tooltip-notifier | cmd/bat файлов | tooltip | UnixUtils |
| @run /hide tooltip | Главной Консоли | tooltip или msg | Работает всегда |
| @run /hide fpquitip | Главной Консоли | tooltip | FP-QUI |
| @tooltip | Главной Консоли | tooltip | FP-QUI или UnixUtils |
|-------------------------------------------------------------------------------------
FP-QUI устанавливается install-daqgroup-notifier.exe
UnixUtils устанавливается install-daqgroup-unixutils.exe
Формат аргументов у всех команд одинаковый.
Они отличаются зависимостями и гарантией вывода в случае отсутсвия дополнительных пакетов.
Команда @tooltip не сделана "работающй всегда" сознательно.
Дело в том, что при отсутствии пакетов FP-QUI или UnixUtils сообщения, конечно,
можно выдавать с помощью запасного метода - командой msg, но эта команда выдает окно,
ведущее себя довольно назойливо (расположено в центре экрана и закрывает основное поле программы).
Поэтому команда @tooltip оставлена для обычных ссообщений (ненавязчивые, но зависят от установки
пакетов FP-QUI или UnixUtils), а особо важные сообщения с гарантией отображения вызываются
через @run /hide tooltip. Есть выбор.
Система всплывающих оповещений FP-QUI все еще допускает возможность оптимизации,
но необходимость дальнейшей оптимизации пока не очевидна.
Например, можно реализовать посылку сообщений в систему FP-QUI минуя вызов fpquitip прямо из пакета CRW32.
Однако в этом случае потеряются некоторые возможности, существующие при вызове через команду @run
(например, подстановка переменных окружения типа %Temp%, даты\времени %date%\%time% и текущего каталога %cd%).
Кроме того, не хочется без необходимости раздувать исполняемый файл основного пакета.
Поэтому пока поработаем с таким вариантом FP-QUI.
Если производительности все еще будет не хватать, сделаем более быстрый вариант.
(Код для этого уже есть, его просто надо вставить в пакет).
Поэтому система всплывающих оповещений FP-QUI пока считается (условно) завершенной.
14.03.2017
tooltip-notifier fpquisend.exe
Дополнение в команде tooltip-notifier.
В ней добавлены кнопки (до 9 кнопок btn1..btn9),
при нажатии которых выполняется соответствующая команда (cmd1..cmd9):
Еще одно дополнение в команде tooltip-notifier.
В ней добавлена анимация (avi):
unix tooltip-notifier ... avi error.avi
Кроме того, анимация вставлена в стандартные наборы (preset).
Анимация служит для привлечения внимания к сообщениям.
Она сделана с помощью специальных avi-файлов малого размера (32x32).
Эти avi-файлы делаются из набора bmp-файлов с помощью утилиты makeavi.exe (которая добавлена в UnixUtils\add\makeavi\).
Типичная анимация содержит 5-10 кадров размера 32x32 и занимает немного (20-30 кб).
Реакция на события Центра Контроля Целостности сделана с учетом новых возможностей (с кнопкой просмотра Журнала).
Система оповещения частично оптимизирована, но все еще допускает существенное увеличение производительности (снижение нагрузки).
Возможно, это будет сделано в будущих версиях.
Небольшое изменение в переменных окружения.
Добавлена переменная CRW_DAQ_CONFIG_TIME_UNITS.
Это может пригодиться в сценариях препроцессора и постпроцессора.
Сделаны метки календарного времени по оси X.
В настоящей версии был реализован вариант, требовавший наименьших изменений в программе.
Календарное время отображается более мелкими буквами вдоль верхней оси абсцисс,
а нижняя ось линейного времени и разметка линий по оси X оставлена неизменной.
Отступ сверху слегка увеличен (на 16px), чтобы уместились надписи с датами.
Визуально это увеличение не очень заметно.
Фонт для шкалы времени описан в секции Crw32.ini [DefaultTimeAxisFont]. По умолчанию это PT Mono 7pt.
Размер фонта (параметр Height) можно брать равным -9 (7pt) или -11 (8pt).
Более мелкие фонты не читабельны, а более крупные могут не уместиться в отведенном поле.
Фонт для шкалы времени должен быть моноширинным (monospace, fixed width).
Такой вариант выбран по следующим причинам.
В пакете, работающем online с данными, быстро меняющимияся в широком диапазоне значений в реальном времени,
приемлемая автоматическая разметка предпочтительнее красоты, достигаемой в пакетах offline обработки.
Работающий алгоритм хорошо справляется с автоматической разметкой линейной шкалы, и ломать его не стоит.
Недостатком данного варианта является то, что разметка, хорошая для линейного времени (например в часах
с полуночи с десятичными долями) не является хорошей разметкой в календарном времени.
Дело в том, что линейное время градуируется в метрической (десятичной) системе,
а время - нет (24 часа, 60 минут, 60 секунд).
Более того, календарная градуировка принципиально неравномерна (в месяцах и годах переменное число единиц).
Поэтому надписи с календарным временем по осям будут не "круглыми". Чтобы сделать "круглые" календарные метки,
надо полностью менять разметку оси X, но тогда линейная разметка станет "некруглой".
В общем, существующая реализация не идеальна, но пока менять хорошо отлаженный код не целесообразно.
Поработаем с этим вариантом - будет видно, нужны ли более серьезные изменения.
Пусть не "круглые", но все-таки какие-то ориентиры календарного времени будут.
Плюс не забываем про отображение даты и времени курсора мыши в статусе.
Для управления отображением шкалы времени также добавлена кнопка в окне и пункт меню "Шкала Времени по X".
Этой кнопкой можно быстро включать и отключать шкалу времени - если она доступна.
Шкала времени недоступна, если окну не задана точка отсчета и масштаб времени.
Шкала времени задается автоматически в окнах DAQ системы.
Окна, открытые вне DAQ системы, шкалы времени по умолчанию не имеют.
Ведь это может быть произвольный набор данных, а не только время.
Для активизации меток календарного времени по оси X в окна добавлена переменная WantTimeAxisX,
задающая начальное желаемое значение отображения шкалы времени по оси Х (1/0 = отображать или нет).
Переменная считывается последовательно из:
Это позволяет указывать в описанных секциях поведение конкретного окна или всех окон по умолчанию.
Напоминаю, что это стартовое значение отображения шкалы времени, которое может быть изменено кнопкой в процессе работы.
Переменная WantTimeAxisX также задается в шаблонном файле
Resource\DaqSite\Default\DAQ.cfg.
При чтении разметки осей окон кривых (AxisX,AxisY) теперь строки не переводятся в верхний регистр, как было раньше.
Это позволяет делать разметку осей более естественным образом.
Серьезно изменен диалог "Пределы графика" для задания диапазона осей координат графика окна с кривыми.
В него добавлена страница "Шкала времени X", в которой можно посмотреть и задать шкалу времени окна.
Раньше эта возможность (просмотра и редактирования шкалы времени окна) отсутствовала, что является недостатком.
Поэтому не было возможности задавать шкалу времени иначе как использовать окна, созданные в DAQ-системе,
где шкала времени окон задается при старте DAQ. Теперь можно смотреть и редактировать шкалу времени в любых окнах.
Это полезно, например, если измеренные данные были сняты при "сбитых" (неверно показывающих) часах.
В этом случае прочитанные даные будут показываеть неверное (смещенное) значение календарного времени.
Теперь, однако, можно отредактировать шкалу времени окна, чтобы метки календарного времени были корректными.
Здесь надо быть внимательным, потому что в паспорте кривых тоже фиксируется шкала времени DAQ-системы,
и она может использоваться в процедурах обработки данных.
Шкала времени окна влияет на отображение данных и также может быть использована в обработке.
При ручном редактировании шкалы времени окна может возникнуть несоответствие между шкалой времени окна и шкалой времени, записанной в кривых.
При правильном задании шкалы времени на график будут выдаваться правильные метки времени на оси Х
и сообщения о времени положения курсора мыши в статусе.
Шкала времени для окон DAQ системы задается автоматически при загрузке конфигурации.
Система всплывающих сообщений (tooltip notifier) давно стала важной частью пакета.
Она, в частности, используется для оповещений инсталлятора, системы безопасности и контроля целостности данных.
Однако до сих пор существовала неуверенность в будущем выбранного для этого графического пакета (FP-QUI).
В то же время поиск альтернатив не дал результата - другие системы оповещения по тем или иным признакам не подходят.
Хотелось этот вопрос решить раз и навсегда. В связи с этим была проведена следующая работа.
Обновлен пакет FP-QUI (который и выдает всплывающие сообщения) и наконец-то получен его исходный код.
Для этого пришлось связаться с автором (Florian Pollak) и попросить его выложить недостающие исходники.
Флориан прислал эти исходники и обновил бинарники.
Исходники (на языке AutoIt3) компилируются нормально.
Есть нерешенные проблемы (с кодировками) и кроме того возможно будет дальнейшее развитие этого проекта.
Но в целом вопрос с системой оповещения теперь окончательно решен (есть компилируемые исходники).
Также обновлена команда unix tooltip-notifier.
В нее добавлена опция preset, позволяющая выбирать по имени один из предопределенных наборов параметров:
unix tooltip-notifier text "Сообщение об ошибке" preset stdError delay 15000
Здесь выражение preset stdError заменяет собой длинную строку типа:
font "PT Mono Bold" fontSize 16 color red ico error.ico audio error.wav noDouble 1
в качестве имени набора preset можно использовать такие константы:
stdOk,stdNo,stdHelp,stdStop,stdDeny,stdAbort,stdError,stdFails,stdSiren,
stdAlarm,stdAlert,stdBreak,stdCancel,stdNotify,stdTooltip,stdSuccess,
stdWarning,stdQuestion,stdException,stdAttension,stdInformation,
stdExclamation
Их назначение понятно из названия. Например, preset stdError используется для сообщений об ошибках,
а preset stdSuccess для сообщений об успешном выполнении операций и т.д.
Введение опции preset позволит резко сократить и упростить описание всплывающих сообщений.
Сравните например:
unix tooltip-notifier text "Сообщение об ошибке" preset stdError delay 15000
и
unix tooltip-notifier text "Сообщение об ошибке" font "PT Mono Bold" fontSize 16 color red ico error.ico audio error.wav noDouble 1 delay 15000
В то же время все предыдущие возможности unix tooltip-notifier сохраняются в полном объеме.
В целях унификации и упрощения организации всплывающих сообщений проделана следующая работа.
Добавлена очень полезная команда Главной Консоли - @Tooltip. Она вызывает всплывающее уведомление.
Собственно, в данный момент это эквивалент вызова @run /hide unix tooltip-notifier.
Однако рекомендуется в дальнейшем использовать команду @Tooltip,
а не вызов @run /hide unix tooltip-notifier.
Потому что во-первых, функционал команды @Tooltip несколько шире (есть "антиспам"),
а во-вторых, со временем реализация всплывающих подсказок может измениться (с сохранением синтаксиса).
Команда unix tooltip-notifier сохраняет свое значение для автономных задач (командных файлов),
а в рамках пакета лучше использовать команду @Tooltip.
Рассмотрим пример:
В этом примере сначала задается "глухое время" 15 секунд командой @tooltip --deaf 15.
Это значит, что в течение 15 секунд всплывающие сообщения такого же вида будут игнорироваться.
Это своего рода "антиспам" в случае, если одинаковые сообщения об ошибках возникают слишком часто.
Потом выдается всплывающее сообщение об ошибке на 25 секунд с стандартным оформлением для ошибок (preset stdError).
Подробности можно узнать вызовом команды @Tooltip без параметров.
Добавлена очень полезная команда Главной Консоли - @Log.
Она обеспечивает работу с журнальными (log) файлами.
@log --event Temp\demo.log Сообщение Запишет дату, время и Сообщение в файл Temp\demo.log
@log --print Temp\demo.log Сообщение Запишет простое Сообщение в файл Temp\demo.log
@log --view Temp\demo.log Вызовет просмотр файла Temp\demo.log
@log --delete Temp\demo.log Удалит файл Temp\demo.log
Примечания:
1) Имена журнальных файлов заданы относительно каталога программы.
2) Допустимо также использовать в именах переменные окружения Windows (типа %Temp%),
а также специальные переменные окружения пакета CRW-DAQ%CRW_DAQ_SYS_HOME_DIR% (каталог программы Crw32.exe),
%CRW_DAQ_CONFIG_HOME_DIR% (каталог DAQ-конфигурации).
Запись в журнальные файлы ведется асинхронно в отдельном потоке с именем @Log,
поэтому команда @Log не задерживает Главную Консоль и не мешает другим командам.
Работать с журналами можно интерактивно в Главной Консоли или из программ DAQ Pascal.
Журналы были добавлены в первую очередь для поддержки средств контроля целостности данных (см.далее).
Однако журнальные файлы могут применяться для любых других целей в случае необходимости ведения тех или иных журналов.
Подробности можно узнать вызовом команды @Log без параметров.
Добавлена утилита просмотра журнальных файлов winlog с автоматическим скроллингом.
Доступна через @run winlog ... и unix winlog.
Используется в команде @Log --view.
Добавлено средство контроля целостности файлов калибровок, а также любых текстовых файлов с секционной структурой - CFG, INI, CRC, CAL, DAT и т.д.
Средство контроля целостности - функция TextMetaData - пригодна для работы с любыми секционированными текстовыми файлами,
но пока контроль включен только для файлов калибровок и (частично) INI файлов (для других типов файлов контроль пока просто не подключен).
Контроль целостности нужен, в частности, для решения вопросов аттестации.
Это сделано следующим образом:
В файл калибровки при записи добавляется секция [MetaData].
Эта секция содержит метку времени, контрольную сумму и другую дополнительную информацию о данных.
Информацию о данных обычно называется метаданными, от латинского meta - цель, предел, край.
Например, размер и имя файла - это метаданные по отношению к содержимому файла.
Так же и здесь - секция метаданных содержит дополнительную информацию о данных, содержащихся в файле.
Контрольная сумма записывается в переменную @CheckSum.
Расчет контрольной суммы (хэш-суммы) ведется по стандартному алгоритму MD5 и записывается в hex-кодировке.
При подсчете контрольной суммы секция [MetaData] вырезается из текста,
так что в контрольную сумму входит всё содержимое файла кроме секции метаданных.
Поэтому в секцию метаданных можно записывать любую информацию без нарушения контрольной суммы.
Это позволяет записать в метаданные и саму контрольную сумму.
Метка времени записывается в переменных @DateTime (календарное время) и @TimeStamp (линейное время).
Метка времени фиксирует момент записи файла и контрольной суммы. В секцию метаданных могут быть также
записаны любые другие текстовые данные в формате "Имя=Значение".
Пример:
При чтении текста секция [MetaData] игнорируется, т.е.
при подсчете контрольной суммы секция [MetaData] вырезается из текста,
так что в контрольную сумму входит всё содержимое файла кроме секции метаданных.
Поэтому секция метаданных может быть отредактирована без изменения контрольной суммы.
Сохраненная в файле в секции метаданных контрольная сумма дешифруется и сравнивается
с контрольной суммой прочитанного текста.
По результатам проверки выдается результат:
0 = Success - проверка целостности прошла успешно
1 = Missing - отсутствует файл или секция [MetaData] в файле
2 = Invalid - контрольная сумма текста не совпадает с сохраненной
3 = Failure - произошел сбой - ошибка чтения, нехватка памяти и т.д.
Результат проверки посылается в Главную Консоль в виде команды @silent @integrity.
@silent @integrity SUCCESS:[MetaData]:@CheckSum file.cal - если проверка файла (file.cal) успешна
@silent @integrity MISSING:[MetaData]:@CheckSum file.cal - если файл или контрольная сумма не найдена
@silent @integrity INVALID:[MetaData]:@CheckSum file.cal - если контрольная сумма не совпадает
@silent @integrity FAILURE:[MetaData]:@CheckSum file.cal - если произошел сбой чтения файла
При выполнении команды должна возникнуть реакция в виде сообщения о нарушении целостности.
Эта реакция задается в виде правил @Integrity --rule, см. ниже.
Добавлена команда Главной Консоли - @TextMetaData.
Через нее можно вызывать утилиту контроля целостности интерактивно или из программ DAQ Pascal.
@textmetadata - получить справку по команде
@textmetadata -a c:\Daq32\Demo\Calibr\Demo.cal - добавить метаданные в файл калибровки (add)
@textmetadata -c c:\Daq32\Demo\Calibr\Demo.cal - проверить целостность файла калибровки (check)
Утилита носит вспомогательный характер, её функционал входит также в команду @integrity.
Добавлена также автономная консольная программа TextMetaData.exe, которая включена в UnixUtils.
Через нее можно вызывать утилиту контроля целостности интерактивно в консоли cmd или из командных файлов операционной системы.
cmd - открыть консоль cmd
textmetadata - получить справку по команде
textmetadata -a c:\Daq32\Demo\Calibr\Demo.cal - добавить метаданные в файл калибровки (add)
textmetadata -c c:\Daq32\Demo\Calibr\Demo.cal - проверить целостность файла калибровки (check)
Наличие отдельной автономной программы TextMetaData.exe весьма полезно,
т.к. позволяет обрабатывать целые группы файлов одним циклом. Для организации цикла можно использовать
командные файлы:
for %%i in ( *.cal ) do unix TextMetaData -a %%i rem добавить контрольные суммы калибровок
for %%i in ( *.cal ) do unix TextMetaData -c %%i rem проверить контрольные суммы калибровок
Для облегчения групповой обработки файлов сделана также автономная консольная итерационная программа
TextMetaDataLoop.cmd, которая тоже включена в UnixUtils.
Эта утилита, в отличие от TextMetaData.exe, может принимать в качестве аргументов не один файл,
а список файлов и файловых шаблонов типа *.cal, *.ini.
Она вызывает команду TextMetaData.exe для каждого файла, подходящего под шаблон.
При этом возможна рекурсивная обработка подкаталогов.
Например:
unix textmetadataloop - справка по команде
unix textmetadataloop -c *.cal *.ini - проверить целостность файлов *.cal *.ini в текущем каталоге
unix textmetadataloop -a *.cal *.ini - добавить контр.суммы в файлы *.cal *.ini в текущем каталоге
unix textmetadataloop -r -c *.cal *.ini - проверить целостность файлов *.cal *.ini рекурсивно
unix textmetadataloop -r -a *.cal *.ini - добавить контр.суммы в файлы *.cal *.ini рекурсивно
Данная утилита позволяет легко обрабатывать весь каталог DAQ-системы одним махом,
проверяя или вычисляя контрольные суммы выбранных файлов во всех подкаталогах.
Её также можно включать в препроцессор для автоматической проверки файлов.
Команда также доступна в Главной Консоли через @run unix textmetadataloop или просто @run textmetadataloop.
Добавлены новые возможности в команду Главной Консоли @integrity, которая превращает её
в полноценный программируемый Центр Контроля Целостности Данных.
Это достигается при помощи ПРАВИЛ (команда @Integrity --rule).
Правила описываются выражениями:
@integrity --rule name body Каждое правило (поименованная последовательность команд) описывает действия @integrity в зависимости
от типа (или имени name) поступающих сообщений. Тип сообщений передается в первом слове поступающих данных.
Таким образом, каждый тип сообщений вызывает свою (программируемую) последовательность команд обработки.
При описании правил после ключевого слова --rule указывается тип (имя) сообщения name и тело body правила.
Тело правила - это команда, которая при обработке поступающих данных помещается в консоль для исполнения.
Для каждого типа сообщений можно задать много правил, исполняемых последовательно, то есть фактически задавать небольшую программу.
При этом в теле правила возможны ссылки - подстановки для поступающих данных: $*, $1, $2 и т.д.
Подстановки позволяют указывать на все данные ($*) или слова ($1,$2,..$9),
а также выделять имена директорий, файлов и расширений ($d1,$n1,$x1).
Рассмотрим пример:
1) Очищаем старое и создаем новое правило (--rule) для событий:
Success:[MetaData]:@CheckSum успешной проверки файла
Missing:[MetaData]:@CheckSum ошибки отсутсвия контрольной суммы
Invalid:[MetaData]:@CheckSum ошибки неверной контрольной суммы
Failure:[MetaData]:@CheckSum ошибки чтения файла
@integrity --rule Success:[MetaData]:@CheckSum
@integrity --rule Success:[MetaData]:@CheckSum @silent @echo Успешное чтение файла $1
@integrity --rule Missing:[MetaData]:@CheckSum
@integrity --rule Missing:[MetaData]:@CheckSum @silent @echo Нет контрольной суммы в файле $1
@integrity --rule Missing:[MetaData]:@CheckSum @silent @tooltip text "Нет контрольной суммы в файле $x1" preset stdError delay 15000
@integrity --rule Invalid:[MetaData]:@CheckSum
@integrity --rule Invalid:[MetaData]:@CheckSum @silent @echo Ошибка контрольной суммы суммы файла $1
@integrity --rule Invalid:[MetaData]:@CheckSum @silent @tooltip text "Ошибка контрольной суммы файла $x1" preset stdError delay 15000
@integrity --rule Failure:[MetaData]:@CheckSum
@integrity --rule Failure:[MetaData]:@CheckSum @silent @echo Ошибка чтения в файле $1
@integrity --rule Failure:[MetaData]:@CheckSum @silent @tooltip text "Ошибка чтения файла $x1" preset stdError delay 15000
При создании правил действуют такие подстановки:
$* - весь список аргументов
$1..$9 - аргумент (слово) 1..9
$d1 - директория аргумента 1 (аналогично 2..9)
$n1 - имя файла аргумента 1 (аналогично 2..9)
$x1 - расширение аргумента 1 (аналогично 2..9)
2) Смотрим и проверяем правила:
@integrity --rule
3) Тестируем правила, вводя в консоль тестовые события:
@integrity Success:[MetaData]:@CheckSum demo.cfg
В консоли должно появиться сообщение:
Успешное чтение файла demo.cfg
4) Теперь в случае чтения файла калибкровки (например c:\Dag32\Demo\Calibr\demo.cal) будут генерироваться
события и по ним выполняться заданные действия в соответствии с введенными правилами.
Правила для Центра Контроля Целостности Данных могут задаваться, например, в секции
[&CronSrv.StartupScript], а также могут генерироваться программно.
В настоящее время в пакете реализована генерация следующих событий @integrity:
Success:[MetaData]:@CheckSum filename успешная проверка файла функцией TextMetaData при загрузке файла
Missing:[MetaData]:@CheckSum filename ошибка отсутсвия контрольной суммы в файле в секции [MetaData]
Invalid:[MetaData]:@CheckSum filename ошибка значения контрольной суммы в файле в секции [MetaData]
Failure:[MetaData]:@CheckSum filename ошибка чтения файла при проверке утилитой TextMetaData
save.cal filename сохранен CAL файл
load.cal filename загружен CAL файл
save.crc filename сохранен CRC файл
load.crc filename загружен CRC файл
save.crw filename сохранен CRW файл
load.crw filename загружен CRW файл
save.dat filename сохранен DAT файл
load.dat filename загружен DAT файл
save.cfg filename сохранен CFG файл
load.cfg filename загружен CFG файл
Примечание:
1) Здесь filename означает полное имя проверяемого файла
2) При создании правил можно использовать $1 (полное имя), $d1 (директория), $n1 (имя), $x1 (расширение).
Система правил для Центра Контроля Целостности Данных позволяют гибко управлять обработкой
событий проверки и оповещения при проверке целостности данных.
Для очистки всех правил можно использовать команду @integrity --clear,
а для загрузки правил из файла можно использовать команду @integrity --load.
Например:
Для проверки и генерации контрольных сумм метаданных можно использовать команды
@integrity --add, @integrity --check:
@integrity --add file data - добавить в файл контрольную сумму и (необязательные) метаданные (URL-encoded)
@integrity --check file - проверить файл и сгененрировать сообщение @integrity с результатами проверки
Эти команды дублируют функции команды @TextMetaData, но кроме того по результатам выполнения команды
генерируется сообщение @integrity, в котором передается результат проверки и имя проверенного файла.
Это сообщение обрабатывается с помощью заданных командой @integrity --rule правил.
Правила по умолчанию загружаются из секции [@integrity.DefaultRules] файла Crw32.ini.
Эта секция также может служить образцом для задания своих правил.
Правила по умолчанию реагируют на результаты проверки выдачей сообщений в консоль и всплывающих сообщений при ошибках.
Это приведет к появлению сообщений об отсутствии контрольных сумм в файлах .CAL при загрузке калибровок.
Чтобы их погасить, есть несколько способов:
Загрузить и сохранить каждую калибровку в Диалоге Калибровок. Муторно, но думать не надо.
Вызвать для каждого файла калибровки команду @textmetadata -a file.cal или @integrity -a file.cal.
Вызвать для каждого файла калибровки автономную команду unix textmetadata file.cal.
Этот вариант удобен тем, что команду можно зациклить, чтобы обработать группу файлов.
Вызвать для группы файлов команду unix textmetadataloop, позволяющая обрабатывать много файлов
сразу по заданному шаблону имени файла.
Поскольку при работе Центра Контроля Целостности Данных идет интенсивный обмен сообщениями
(особенно в момент загрузки), была найдена и устранена проблема переполнения буфера Главной Консоли.
Это, кстати, могло приводить к подвисанию Главной Консоли, когда она перестает реагировать на ввод.
Теперь буферы существенно увеличены, а кроме того позволен их динамический рост до достаточно
больших пределов (в настоящее время этот предел установлен в 64 МБ).
Дополнительный буфер выделяется только по факту переполнения, поэтому система возьмет не больше, чем надо.
В то же время принципиально предел должен оставаться, чтобы система была защищена от фатального сбоя
при возникновении бесконечной рекурсии по сообщениям (которая в принципе возможна при неверном
программировании правил).
Добавлен типовой конфигурационный файл
Resource\DaqSite\Default\Integrity.cfg,
в котором задаются образцы для задания правил для Центра Контроля Целостности Данных.
Он используется совместно с сервером &CronSrv.
Его можно использовать как образец для создания новых конфигураций,
а также можно включать в свои конфигурации как готовый инструмент:
Немного поправлена демонстрационная конфигурация DEMO_UNIHEAT.
В ней используются типовые (Default) конфигурации DAQ.cfg,
Integrity.cfg.
Немного поправлена система UniHeat в плане интерфейса. Редакция Н.Гурина.
Обновлен пример DEMO_TMC610 драйвера для управления шаговыми двигателями.
Разработка Н.Гурина, все вопросы к нему. В конфигурации применена утилита textmetadata для защиты файлов калибровок.
Стандартная библилтека модифицирована так, чтобы обеспечить автоматическую проверку INI-файлов.
Если точнее, измененена функция CustomIniRW,
которая при сохранении и загрузке INI-файлов посылает в Главную Консоль команду
@integrity, которая и осуществляет проверку.
При записи INI-файлов в них добавляется контрольная сумма, а при чтении она проверяется.
По результатам проверки выдается сообщение в консоль и всплывающее сообщение.
Таким образом, при использовании стандартной библиотеки защита INI-файлов обеспечивается автоматически.
При этом INI-файлов, разумеется, должны быть исключены из подсчета контрольных сумм checksum.md5.
Таким образом, защита данных концептуально строится так:
Исполняемые файлы CRW защищаются автоматически при инсталляции пакета контрольными суммами checksum.md5
и проверяются с помощью checksum.exe, вызов которой происходит автоматически в сценарии Crw32.Logon.cmd.
По результатам проверки выдается всплывающее сообщение.
Контрольными файлами пакета являются checksum.md5 (в каталоге пакета Crw32exe) и checksum.exe,
которые обеспечивают защиту всего остального.
Их самих защищают при помощи свободной утилиты HashCheck, которая также входит в сборку crw32-runtime.
Конфигурационные файлы прикладной DAQ-системы защищаются контрольными суммами checksum.md5
и проверяются с помощью checksum.exe, которая вызывается интерактивно или автоматически из препроцессора.
Для автоматической проверки надо вставлять вызов DAQ.Verify.cmd в препроцессор и постпроцессор.
Это делается индивидуально для каждой системы. По результатам проверки выдается всплывающее сообщение.
Контрольными файлами DAQ-системы являются checksum.md5 (в каталоге DAQ-системы) и checksum.exe (тот же самый),
которые защищают все нужные файлы DAQ-системы (конфигурации, программы DAQ Pascal и т.д.).
Их самих защищают при помощи свободной утилиты HashCheck, которая также входит в сборку crw32-runtime.
Калибровки и INI-файлы, поскольку они меняются, исключаются из списка файлов checksum.md5 и защищаются другими средствами.
Файлы калибровок (.CAL) и файлы инициализации (.INI) защищаются собственными контрольными суммами при помощи секции [MetaData] @CheckSum.
Запись контрольных сумм в метаданные идет при сохранении файла в Диалоге Калибровки либо вызовом утилиты
unix textmetadata -a file или команды @textmetadata -a file или команды @integrity -a file.
Проверка контрольных сумм вызывается автоматически при загрузке, либо вызовом утилиты
unix textmetadata -c file или команды @textmetadata -c file или команды @integrity -c file.
Файлы калибровок и INI-файлы не включаются в контрольные суммы checksum.md5, так как уже защищены своими контрольными суммами.
Эти файлы могут меняться, при условии что они загружаются и сохраняются в Диалоге Калибровки или через стандартную библиотеку.
Команды unix textmetadata, @textmetadata, @integrity также могут менять контрольную
сумму, но они используются либо в сценариях автоматической обработки, либо разработчиками в процессе разработки.
Конечный же пользователь для изменения калибровок использует только Диалог Калибровки.
Любое ручное вмешательство в файлы калибровки будет обнаружено с выдачей всплывающего сообщения.
При этом Диалог Калибровки сам может быть защищен паролем средствами встроенного Центра Безопасности.
Таким образом, все компоненты пакета и DAQ системы оказываются защищенными, при сохранении возможности
менять калибровки и INI-файлы.
При этом система любого уровня сложности может быть защищена фиксацией (в автономном числовом виде)
всего только трех файлов:
Файл chechsum.md5 в каталоге Crw32exe. Создается автоматически при инсталляции пакета.
Файл chechsum.md5 в каталоге DAQ-системы.
Создается разработчиком либо автоматически программой инсталляции.
Файл chechsum.exe в каталоге Crw32exe. Файл всегда одинаков.
Служит для проверки и подсчета контрольных сумм.
При этом переменные файлы (калибровки и INI-файлы) защищаются средствами программы автоматически.
С точки зрения DAQ-старых систем, где контроль целостности не велся и файлы не защищены метаданными,
работа Центра Контроля Целостности Данных может приводить к избыточному количеству сообщений
в Главной Консоли при загрузке конфигурации.
Это поведение можно отключить, очистив все правила Центра Контроля Целостности Данных.
Для этого можно использовать готовый файл IntegrityOff.cfg:
[ConfigFileList] ; Default @Integrity settings OFF
ConfigFile = ~~\Resource\DaqSite\Default\IntegrityOff.cfg
[]
Однако лучше будет все же привести все системы в соответствие новым веяниям, тем более посчитать контрольные
суммы теперь нетрудно. Файлы калибровок и INI-файлы защищаются вызовом TextMetaDataLoop,
а остальные файлы - вызовом checksum с соответствующими параметрами (шаблонами файлов).
Таким образом, на сегодняшний день задача контроля целостности ПО и данных в первом приближении решена.
Надеюсь, это поможет завершить вопрос аттестации.
Центр контроля целостности данных вероятно будет развиваться по мере необходимости.
То есть добавились синонимы hex = base16, mime = base64,
новый метод кодирования nice = base32 и функция hash-индекса.
Алгоритм Base32 - один из стандартизованных
и широко используемых алгоритмов кодирования двоичных данных, используемый для обработки
и отказоустойчивой передачи двоичных данных по текстовым каналам связи.
Алгоритм Base32 имеет несколько распространенных модификаций, отличающихся алфавитом (набором символов),
поэтому в библиотеку добавлена функция выбора алфавита. По умолчанию в библиoтеке используется алфавит
zbase32,
который дает наиболее "читабельный" текст.
Особенностью алгоритма Base32 является то, что он генерирует строки, устойчивые к смене регистра, а также
пригодные для использования в качестве имен идентификаторов языков программирования, паролей или файлов.
Для сравнения, метод Base64=MIME, например, такими свойствами не обладает, так как его алфавит
чувствителен к регистру и содержит не только буквенно-цифровые символы.
Для генерации имен может использоваться Base16=HEX, но он уступает Base32 в плане компактности
(генерирует более длинные строки).
Алгоритм HashIndexOf вычисления ХЭШ-индекса может использоваться для существенного ускорения работы
алгоритмов, связанных с поиском и индексированием строк, см. описание функции.
Добавлены новые переменные и функции StdLibrary:
DIM_GuardParams - чтение параметров безопасности
DIM_GuiClickSend - посылка графического события серверу
DIM_GuiClickCopy - копирование графического события в буфер для пересылки серверу
DIM_GuiClickScan - чтение параметра из буфера графического события
DIM_GuiClickWhat - проверка удаленного события - прав доступа и типа события
DIM_GuiClickPack - упаковка события для программной генерации графических событий
DIM_GuiClickTag - переменная содержит тэг для передачи графических событий
DIM_GuiClickBuff - переменная содержит буфер для хранения графических событий
DIM_GuiClickCmnd - константа содержит идентификатор команды @DimGuiClick
Введенные функции касаются организации графических интерфейсов в распределенных DIM системах.
Добавлены новые функции StdLibrary:
TextAppendText - добавляет к тексту другой текст
TextAssignText - назначает тексту содержимое из другого текста
TextAppendString - добавляет к тексту другой текст, заданный длинной строкой
TextAssignString - назначает тексту содержимое из текста длинной строки
Введенные функции касаются работы с текстами.
Добавлена конфигурация с набором значений секции [DAQ] по умолчанию:
Это позволяет существенно сократить объем секции [DAQ], убрав из нее параметры по умолчанию.
Модифицирован пример DEMO_DOZA,
который теперь стал "векторный" - то есть позволяет генерировать файл конфигурации из таблицы.
В текущей версии включен "локальный" (без поддержки сети DIM) вариант драйвера,
работа над распределенным (сетевым DIM) вариантом продолжается.
Добавлен пример DEMO_TMC610, драйвер для управления шаговыми двигателями.
Разработка Н.Гурина, все вопросы к нему.
Модифицирован (в плане удобства GUI) UniHeat, редакция Н.Гурина.
Обновлен и по возможности протестирован сервер &ModbusProxy.
В сервер добавлен параметр @TimeGap 1 10 (пауза 10 мс для логического порта 1), задающий паузу ("временной зазор") между опросами.
Пауза (TimeGap) необходима для корректной работы MODBUS RTU, чтобы отделять сообщения друг от друга.
Длительное тестирование с устройствами ДОЗА показало устойчивую работу &ModbusProxy.
Добавлен пример DEMO_DOZA, который демонстрирует работу драйверов
ДОЗА УДГБ-01 с протоколом MODBUS RTU с использованием &ModbusProxy.
Драйверы рабочие - проверялось на аппаратуре. Есть симулятор.
В дистрибутив crw32-runtime добавлены две утилиты, являющиеся расширениями оболочки
(Shell Extension), то есть вызываются в контекстном меню по правой кнопке мыши:
CmdOpen - при щелчке правой кнопкой
на папке утилита показывает меню "Открыть командную строку" в указанной папке.
Полезно для работы (консоль всегда под рукой).
HashCheck - при щелчке правой кнопкой
на файле показывает меню "Создать файл контрольной суммы...".
А для файла *.md5 показывает меню "Открыть с помощью\HashCheck Shell Extension",
с помощью которого можно проверить целостность данных по сохраненным контрольным суммам.
Также в диалог "Свойства" добавляется закладка "Контрольные суммы",
позволяющая вычислять и проверять контрольные суммы файлов.
Эти утилиты выбраны потому что:
Полезны для работы (консоль всегда под рукой).
Нужны для аттестации (проверка контрольных сумм).
Очень компактны, имеют маленький размер.
Совместимы со всеми версиями Windows.
Свободны. Доступны с исходным кодом.
Предприняты усилия для обеспечения корректной работы программы при включенном UAC
(User Access Control, Контроль Доступа Пользователей).
Напомню, при включенном UAC программы оболочки (Рабочий стол) работают под
ограниченным пользователем (даже если запущены под учетной записью Администратора).
Для выполнения привилегированных операций нужна еще одна операция - повышение прав
(Elevation).
Программа AdmiLink была создана во времена XP и умеет выполнять вход
под учетной записью Администратора. Но после входа этот "урезанный" Администратор
все еще имеет права Пользователя. Для получения прав Администратора нужно выполнить
операцию Повышения (Elevation), которая (в зависимости от настроек UAC)
может выполняться молча, выдавать запрос на подтверждение (по умолчанию) или
всегда запрашивать пароль (параноидальные настройки UAC).
На работу UAC влияет 10 параметров реестра.
Запомнить их сложно. Поэтому для проверки и задания настроек UAC нужны инструменты.
Для поддержки UAC:
Сделана утилита uac.cmd,
позволяющая управлять работой UAC.
Эту команду можно вызывать из Главной Консоли:
@run uac & pause - посмотреть справку
@run uac see & pause - посмотреть статус UAC
@run uac on & pause - Вкючить UAC (другие настройки не менять)
@run uac off & pause - Отключить UAC (другие настройки не менять)
@run uac pro & pause - рекомендуемые настройки UAC версий Windows Profession
@run uac ent & pause - рекомендуемые настройки UAC версий Windows Enterprise
@run uac daq & pause - рекомендуемые настройки UAC для Daq Group
@run uac low & pause - эмуляция слайдера UAC на низком уровне защиты
@run uac mid & pause - эмуляция слайдера UAC на среднем уровне защиты
@run uac top & pause - эмуляция слайдера UAC на высоком уровне защиты
@run uac nul & pause - отключает UAC и сбрасывает все параметры в 0
@run uac doc - открыть папку с документацией по UAC
@run uac reg - открыть папку с файлами реестра для настройки UAC
@run uac man - открыть мануал по настройке параметров UAC
Эти команды добавлены в меню Инструменты\Консольные утилиты, чтобы были под рукой.
Написана библиотека _uac.pas для работы с UAC.
Добавлены файлы манифеста (см. ниже).
Переработана программа CrwGo.exe.
Теперь она (по возможности) запрашивает повышение прав при вызове Crw32.exe.
Напомню, программа CrwGo.exe задумана как "стартер" для корректного вызова
основной программы Crw32.exe, подготавливая для нее необходимое окружение
и передавая ей параметры командной строки.
Именно она должна указываться в ярлыках Admilink и скриптах для вызова Crw32.exe.
Результатом проведенной работы является корректная работа ярлыков для запуска программы
при включенном UAC. А также возможность контроля и быстрой настройки UAC.
Добавлены файлы манифеста
Crw32.exe.manifest,
CrwGo.exe.manifest
которые нужны для задания параметров работы программы в современных версиях Windows.
Манифест декларирует некоторые свойства исполняемого файла, такие как настройки GUI,
требуемые версии DLL библиотек, совместимость с разными версиями ОС,
а также требуемые права доступа.
Файл манифеста учитывается системой при запуске программы.
Манифеcт носит рекомендательный характер, то есть - как он сработает (если сработает),
зависит от многочисленных настроек Windows.
Поэтому слишком полагаться на манифест не стоит, но в принципе штука полезная...
В настоящей версии с помощью манифеста декларируется требование запуска под Администратором.
Поправлена функция IsAdministartor (определение наличия прав Администратора).
В предыдущей версии (разработанной под XP, когда UAC не было) эта функция работала
неверно при запуске Win7/8/10 при наличии включенного UAC.
Теперь все должно работать правильно.
В стартовом сценарии запуска программы добавлено определение и отображение прав
пользователя, под которым запущена программа.
Переработана программа grun.exe и specrun.exe с учетом UAC, а также
расширений оболочки, чтобы иметь универсальную "запускалку" для программ.
Добавлены новые ключи запуска:
grun -c myprogram.exe - выполнит программу myprogram.exe в консоли CMD и закроет окно
grun -k myprogram.exe - выполнит программу myprogram.exe в консоли CMD и оставит окно открытым
grun -e myprogram.exe - запросит повышение прав (elevate) и выполнит программу с правами АДМИНа
grun -s c:\manual.pdf - выполнить для файла действие оболочки (shell) по умолчанию
grun -o c:\manual.doc - откроет (open) документ для просмотра или редактирования
grun -m c:\manual.txt - откроет (edit) файл для редактирования (модификации)
grun -x c:\myfolder\ - откроет (explore) каталог для просмотра
в сочетании с другими флагами grun позволяет гибко управлять запуском программ:
grun -er7 myprogram.exe - выполнить с правами АДМИНа, приоритетом REALTIME, в свернутом окне
grun -eih defrag.exe - выполнить с правами АДМИНа, приоритетом IDLE, в скрытом окне
и так далее.
Благодаря большому числу опций и поддержке UAC, grun.exe
(в сочетании с AdmiLink) стала мощной и универсальной "запускалкой" программ,
закрывая основные потребности, связанные с запуском процессов (ярлыки, командные файлы
и скрипты и т.д.).
Обновлены многие сборки программ (Firefox,Office,...) и настройки TotalCommander.
if IsRefDevice(dev) // Проверяем ссылку - это Device?
then n:=DevSend(dev,msg) // Если да, посылаем сообщение
else Trouble('Invalid device reference!'); // Иначе фиксируем ошибку
bNul(iSetTagBitState(tag,3,false)); // Сбросить 3-й бит тега в 0
bNul(iSetTagBit(tag,0,1)); // Установить 0-й бит тега в 1
bNul(iSetTagXor(tag,1)); // Инвертировать 0-й бит тега
Обновлена библиотека NetModbus (поддержка протокола MODBUS).
В нее добавлен ряд функций, который призван облегчить разработку драйверов с использованием &ModbusProxy.
Обновлен и по возможности протестирован сервер &ModbusProxy.
Обновлен пример DEMO_MDBS, который иллюстрирует работу драйверов MODBUS
с использованием &ModbusProxy.
Прототип типового драйвера MODBUS (с использованием &ModbusProxy) добавлен в шаблоны
Resource\EditorTemplates\Daq-Pas-Program.
В дистрибутив добавлены фонты PT Astra Sans, PT Astra Serif.
Эти фонты добавлены потому, что они
Специально разработаны для замены Times New Roman на системах СПО.
Имеют точную метрику (размеры) Times New Roman, т.е. могут заменять его без "ломки" форматирования документа.
Имеют свободную лицензию, то есть могут распространияться без ограничений.
Таким образом, эти фонты рекомендуются в качестве переносимой замены Times New Roman.
04.12.2016
NetLibrary NetModbus &ModbusProxy DEMO_MDBS
Обновлена библиотека NetModbus (поддержка протокола MODBUS).
В нее добавлен ряд функций, который призван облегчить разработку драйверов с использованием &ModbusProxy.
Обновлен и по возможности протестирован сервер &ModbusProxy.
Обновлен пример DEMO_MDBS, который иллюстрирует работу драйверов
с использованием &ModbusProxy.
Специфика MODBUS сведена до минимума.
При использовании &ModbusProxy работа с протоколом MODBUS фактически сводится
к вызову трех функций (modbus_proxy_poll, modbus_proxy_nice, modbus_proxy_reply).
Все остальное - упаковка и распаковка данных (modbus_dump_int16, modbus_take_int16 и т.д.).
24.11.2016
NetLibrary NetModbus &ModbusProxy DEMO_MDBS
Обновлена библиотека NetModbus (поддержка протокола MODBUS).
В нее добавлен ряд функций, который призван облегчить разработку драйверов для MODBUS IP/RTU/ASCII.
Новый клиент &ModbusProxy создан
с использованием библиотеки NetLibrary для разработки драйверов MODBUS.
Он обеспечивает приемо-передачу сообщений при наличии множества устройств на одном порте, выстраивая запросы в очередь.
Обновлен пример DEMO_MDBS, который иллюстрирует работу драйверов
с использованием &ModbusProxy.
05.11.2016
NetLibrary NetModbus StartingOrder StoppingOrder
В стандартную библиотеку добавлены модули:
NetModbus (поддержка протокола MODBUS)
и NetLibrary (библиотека сетевых протоколов).
Модуль NetModbus входит в библиотечный модуль NetLibrary.
Библиотечный модуль NetLibrary призван облегчить разработку драйверов для различных сетевых протоколов.
Пока в него включен только протокол MODBUS IP/RTU/ASCII, но в будущем, возможно, этот список будет расширен.
Сервер &ModbusSrv модифицирован
с использованием библиотеки NetLibrary.
Желательно все прочие имеющиеся в наличии драйверы MODBUS отредактировать с учетом этой библиотеки.
Новые драйверы рекомендуется создавать с её использованием.
Исправлена небольшая погрешность в Редакторе Калибровок.
В конфигурацию устройств добавлена возможность управления порядком старта и остановки устройств.
До сих пор устройства выполняли СТАРТ и СТОП в порядке описания в конфигурационном файле,
который в общем довольно произволен.
Теперь СТАРТ и СТОР выполняется в порядке, которые определяются параметрами StartingOrder, StoppingOrder.
Оба параметра имеют значение по умолчанию 0.
При этом СТАРТ выполняяется в порядке возрастания StartingOrder,
а СТОП выполняяется в порядке возрастания StoppingOrder.
Устройства с одинаковым значением StartingOrder, StoppingOrder выполняются в прежнем (произвольном) порядке.
Это значит, что при отрицательных значениях порядка выполнение будет первым, а при положительных - последним.
[&DeviceList]
&demo = device software program
[&demo]
StartingOrder = -10 ; выполнить СТАРТ раньше обычного
StoppingOrder = +10 ; выполнить СТОП позже обычного
...
Управление порядком старта устройств позволит сделать процедуру старта и завершения более предсказуемой
в случае, если работа устройств зависит от работы других устройств.
При этом можно, например, задать порядок старта так, чтобы независимые устройства стартовали первыми,
а зависимые - после них.
Указанные параметры влияют только на порядок выполнения СТАРТ/СТОП.
Опрос устройств в цикле опроса определяется приоритетом и частотой и не зависит от параметров СТАРТ/СТОП.
С помощь параметров StartingOrder, StoppingOrder сделано так, что все стандартные сервера
будут теперь стартовать перед и завершаться после обычных устройств, то есть:
При этом сервер &CronSrv будет стартовать первым и завершаться последним.
Здесь предполагается, что для конфигурирования используются стандартные конфигурации серверов,
например, ~~\Resource\DaqSite\CronServer\CronSrv.cfg.
22.10.2016
Calibrations Fixed Coeff
В калибровках добавилась возможность задания фиксированного полинома.
Обычно, как всегда было раньше, полином вычисляется автоматически по опорным точкам калибровки.
Теперь кроме этого есть возможность прямо задавать фиксированные коэффициенты полинома,
см. пример:
[U(mV)-T(°C) calibration] ; Секция калибровки
FitMethod = Polynom ; Метод аппроксимации
TransformX = Line ; Калибровочное преобразование по X (линейная шкала)
TransformY = GOST_TC_K ; Калибровочное преобразование по Y (термопара тип K)
Power = 1 ; Степень полинома
Center = 0 ; Центр полинома
Scale = 1 ; Масштабный коэффициент
Bounds = -6.458 54.886 ; Рабочие пределы аргумента X
Fixed = 1 ; 0 = МНК, 1 = фиксированные коэффициенты
Coeff[0] = 0 ; Коэффициент полинома при 0 степени
Coeff[1] = 1 ; Коэффициент полинома при 1 степени
... ; и так далее
В частности, фиксированные полиномы теперь используются в стандартных калибровках термопар и RTD по ГОСТ.
В Редакторе Калибровок тоже добавилась возможность задания фиксированного полинома.
Это может быть полезно, если полином известен из литературы или из паспорта измерительного устройства.
Приложены большие усилия к созданию устойчивого алгоритма вычисления обратной функции калибровки.
Прежний алгоритм был неустойчив за пределами интервала, где заданы опорные точки калибровки.
Если прямая функция калибровки, например, вычисляет T(°C) по U(mV), то обратная функция вычисляет U(mV) по T(°C).
Это требуется в некоторых задачах - например, для определения порога срабатывания в mV, соответствующего заданной температуре.
В пакете давно существовала проблема с модальными окнами, ожидающими ввода пользователя - они могли оказаться
невидимыми под другими "всплывающими" окнами, что приводило к иллюзии зависания программы.
На самом деле работа продолжалась нормально, просто модальное окно, ожидающее ввода, было скрыто под другими
"всплывающими" окнами, с установленными атрибутами TOPMOST ("окно всегда наверху").
Теперь этот эффект не должен проявляться, так как модальным окнам теперь тоже присваивается свойство
"StayOnTop" или "TopMost", то есть "всплывающие", "всегда наверху".
То есть активное модальное окно, ожидающее нажатия кнопки, должно быть всегда наверху, даже если открыты
другие "всплывающие" окна.
Новое поведение управляются переменными Crw32.ini [System] UseSystemMessageBox = 1, MakeModalTopMost = 1,
при отключении этих переменных ( = 0 ) возвращается прежнее поведение диалогов (сохранено для возможности отката к прежней версии).
Переменная UseSystemMessageBox задает вид стандартных диалогов "Предупреждение", "Подтверждение",
"Информация", "Ошибка". В новой версии эти диалоги вызывают Application.MessageBox с атрибутом TOPMOST.
Переменная MakeModalTopMost принудительно устанавливает атрибут TOPMOST активным модальным формам.
Эти две переменные действуют независимо, имея один результат - модальные диалоги теперь не должны
"прятаться" под другими "всплывающими" (TOPMOST) окнами.
В справочный раздел Mathematics добавлены классические книги,
которые желательно изучить всем коллегам. Входит в состав crw32-demodoc.
Книги и статьи - классика на тему 1) статистики и обработки экспериментальных данных,
2) сглаживания, 3) устойчивых вычислительных методов.
Пакет создавался (по математической части) в значительной мере на основе этих книг.
В будущих DAQ-системах рекомендуется к использованию:
1)обновленный набор логотипов:
Resource\Bitmap\daq_status_logo.gif ,
Resource\Bitmap\daq_status_logo.bmp ,
2) обновленный шаблон заставки в момент загрузки:
Resource\Bitmap\daq_demo_logo.bmp
Использование шаблонных логотипов унифицирует внешний вид заставок, сделает наше ПО более узнаваемым.
17.10.2016
PhysLibrary PhysRtdTc калибровки GOST
Это обновление пакета целиком посвящено метрологическим вопросам температурных измерений и системе калибровок.
Дело в том, что использовавшиеся в пакете стандартные калибровки (термопары, датчики RTD) устарели,
т.к. со времени создания пакета вышли новые версии ГОСТ.
Кроме того, калибровки до сих пор не были документированы в достаточной степени.
В связи с этим были введены новые таблицы стандартных датчиков
на основе действующих ГОСТ-ов и соответственно новые
файлы калибровки для их использования.
Новые таблицы введены под новыми именами (например, GOST_TC_K, GOST_RTD_PT100_385).
При этом старые таблицы и калибровки остались неизменными для совместимости ПО.
В стандартную библиотеку Object Pascal добавлен модуль
_RtdTc.pas
для поддержки термопар и датчиков RTD в EXE программах.
В стандартную библиотеку DaqPascal добавлен модуль
PhysRtdTc
для поддержки термопар и датчиков RTD, который входит в модуль
PhysLibrary.
Все функции модуля соответствуют действующим ГОСТ Р 8.585—2001 (термопары) и ГОСТ 6651-2009 (датчики RTD).
В библиотеку расчетных расширений (плагинов) добавлены модули
_GOST_TAB_THERMOCOUPLE.DPR,
_GOST_TAB_RTD.DPR.
Они позволяют в любой момент сгенерировать по полиномиальным формулам таблицы
ГОСТ Р 8.585—2001 (термопары) и ГОСТ 6651-2009 (датчики RTD). Формулы взяты из тех же ГОСТ.
Модули также позволяют изучать и анализировать стандартные калибровки (например, точно вычислять производные и т.д.).
При необходимости код этих утилит легко переносится в другие программы.
Значительно переработан диалог Редактора Калибровок.
В него добавлен калькулятор, который позволяет вычислять прямое и обратное значение по калибровке в любой точке,
а также справочная информация - текст калибровки, коэффициенты калибровочного полинома.
Хочется надеяться, что с добавлением новых калибровок и возможностей их редактирования
вопрос калибровки стандартных датчиков (термопар, RTD) на ближайшие годы закрыт.
unix tooltip-notifier text "Пример onClick" onClick "unix lister demo.txt"
Данный пример по клику на всплывающей строке выполняет указанную команду:
unix lister demo.txt (открывает для просмотра текстовый файл demo.txt)
Немного изменена структура инициализационных файлов:
Crw32.ini основной файл, ссылается на следующие файлы:
Temp\Crw32.ini пользовательские настройки
Temp\Crw32.lng выбор языка RUS/ENG
Resource\Crw32.Param.ini описание большинства параметров
Resource\Crw32.Fonts.ini описание внедряемых фонтов
Resource\Crw32.Tools.ini описание команд @run
Resource\Crw32.Utils.ini описание консольных утилит
Программа теперь содержит контроль целостности кода (защиту от изменения программного кода).
Это сделано в рамках работ по аттестации ПО для использования в измерительных системах.
Защита обеспечена следующими мерами:
Дистрибутив install-daqgroup-runtime32.exe защищен контрольными суммами штатными средствами инсталлятора.
В качестве контрольной суммы для сертификата ПО можно брать контрольную сумму инсталлятора.
В момент инсталляции (развертывания) дистрибутива инсталлятор автоматически расчитывает
контрольные суммы критически важных (т.е. метрологически значимых) файлов путем вызовова сценария
Resource\Crw32.Secure.cmd.
В настоящее время в контрольную сумму включаются исполняемые файлы (*.exe, *.dll, *.bat, *.cmd),
программы (*.pas, *.inc), а также некоторые конфигурационные файлы (*.ini, *.cfg).
Из контрольных сумм исключаются служебные каталоги (Temp\, Demo\, Demo16\ и т.д.).
Результат записывается в checksum.md5.
В стартовом сценарии Resource\Crw32.Logon.cmd и в завершающем сценарии
Resource\Crw32.Logout.cmd
выполняется проверка целостности программы путем вызова утилиты
Resource\Crw32.Verify.cmd,
которая вызывает программу checksum.exe,
проверяющую целостность файлов по записям из checksum.md5.
При нарушении целостности программы выдается всплывающее предупреждение.
Оператор, таким образом, получает уведомление в случае нарушения целостности программного кода после инсталляции.
В настоящей версии других действий кроме уведомления оператора при нарушении целостности кода не предпринимается.
Такие действия при необходимости могут быть добавлены в стартовый сценарий.
Набор ПО для контроля целостности кода в настоящее время включает:
Для Crw32exe:
checksum.exe - основная утилита проверки и создания контрольных сумм
Resource\Crw32.Logon.cmd - вызывается автоматически при запуске Crw32.exe
Resource\Crw32.Logout.cmd - вызывается автоматически при завершении Crw32.exe
Resource\Crw32.Secure.cmd - создание контрольной суммы (с опцией --secure-checksum)
Resource\Crw32.Verify.cmd - вызывается из Logon/Logout для проверки целостности Crw32exe
Для Daq32 конфигураций:
Resource\Daq32.Logon.cmd - прототип; копируется в Daq32\xxx\Utility
вызывается из препроцессора при запуске конфигурации
Resource\Daq32.Logout.cmd - прототип; копируется в Daq32\xxx\Utility
вызывается из постпроцессора при завершении конфигурации
Resource\Daq32.Secure.cmd - прототип; копируется в Daq32\xxx\Utility
создание контрольной суммы (с опцией --secure-checksum)
Resource\Daq32.Verify.cmd - вызывается из Logon/Logout для проверки целостности Daq32
Модуль _DATSAVE переработан с использованием стандартной библиотеки.
Есть небольшая несовместимость в переменной OpenConsole (0/1/2=Hide/Show/Mini).
Немного поправлена система UniHeat
и демонстрационная конфигурация DEMO_UNIHEAT.
Внесены (с поправками) коррективы Н.Гурина.
Изменена заставка (Logo),
которая предлагается в качестве образцовой заставки, содержащей логотипы (РосАтом, Саров, ВНИИЭФ, ИЯРФ).
Кроме того, в DEMO_UNIHEAT добавлен пример контроля целостности кода:
1) В каталог \Utility копируются файлы Daq32.Logon.cmd, Daq32.Logout.cmd, Daq32.Secure.cmd из Crw32exe\Resource.
2) В препроцессор и постпроцессор DAQ-системы добавляются вызовы Daq32.Logon.cmd, Daq32.Logout.cmd.
3) Файл Daq32.Secure.cmd редактируется так, чтобы в контрольные суммы включались нужные файлы и исключались ненужные.
В большинстве случаев, вероятно, настройки по умолчанию подойдут и редактирование не потребуется.
Нужные и ненужные файлы задаются в списках:
set exelist=*.exe *.dll *.bat *.cmd *.pas *.inc - список включаемых исполняемых файлов
set cfglist=*.cfg *.crc *.cal - список включаемых файлов конфигурации
set exclude=Temp\ Data\ - список исключаемых имен файлов или каталогов
4) В момент готовности ПО из консоли вызывается утилита создания контрольной суммы:
Daq32.Secure.cmd --secure-checksum
Аргумент (--secure-checksum) служит для защиты от непреднамеренного обновления контрольных сумм
при случайном вызове утилиты. Вызов утилиты подсчета контрольных сумм может также происходить
автоматически при работе инсталлятора (если данная DAQ-система его имеет).
При условии выполнения перечисленных действий при каждом старте и завершении DAQ системы
будет осуществляться контроль целостности РПО с выдачей соответствующего сообщения.
Изменена команда @integrity.
Сейчас она пересылает все поступающие команды в файл, на который указывает
Crw32.ini [System] IntegrityEventsLog = Temp\@IntegrityEvents.log
Предполагается, что Центр Контроля Целостности Данных (это будет, скорее всего, отдельный процесс,
запускаемый через Crw32.Login.cmd) периодически заглядывает в этот файл и проверяет файлы,
которые считываются или записываются программой.
@integrity save.crw c:\data\demo.crw - данные прочитаны из файла, можно проверить контрольную сумму
@integrity load.crw c:\data\demo.crw - данные записаны в файл, можно обновить контрольную сумму
Центр Контроля Целостности Данных еще предстоит создать, однако это скорее всего слабо затронет основной файл Crw32.exe,
так как предполагается, что контроль целостности данных будет выполнять отдельный процесс, берущий команды из файла.
Для отключения контроля Целостности надо закомментировать переменную Crw32.ini [System] IntegrityEventsLog.
Консольная команда @silent в Главной Консоли сделана еще более "тихой".
Предыдущая версия @silent подавляла печать эхо (дублирование консольного ввода)
и печать конечного результата расчетов, сохраняя при этом промежуточную печать
в ходе вычислений.
Например, команда @silent @run ... выдавала сообщение:
@run cmd
Pid "4888" started by command "C:\WINDOWS\system32\cmd.exe"
Теперь промежуточная печать в ходе вычислений по возможности подавляется, кроме случаев,
когда эта промежуточная печать является основным результатом работы команды.
Промежуточная печать также будет появляться в случае возникновения серьезных ошибок
(исключений) в процессе исполнения.
Например, в команде @silent @run cmd основным результатом работы является запуск
процесса, а промежуточная печать (сообщение о запуске) подавляется.
А вот в команде @silent @pid list промежуточная печать (список процессов) является
основным результатом работы команды и поэтому не подавляется.
Встроенные фонты все-таки было решено вынести в отдельные TTF файлы,
а не хранить в ресурсах EXE. Поэтому объем Crw32.exe уменьшился до обычного размера.
Встраивание фонтов теперь конфигурируется в секции
Crw32.ini [EmbeddedFontList].
Это делает встраивание фонтов легко расширяемым и конфигурируемым.
В стандартной библиотеке серьезно изменен основной цикл опроса
_std_main.inc.
Он стал более гибким и настраеваемым.
Изменения коснулись в первую очередь обработки консольного ввода.
Сейчас можно задавать режимы обработки консольного ввода при старте и остановке,
перед и после процедуры опроса.
Можно задавать Timeout (максимальное время) на обработку консольных сообщений.
Подробности см. ниже.
В стандартную библиотеку добавлена обработка сообщений
@Cron cmd Послать команду cmd в консоль серверу &CronSrv для исполнения
@StartupScript Вызвать RunStartupScript
@FinallyScript Вызвать RunFinallyScript
В стандартную библиотеку добавлены параметры
StartingDevMsg,
StoppingDevMsg и функция
StdIn_SetScripts.
Они позволяют задавать сообщения, посылаемые в консоль после старта программы
и перед её завершением. Например:
procedure InitApplication;
begin
StartingDevMsg:='@StartupScript'; Задать стартовое сообщение в консоль
StoppingDevMsg:='@FinallyScript'; Задать завершающее сообщение в консоль
StdIn_OnStopPoll:=MaxInt; Разрешить обработку завершающих консольных команд
end;
либо
procedure InitApplication;
begin
StdIn_SetScripts('@StartupScript','@FinallyScript'); Задать стартовое,завершающее сообщение в консоль
StdIn_SetTimeouts(0,MaxInt,MaxInt,0); Разрешить обработку завершающих и циклических консольных команд
end;
...
В результате (при условии что в StdIn_Processor вызывается StdIn_DefaultHandler)
будет выполнен StartupScript на старте и FinallyScript при завершении.
В стандартную библиотеку добавлена функция DebugFlagEnabled.
Она проверяет отладочные флаги и нужна для фильтрации консольного вывода в шаблонных программах
DaqPascal.
Немного изменен шаблон template.pas.
В InitApplication добавлен вызов StdIn_SetScripts('',''); StdIn_SetTimeouts(0,0,0,MaxInt);,
чтобы напомнить о важности правильной настройки обработки консольного ввода.
Некорректная настройка может привести к трудно обнаружимым ошибкам при обработке консольного ввода.
Ведь это важно, например, вызывается цикл обработки консоли до или после процедуры опроса PollApplication.
Сервер &WebSrv переработан с использованием стандартной библиотеки.
Сервер &PlotSrv переработан с использованием стандартной библиотеки.
Сервер &CronSrv переработан с использованием стандартной библиотеки.
Кроме того, в сервер добавлен "тихий" режим вычислений (SilentEval).
Его можно задать в переменной или через консольную команду:
[&CronSrv]
SilentEval = 0 отключить тихий режим через переменную
[&CronSrv.StartupScript]
@SilentEval 1 включить тихий режим через консольную команду
@ShowMainToolbar 0 спрятать строку инструментов
@ShowMainMenu 0 спрятать главное меню
@pid kill dns.exe убить некий процесс
@run dimtree.exe запустить процесс
При выполнении данных команд вывод в Главной Консоли будет подавлен.
Сервер &SpeakSrv переработан с использованием стандартной библиотеки.
Сервер &EmlSrv переработан с использованием стандартной библиотеки.
Сервер &DimSrv переработан с использованием стандартной библиотеки.
Сервер &VkbdSrv переработан с использованием стандартной библиотеки.
Сервер &OpcCln переработан с использованием стандартной библиотеки.
Модуль _MVTOPU переработан с использованием стандартной библиотеки.
Модуль _MVTOTC переработан с использованием стандартной библиотеки.
Использование стандартной библиотеки для реализации перечисленных серверов и модулей
позволит не только унифицировать и упорядочить программы,
но и повысить их отказоустойчивость при программных ошибках и серьезных сбоях,
так как в стандартную библиотеку заложен механизм восстановления
после обнаружения программных сбоев.
В стандартной библиотеке изменена реакция на консольную команду @help.
Теперь кроме выдачи консольной справки производится поиск одноименного
файла программы с расширением *.HTM в каталоге источника программы.
Например, если программа расположена в DaqPas\demo.pas, ищется файл DaqPas\demo.htm.
Если такой файл найден, он будет открыт для просмотра.
Это значит, легко найти справку по программному модулю,
если в каталоге программы создать одноименный файл справки.
В консольной команде @run сделано расширение имен файлов из переменных окружения.
Расширение делается для каталога (/cd) и исполняемого файла команды (первый аргумент).
Остальные аргументы передаются "как есть".
Например:
@run %comspec% пуск c:\windows\system32\cmd.exe в каталоге c:\Crw32exe
@run /cd %temp% %comspec% пуск c:\windows\system32\cmd.exe в каталоге c:\windows\temp
@run /cd %CRW_DAQ_CONFIG_HOME_DIR% cmd пуск cmd в каталоге DAQ-системы типа с:\Daq32\Demo\Config
@run /cd %CRW_DAQ_CONFIG_HOME_DIR%\..\Utility cmd пуск cmd в каталоге DAQ-системы типа с:\Daq32\Demo\Utility
@run %CRW_DAQ_CONFIG_HOME_DIR%\..\Utility\preprocessor.cmd пуск с:\Daq32\Demo\Utility\preprocessor.cmd
@run cmd /c echo %unixroot% & pause напечатает c:\Program Files\UnixUtils, т.к. cmd сам делает расширение аргументов
Надо иметь в виду, что командные процессоры cmd и unix делают расширение своих аргументов автоматически,
поэтому при необходимости расширения других аргументов надо вызывать команду через cmd или unix,
как показано в последнем примере.
Слегка поправлена система UniHeat
и демонстрационная конфигурация DEMO_UNIHEAT.
Добавлена возможность переключения между нагревом и охлаждением (Н.Гурин).
В консоль добавлена очень важная для планируемой сертификации команда @integrity.
Пока она умеет немного:
@integrity - show help
Но в ближайшем будущем на основе этой команды планируется сделать "Центр Контроля Целостности Данных",
через который планируется организовать расчет и проверку контрольных сумм критически важных файлов.
Идея такая:
При записи файлов (например в редакторе калибровок) в консоль будет посылаться
команда @integrity write для записи состояния файла (например калибровки)
в том или ином хранилище контрольных сумм.
При чтении файлов (например при загрузке калибровки) в консоль будет посылаться
команда @integrity check для проверки состояния файла (например калибровки)
по данным из хранилища контрольных сумм.
Если сумма изменилнь, ЦКЦД тем или иным образом известит оператора о нарушении
целостности данных.
Такой способ выбран для минимизации изменений в уже отлаженных процедурах, трогать которые не хочется.
Весь контроль целостности будет сосредоточен в одном месте.
С помощью @silent этот контроль можно будет "спрятать" от конечного пользователя,
в то же время разработчики при необходимости смогут посмотреть весь протокол работы.
Реализация ЦКЦД потребует времени, но начало положено уже в этой версии.
08.09.2016
unix tooltip-notifier UnixTooltipNotifier
Добавлена опция noDouble 1 в команду unix tooltip-notifier.
Соответственно изменилась функция UnixTooltipNotifier,
работающая через пакет UnixUtils и выдающая всплывающее окно сообщения в области уведомлений
с выбором цвета, фонта и времени показа.
Опция noDouble 1 позволяет избегать повторения сообщения с тем же текстом.
Например, если периодически генерируется сообщение об ошибке или аварийной ситуации,
его следует выдавать с опцией noDouble 1, чтобы одно и то же сообщение
не появлялось на экране повторно. Следует, однако, учесть, что данная опция,
экономя пространство на экране, не снижает затрат процессора на вызов команды
unix tooltip-notifier. Поэтому, несмотря на наличие опции, не следует
генерировать периодические сообщения unix tooltip-notifier слишком часто,
во избежание загрузки процессора.
Пример:
UnixTooltipNotifier('text "Операция успешно завершена." delay 15000 trans 255 bkColor green textColor 0x000000'
+' font "PT Mono Bold" fontSize 14 ico notify.ico audio notify.wav noDouble 1');
где:
text "Операция успешно завершена." - выводимый текст, обязательно в кавычках
delay 15000 - автоматическое закрытие через 15000 ms
trans 255 - прозрачность (transparency), 0..255
bkColor green - цвет фона по имени (red,green,...) или HEX RGB
textColor 0x000000 - цвет текста, HEX RGB, 0xRRGGBB
font "PT Mono Bold" fontSize 14 - имя фонта и размер, pt
ico notify.ico - имя файла картинки (exe,dll,ico)
audio notify.wav - имя звукового файла (wav)
noDouble 1 - избегать повторения сообщения с тем же текстом
23.06.2016
lua win32.lua %UnixRoot%
Добавлена новая возможность в механизм файловых ссылок, а именно "расширение переменных среды".
Это значит, что в файловых ссылках в INI и CFG файлах теперь допустимо использовать переменные
окружения, например:
При этом в момент работы DAQ-системы в среде окружения кроме стандартных переменных
типа %WinDir% или %ProgramFiles% доступны также такие дополнительные переменные:
CRW_DAQ_CONFIG_BASE_TIME базовое время отсчета time, мс
CRW_DAQ_CONFIG_TIME_UNITS единицы измерения времени, мс
CRW_DAQ_CONFIG_DATA_PATH каталог данных DAQ системы
CRW_DAQ_CONFIG_FILE главный конфиг DAQ системы
CRW_DAQ_CONFIG_HOME_DIR домашний каталог DAQ системы - где находится главный конфиг
CRW_DAQ_CONFIG_LOAD_TIME время загрузки DAQ системы, мс
CRW_DAQ_CONFIG_PATH список путей поиска файлов DAQ системы [Daq] SearchPath
CRW_DAQ_CONFIG_START_TIME время старта DAQ системы, мс
CRW_DAQ_CONFIG_TEMP_PATH временный каталог DAQ системы
CRW_DAQ_INCLUDE_PATH список путей поиска включаемых файлов DaqPascal
CRW_DAQ_SYS_EXE_FILE полный путь файла CRW32.EXE
CRW_DAQ_SYS_EXE_PID идентификатор процесса CRW32.EXE
CRW_DAQ_SYS_EXE_TID идентификатор GUI потока CRW32.EXE
CRW_DAQ_SYS_HOME_DIR каталог CRW32EXE
CRW_DAQ_SYS_INI_FILE полный путь файла CRW32.INI
CRW_DAQ_SYS_MESSAGE идентификатор сеанса
CRW_DAQ_SYS_PATH список путей поиска
При работе с переменными окружения надо быть внимательным, так как имена файлов
с пробелами могут привести к неверной работе программы и их следует избегать.
Расширение переменных также действует в функции daqfileref.
Однако при чтении имен файлов через readini
расширение переменных среды не делается, так как readini просто читает строку,
не интерпретируя её как имя файла.
Поэтому для применения расширения переменных окружения в DaqPascal надо делать
вызов примерно так:
Поскольку для записи имен файлов часто используется URL кодировка, то для сохранения
совместимости при расширении переменных окружения пропускаются выражения вида
%hh с шестнадцатеричным числом hh, например %F1. Такие выражения пропускаются
и не интерпретируются как ссылки на переменные окружения.
В состав UnixUtils включен мощный встраиваемый скриптовый язык программирования
Lua.
На него возлагаются большие планы, после того как будут накоплены нужные библиотеки.
Сейчас идет активное накопление библиотек языка Lua.
Обновлена демонстрационная конфигурация DEMO_P48.
В частности, там продемонстрировано использование Lua для создания диалогового
окна, взаимодействующего с основной программой.
Обновлена демонстрационная конфигурация DEMO_BDMG.
Это драйвер для измерителя гамма-активности БДМГ-200.
Добавлена демонстрационная конфигурация DEMO_OSM.
Это драйвер для контроллера шагового двигателя Онитекс OSM42-RA.
18.05.2016
New Installer checksum.exe getspecialfolderpath
Сделана полная реструктуризация дистрибутива.
Новая структура кратко описана в readme.htm,
находящемся также на сайте.
install-daqgroup-all.exe запускает все инсталляторы в тихом режиме, с опциями по умолчанию.
install-daqgroup-crw32-runtime.exe запускает инсталлятор CRW-DAQ (исполняемые файлы).
Инсталлятор по возможности сокращен до минимума.
install-daqgroup-crw32-demodoc.exe запускает инсталлятор CRW-DAQ (демо+документация).
Его необходимо устанавливать разработчикам и в обычных случаях (когда нет дополнительных ограничений).
install-daqgroup-crw32-commander.exe содержит новую (легальную) версию Total Commander.
install-daqgroup-unixutils.exe запускает инсталлятор UnixUtils.
И т.д.
Инсталляторы контролируют версии и по возможности минимизируют время инсталляции,
избегая повторной установки пакетов.
Работа над инсталлятором будет по возможности продолжена.
Целью будет оптимизация размеров (особенно минимизация crw32-runtime) и времени инсталляции.
Для аттестации и обеспечения безопасности ПО сделаны средства контроля идентичности системного
ПО и прикладного РПО.
Теперь в каталоге Crw32 присутствуют: утилита checksum.exe и файл контрольных сумм checksum.md5.
Утилита проверяет все файлы на предмет соответствия контрольной сумме.
При замене или удалении исполняемых файлов будет показана ошибка.
Утилита checksum.exe добавлена в пакет UnixUtils.
Она содержит все, что надо для организации контроля идентичности прикладных систем.
checksum - проверяет файлы по контрольным суммам из checksum.md5
checksum -cAnother - проверяет файлы по контрольным суммам из Another.md5
checksum -m checkme.exe - генерирует контрольную сумму checkme.exe в консоли
checksum -mOut checkme.exe - генерирует контрольную сумму checkme.exe в файл Out.md5
checksum -mchecksum -r - генерирует к.с. файлов *.* рекурсивно и пишет в checksum.md5
checksum -mchecksum *.exe -r - генерирует к.с. файлов *.exe рекурсивно в checksum.md5
checksum -mchecksum *.exe -r -e skip.exe - то же, кроме файла skip.exe
checksum -mchecksum -r -e Temp\ *.ini - ген.к.с. кроме каталога Temp\ и файлов *.ini
и т.д.
Утилита checksum очень мощная и (как кажется) закрывает все потребности.
Измерительные конфигурации будут включать файл checksum.exe и checksum.md5,
который будет содержать к.с. "метрологически значимых" частей РПО.
Добавлено много полезных утилит в UnixUtils.
getspecialfolderpath n - возвращает имена специальных каталогов по имени n
это нужно чтобы в командных сценариях находить нужные
системные каталоги (типа "общие программные файлы" и т.д.)
getspecialfolderpath fonts - для примера возвращает каталог фонтов c:\Windows\Fonts
update-files-in-folders a b - обновляет все копии файла a в подкаталогах данного каталога b
используется для обновления файлов, если есть несколько копий
файла, находящихся в разных подкаталогах
list-extensions - список всех расширений файлов в данном каталоге и подкаталогах
это нужно для того, чтобы понять, какие файлы надо исключать
при вызове checksum.exe ...
и т.д. (долго перечислять) - смотри мануал по unix -m
Просьба активно участвовать в тестировании.
28.04.2016
@silent @silence @fonts PT Mono PT Sans PT Sans Narrow PT Serif
В связи с разговорами об аттестации и безопасности ПО сделаны средства контроля
идентичности системного ПО.
Теперь в каталоге Crw32 присутствуют: файл контрольных сумм Check.md5 и утилита Check.cmd.
Утилита проверяет все *.exe *.dll и т.д. файлы на предмет соответствия контрольной сумме.
При замене или удалении исполняемых файлов будет показана ошибка.
Утилита Check.cmd использует пакет UnixUtils, который предполагается установленным.
По этому примеру можно будет делать средства контроля идентичности для прикладных систем.
В главной консоли Crw32 добавлена консольная команда @silent:
@silent setclockres(1) задать частоту опроса без лишней печати
@silent @run cmd запустить программу без лишней печати
Эта команда нужна для того, чтобы выполнять в главной консоли нужные команды
без засорения консоли ненужными сообщениями.
При вызове из прикладной программы Daq Pascal команды главной консоли вызываются
асинхронно, поэтому вызов будет выглядеть примерно так:
@system @async @silent setclockres(1) задать частоту опроса без печати ввода/вывода
@system @async @silent @ShowMainToolBar 0 спрятать ToolBar без лишней печати
Введение данной команды давно назрело и позволяет активно использовать главную консоль
для решения нужных задач без загромождения консоли лишним выводом.
В главной консоли Crw32 добавлена консольная команда @silence:
@silence 1 1 подавлять ввод, подавлять вывод в команде @silent
это режим по умолчанию
@silence 0 1 печатать ввод, подавлять вывод в команде @silent
@silence 1 0 подавлять ввод, печатать вывод в команде @silent
@silence 0 0 печатать ввод, печатать вывод в команде @silent
этот режим отключает тихое выполнение @silent
@silence * * вывести текущий режим работы команды @silent
Команда @silence нужна для того, чтобы при отладке отключить тихий режим работы @silent.
По умолчанию команда @silent подавляет ввод и вывод.
Для отладки можно временно вернуть ввод/вывод.
В главном конфигурационном файле Crw32.ini добавлена секция
[System.StartupScript].
Эта секция позволяет задавать команды главной консоли, выполняемые при старте Crw32.exe.
Например:
[System.StartupScript]
@silent @fonts menu RUSSIAN_CHARSET ; задать русский язык в меню
@silent @fonts menu PT Sans ; задать имя шрифта меню
@silent @fonts menu bold ; задать жирность шрифта
@silent @fonts menu -16 ; задать высоту шрифта 12pt
@silent @echo Привет! ; напечатать приветствие
[]
Сделана попытка окончательно закрыть вопрос с фонтами.
Проблема тут вот в чем. Система развивалась много лет, под разными версиями ОС.
При этом в разное время использовались самые разные фонты:
FixedSys, Courier, Courier New, Tahoma, Arial, Arial Narrow, Arial Black,
Times New Roman, Liberation Mono, Dejavu Sans Mono, ...
При этом в разных версиях ОС эти шрифты бывают доступными или нет, как повезет.
Версии шрифтов также могут отличаться - например, могут не содержать нужного языка.
Кроме того, хаотично используемые фонты имеют разный набор доступных специальных
символов типа градуса (°C) или микро (µKu).
Из-за этого могли возникать ситуации, когда вместо желаемого вида окон на экране
наблюдаются непонятные "кракозябры", особенно если Windows не локализованный.
Единственным надежным методом обеспечения доступности желаемых шрифтов представляется
их внедрение в приложение. При этом файлы фонтов внедряются в EXE файл,
т.е. помещаются в ресурсы, а в случае отсутствия фонтов они берутся из ресурсов.
Другой проблемой из-за разнобоя со шрифтами является непредсказуемость визуального образа
приложения, который зависит от установленных шрифтов. В общем, бардак пора заканчивать.
По результатам долгого тестирования предпочтение было отдано семейству фонтов PT
московской фирмы ParaType, на мой вкус это лучшие шрифты для наших целей
(программирование, отображение алфавитно-цифровой информации на мнемосхемах).
В программу (Crw32.exe) внедрено 4 основных шрифта:
PT Mono - моноширинный шрифт для редактирования программного кода и отображения
числовой информации.
На замену FixedSys, Courier, Courier New, Liberation Mono,
Dejavu Sans Mono.
PT Sans - шрифт для редактирования обычного текста, где моноширинность не нужна.
Например, полезен для текстовых меток и поясняющих надписей.
На замену Arial, Tahoma.
PT Sans Narrow - шрифт для отображения узкого текста, например в длинных полях
редактирования, когда места для моноширинного шрифта не хватает.
На замену Arial Narrow, MS Sans Serif.
PT Serif - шрифт для редактирования обычного текста.
На замену Times New Roman, MS Sans Serif.
Поскольку фонты PT будут гарантированно доступными в программе, настоятельно
рекомендуется использовать для разработки прикладных систем именно эти шрифты.
Редактирования документов общего назначения это не касается.
Для управления внедрением шрифтов введены следующие параметры
Crw32.ini:
[System]
PtFontsEmbeddingMode = 1 ; PT fonts embedding mode: 0=None, 1=Force, 2=Smart
PtFontsSavingMode = 1 ; PT fonts saving mode: 0=None, 1=Save if not exist
PtFontsEmbeddingMode=0 отключает внедрение шрифтов (опция на всякий случай)
PtFontsEmbeddingMode=1 внедряет все шрифты, включая имеющиеся в системе
PtFontsEmbeddingMode=2 внедряет только шрифты, которые не найдены в системе
PtFontsSavingMode=0 отключает сохранение шрифтов
PtFontsSavingMode=1 сохранияет в C:\Windows\Fonts отсутствующие в системе шрифты,
так что после запуска программы шрифты PT в системе появятся
Создана и добавлена в сборку UnixUtils утилита enumfonts:
unix enumfonts печатает список всех шрифтов в системе
unix enumfonts * 1 печатает список всех моноширинных шрифтов
unix enumfonts 204 печатает список всех шрифтов, содержащих кириллицу
unix enumfonts 204 1 печатает список всех моноширинных шрифтов, содержащих кириллицу
unix enumfonts * * PT печатает список всех шрифтов, начинающихся с PT
unix enumfonts -p печатает путь системного каталога шрифтов типа c:\Windows\Fonts
unix enumfonts -k c:\Windows\Fonts\xxx.ttf удаляет из системы регистрацию шрифта (но не файл)
unix enumfonts -a c:\Windows\Fonts\xxx.ttf регистрирует в системе шрифт из данного файла
unix enumfonts -t c:\Windows\Fonts\xxx.ttf проверяет зарегистрирован ли в системе фонт
и так далее
Эта утилита решает проблемы, которые могут возникать в системе с фонтами по разным причинам.
Например, возможна ситуация, когда файл фонта в каталоге c:\Windows\Fonts есть, но в системе
он не зарегистрирован - так бывает. Бывает и наоборот: фонт зарегистрирован, но файла нет.
При этом возможны сбои в работе графики, такие как окна с пустыми полями вместо текста.
Утилиту enumfonts можно использовать в препроцессоре или в командных сценариях
при запуске систем для проверки и установки нужных шрифтов.
В Crw32 создана консольная команда @fonts:
@fonts list screen список всех зарегистрированных экранных шрифтов
@fonts list printer список всех зарегистрированных шрифтов принтера
@fonts list system 204 1 p список русских моноширинных шрифтов, начинающихся с p
@fonts embed info список внедренных в приложение шрифтов
@fonts embed force форсировать внедрение всех шрифтов
@fonts embed smart внедрять только отсутствующие
@fonts embed save сохранить шрифты в системе
@fonts path печать каталога шрифтов, обычно c:\Windows\Fonts
@fonts add c:\Windows\Fonts\x.ttf зарегистрировать в системе фонт из файла .ttf
@fonts kill c:\Windows\Fonts\x.ttf удалить регистрацию в системе (но не файл)
@fonts menu RUSSIAN_CHARSET задать русский язык для меню (против кракозябр)
@fonts menu PT Sans задать имя шрифта для меню
@fonts menu normal задать стиль шрифта меню: normal/bold/italic/bolditalic
@fonts menu -16 задать высоту шрифта, -16 соответствует 12pt
Подредактирована основная часть конфигураций (фонты TotalCommander, Notepad++ и т.д.),
так чтобы при инсталляции пакета везде были одинаковые PT шрифты.
Полностью переработать все файлы затруднительно, это будет делаться постепенно.
Однако пакет Crw32 и основные инструменты по умолчанию используют PT Mono как основной шрифт.
Слегка поправлена система UniHeat
и демонстрационная конфигурация DEMO_UNIHEAT.
Добавлена реакция на нажатие поля отображения датчика температуры (показывается график).
Все шрифты заменены на PT. Сделаны генераторы конфигураций (Н.Гурин).
Эту подсистему можно считать 100% готовой.
Обновлена демонстрационная конфигурация DEMO_P48.
Систему обновил Н.Гурин. Внесены небольшие правки (шрифты заменены на PT).
Система выглядит симпатично, поэтому перенесена из Extra в основной пакет.
07.04.2016
Metrology PhysLibrary _DEWTORH.PAS DEMO_FAHT
Учитывая высокую роль стандартизации, решено завести справочную папку по метрологии
Metrology. Эта папка вынесена в TopList справки.
В ней будут располагаться основополагающие нормативные документы по метрологии - ГОСТы и
международные стандарты, а также классические статьи, на которые часто ссылаются.
В настоящее время там помещены документы по единицам измерения СИ, а также измерениям
температуры, давления и влажности.
Создана библиотека PhysLibrary.
По задумке это набор средств для выполнения расчетов, связанных с экспериментальной физикой.
В настоящее время она включает минимальный набор функции преобразования некоторых единиц измерения,
а также функции измерения влажности, давления водяного пара и т.д. Библиотека будет пополняться.
Все функции выполняются в соответствии с ГОСТами и международными стандартами.
Создана библиотечная программа _DEWTORH.PAS.
Она готова к использованию и служит для преобразования температуры точки росы (а также температуры
и давления воздуха) в относительную и абсолютную влажность.
Программа создана для работы с измерителями температуры точки росы, например
EasyDew
фирмы Michell Instruments.
Программа использует библиотеку PhysLibrary.
Обновлена демонстрационная конфигурация DEMO_FAHT.
Демо-версия синхронизирована с текущей рабочей конфигурацией.
В ней используется новый модуль _DewToRH.pas.
25.03.2016
UnixUtils svg-edit svg-edit DEMO_VSPE
Серьезно обновлена библиотека шрифтов, включающая большое множество семейств свободно
распространяемых шрифтов, таких как:
Adobe Source Code Pro, Alef, Bitstream Vera, Cantarell, Culmus, Dejavu, GNU Free,
Inconsolata, Liberation, Libertine, Overpass, Oxygen, SJ, UniFont,
Droid, Ubuntu, Roboto, ParaType PT, Nova, Fira.
Эти шрифты распространяются известными компаниями (Google, Adobe, Mozilla, RedHat, ParaType)
и с большой вероятностью могут использоваться в различных документах, распространяемых в Сети,
и поэтому должны быть доступны на любой машине.
При выборе шрифтов предпочтение отдавалось семействам, включающим моноширинные шрифты,
которые рекоментуется использовать при редактировании программных кодов и создании
мнемосхем для измерительных систем.
Например, можно использовать моноширинные шрифты:
Droid Sans Mono, DejaVu Sans Mono, Fira Mono, NovaMono, Oxygen Mono, FreeMono,
Liberation Mono, Linux Libertine Mono O, Roboto Mono, Ubuntu Mono,
Bitstream Vera Sans Mono, Inconsolata, Source Code Pro, PT Mono.
Многие из этих шрифтов специально разработаны для программирования и систем отображения
алфавитно-цифровой информации в системах управления.
Так, например, многие обычные шрифты имеют очень похожее начертание нуля ("0") и буквы ("O") ,
единицы ("1") и латинской буквы ("l").
Наиболее "читабельными" в смысле различения похожих букв кажутся такие шрифты как:
Inconsolata, DejaVu Sans Mono, Bitstream Vera Sans Mono, Fira Mono, Oxygen Mono, Ubuntu Mono,
Source Code Pro, PT Mono.
Именно их рекомендуется использовать для редактирования текстов программ или для мнемосхем.
Некоторые шрифты служат для "спецэффектов", например прописные Monofur, Lobster или имитатор LED дисплея Digital Numbers:
0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ : Digital Numbers
0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ : GOST type A
0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ : GOST type B
0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ : Lobster
0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ : Lobster Two
0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ : Alef
Для справки - штатные (в большинстве не моноширинные) шрифты Windows:
0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ : Arial
0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ : Times New Roman
0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ : Verdana
0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ : Tahoma
0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ : Bodoni MT
0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ : Small Fonts
По моему личному вкусу наилучшим шрифтом для создания мнемосхем является семейство PT (ParaType).
Эти шрифты разработаны в России фирмой ParaType
и распространяются по свободной лицензии.
Поэтому в будущем рекомендуется использовать при определении шрифтов следующие:
Шрифт | На замену... | С целью отображения для...
----------------------------------------------------------------------------------------
PT Mono (bold) | FixedSys | числовых полей (LED)
PT Mono | Courier New | числовых полей, редактирования программного кода
PT Mono | Liberation Mono | числовых полей, редактирования программного кода
PT Sans | Arial | поясняющих надписей
PT Sans Narrow | Arial Narrow | узких надписей и экономии места в строковых полях
PT Serif | Times New Roman | поясняющих надписей, редактирования обычного текста
----------------------------------------------------------------------------------------
В настоящий момент используются в основном: FixedSys, Courier New, Liberation Mono, Arial, Times New Roman.
Из-за большого объема ссылок менять ситуацию немедленно - нецелесообразно.
Но в будущем предлагается постепенно заменять шрифты на указанные здесь, по крайней мере на мнемосхемах.
В качестве образцов можно взять файлы описания фонтов для мнемосхем
DEMO_BDMG,
DEMO_FAHT.
Запустив эти ДЕМО, можно посмотреть, как это выглядит на практике.
Так или иначе, все перечисленные выше шрифты отныне входят в библиотеку и на них можно рассчитывать.
Обновлена сборка UnixUtils.
Cygwin (основа сборки UnixUtils) обновлен с версии 2.4.0 до 2.4.1.
Добавлено несколько новых утилит:
unix fontreg Утилита обновляет и исправляет регистрацию всех фонтов,
находящихся в системном каталоге c:\Windows\Fonts.
В реестре удаляются регистрационные записи о фонтах,
которые отсутствуют в системном каталоге на диске.
А также регистрируются фонты, которые найдены в
системном каталоге, но еще не зарегистрированы.
unix fontreg /copy Копирует в системный каталог и регистрирует в системе
все фонты TTF,OTF,FON, находящиеся в текущем каталоге.
unix fontreg /move Перемещает в системный каталог и регистрирует в системе
все фонты TTF,OTF,FON, находящиеся в текущем каталоге.
unix system-fonts-install Инсталляция всех TTF,OTF,FON фонтов, входящих в состав
UnixUtils, включая семейства: Adobe Source Code Pro, Alef,
Bitstream Vera, Cantarell, Inconsolata, Culmus, Dejavu, SJ,
Liberation, Libertine, GNU Free, Overpass, Oxygen, UniFont.
unix system-fonts-install dir1 dir2 .. Инсталляция всех TTF,OTF,FON фонтов, входящих в состав
UnixUtils, а также всех фонтов, находящихся внутри
каталогов dir1, dir2 .. (поиск файлов идет рекурсивно).
unix system-fonts-view Просмотр списка всех установленных фонтов,
зарегистрированных в системе (работает медленно).
unix system-fonts-view mono Просмотр списка всех установленных фонтов,
зарегистрированных в системе и имеющих
в составе имени заданную строку (mono).
unix system-start-button show Показать кнопку Start (Пуск).
unix system-start-button hide Спрятать кнопку Start (Пуск).
unix system-start-button enable Разрешить кнопку Start (Пуск).
unix system-start-button disable Запретить кнопку Start (Пуск).
unix system-start-button show enable Показать и разрешить (Пуск).
unix system-start-button hide disable Спрятать и запретить (Пуск).
unix svg-edit Вызвать редактор SVG для редактирования
векторной графики (Scaleable Vector Graphics).
Редактор svg-edit работает в Web (Firefox) на
Java Script и позволяет создавать как векторные
изображения SVG, так и растровые BMP,PNG,JPG.
unix system-enum-com-ports Отображает список доступных COM портов.
Эта утилита полезна для разных командных файлов,
например для проверки доступности COM портов при
старте в препроцессоре DAQ системы.
unix system-stress-test Утилита стрессового тестирования для проверки
работы системы в условиях экстремальных нагрузок.
unix system-* --help Все перечисленные system- утилиты имеют --help
Обновлены сборки Commander и DaqGroupTools: Firefox, LibreOffice, Adobe, KLite Codec и т.д.
Редактор svg-edit добавлен в Top-List
основного HELP.
Он распространяется компанией Google,
работает как online,
так и offline
под любым современным Web-обозревателем и является Web-ориентированным редактором
векторных изображений в формате SVG (Scaleable Vector Graphics),
который является официальным стандартом консорциума W3C,
который занимается стандартизацией HTML.
Это значит, что формат SVG является таким же перспективным как HTML и таким же надежным в смысле поддержки в будущем.
Редактор svg-edit очень компактный (1 МБ в zip архиве) и работает на java script.
Помимо простого создания картинок (векторных и растровых) у редактора SVG есть то преимущество,
что формат SVG поддерживается всеми современными Web обозревателями (Firefox, Chrome, IE)
и может быть использован для создания Web-ориентированных "живых" (активных) мнемосхем,
см. например, сайт svgmnemo.ru/, где объясняется,
как создавать Web-ориентированные системы SCADA на основе SVG мнемосхем.
Поскольку у нас есть встроенный в CRW-DAQ Web-сервер, SVG - мнемосхемы могут пригодиться
для создания систем по типу (Web-сервер <--> Web-клиенты), когда измерения идут
на сервере под CRW, а наблюдение ведется на удаленных Web клиентах с использованием
связки HTML + SVG + JavaScript.
Редактор svg-edit, таким образом,
является "закладкой на будущее" для развития в сторону Web-технологий.
Обновлена демонстрационная конфигурация DEMO_VSPE.
В препроцессор
и постпроцессор
добавлен автомат,
который при старте системы запрещает и скрывает системную кнопку Windows Start (Пуск).
Это нужно для создания высоко защищенных систем, в которых по тем или иным причинам
требуется ограничить доступ пользователей к вызову посторонних программ.
Например, в системах, работающих удаленно (через удаленный Рабочий Стол) часто требуется
запретить вызов Shutdown, Restart или Log Off, чтобы предотвратить непреднамеренное
завершение работы. В других системах требуется запретить вызов посторонних программ
(игрушек, аудио и видео проигрывателей и т.д.) во избежание аварий из-за "человеческого
фактора". Для этого можно запрещать и скрывать кнопку Start (Пуск), оставляя пользователям
на панели инструментов ярлыки только на те программы, которые им разрешены.
Демонстрационная конфигурация DEMO_VSPE может
служить образцом и шаблоном для таких систем.
Обновлена демонстрационная конфигурация DEMO_FAHT.
Демо-версия синхронизирована с текущей рабочей конфигурацией.
В нее также добавлено запрещение кнопки Start (Пуск).
Добавлена демонстрационная конфигурация DEMO_BDMG.
Эта конфигурация содержит драйвер для управления блоками детектирования «БДМГ-200» производства НПП «Доза».
Несмотря на то что это "сырая" версия драйвера, который в настоящее время активно разрабатывается
Николаем Гуриным, его включение в дистрибутив уже имеет смысл, т.к. драйвер уже вполне рабочий.
ДЕМО версии систем служат хранилищем для многократно используемого программного кода,
а также в качестве "шпаргалки" с информацией, необходимой для создания новых систем.
В этом смысле образцы не завершенных (но уже рабочих) версий прикладного ПО имеют свою пользу.
ДЕМО версия драйвера будет обновляться по мере разработки.
Обновлена ДЕМО конфигурация DEMO_ALIPHOSCOOL.
Она синхронизирована с текущей версией РПО, только в ДЕМО исключена объемная документация
и сделаны мелкие изменения специально для демо версии.
01.01.2016 ... 18.01.2016
UnixUtils DEMO_EMAPS
Обновлена демонстрационная конфигурация DEMO_EMAPS.
Там добавлен драйвер TDS для измерения частоты и амплитуды NMR.
Обновлена сборка UnixUtils.
Cygwin (основа сборки UnixUtils) обновлен с версии 2.2.1 до 2.4.0.
Обновлены сборки Commander и DaqGroupTools: Firefox, LibreOffice, Adobe, KLite Codec, SumatraPdf и т.д.
26.10.2015 ... 28.10.2015
Windows 10 DEMO_EMAPS ClassicShell
Добавлена демонстрационная конфигурация DEMO_EMAPS.
Эта конфигурация содержит два драйвера с симуляторами:
драйвер источника питания "Пульсар Смарт" производства ООО "Навиком"
и драйвер аналогового ПИД регулятора SIM900/SIM960 производства "Stanford Research Systems".
Также содержит заготовку GUI (графического интерфейса) верхнего уровня.
Это хороший шаблон для разработки новых систем и драйверов.
Остальные изменения в основном связаны с переходом под Windows 10.
Серьезно обновлена сборка UnixUtils.
Изменения сделаны в основном с целью совместимости с Windows 10.
Для этого Cygwin (основа сборки UnixUtils) был обновлен с версии 1.7.15 до 2.2.1.
Также обновлен Notepad++.
Практически полностью обновлены сборки Commander и DaqGroupTools: обновлены Firefox, LibreOffice, Adobe, KLite Codec, Lazarus и т.д.
Внесены правки и сделаны настройки Commander для совместимости с Windows 10.
Для настройки Windows 10 в классическом стиле в сборку Commander добавлены утилиты:
Файлы
для настройки Контроля Доступа Пользователей UAC (User Access Control).
Файл
disable-uac.reg
отключает UAC. Это нужно для корректной работы ярлыков AdmiLink (запуск с правами Администратора).
Другие файлы служат для сохранения настроек UAC и восстановления значений по умолчанию.
Команды
для настройки темы окон (ClassicTheme.cmd) и классического меню "Пуск" (ClassicShell.cmd).
Команда ClassicTheme.cmd устанавливает классическую тему окон
ClassicTheme,
в стиле Windows-XP Classic.
Команда ClassicShell.cmd вызывает установку пакета
ClassicShell,
эмулирующего классический стиль меню "Пуск" в Windows/8/10.
В той же папке находится файл с типичными настройками Menu Settings - Alex.xml.
01.07.2015 ... 25.07.2015
cmdautorun DEMO_FAHT DEMO_VSPE
Добавлена демонстрационная конфигурация DEMO_FAHT.
Несмотря на незавершенность проекта, там есть много полезного для копирования в другие АСКУ:
система наименований для изображений,
средства для работы с драйвером VSPE (Virtual Serial Port Emulator).
Добавлена демонстрационная конфигурация DEMO_VSPE.
Это шаблон для копирования в системы, использующие драйвер VSPE (Virtual Serial Port Emulator),
например, для туннелирования COM портов через TCP в виртуальных машинах VirtualBox.
Серьезно обновлена сборка UnixUtils. В ней добавились утилиты:
medit - мощный кросплатформенный редактор, альтернатива notepad++
grun - утилита для запуска программ в разных графических режимах
DetectVirtualBoxVersion - определяет версию VirtualBox, для работы с виртуальными машинами
DetectVirtualBoxSharedFolders - определяет список общих папок VirtualBox в виртуальной машине
NetUseVirtualBoxSharedFolders - подключает общие папки VirtualBox, зарегистрированные в системе
.cmdautorun.cmd - скрипт для автоматического вызова при каждом вызове cmd.exe
.cmdautorun /r - (register) регистрация в системе
.cmdautorun /u - (unregister) отмена регистрации в системе
.cmdautorun /s - (status) проверка регистрации
.cmdstartup.cmd - скрипт для автоматического вызова при первом старте cmd.exe
используется для реализации таких функций как: автоматическое
подключение дисков VirtualBox; установка цветов консольного окна
в зависимости от типа учетной записи пользователя (admins,users)
admins:зеленый на черном, users:светло серый на черном; задание
переменных окружения: _AccountMembership=admins/users, а также
_VirtualBoxVersion для дальнейшего использования в командных файлах.
Возможно добавление дополнительных функций путем создания файлов типа
.cmdstartup.*.cmd (например, .cmdstartup.1.demo.cmd) в каталоге Windows.
.MachineStartup.cmd - скрипт для выполнения при запуске машины
.MachineShutdown.cmd - скрипт для выполнения при завершении работы машины
.UserLogon.cmd - скрипт для выполнения при входе пользователя в систему
.UserLogoff.cmd - скрипт для выполнения при выходе пользователя из системы
эти системные скрипты служат для выполнения заданных действий при
запуске/завершении работы машины или входа/выхода пользователя в систему.
Возможно добавление дополнительных функций путем создания файлов типа
.MachineStartup.*.cmd (типа .MachineStartup.1.demo.cmd) в папке Windows.
Для использования надо зарегистрировать эти скрипты в системе через
утилиту gpedit.msc.
По набору утилит cmdautorun имеется справка.
Этот набор, сам по себе полезный, имеет особенное значение для систем, работающих в виртуальных
машинах VirtualBox, которые планируется активно использовать в будущем.
Обновлены сборки Commander и DaqTools: обновлены Firefox, LibreOffice, Adobe, KLite Codec, Lazarus и т.д.
Добавлены новые кнопки Commander, редактор medit (кроссплатформенный, Linux + Windows).
Переработаны ярлыки для запуска приложений DaqGroup (DAQ Run, Cmd as root, Commander as main и т.д.).
24.02.2015 ... 27.02.2015
UniHeat DEMO_UNIHEAT DIBUS
Слегка поправлена система UniHeat
и демонстрационная конфигурация DEMO_UNIHEAT.
Добавлена документация и отладочная утилита по DIBUS.
21.02.2015 ... 23.02.2015
UniHeat DEMO_UNIHEAT GOST
Обновлены некоторые программы, входящие в сборку InstallDaqGroupTools и InstallTotalCommanderExtra.
В частности, SumatraPDF, LibreOffice, Firefox, Thunderbird, PoEdit, KLCodecPack, Java Runtime Environment (JRE) и другие.
Обновлены (исправлены) ГОСТ-овские фонты GOST type A, GOST type B.
Обновлена система UniHeat
и демонстрационная конфигурация DEMO_UNIHEAT.
Изменен интерфейс и документация.
Обновлены некоторые программы, входящие в сборку InstallDaqGroupTools и InstallTotalCommanderExtra.
В частности, SumatraPDF, LibreOffice, Firefox, Thunderbird, Lazarus, FreePascal, PoEdit, KLCodecPack, Pdf24, AdobeReader и другие.
Добавлены: Java Runtime Environment (JRE), Midnight Commander (MC), ГОСТ-овские фонты GOST type A, GOST type B.
Обновлена система демонстрационная конфигурация DEMO_SPVZK.
Поправлена подпрограмма автоматического позиционирования.
30.09.2014 ... 05.10.2014
UnixUtils DCC32 UniHeat DEMO_UNIHEAT DEMO_LINCORR
Обновлены некоторые программы, входящие в сборку InstallDaqGroupTools и InstallTotalCommanderExtra.
UnixUtils модифицирован для большей совместимости с Linux/Wine.
Также в него добавлен компилятор командной строки DCC32 для компиляции программ Object Pascal.
В системе универсальных нагревателей UniHeat добавлена возможность назначать имена нагревателям.
Например, BS1, BS2, F1 и т.д. Это необходимо для систем с большим количеством печей, где вопрос именования очень важен.
Стандартные имена нагревателей (печей) по умолчанию - HEAT-1, HEAT-2, ... - могут быть изменены и сохранены в INI файле.
Соответственно изменен пример DEMO_UNIHEAT.
Добавлена демонстрационная конфигурация DEMO_LINCORR, иллюстрирующая
использование новой библиотечной программы _LINCORR.PAS.
Эта программа вычисляет производную (линейную корелляцию) зашумленного сигнала.
Например, если нужно определить фазовый переход, его можно увидеть по минимуму производной на графике температуры.
Однако для численно устойчивого дифференцирования зашумленного сигнала необходимо иметь устойчивый к помехам
алгоритм расчета производной.
Именно это и делает программа _LinCorr.pas, вычисляющая среднее и производную устойчивым к шуму методом.
Имеется описание lincorr.htm.
Обновлены все основные программы, входящие в сборку InstallDaqGroupTools и InstallTotalCommanderExtra.
В UnixUtils добавлена команда ismemberof для проверки прав доступа.
Может использоваться в командных файлах.
Например:
Проверить, входит ли пользователь в локальную группу Администраторы:
unix ismemberof admins && echo User is member of Administrators local group
Выполнить команду defrag, если пользователь входит в группу Администраторы:
unix ismemberof admins 1>nul 2>nul && echo User is member of Administrators local group
Узнать в какие "хорошо известные группы" входит пользователь:
unix ismemberof -m
Получить список "хорошо известных групп"
unix ismemberof -l
Добавлен ДЕМО пример DEMO_SPVZK, содержащий
драйвер инвертера Mitsubishi FR-F740 для управления 3-фазными двигателями,
а также драйвер энкодеров I-7083.
Эти драйверы могут как использоваться непосредственно, так и служить прототипом для создания других драйверов
для похожих устройств с интерфейсами RS-232/485.
В пакет добавлена система универсальных нагревателей UniHeat
(universal heaters), содержащая до 30 каналов для управляемого нагревания и термостабилизации объектов
с системой блокировок по температуре, давлению и внешним сигналам.
Имеется документация в uniheat.htm
В стандартную библиотеку добавлены функции
WinListByCurve,
WinSelectByCurve,
DeviceListEnum,
CalibrOpenByCurve.
Эти функции предназначены для организации интерфейсов пользователя.
Например, с помощью вызова WinSelectByCurve по нажатию на сенсор можно открывать окна графиков, отображающих кривую, связанную с этим сенсором.
А с помощью функции CalibrOpenByCurve можно открыть окно редактора калибровки, связанной с данной кривой.
Пример использования этих функций имеется в DEMO_UNIHEAT.
Решены некоторые проблемы совместимости (инсталлятора) с Windows x64.
В стандартную библиотеку добавлена функция UnixTooltipNotifier,
работающая через пакет UnixUtils и выдающая всплывающее окно сообщения в области уведомлений
с выбором цвета, фонта и времени показа.
Имеет то достоинство, что окно является неблокирующим, не сбивает фокус ввода и исчезает само,
при этом сообщение автоматоматически журналируется в консоли. Пример:
UnixTooltipNotifier('text "Операция успешно завершена." delay 15000 trans 255 bkColor green textColor 0x000000'
+' font "Arial Black" fontSize 16 ico notify.ico audio notify.wav');
где:
text "Операция успешно завершена." - выводимый текст, обязательно в кавычках
delay 15000 - автоматическое закрытие через 15000 ms
trans 255 - прозрачность (transparency), 0..255
bkColor green - цвет фона по имени (red,green,...) или HEX RGB
textColor 0x000000 - цвет текста, HEX RGB, 0xRRGGBB
font "Arial Black" fontSize 16 - имя фонта и размер, pt
ico notify.ico - имя файла картинки (exe,dll,ico)
audio notify.wav - имя звукового файла (wav)
Небольшой пример и тест использования функции UnixTooltipNotifier включен в демо
DEMO_TESTBENCH.
Аварийное уведомление по умолчанию PostMortalWill
теперь также сделано на базе tooltip-notifier.
Это более приятный для пользователя режим уведомления, не мешающий работать, так как всплывающее окно
не модальное и не сбивает фокус ввода.
Он внес неоценимый вклад в создание пакета. И вообще в нашу жизнь.
Для нас всех, членов Daq Group, это невосполнимая утрата.
Но жизнь продолжается. В том числе развитие пакета CRW-DAQ.
Этот дистрибутив посвящен в основном обновлению инсталляторов и дополнительных свободных пакетов.
Полный дистрибутив теперь включает такие компоненты:
InstallCrw16.exe - инсталлятор CRW-DAQ for Dos16.
InstallCrw32.exe - инсталлятор CRW-DAQ for Win32.
InstallCrw32Extra.exe - дополнения (документация и ДЕМО) для CRW-DAQ.
InstallDaqGroupTools.exe - инсталлятор большой коллекции свободных программ для разработчиков.
InstallTotalCommanderExtra.exe - инсталлятор Commander с большой встроенной коллекцией свободных программ.
InstallUnixUtils.exe - автономный инсталлятор пакета UnixUtils, входящий также в CRW-DAQ.
Обновлены все служебные пакеты (ROOT, Firefox, SumatraPDF, KLCodec, WinAmp), добавлена куча новых.
Добавлены компиляторы (Free Pascal, Lazarus), редакторы (Geany, HexEdit, PoEdit), свободный Офис (Libre Office).
Все включенные пакеты являются свободными, их можно ставить на любые машины.
Решение о создании этой большой сборки связано с несколькими обстоятельствами.
Во-первых, на компьютерах, поставляемых с измерительными системами сторонним организациям, должен стоять только свободный софт, чтобы не было лишних проблем.
Во-вторых, имея в виду перспективы активного использования ROOT и Free Pascal, необходимо всегда иметь эти инструменты под рукой.
Для этого они должны быть в сборке.
Наработанная сейчас структура инсталляторов позволит в будущем более легко обновлять сборки, менять их состав.
Значительно расширен и переработан пакет UnixUtils,
в котором уже более 500 команд.
Так, в этот пакет встроен маленький компилятор tcc языка C. Есть другие полезные новшества.
Например, полезная программка fp-qui, которая выводит сообщения в всплывающих окнах, расположенных рядом с треем.
Это очень удобно для ненавязчивых уведомлений о разных событиях. Примеры:
Компиляция программ:
unix tcc demo.c компиляция программы C
unix tcc-doc вызов справки по tcc
Вывод уведомления на 15 сек, крупным шрифтом 32pt:
unix fp-qui "<delay>15000</delay> <fontSize>32</fontSize> <text>Уведомление о событии X.</text>"
Закрыть программу всплывающих уведомлений:
unix fp-qui-kill
Все перечисленные команды доступны из Главной Консоли CRW-DAQ.
Их также выполнять в программах DaqPascal вызовом eval(), например:
rNul(eval('@system @async @run unix fp-qui "<text>Уведомление о событии X.</text>"'))
Справку (HTML) по всем командам UnixUtils можно получить вызовом unix -m
Там кратко описаны и команды fp-qui
Поскольку программа fp-qui имеет довольно сложный синтаксис вызова, для нее сделана более простая "обертка" tooltip-notifier.
Примеры (для Главной Консоли Crw32):
@run /hide unix tooltip-notifier text "Уведомление о событии." delay 15000 font "Arial" fontSize 32 bkColor yellow textColor 0x0000FF
@run /hide unix tooltip-notifier text "Уведомление с музыкой." delay 15000 audio notify.wav trans 210 ico msiexec.exe
параметры вызова:
text "Уведомление о событии." - задает текст уведомления
delay 15000 - закрывает уведомление через 15000 ms
font "Arial" fontSize 32 - задает фонт Arial размером 32 pt
textColor 0x0000FF - цвет текста, RGB, Hex, 0xRRGGBB, в данном случае blue
bkColor yellow - цвет фона, 0xRRGGBB или (red,gree,blue,yellow etc)
audio notify.wav - задает звуковой файл для проигрывания (*.wav)
ico msiexec.exe - задает файл иконки (*.ico,*.exe,*.dll)
trans 255 - задает прозрачность (0..255)
tooltip-notifier призван помочь в разработке удобных интерфейсов.
Для измерительных систем всплывающие подсказки очень удобны, так как они информируют пользователя о событиях,
не нарушая его работы. Не надо каждый раз кликать кнопку Ok, не надо искать "спрятанные" модальные окна.
Это удобно.
Сильно переработана структура инсталлятора и система катологов Crw32exe (Resource,Package).
При этом основной файл (Crw32.exe) не затронут. Надо обратить внимание на побочные эффекты.
Хотя сам пакет Crw32.exe не менялся, могут не заработать мелкие функции, где используются ссылки на файлы.
Реструктуризация каталогов связана с желанием унифицировать инсталляторы и сократить число дублирований файлов.
Дублирование файлов возникало непроизвольно в процессе развития пакета. Сейчас пришла пора упорядочить структуру файлов.
В дополнительный пакет (Extra) добавлен пример DEMO_P20,
который иллюстрирует возможности создания систем быстрого сбора на базе драйвера E140.
Там также свежая версия UniHeat, которую можно использовать как прототип для работы с нагревателями.
Кроме того, есть примеры кнопок вызова калибровок для каждого канала, новые процедуры обработки данных
(сдвиг по X,Y; масштабирование; смещение нуля). В общем, полезный пример.
В библиотеку стандартных DAQ-Pascal программ добавлены:
1) Программа _CRWSVR.PAS для сохранения данных в формате CRW:
ProgramSource = ~~\Resource\DaqSite\StdLib\DaqPas\_CRWSVR.PAS
2) Программа _GATEXY.PAS для сдвига/масштабирования(X,Y)/ворот сигнала:
ProgramSource = ~~\Resource\DaqSite\StdLib\DaqPas\_GATEXY.PAS
Программа _CRWSVR.PAS
является аналогом _CRWSAVE.PAS (которую она призвана заменить),
но дополнительно может сохранять имя последнего сохраненного файла в теге.
Это удобно, чтобы после сохнанения ссылаться на файл, открывать его в диалоге и т.д.
Использование программы иллюстрируется в DEMO_P20.
Программа _GATEXY.PAS
служит для обработки сигналов в системах как медленных, так и быстрых измерений.
Она умеет выполнять сдвиг и масштабирование по осям X,Y, а также содержит ворота на пропускание сигнала.
Кроме того, программа может осуществлять динамическое переключение каналов (signal mapping).
Сдвиги, масштабные коэффициенты, ворота и номера переназначаемых каналов задаются в тегах.
Причем можно использовать один тег для нескольких каналов, например, использовать для сигналов общие ворота.
Использование программы иллюстрируется в DEMO_P20.
15.02.2013 ... 16.05.2013
UnixUtils DEMO_E140 DEMO_CCTB Search and Replace
Добавлена пара программ (upx,strip) в пакет UnixUtils,
которые служат для сжатия исполняемых файлов. На будущее.
В сборку Commander, в дополнительную панель инструментов, добавлена программа Search and Replace, которая
позволяет искать\заменять фрагменты текста сразу в группе файлов. Это незаменимый инструмент в случае, когда, например,
надо переименовать группу тегов, разбросанных по нескольким конфигурационным файлам. Для работы утилиты требуется
наличие пакета .NET 4.0 или выше (в Win-7 он присутствует по умолчанию).
Кроме того, обновлены Firefox, SumatraPDF, KLCodec.
Обновлен драйвер E14-140, с возможностью подключения нескольких карт.
Есть одна проблема - времена самплинга разных карт не синхронизованы - у каждой карты свой тактовый генератор.
Другая проблема - хотя драйвер работает надежно, при запуске конфигурации из нескольких карт возможно появление
нескольких ошибок перезапуска драйвера. Это возникает из-за того, что в момент старта несколько экземпляров программы
драйвера одновременно пытаются захватить устройства, а владелец у них может быть только один.
После (возможно) нескольких перезапусков каждый драйвер захватывает свое устройство (по серийному номеру) и далее работает
с ним без помех.
Это надо учитывать при построении систем.
Обновлен пример DEMO_E140, который иллюстрирует новые возможности
драйвера E140. Для конфигурирования надо отредактировать файл E140_CTRL.CMD, и затем запустить
его для генерации файла E140_CTRL.CFG. При редактировании в процедуре :E140Table описывается
набор используемых преобразователей, каждый из которых идентифицируется серийным номером (SerialNum),
написанным на крышке преобразователя. Кроме того задаются диапазоны (Gain-mapping) и карты опроса (Gate-mapping),
режим симуляции (Simul) и суффикс (Suffix) имени карты, для её именования в конфигурации. Серийные номера и суффиксы
должны быть уникальными (в рамках одной конфигурации). Если подключена только одна карта, серийный номер
можно не указывать (пустая строка).
В дополнительный пакет (Extra) добавлен пример DEMO_CCTB (control channels test bench),
который иллюстрирует ряд новых подходов к конфигурированию систем, содержащих много однородных элементов,
в данном случае 48 устройств ADAM-7011 на 6 COM-портах и 6 карт E140.
Общий принцип конфигурирования таков. Создается файл шаблона, для примера, adam_ctrl.gen, описывающий одно устройство.
Параметры устройства (имя, порт, адрес и т.д.) параметризуются в виде {Name}, где Name - имя параметра.
Затем создается одноименный командный файл adam_ctrl.cmd, содержащий таблицу параметров и генерирующий из шаблона
файл конфигурации adam_ctrl.cfg. Это делается путем замены параметризованных параметров файла-генератора на параметры,
заданные в таблице. При добавлении новых или изменении старых устройств редактируется, а затем исполняется командный файл,
генерирующий новую конфигурацию. Генератор построен на базе UnixUtils.
Главное преимущество данного подхода (кроме экономии времени) - сокращение числа ошибок "по невнимательности" при работе с системами,
содержащими много похожих (однородных) подсистем. Проще один раз написать генератор из таблицы параметров, чем всякий раз править
огромные конфигурации.
Также система интересна с точки зрения симуляции. С помощью включения в конфигурацию различных файлов и задания параметров
симуляции в генераторе удается реализовать много режимов симуляции:
Симуляция для проверки MODBUS. При этом ADAM и E140 отключены, а данные для передачи задаются пользователем
в диалоге.
Симуляция ADAM. При этом используется виртуальный COM-порт c конфигурацией cctb.vspe.
Драйверы ADAM работают как бы с реальными устройствами, но вместо них к виртуальным портам подключаются симуляторы.
Симуляция E140. Требуется при отсутствии карт E14-140.
Симуляторы бывают совершенно необходимы, когда по условиям работ приходится вести разработку РПО при отсутствии
нужного оборудования. Симуляция разных уровней, от искуственной генерации данных до полноценной работы штатных драйверов,
к которым подключаются симуляторы, позволяют тестировать практически весь тракт сбора и обработки данных.
07.02.2013 ... 14.02.2013
UnixUtils Virtual Com Port &ModbusSrv DEMO_MDBS AdamTraffic
Добавлено значительное число (более 40) новых утилит в пакет
UnixUtils.
Например:
unix setclosemenu -d - запретить кнопку "закрыть" в консольном окне (против случайного закрытия)
unix setclosemenu -e - разрешить кнопку "закрыть" в консольном окне (когда нужная работа сделана)
unix junc c:\link d:\work - создает символическую ссылку link на каталог work
unix nirsoft - выдать список диагностических утилит от NirSoft
unix nirsoft cports - посмотреть список открытых TCP/IP портов
unix nirsoft awatch - посмотреть параметры сети Ethernet и сетевых адаптеров
unix nirsoft pinginfoview - пинговать список серверов
... и так далее...
unix -m - справка по всем командам пакета UnixUtils
В меню "Инструменты\Консольные утилиты" добавлено значительное число новых пунктов.
В основном они касаются диагностики и настройки системы и ориентированы на тот случай,
когда (по разным причинам) настройку нельзя сделать стандартными средствами.
Например, когда работа идет под ограниченным пользователем или доступ к инструментам закрыт.
В инсталлятор TotalCommander добавлено два (free) пакета для создания виртуальных
COM портов. Один из них работает под Win XP, другой требует Win 7+,
но имеет поддержку x64. Виртуальные порты нужны для следующих целей:
Возможность отладки DAQ-систем на машинах, где нет COM портов.
Возможность создания полнофункциональных симуляторов (с реальным обменом данными).
Удаленный сбор данных по сети Ethernmet через переадресацию портов
COM <==> TCP/IP. Это позволяет в ряде случаев сократить
число кабельных работ (при наличии сети и дешевых или старых компьютеров).
if devmsg('&I7011_1 InquiryPeriod=100')>0
then Sussess('Polling period 100 ms assigned')
else Trouble('Could not set polling period.');
InquiryPeriod позволяет устанавливать период опроса от 0 до 2147483647 ms (около 24.5 дней).
Это позволяет динамически отключать опрос устройств, либо варьировать его частоту.
При указании InquiryPeriod=0 реально можно достичь частоты опроса около 150 Гц на
один порт (делим на число каналов).
Установку периодов опроса можно занести в секцию инициализации:
Здесь надо отметить, что с помощью консольной команды @daq devsend
сообщение посылается серверу &CronSrv, который уже пересылает его нужному устройству.
Это необходимо потому, что команда @daq devsend умеет посылать сообщения только
устройствам program - таково ограничение Главной Консоли.
Возможность динамического изменения частоты опроса разных устройств позволит менять
на ходу (по кнопке) ход измерений, выделяя группу каналов для быстрого опроса,
а другую группу - для медленного.
В драйвере ADAM-7011 сделаны
изменения, позволяющие ускорить опрос каналов до 4 раз. Это достигается путем
сокращения числа ненужных сообщений. Так, если кривая к цифровому выходу не подключена,
то цифровой канал (в данном случае - состояние реле LO, HI) не нужно опрашивать.
В драйвере устройств ADAM сделан подстчет траффика.
Он доступен через вызов функции ParamStr.
Например:
traffic:=paramstr('AdamTraffic *'); // трафик для всех устройств ADAM
traffic:=paramstr('AdamTraffic COM1'); // трафик для всех устройств на COM1
traffic:=paramstr('AdamTraffic XXXX'); // трафик для устройства с именем XXXX
tx_polls:=rVal(ExtractWord(1,traffic)); // счетчик опросов передатчика
tx_bytes:=rVal(ExtractWord(2,traffic)); // счетчик байтов передатчика
rx_polls:=rVal(ExtractWord(3,traffic)); // счетчик ответов в приемнике
rx_bytes:=rVal(ExtractWord(4,traffic)); // счетчик байтов приемника
Эти счетчики позволяют оценить скорость опроса устройств - полезно для диагностики.
В сервер &ModbusSrv добавлены счетчики
траффика и подсчет скорости опроса (это чрезвычайно полезно при отладке и оценке состояния измерений).
Это выглядит примерно так:
[&ModbusSrv.StartupScript]
@Reset
@Port 1 ip tcp port 502 server 16
@PortByteCounters 1 MDBS.BYTECOUNT.RX MDBS.BYTECOUNT.TX
@PortPollCounters 1 MDBS.POLLCOUNT.RX MDBS.POLLCOUNT.TX
@PortErrorCounters 1 MDBS.BUGSCOUNT.RX MDBS.BUGSCOUNT.TX MDBS.BUGSCOUNT.EX
@PortByteRates 1 MDBS.BYTERATE.RX MDBS.BYTERATE.TX
@PortPollRates 1 MDBS.POLLRATE.RX MDBS.POLLRATE.TX
@PortErrorRates 1 MDBS.BUGSRATE.RX MDBS.BUGSRATE.TX MDBS.BUGSRATE.EX
@ZeroPortCounters
и так далее
Счетчики подсчитывают (COUNT) число опросов (POLL) или байтов (BYTE) приемника (RX) или передатчика (TX).
Скорость (RATE) подсчитывается как изменение соответствующих счетчиков за одну секунду.
Обновлен пример DEMO_MDBS, который иллюстрирует
новые возможности сервера &ModbusSrv,
а также использование счетчиков траффика ADAM.
01.01.2013 ... 06.02.2013
MODBUS &ModbusSrv DEMO_MDBS StdLib
Добавлен новый сервер - &ModbusSrv.
Этот сервер умеет работать в качестве подчиненного устройства с протоколами обмена
MODBUS TCP/IP, MODBUS RTU, MODBUS ASCII.
Описание с примерами тут.
Для использования сервера надо включить его в конфигурацию (секция [ConfigFileList]),
задать подключения кривых (секция [&ModbusSrv]) и задать таблицы портов, узлов
и адресов MODBUS (секция [&ModbusSrv.StartupScript]):
---Включаем в конфигурацию:
[ConfigFileList]
ConfigFile = ~~\Resource\DaqSite\ModbusServer\ModbusSrv.cfg
[]
---Задаем подключение кривых:
[&ModbusSrv]
AnalogInputs = 4
Link AnalogInput 0 with curve MDBS.PARAM.P1.1
Link AnalogInput 1 with curve MDBS.PARAM.P1.2
Link AnalogInput 2 with curve MDBS.PARAM.P2.1
Link AnalogInput 3 with curve MDBS.PARAM.P2.2
[]
---Задаем таблицу портов, узлов и адресов MODBUS:
[&ModbusSrv.StartupScript]
@Reset
@Port 1 ip tcp port 502 server 16
@Node 1 1 1
@HoldingRegister 1 40001 float AnalogInput 0
@HoldingRegister 1 40003 float AnalogInput 1
@HoldingRegister 1 40005 float AnalogInput 2
@HoldingRegister 1 40007 float AnalogInput 3
[]
Обновлена библиотека UnixUtils. Это необходимо для будущих разработок.
Обновлена стандартная библиотека StdLib. В библиотеку добавилось несколько полезных функций и возможностей.
В библиотеку добавлен "виртуальный" модуль - заглушка StdAddons,
включающий три файла _con_StdAddons.inc, _var_StdAddons.inc, _fun_StdAddons.inc.
Эти заглушки (в системном каталоге) являются пустыми, но они интегрированы в стандартную библиотеку.
Если пользователю надо добавить в рамках данной конфигурации какие-то общие функции, надо просто
скопировать эти файлы в каталог Daqpas и заполнить своим содержимым. При этом локальные копии
файлов автоматически перекроют системные заглушки, а пользовательские функции будут доступны всем
программам в данном каталоге, использующим стандартную библиотеку по обычному шаблону.
При этом сами программы, использующие новые функции, менять не надо, так как модуль
StdAddons уже интегрирован в библиотеку.
Это самый простой способ корректной инкапсуляции (включения) локального (для данной конфигурации)
пользовательского кода в стандартную библиотеку.
Добавлена функция UnixWBox, работающая через
библиотеку UnixUtils и выдающая окно сообщения с выбором размеров, фонта и времени показа.
Имеет то достоинство, что окно является неблокирующим, и исчезает само, при этом сообщение автоматом
журналируется в консоли. Пример:
UnixWBox("Уведомление","Операция успешно завершена.",600,16,15);
Добавлена функция CustomIniRW, которая призвана закрыть
основные вопросы работы с INI файлами. В сложных системах бывает нужно выполнить настройки некоторых
параметров (то есть группы тегов) и затем сохранить их, чтобы затем автоматически загружать эти настройки,
либо при старте системы, либо по кнопке.
Как это сделать с помощью функции CustomIniRW?
Вот самый простой способ:
Помещаем в секции описания устройства переменные
CustomIniFileRef = ..\Config\Custom.ini ; Ссылка на INI файл для записи
CustomIniSection = [CustomParameters] ; Имя секции где храняться параметры
CustomIniTagList = [CustomParameters.TagList] ; Имя секции со списком сохраняемых тегов
CustomIniBackups = ..\Data\Custom ; Имя каталога для резервных копий INI файлов
Помещаем в секции [CustomParameters.TagList] список тегов, которые надо читать/записывать,
в виде строк типа "TagList = Tag1, Tag2, ..."
В нужном месте (по кнопке) вызываем CustomIniRW('W','',0).
По этому вызову указанный в секции список тегов сохраняется в указанном INI-файле.
При необходимости загрузки тегов из INI-файла (по кнопке или при старте программы)
вызываем CustomIniRW('R','',0).
Кроме этого простого использования с параметрами "по умолчанию", можно решать более сложные задачи,
например, сохранять и считывать настройки в разных INI файлах, в зависимости от каких-то условий.
Для этого надо лишь правильно задать аргументы функции CustomIniRW,
как подробно описано в документации по ссылке. Там же приводится пример.
Добавлен пример DEMO_MCA_SCAN, который фиксирует
последние достижения в:
Создании программ сбора данных в режиме ListMode с использованием общей памяти
и неблокирующих очередей событий.
Создании программ OFFLINE обработки данных в формате LMD.
Создании довольно сложных программ интерактивной обработки данных (LocusEditor) в пакете ROOT.
Создании гетерогенных программных комплексов из нескольких пакетов (CRW-DAQ + ROOT + UnixUtils)
с помощью тесного взаимодействия пакета CRW-DAQ с внешними программами.
Данный пример фактически открывает новую страницу развития проекта CRW-DAQ, так как структурно
(т.е. не по объему, а по числу разнородных компонентов и сложности механизмов их взаимодействия) MSA_SCAN
является сейчас, пожалуй, наиболее сложной системой, созданной в пакете.
Пример может прототипом и "шпаргалкой" при создании других систем сбора и offline обработки.
В настоящее время в качестве DEMO взята просто рабочая версия из EGP.
Хотя она не завершена и содержит неотлаженные фрагменты, в ней столько находок и достижений,
что просто необходимо ее сохранить для облегчения дальнейшей работы.
Пример DEMO_MCA_SCAN также иллюстрирует использование новых функций
(UnixWBox, CustomIniRW),
которые там весьма активно используются.
01.08.2012 ... 14.08.2012
WinDraw LoadSpd SaveSpd
В функции WinDraw добавились команды LoadSpd, SaveSpd.
Они применяются для спектрометрических окон и служат для программной загрузки и сохранения спектров.
В именах файлов можно использовать короткие имена относительно основного конфигурационного файла.
Например:
Эти команды служат для загрузки спектров, полученных внешней программой обработки данных.
Работает это примерно так:
В составе конфигурации имеем спетрометрические окна и сервер &CronSrv.
Имеется также некоторый внешний срипт, который умеет обрабатывать данные и генерировать спектры.
По какой-то кнопке вызывается внешний скрипт (bat, cmd или sh) с программой обработки.
Перед запуском этого скрипта надо не забыть послать в главную консоль команду
@tty listen 0
чтобы открыть канал связи.
Вызов скрипта можно осуществлять, например, консольной командой @run.
Вызванный скрипт с помощью программы обработки каким-то образом генерирует интересующие файлы спектров SPD.
Одной из последних команд скрипта стоит посылка команды в консоль CRW-DAQ через вызов типа:
unix printf "@daq devsend &CronSrv @WinDraw SpectrWindow|LoadSpd=..\Data\Demo.spd" | unix u2d | unix send2crwdaq
где
unix printf "xxx" - команда вывода сообщения xxx. В ней можно использовать форматирование, для справки см. unix -m
unix u2d - комада преобразования текста из формата unix в windows.
unix send2crwdaq - посылает сообщение в главную консоль CRW-DAQ.
Сообщение содержит команду @daq devsend, передающую сообщение устройству &CronSrv.
Передаваемое сообщение @WinDraw SpectrWindow|LoadSpd=..\Data\Demo.spd означает, что в спектрометрическое окно
с именем SpectrWindow надо загрузить SPD файл с именем ..\Data\Demo.spd.
Посланная команда попадает в главную консоль CRW-DAQ, затем передается в консоль &CronSrv
и исполняется, загружая в указанное спектрометрическое окно указанный файл спектра.
Создан пример DEMO_LMD_READER, который будет служить иллюстрацией
и прототипом для программ OFFLINE обработки данных в формате LMD.
Есть описание: demo_lmd_reader.htm.
Данный пример позволяет обрабатывать LMD-файлы данных, содержащих многопараметрические события, строить спектры
и загружать их в спектрометрические окна. Собственно программа обработки (заполнения спектров) пишется как
отдельная программа и запускается из измерительной конфигурации с помощью командного BAT-файла.
Параметры обработки передаются через скриптовый DQS-файл. Программа обработки запускается как отдельный процесс
и работает автономно, по завершении работы шлет сообщение в главную консоль, с помощью которого возвращает данные через
файлы спектров SPD.
Такой способ обработки имеет ряд достоинств - высокая отказоустойчивость, модульность.
Но при этом для освоения придется попыхтеть, так как получается сложная многокомпонентная система.
Созданный пример DEMO_LMD_READER будет прототипом
для программы обработки данных микрозонда, которая должна появиться в ближайшее время.
В инсталляцию Commander добавлен ряд полезных утилит.
В частности, WhoLockMe - утилита, показывающая, какой процесс заблокировал данный файл.
Применяется в случае, когда файл почему-то не удаляется из-за того, что какой-то процесс его заблокировал.
Огромная работа проведена по UnixUtils. Теперь они базируются на библиотеке Cygwin,
которая является, как представляется, наилучшей библиотекой поддержки Unix - среды под Windows.
По-видимому, вопрос на будущее вполне решен.
Основным инструментом для создания скриптов для связки CRW-DAQ + ROOT будет пакет
Cygwin,
который включает в себя и командный интерпретатор BASH, принятый в Linux.
Это достаточно мощный язык программирования, очень хорошо подходящий для задач интеграции разных
независимых программ в единый программный комплекс.
Немаловажно, что Cygwin имеет поддержку фирмы (Cygnus) и большое сообщество пользователей.
GnuWin32 убран из дистрибутива, так как UnixUtils его полностью заменяет.
В состав UnixUtils также вошла библиотека Ploticus,
которая видимо заменит PlotUtils (эта библиотека удалена вместе с GnuWin32).
Библиотека Ploticus очень компактная, ничего лишнего. Она рисует графики в GIF или PS.
Идеально подходит для WEB. Компактность библиотеки обещает высокую скорость рисования.
Возможно, Ploticus заменит и GnuPlot (пока не ясно). Но скорее всего, останутся обе библиотеки.
Решение о замене возможно будет принято после тщательного тестирования.
Небольшой демо пример по Ploticus.
Пример очень условный, на большее не хватило времени - пока есть более срочные задачи.
Для демонстрации связки CRW-DAQ+ROOT на основе команднного языка Unix Shell
сделана утилита _ROOT_HIST_1D.sh,
и модифицирована
_ROOT_HIST_1D.DPR.
Старый вариант (на bat файле) остался как опция (можно выбрать).
Вариант Shell явно выглядит более понятно - скрипт имеет четкую структуру,
используются функции. Хотя Shell имеет свои особенности, он все же является
регулярным языком программирования, который можно выучить, а не набором кабаллистических
надписей, как язык CMD, который понять практически невозможно, потому что исключений
там явно больше, чем правил.
Новые консольные команды @daq и @tty.
@daq compile &name компилировать &name, эквивалентно @compile device &name
@daq devsend &name msg послать сообщение msg устройству &name
@daq devmsg &name msg послать сообщение msg устройству &name
@tty status посмотреть статус TTY (какие порты открыты)
@tty listen 0 открыть порт 0 для ввода данных в главную консоль
@tty listen 54321 открыть PCP/IP порт 54321 для ввода в CRW-консоль
@tty close 54321 закрыть порт 54321
@tty close 0 закрыть порт 0
@tty shield ON включить защиту - команды принимать, но не исполнять
@tty shield OFF отключить защиту - команды принимать и исполнять (по умолчанию)
@tty verbose ON включить отладочный режим, с выводом подробностей
@tty verbose OFF отключить отладочный режим, работать молча (по умолчанию)
@tty panic паника (подозрение на атаку), срочно закрыть все открытые порты
Примечание:
1) TTY порт 0 соответствует очереди сообщений, посылаемых командой unix send2crwdaq.
Эта очередь реализована через посылку сообщения WM_COPYDATA и работает только локально.
Зато ее работа не зависит от настроек Firewall, так как сетевые порты не используются.
Например, следующая команда из командного скрипта корректрно завершает работу CRW-DAQ:
unix send2crwdaq @daq devsend ^&CronSrv @shutdown crw exit
здесь символ шляпки ^ используется для экранирования спец.символа &
или
unix printf "@daq devsend &CronSrv @shutdown crw exit" | unix send2crwdaq
здесь printf используется вместо echo, т.к. с ней легче передавать спец.символы типа &.
unix printf также позволяет передавать перевод строки \n, кавычки \" и форматировать числа,
см. описание (unix -m).
2) TTY порты в диапазоне 1024..65535 включительно соответствуют TCP/IP портам (сокетам).
Это позволяет посылать сообщения как локально (по адресу 127.0.0.1), так и удаленно
(по имени компьютера). Для посылки сообщений в консоль в этом случае используется стандартная
утилита unix nc (сокращение от netcat, т.е. сетевой вариант cat).
Например, следующая команда из командного скрипта корректрно завершает работу CRW-DAQ:
unix printf "echo @daq devsend &CronSrv @shutdown crw exit" | unix nc 127.0.0.1 54321
здесь printf используется вместо echo, т.к. с ней легче передавать спец.символы типа &.
unix printf также позволяет передавать перевод строки \n и форматировать числа, см. описание.
3) Использование портов 1..1024 запрещено, т.к. по стандарту этот диапазон зарезервирован для
работы зарегистрированных (well-known) программ.
Рекомендуемое значение порта для связи пусть будет 54321 (легко запомнить).
Перечисленные команды нужны для создания "обратной связи" между CRW-DAQ и скриптами,
которые запускаются из него.
Под TTY (стандартное сокращение от teletype) понимается консольный канал для внешней связи,
по которому другие программы могут посылать команды в главную консоль CRW-DAQ.
Главная консоль в свою очередь может послать сообщение DAQ-устройству (@daq devsend).
Из соображений безопасности по умолчанию этот канал закрыт.
При этом канал TTY 0 соответствует очереди сообщений WM_COPYDATA,
передаваемых с помощью unix send2crwdaq (только локально),
а канал TTY n с номером n=1024..65535 соответсвует портам TCP/IP (сокетам),
передаваемых с помощью unix nc (сетевой вариант).
Нулевой порт, хотя работает только локально, не зависит от сетевого фильтра (Firewall),
поэтому его использование со скриптами (которые запускаются локально) надежнее.
При локальном использовании сокетов рекомендуется использовать адрес 127.0.0.1, который
соответствует локальной системе и обычно не контролируется файерволом.
При использовании удаленного доступа придется настроить firewall.
Предполагается, что прикладная программа в начале работы (перед запуском скрипта обработки данных)
открывает порт TTY посылкой в консоль команды @TTY LISTEN 0 (здесь для примера взят нулевой порт),
после чего консоль TTY переходит в состояние прослушивания (LISTEN) входных сообщений.
Затем прикладная программа запускает скрипт обработки данных (.sh или .bat), в котором
происходит подготовка данных, вызов ROOT, ожидание завершения и в конце - посылка уведомляющего
сообщения в консоль CRW-DAQ, получив которое прикладная программа забирает результат обработки.
По завершении работы порт закрывается консольной командой @TTY CLOSE 0.
При этом открытие-закрытие порта работает со счетчиком - открытие\закрытие порта
инкрементирует\декрементирует счетчик. Это значит, что несколько программ могут открывать и
закрывать порт, не мешая друг другу. Реально же порт закроется, когда счетчик станет равным нулю.
Здесь вместо порта 0 можно использовать любой другой допустимый номер.
Предлагается использовать порт 54321 для сетевого варианта (этот номер легко запомнить).
Локальные сообщения (TTY 0) передаются с помощью консольной команды unix send2crwdaq.
Текст сообщения можно передавать или в командной строке, или через StdIn с помощью канала.
unix send2crwdaq mmm послать сообщение mmm в главную консоль CRW-DAQ (из аргументов)
echo mmm | unix send2crwdaq послать сообщение mmm в главную консоль CRW-DAQ (из канала StdIn)
type fff | unix send2crwdaq послать сообщение mmm в главную консоль CRW-DAQ (из файла fff)
Для посылки сообщения программа использует идентификатор процесса CRW-DAQ, который либо
записан в переменной %CRW_DAQ_SYS_PID% (по умолчанию), либо передается в аргументах
при вызове (-p pid). Это удобно, потому что дочерние процессы (скрипты), запускаемые из
CRW-DAQ, автоматически наследуют переменную %CRW_DAQ_SYS_PID% от родительского
процесса. При этом, хотя может быть запущено несколько копий CRW-DAQ, они интерферировать
не будут, потому что у каждого свой PID.
При передаче сообщений возникает проблема спец.символов (<, >, &, | и т.д.), которые
используются в командном интерпретаторе CMD и должны экранироваться с помощью шляпки ^.
Правила экранирования сложны и запутанны. Поэтому вместо этого можно использовать более простой
и понятный способ записи с использованием unix printf:
послать сообщение в главную консоль CRW-DAQ (через канал StdIn):
unix printf "@daq devsend &CronSrv @Speak Привет\n@echo Привет" | unix send2crwdaq
либо
unix -n echo -e "..." | unix send2crwdaq
Здесь не потребовалось экранировать спец.символ &, а кроме того, в сообщении можно передавать
несколько строк с разделителем \n. Правда, в этом случае, если в строке сообщения присутствуют
двойные кавычки (") или знак процента (%), их придется экранировать с помощью обратного слэша
(\", \%).
Однако все равно возможности printf больше, а правила использования проще, чем в CMD,
поэтому есть смысл использовать printf всегда.
Команда unix -n echo -e "..." также является удобной командой вывода, она отличается от printf
тем, что не форматирует числа, как делает printf. Такая сложная форма записи связана с тем, что в
Windows тоже есть своя команда echo. Запись unix -n echo -e "..." означает
что будет вызывана unix-команда echo.exe вместо windows-команды echo,
а опция -e разрешает использовать экранирование для передачи спец.символов (\n и т.д.)
Сетевые сообщения (TTY port, port=1024...65535) передаются с помощью консольной команды
unix nc addr port, где addr - адрес удаленного компьютера или 127.0.0.1 для локальной
системы (альтернатива TTY 0).
Например:
послать сообщение в главную консоль CRW-DAQ через TCP/IP порт 54321:
unix printf "@daq devsent &CronSrv @Speak Привет\n@echo Привет" | unix nc 127.0.0.1 54321
Разумеется, порт должен быть перед этим открыт командой @tty listen 54321.
Введение данных команд (@daq,@tty) и утилиты send2crw-daq замыкает
цикл анализа данных в связке CRW-DAQ + ROOT. Это будет работать так:
CRW-DAQ подготавливает данные для обработки, открывает порт TTY
и запускает скрипт для обработки (bat или sh).
После чего продолжает обычную работу.
Скрипт организует процесс обработки: запускает программу обработки (ROOT, например),
дожидается получения результата, копирует или удаляет файлы, открывает файлы для просмотра и т.д.
После выполнения программы обработки скрипт посылает уведомляющее сообщение в главную консоль
вызовом unix send2crwdaq или unix nc.
Чтобы передать сообщение конкретному устройству, надо через это сообщение послать команду
@daq devsend требуемому устройству.
Получив сообщение, CRW-DAQ предпринимает нужные действия, например, загружает обработанные
данные из файлов, отображает данные и т.д.
По завершении обработки программа закрывает порт TTY, из соображений безопасности.
Данный способ взаимодействия позволяет строить весьма сложные системы обработки данных, в то же время
не загружая пакет CRW-DAQ лишней работой - не надо делать циклов ожидания результатов,
следить за работой пакета анализа данных и т.д. Все это берет не себя скрипт.
Программе обработки (ROOT) и DAQ-программе остается лишь взять готовые результаты,
получив сообщение от скрипта обработки.
Программа DPR при вызове скрипта открывает порт @tty listen 0.
Скрипт по завершении работы посылает команду @open file.log и @tty close 0.
Получив сообщение, CRW-DAQ открывает окно редактора для отображения журнального
файла (file.log) и закрывает порт TTY, возвращая систему в безопасное состояние.
В принципе, этот пример является готовым прототипом для последующих утилит обработки данных.
Дальнейшее развитие обработки данных (в частности, ЭГП) будет строиться по принципам,
связки CRW-DAQ + ROOT , которые проиллюстрированы этим примером.
Поэтому стоит изучить его подробно.
При этом, если потребуется справка по unix-командам и языку программирования Shell,
можно использовать следующие команды.
В консоли Windows:
unix -m - вызов справочного центра unix, там всё
unix -l - список всех доступных unix-программ
В консоли CRW-DAQ
@run unix -m
Там же есть учебник Bash на русском.
При работе с unix - утилитами под windows есть ряд особенностей, которые надо учитывать.
В основном это касается способов именования файлов, а также формата разделителей строк.
Преобразование имен файлов:
$(cyqpath -w filename) - имена в стиле чистого windows, например:
c:\windows\system32\cmd.exe
$(cyqpath -u filename) - имена в стиле чистого unix, например:
/cygdrive/c/windows/system32/cmd.exe
$(cyqpath -m filename) - имена в промежуточном стиле unix+windows, например:
c:/windows/system32/cmd.exe
Видимо, в будущем в основном будет использоваться промежуточная форма записи файлов, потому что
она работает в обоих системах (особенно если имена файлов помещать в кавычки).
Однако надо знать, что имя одного и того же файла под windows и unix
выглядит немного по-разному и не пугаться этого - ничего страшного тут нет.
Под "чистым" windows, например, изначально существуют альтернативные "короткие имена"
типа "PROGRA~1" вместо "Program Files" - и никого это не пугает.
Так и тут, дело привычки, не более того.
При возникновении проблем имена легко конвертируются из одной формы в другую,
так что я не вижу тут особого затруднения.
Преобразование разделителей:
Тексты в unix имеют разделитель LF вместо CR,LF, поэтому в некоторых случаях
нужно конвертировать форматы.
Для этого есть утилиты u2d и d2u (или unix2dos и dos2unix).
Зачастую конверсия происходит "на лету" (в конвейере) и не вызывает проблем.
Примеры:
cat file.txt | u2d | send2crwdaq послать файл в консоль CRW-DAQ, преобразовать LF->CRLF на лету
notepad "$(cygpath -w $filename)" передать windows-программе имя файла в форме windows
cat "$(cygpath -u $filename)" передать unix-программе имя файла в форме unix
Резюме: первая версия интеграции ROOT+CRW-DAQ состоялась.
На этой базе будет идти развитие ЭГП.
По просьбам трудящихся.
В секцию [DAQ] введена переменная CalibDialogMode.
Эта переменная разрешает оператору различные функции редактирования калибровок.
По умолчанию CalibDialogMode=0, что соответствует максимальной безопасности (опасные и технологические установки).
Значение CalibDialogMode=31 соответствует максимальной функциональности (лабораторные и исследовательские установки).
В добавление к этому, в диалоге выбора калибровки будет показываться подробная информация о калибровке,
а то работать по одним номерам калибровок как-то неудобно.
В связи с 1) планами активного внедрения ROOT и 2) проблемами поиска софта, работающего как под
Win32, так и под Win64 (т.е. WinXPx32 и Win7x64), сделано мощное обновление
дистрибутива TotCommanderExtra.
Поскольку сейчас CD уже почти не осталось и у всех есть DVD - приводы, было решено отказаться от
лимита на дистрибутив 200 MB (это размер маленького CD). Теперь лимитом для дистрибутива считается
1.4 GB (это размер маленького DVD). Это довольно большой объем, в который было решено собрать
программное обеспечение, необходимое для DAQ - разработки. В него, разумеется, не включается сама система
Windows, антивирусы (они слишком часто меняются) и офис (у всех свои предпочтения на этот счет).
В пакет включены программы, работающие (за немногими исключениями) под Win32 и Win64.
Большинство из этих программ - результат поиска в Сети, сравнения с аналогами и трудного выбора.
Если антивирусы и офисы в сетке есть везде, то значительную часть программ, включенных в пакет,
было не так-то просто отыскать даже в Internet, а в локальной сети их уж точно нет.
Все добавленные утилиты - свободно распространяемые, никаких "патчей" и "кряков".
Поскольку многие из этих программ планируется использовать либо в качестве штатных инструментов при разработке,
либо как компоненты при работе прикладных программ, то этот пакет следует считать штатной частью DAQ системы.
Все пакеты ставятся молча в папки "по умолчанию", чтобы было заранее известно, где их искать.
Это важно для написания командных скриптов. Инсталлятор пропускает установку пакетов, если они уже
установлены, поэтому при необходимости можно спокойно ставить при установке любые "галочки" - лишней работы
инсталлятор делать не будет.
Я постарался найти и включить в пакет одну (по возможности наилучшую) программу для решения задач каждого класса.
Обновлены (до наисвежайшей доступной версии) следующие программы:
7-zip 9.20 - наш любимый архиватор.
GhostScript 9.05 - утилиты для работы с PS и PDF.
GsView 5.0 - утилита просмотра файлов PS, PDF.
SumatraPDF 2.0.1 - быстрый просмотрщик PDF.
Firefox 11.0 - наш основной Web Browser.
KLCodec 8.6.0 - все для видео.
WinAmp 5.623 - все для звука.
WinDjVu 1.0.3 - просмотр DJVU.
VirtualCD - маленький и надежный виртуальный CD + DVD.
VD_Driver - позволяет подключать виртуальные образы дисков (HDD.img,FDD,ISO).
Как можно заметить, большое значение уделяется работе с документами PDF, PS, DJVU.
Это связано с тем, что документация в основном доступна в PDF, формат PS является одним из
основных форматов вывода графиков в ROOT, ну а DJVU лидирует по компактности файлов.
Оффис с этими форматами не работает, а Adobe уж больно тормозит.
Добавлены следующие программы:
GnuWin32 - библиотека подмножества POSIX (т.е. Unix-подобных) команд.
Предположительно эта библиотека будет использоваться для написания скриптов и командных файлов
в составе измерительных систем. Все команды - консольные. Многие задачи решаются совместным
использованием нескольких команд, как это принято в мире Unix.
В состав GnuWin32, в частности, входит пакет команд PlotUtils, которые позволяют
строить из командной строки графики в PNG или GIF файлы.
Возможно, этот пакет будет использоваться для Web-серверов - время покажет.
В c:\Program Files\GnuWin32 лежит скрипт PlotDemo.cmd для примера построения графиков.
Однако тут надо заметить, что из-за довольно большого объема будущее пакета GnuWin32
(в смысле его включения в дистрибутив) пока не вполне ясно.
Его включение в текущий дистрибутив носит (пока) экспериментальный характер.
UnxUtils - еще одна реализация подмножества из около сотни команд UNIX.
Она включена в дистрибутив потому что она довольно компактная (около 2 MB в сжатом виде) и в то же время
довольно - таки полная и содержит наиболее часто употребляемые команды.
Эта библиотека, которая очевидным образом конкурирует с GnuWin32, в настоящее время, наверное,
является основным претендентом на использование в качестве UNIX - подсистемы - время покажет.
В основном этот пакет планируется использовать в командных файлах, которые будут работать в рамках
измерительных систем. Консольные утилиты (не из набора команд UNIX) уже самым активным образом
у нас используются, поэтому идея включить в пакет еще и подмножество UNIX-команд была у меня давно.
Со временем одна из библиотек (GnuWin32 или UnxUtils) может быть отброшена.
Но скорее всего пакет UnxUtils в любом случае останется, из-за малого размера.
CCleaner 3.17 - утилита чистки диска и реестра.
Имеет опцию полной чистки диска (для удаления следов конфиденциальных документов).
Интегрирована в дополнительную панель инструментов Commander.
USB Oblivion 1.8.0.0 - удаление следов флешек.
Интегрирована в дополнительную панель инструментов Commander.
Delphi 5 - урезанная до необходимого минимума среда разработки Object Pascal.
Предполагается, что вся дальнейшая поддержка CRW-DAQ будет идти через этот минимальный пакет.
Наличие компилятора означает, что среду разработки пакета можно развернуть с дистрибутива CRW-DAQ,
полностью с нуля, имея под рукой только "голый" Windows. Это важно, поскольку в командировках
под рукой часто ничего нет. Ярлык Delphi добавлен в дополнительную панель инструментов.
Bat To Exe - небольшая утилита, которая позволяет преобразовывать BAT файлы в EXE.
Ну, ничего особенно сложного утилита не делает: она упаковывает (сжимает) BAT файл и другие
файлы ресурсов, указанные при сборке, затем создает исполняемый файл, который при запуске распаковывает
командный файл и файлы ресурсов во временный каталог и запускает командный файл с помощью CMD.EXE.
Предполагается, что командный файл выполняет какую-то полезную работу, при этом он может использовать
необходимые ему для работы файлы ресурсов. В сущности, Bat To Exe дает еще один инструмент
для создания инсталляторов или простых приложений, которые позволяют делать что-то при помощи командных
файлов и набора консольных утилит, которые прилагаются к нему. Сборка в один EXE с автоматической
распаковкой дает удобный способ хранения и переноса командных файлов и ресурсов, по принципу
"все в одном месте" с простым запуском. В общем, полезная штука.
Ярлык Tat To Exe добавлен в дополнительную панель инструментов.
ROOT 5.32 - мощнейший пакет, разработанный в CERN для анализа данных и научной графики,
а также минимальная документация к нему, чтобы быстро войти в курс дела.
Полная документация весит под гигабайт, поэтому она не включена.
Но она обычно и не нужна - помогают готовые примеры программ (см. c:\root\tutorials).
Пакет ставится в каталог c:\root и может быть вызван из консоли CRW командой @run root.
Этот пакет предполагается использовать в будущем как основной инструмент для анализа данных, поэтому будет
активно развиваться интеграция CRW-DAQ с ROOT. Предполагается, что ROOT будет
использоваться в пакетном режиме - в CRW-DAQ с помощью Daq Pascal готовится задание,
а потом командой @run root передается для исполнения в ROOT.
Вот тут-то и пригодятся POSIX команды, они смогут облегчить создание командных скриптов.
ROOT - это настолько мощный пакет, что о нем надо говорить отдельно. Для нас сейчас важно то, что
отныне он будет частью дистрибутива и на его наличие в системе можно будет надежно рассчитывать.
Ярлык ROOT добавлен в основную панель инструментов.
Dependency Walker - программа, которая умеет показывать дерево зависимостей EXE файлов
от библиотек DLL. Это довольно актуально - частенько программы не запускаются из-за отсутствия
нужных библиотек, найти зависимости бывало трудно. Теперь это будет легко.
Ярлык Dependency Walker добавлен в дополнительную панель инструментов.
Duplicate File Eraser - программа, которая умеет находить и удалять дубликаты файлов.
Полезно для поиска одинаковых файлов.
Ярлык Duplicate File Eraser добавлен в дополнительную панель инструментов.
ShareWatch - программа, которая умеет показывать, какие файлы открыты по сети.
Ярлык ShareWatch добавлен в дополнительную панель инструментов.
DoPdf, Pdf24, BullZipPDF - три PDF принтера, позволяющих создавать
документы PDF из любого другого документа, путем его "печати" в PDF файл.
Были попробованы и отбракованы многие известные по статьям в Сети принтеры.
Например, известный PrimoPdf был сразу отбракован (даже без тестирования) потому что он зависит
от библиотеки .NET 2.0, размером под 300 MB. А кто гарантирует, что она установлена?
Потом был отбракован CuteWriter - печатать он вообще отказался (каких-то библиотек не хватало),
зато установил "левые" плагины для FireFox, которых мне никак не надо.
Использовавшийся мной ранее PDFCreator был тоже отбракован, так как он не работает под Win64.
И так далее.
Почему я в результате включил три принтера? Я не смог выбрать лучший. Со всеми были проблемы.
doPDF надежно работает под обеими системами, но имеет один важный недостаток - он создает файлы
в 1.5-2 раза большего размера, чем другие принтеры. Иногда это существенно.
BullZipPDF - очень неплохой принтер, с большими возможностями, по документации должен
работать под Win64, но при установке ругается, что не может установить драйвер принтера.
Наконец, Pdf24 - принтер, который мне понравился больше всех протестированных.
Он создает самые маленькие по размеру файлы, очень много умеет (например, сохранять PDF в JPG
и редактировать PDF - удалять страницы, соединять документы и т.д.) и работает под обеими платформами
(Win32 и Win64).
Но вот беда - под Win64 вообще все хорошо, а вот в Win32 он почему-то виснет при попытке вызова
редактора PDF. Если редактор не вызывать, все работает нормально. Возможно, эта проблема в конкретной
конфигурации моего компьютера, но все-таки проблема есть.
Так и осталось три принтера. Я надеюсь, что в будущем останется один принтер. А пока будем тестировать.
RAMDisk - виртуальный диск в памяти. Свободная версия имеет ограничение - диск не более 4 GB.
Интересно, что под Win32 программа умеет использовать всю память (за пределами 3 GB),
что позволяет полностью использовать всю память на машинах под Win32 - при этом 3 GB
можно использовать под оперативку, а остальные гигабайты - как диски. Но это все экзотика.
А реально RAMDisk планируется использовать для ускорения работы программ.
Так, если таблицы данных GnuPlot передавать через RAMDisk, скорость работы может сильно
увеличится (так как работы с жестким диском фактически не происходит - все делается в быстрой памяти).
RAMDisk может ускорить работу, если в системе есть запас памяти (если установлено более 1 GB).
На основе оригинальной версии (UnxUtils) собран новый пакет
UnixUtils, включающий в себя уже более
200 консольных команд.
Эти команды в основном касаются обработки файлов, тестов, работы с каналами связи и сетью. Это мощнейший инструмент,
который позволит очень многие задачи решать с помощью скриптов (командных файлов).
Достоинство такого подхода состоит в том, что множество задач может быть вынесено за рамки основного (измерительного)
процесса и выполняться в виде отдельных фоновых задач.
В HELP включен быстрый доступ к справке по этим командам (в списке TOP-20).
Название пакета связано с тем, что в нем много Unix-подобных команд (более 120), хотя также много и совсем
не-Unix команд (более 90), которые, однако, тоже выполнены в стиле Unix.
Исключение составляют несколько программ с графическим GUI для просмотра и редактирования текстов и изображений.
Скриптовое программирование (файлы BAT, CMD, а теперь еще доступны и SHELL скрипты)
у нас уже решает много задач, и будет развиваться дальше. Примеры - 1)Генерация конфигураций RDMS,
2) утилиты обслуживания дисков в составе &CronSrv, 3)Препроцессоры, 4)Связующая операционная среда
для связки разных пакетов обработки (пример см. далее).
Но чтобы скриптовое программирование было надежным и не зависело от настроек конкретной машины, надо иметь
тщательно подобранную библиотеку команд, на которые можно надежно ссылаться в скриптах. Иначе может возникнуть
ситуация, когда в системе вдруг не находится нужной команды и жизненно важный скрипт не работает.
А на практике, например, в моем в дистрибутиве Win7x64 отсутствует команда msg.exe (непонятно почему).
В результате выдача сообщений через @run msg ... там не работает. Другой пример - было замечено, что
при установке PVSS перестала работать команда завершения и перезагрузки компьютера. Оказалось, что при
инсталляции PVSS подменяет системный shutdown.exe своей версией, имеющей совсем другие параметры
командной строки. Таким образом, для надежности использования скриптов надо иметь свой, проверенный инструментарий,
а не полагаться на то, что на произвольно взятой машине этот инструментарий будет доступен. Тем более что не на всех
компьютерах, где стоит CRW-DAQ, мы являемся администраторами, часто работа идет на чем попало.
Вот пакет UnixUtils и претендует на то, чтобы стать таким надежным инструментарием.
При объеме около 10 МБ он содержит более 200 консольных команд, с которыми командные файлы,
да еще в сочетании с консолью CRW-DAQ превращаются в мощный инструмент.
Пакет UnixUtils теперь входит в инсталляторы CRW-DAQ и Commander, то есть их наличие
гарантировано дистрибутивом. При этом пакет разработан так, что весь доступ к его функциям осуществляется
через одну-единственную ключевую команду (написанную мной) со скромным названием -
unix.
Но что еще важнее, этот набор команд работает надежно и безопасно независимо от настройки окружения
конкретой машины.
Команда unix cmdline подготавливает правильную "среду окружения" и затем вызывает переданную
ей в аргументе команду cmdline. То есть команда гарантированно стартует с предустановленной
средой окружения, так чтобы ее работа была предсказуемой.
Все подробности того, как это работает, описаны в приведенных выше ссылках.
А здесь я просто приведу пример использования:
1)Копирование файлов с выводом на экран и одновременной записью в журнальный файл:
copy /Y Source\*.dat Target\ | unix tee debug.log
2)Замена строк $tagX$, $crvX$ в файле на demoX,curvX (препроцессор)
type сonfig.gen | unix gsar -F -s$tagX$ -rdemoX | unix gsar -F -s$crvX$ -rcurvX > config.cfg
вместо unix gsar -F -sAAA -rBBB можно использовать более понятную команду unix replacestr AAA BBB
однако префикс unix и в этом случае надо оставлять - он гарантирует, что команда будут найдена
(а вдруг ее нет в пути поиска)?
3)Проигрывание звукового или видео файла (без вызова WMPlayer):
unix gplay file.wav file.mp3 file.avi
4)Окно сообщения с таймером (здесь 15 sec) - замена ненадежного msg.exe.
unix wprompt "Caption" "Message" Ok 1:15
Это окно хорошо тем, что оно не блокирует управление CRW, в отличие от своих модальных окон.
Продолжать можно долго. Я и сам еще до конца не попробовал все команды, но уже хорошо понимаю,
насколько мощный инструмент мы приобрели (с минимальными усилиями).
Смотрите список команд.
Предполагается, что в будущем измерительные системы будут активно использовать командные файлы и команды
UnixUtils, формируя вызовы нужных команд через посылку команды @run command....
Так могут решаться задачи обслуживания дисков и сети, ведение журнальных файлов, формирования отчетов и т.д.
Поскольку &CronSrv может выдавать такие сообщения по расписанию, можно организовывать
самообслуживание систем с вызовом дефрагментации дисков, резервного копирования данных, очистки дисков от
устаревших файлов, рассылкой мейлов в случае аварийных ситуаций (подобно тому как сделано в PHOS) и т.д.
Кроме того, команды из набора UnixUtils будут использоваться для "связки" совместно работающих программ,
CRW-DAQ + ROOT + ...
Как уже было сказано, использование той или иной конкретной реализации подсистемы unix (GnuWin32
или UnxUtils) все еще остается под вопросом, однако вас это не должно беспокоить - команда unix
при любом выборе реализации будет подготавлявать правильную среду окружения и скроет от прикладного программиста
ненужные ему подробности.
Продолжены работы по обеспечению режима отказоустойчивости. На этот раз борьба идет против "подвисания" из-за
замкнутых циклов или слишком долгого ожидания чего-то. Предприняты следующие меры:
В DAQ-систему введен программный сторожевой таймер (Watcgdog). В отличие от общего сторожевого
таймера, который работает в основном (низкоприоритетном) потоке и только лаять умеет, новый сторожевой таймер
работает в отдельном высокоприоритетном потоке и умеет не только лаять, но и перезапускать подвисшие программы
DaqPascal. Он описывается в секции [DAQ]
и по умолчанию равен WatchdogPolling = 1000, tpTimeCritical.
В секции описания программ Daq Pascal появилась переменная
WatchdogDeadline,
которая задает максимальное время ожидания срабатывания сторожевого таймера (в миллисекундах).
Его можно задать также в секции [DAQ].
По умолчанию это время равно 60000 (одна минута).
Задание нулевого значения запрещает работу сторожа.
Если за время WatchdogDeadline устройство не подает признаков жизни, то есть не завершает очередной
цикл работы и не сбрасывает таймер вызовом wdt_reset, то системный сторожевой таймер генерирует
ошибку и принудительно прерывает работу подвисшей программы с ошибкой Watchdog Deadline.
Были сделаны изменение в стандартной библиотеке
и шаблоне template.pas
канонической прикладной программы, чтобы при возникновении ошибки Watchdog Deadline цикл работы
программы останавливался (во избежание новых подвисаний) и выполнялось "завещание".
Подробности см. в
FatalHangsBugs,
PostMortalWill.
Если прикладная программа выполнена по шаблону, а в завещании указана перекомпиляция,
то программа будет автоматически перезапущена "с нуля", чтобы попытаться продолжить нормальную работу.
Сделана загрузка начального значения PostMortalWill из
конфигурационного файла, при этом, если пользователем явно ничего не задано, в качестве завещания
принимается компиляция (перезапуск) устройства и выдача окна сообщения на 60 секунд с автоматическим
исчезновением с экрана:
Правила начальной загрузки PostMortalWill описаны.
Обращаю также внимание, что для вывода сообщения используется unix wprompt - потому что, как оказалось на практике,
надеяться на msg.exe не приходится - ее может не быть в системе.
А для проигрывания привлекающего внимание звукового файла используется unix gplay.
Это первое практическое применение команд подсистемы unix, показывающее их важность и актуальность.
Для улучшения конфигурируемости параметры обработки критических ошибок
PostMortalWill,
FatalMaxAvail,
FatalVitalBugs,
FatalHangsBugs
можно задавать как индивидуально (в секции устройства), так и всем сразу (в секции [DAQ]),
или будет принято значение по умолчанию из Crw32.ini. Это сделано на уровне стандартной библиотеки.
Предыдущие пункты означают, что теперь режим отказоустойчивости принят по умолчанию для всех программ на основе
шаблона и стандартной библиотеки. Это еще один аргумент в пользу её активного внедрения.
Для тестирования режима отказоустойчивости прикладной программы в "тестовый стенд"
DEMO_TESTBENCH добавлены тесты @Test -3, @Test -4,
которые активизируют симулятор подвисания в виде бесконечного цикла
while True do bNul(Sleep(1)); // Test -3 - низкая нагрузка
while True do bNul(False); // Test -4 - высокая нагрузка
При этом сначала "вылезает" собака, потом (через минуту) происходит рестарт зависшей программы.
Это прямое доказательство того, что режим отказоустойчивости работает как надо.
В функции ParamStr добавлена переменная SysIniFile, которая возвращает имя основного
CRW32.INI файла - ParamStr('SysIniFile').
В мониторе ресурсов, в списке потоков, в последнем столбце (Pr) теперь отображается абсолютный приоритет потока.
Для демонстрации связки CRW-DAQ+ROOT сделана утилита (сама по себе полезная), которая строит распределение
величины (задаваемой по формуле, по умолчанию y).
Она расположена в Resource\DataAnalysisPlugins и включает три файла:
_ROOT_HIST_1D.DPR,
_ROOT_HIST_1D.bat,
_ROOT_HIST_1D.C.
Первый файл (DPR) содержит динамически загружаемую программу DLL, которая берет данные из кривой
в окне CRW и помещает в промежуточный dat файл, вместе с параметрами, типа заголовка окна,
названия гистограммы и т.д.
Подготовив dat файл данных, DLL вызывает командный файл bat, которому передается имя
файла данных. Задачей командного файла является подготовка параметров и вызов файла ROOT-программы
на языке C. Командный файл выполняет важную роль "связующего звена", подготавливая данные, необходимые
для вызова ROOT и наблюдения результатов обработки.
Программа ROOT, которая вызывается из командного файла, берет данные из подготовленного dat-файла,
строит гистограмму распределения и выводит ее в GIF файл.
Этот файл открывается командным файлом, который ожидает завершения исполнения программы ROOT.
Для тестов удобно брать файл GAUSSNOISE.CRW, в котором содержатся
данные с гауссовским шумом. Загрузите кривую оттуда и попробуйте вызвать утилиту _ROOT_HIST_1D.DPR.
Должен получиться симпатичный график с гамма-фитом.
Обращаю внимание, что в командном файле очень активно используются утилиты unix.
Без них решать поставленную задачу организации совместной работы CRW-DAQ+ROOT было бы затруднительно.
Это еще один аргумент в пользу пакета UnixUtils.
Предполагается, что приведенный пример - "первая ласточка", и в будущем связка пакетов CRW-DAQ+ROOT
будет возрастать, а число утилит подобного рода будет увеличиваться.
Надо понимать, что пакеты CRW-DAQ и ROOT никак не конкурируют, но дополняют друг друга.
CRW-DAQ используется для сбора данных и управления в реальном времени, а ROOT - для обработки и анализа.
Предполагается, что система сбора и анализа данных ЭГП будет построена на этой связке пакетов.
В свою очередь, пакет UnixUtils будет играть роль связующего "клея", создавая операционную среду, которая
помогает склеивать эти независимые пакеты в одну задачу.
При запуске и завершении Crw32.exe теперь будут исполняться стартовый скрипт (LogonScript) и завершающий
скрипт (LogoutScript). Эти скрипты описываются в Crw32.ini:
Crw32.ini:
[System]
LogonScript = Resource\Tools\Bat\crw-daq-logon.bat ; Script to be called on CRW-DAQ logon.
LogoutScript = Resource\Tools\Bat\crw-daq-logout.bat ; Script to be called on CRW-DAQ logout.
LogonTimeout = 0 ; Timeout to wait LogonScript execution.
LogoutTimeout = 0 ; Timeout to wait LogoutScript execution.
[]
Там также приводится время ожидания завершения скрипта (по умолчанию нет). Если время не указано, запущенный скрипт
просто исполняется параллельно с пакетом в скрытом окне.
Цель введения скриптов - подготовка сеанса работы (настройка файлового окружения) и его завершение (очистка файлов).
В настоящее время скрипты делают следующее.
LogonScript заводит журнальный файл Crw32exe\Temp\crw-daq-logon.log и делает пометку о входе.
Затем проверяет наличие пакета UnixUtils. Если этот пакет не установлен, запускается его установка.
Затем очищается каталог Crw32exe\Temp в соответствии с принятой квотой (512 MB).
Это чтобы журнальные файлы не слишком разрастались.
В конце в журнальном файле делается пометка о выходе.
LogoutScript заводит журнальный файл Crw32exe\Temp\crw-daq-logout.log и делает пометку о входе.
Затем очищается каталог Crw32exe\Temp в соответствии с принятой квотой (512 MB).
Это чтобы журнальные файлы не слишком разрастались.
В конце в журнальном файле делается пометка о выходе.
Таким образом, в данный момент стартовый скрипт гарантирует установку UnixUtils - это важно, чтобы правильно работали
скрипты, запускаемые из среды пакета. Он также следит за диском и очищает временный каталог.
Со временем число функций стартового и завершающего скрипта может возрасти (время покажет).
Стартовые скрипты могут использоваться в конкретных случаях для выполнения различных операций типа подключения сетевых
дисков, резервного копированния данных и т.д.
В консольную команду @Compile добавлена функция (пере)компиляции программы DaqPascal.
Например:
@compile device &WebSrv - (пере)компиляция устройства &WebSrv
Перекомпиляция программ означает их полный рестарт, при этом все происходит так же,
как если бы перекомпиляция шла из окна редактора.
Это очень важная возможность полного перезапуска данной программы без остановки всей системы.
Если какой-то сервер "подвис", его можно перекомпилировать. При этом произойдет его остановка,
освобождение всех ресурсов, компмляция, и новый старт, со значением RunCount=1.
Все теги, разумеется, сохраняют значения, в то время как локальные переменные программы
создаются заново. Новая возможность призвана служить средством постоения отказоустойчивых программ,
которые сами восстанавливаются после серьезных сбоев.
В рамках стандартной библиотеки и шаблона прикладной программы реализованы средства повышения
отказоустойчивости при критических сбоях в программах Daq Pascal. Работает это
примерно так:
procedure InitApplication;
begin
FatalMaxAvail:=128; // Задаем минимальный размер таблицы строк. Это значение по умолчанию.
FatalVitalBugs:=128; // Задаем предельное число критических сбоев. Это значение по умолчанию.
// Задаем "завещание" - команды и сообщения в случае принудительной остановки программы.
PostMortalWill:='@system @async @run /hide msg * "I am dead."'+CRLF
+'@system @async @compile device '+DevName+CRLF
+'&CronSrv @Warning I am dead.';
end;
procedure PollApplication;
begin
writeln(1 div 0); // Фатальная ошибка - целочисленное деление на ноль!
end;
В приведенном примере в процедуре опроса Poll есть фатальная ошибка - целочисленное деление на ноль.
После 128 попыток выполнить программу будет зафиксировано предельное число критических ошибок
времени исполнения (vital bugs - дословно жизненно важные сбои). При этом программа будет остановлена,
веведена диагностика, а также будет исполнено её "завещание" - в данном случае будет выполнена команда
Eval('@system @async @run /hide msg * "I am dead."') - запуск команды msg для вывода сообщения
Eval('@system @async @compile device '+DevName) - перезапуск программы путем перекомпиляции
DevMsg('&CronSrv @Warning I am dead.') - посылка сообщения серверу &CronSrv
В зависимости от задачи в "завещании" можно указать, например, перезапуск программы или всей системы,
включение блокировок или отключение аппаратуры и т.д.
Подробности см. в
FatalMaxAvail,
FatalVitalBugs,
PostMortalWill.
Таким образом, программа с критическими ошибками не будет бесконечно долго генерировать ошибки,
как было до сих пор. Теперь по достижении предельного числа критических ошибок цикл опроса
прекращается, программа фактически останавливается (цикл опроса Polling не идет),
с выводом диагностики и исполнением некоторого набора заранее заданных команд.
Все это позволяет создавать отказоустойчивые системы, которые сами себя перезапускают при возникновении
серьезных ошибок.
Возможен как "жесткий" перезапуск всей DAQ системы, так и "мягкий" перезапуск данной программы.
Жесткий перезапуск можно сделать, например, посылкой команды @Shutdown Daq Restart серверу &CronSrv.
Мягкий перезапуск делается с помощью '@system @async @compile device '+DevName.
Разумеется, принудительная остановка прикладной программы или перезапуск не решает всех проблем.
Если ошибок очень много, программа будет постоянно падать и перезапускаться и толку от нее не будет.
Но в случае достаточно редких ошибок автоматическое отключение сбойных программ и их перезапуск
может решить проблему обеспечения отказоустойчивости, особенно в длительно работающих системах.
Так или иначе, новый инструментарий представляется полезным.
Для тестирования функций стандартной библиотеки и прикладной программы реализован "тестовый стенд"
DEMO_TESTBENCH. Этот стенд сделан специально для тестирования
разных функций компилятора и стандартной библиотеки, а также для того, чтобы под рукой прикладного
программиста всегда был "тестовый полигон" для испытаний разных пользовательских функций, который,
в отличие от прикладной программы, не жалко "поломать", ведь он есть в дистрибутиве и никуда не денется.
А ведь необходимость тестирования разных кусков программ возникает все время. Тестовый стенд
TestBench призван упорядочить этот процесс "черновой" отладки алгоритмов прикладных программ.
В данном случае можно попробовать, как работает обработка ошибок.
Наберите в консоли &Demo_TestBench команду @Test -1 и через несколько секунд увидите,
что программа аварийно остановилась с выводом диагностики. В тесте специально генерируется
критическая ошибка (деление на ноль), так чтобы проверить работу процедуры обработки ошибок программы.
Обратите внимание, что после сбоя программа перекомпилируется и запускается снова, при этом ошибки
прекращаются (пока мы их снова специально не спровоцируем). Вот это и есть пример отказоустойчивой программы.
Это хороший задел на будущее.
Обратите также внимание, что при остановке программы (DAQ Stop) в консоль выводится подробная статистика
сеанса работы программы - она доступна при установке 4-го бита @DebugFlags (см. dfDetails).
Это дополнение к @CpuProfiler, для облегчения разработки программ. В программах становится
все больше трудно уловимых вещей, связанных с реальным временем - цикл опроса, посылка сообщений и команд,
и т.д. Тут требуется расширение средств отладки, иначе трудно находить ошибки.
26.03.2012 ... 01.04.2012
StdLibrary Tempate.pas SysTimer_Pulse DEMO_RDMS
Небольшое (косметического характера) изменение в шаблоне
template.pas
канонической прикладной программы. Изменение шаблона не влияет на совместимость с предыдущей версией.
Небольшие внутренние изменения в стандартной библиотеке (введена переменная StdIn_EnablePoll)
и в основном теле канонической программы. Изменения не влияют на совместимость с предыдущей версией.
Цель изменений - расширить число прикладных программ, которые можно безболезненно "загнать" под шаблон.
Предыдущая версия основного тела программы не подходила для некоторых случаев - драйверов, в которых
цикл обработки консоли отличался от стандартного.
Теперь (благодаря флагу StdIn_EnablePoll) и этот класс программ тоже можно делать по шаблону.
Добавлено еще несколько функций в стандартную библиотеку. В основном это строковые функции.
Слегка переработаны демо-конфигурации DEMO_WEB4DAQ
и DEMO_HVSS. Изменения косметические.
Почти целиком переработана конфигурация DEMO_RDMS.
В ней добавлена поддержка 2-канального радиометра, который назван RGM - радиометр газов модифицированный.
Работать он должен с прошивкой RTA, надо только запретить 2 канала.
Формально он имеет 4 канала, но 3,4 каналы всегда запрещены.
Обмен данными идет по 2 каналам, а диалог свойств 3,4 канала недоступен.
Полностью переработан WEB - сервер RDMS, это теперь вполне полноценный инструмент,
который умеет показывать таблицы в реальном времени, генерировать отчеты в виде таблиц и графиков,
как суточных, так и архивных (за неделю, месяц и т.д.).
Проблем во время предварительного тестирования (симулятор + RGM с прошивкой RTA) не найдено.
Однако требуется более тщательное тестирование.
Таким образом, по двум системам (HVSS и RDMS) демо-версии содержат самый свежий на текущий момент
рабочий вариант программ, выправленных в соответствии с шаблоном.
В системную библиотеку добавлены таймеры коллективного пользования,
см. SysTimer_Pulse.
Использовать их легко - ничего заводить и инициализировать не надо, просто вызывается SysTimer_Pulse(Period).
Коллективный таймер распознается по своему периоду, который предполагается постоянным и служит его идентификатором.
При этом много независимых подпрограмм могут использовать один таймер (потому он и коллективный).
Функция возвращает либо ноль, если цикл еще на наступил, либо положительное число - номер цикла, когда он наступил.
Номер цикла сохраняется до завершения текущего прогона программы (RunCount).
Подробности см. в описании SysTimer_Pulse.
Пример:
if SysTimer_Pulse(1000)>0 then begin
writeln('Этот вызов будет происходить каждые 1000 ms.');
writeln('Текущий № вызова равен ',SysTimer_Pulse(1000));
end;
if SysTimer_Pulse(5000)>0 then begin
writeln('Этот вызов будет происходить каждые 5000 ms.');
writeln('Текущий № вызова равен ',SysTimer_Pulse(5000));
end;
if SysTimer_Pulse(1000)>0 then begin
writeln('Этот вызов тоже происходит каждые 1000 ms.');
writeln('Текущий № вызова равен ',SysTimer_Pulse(1000));
end;
Коллективные таймеры удобно применять для процедур фонового опроса внешних по отношению к программе
условий и объектов, не привязанных к состоянию внутренних переменных программы.
Для тестирования функций коллективного таймера использована программа
DEMO_WEB4DAQ, где цикл генерации данных сделан на вызове SysTimer_Pulse.
В цикле опроса системной библиотеки сделан контроль ошибок времени исполнения, включая контроль над
строками и критическими ошибками, типа целочисленного деления на ноль или ошибки индексации массивов.
Цикл выполнения программы останавливается с выводом диагностики, если таблица строк близка к исчерпанию,
или если достигнуто заданное число критических ошибок. Продолжение исполнения программы в этих случаях
лишено смысла. Контроль ошибок можно отключить, занулив системные переменные
(см. FatalMaxAvail,
FatalVitalBugs).
Замечания философского характера.
Следует избегать лишних временных глобальных переменных, да и локальных, по возможности, тоже.
Временные переменные, если они нужны, надо помещать внутри процедур, которые их используют.
Глобальными должны быть только переменные, которые должны сохранять значения между вызовами программы,
например, буферы ввода, счетчики событий и т.д.
Для борьбы с излишними временными переменными предлагается следующее.
Вместо var b:Boolean; ... b:=Voice(snd_Click); теперь можно писать просто
bNul(Voice(snd_Click));. Процедура bNul - это
как бы виртуальный канал Nul для boolean. Канал Nul отличается тем,
что он "съедает" любые данные без всяких следов.
Процедуры по возможности должны не зависеть от глобальных переменных и все получать из аргументов вызова.
В системе DEMO_RDMS есть интересная процедура
CompileDprProject
для компиляции EXE программ из исходных DPR файлов.
Это сделано чтобы сократить объем дистрибутива - исполняемые файлы гененируются по мере надобности.
Может пригодится и в других случаях.
При тестировании клиента DEMO_RDMS обнаружена интересная проблема.
Там был код обработчика консольного ввода типа:
...
if IsSameText(cmd,'@Browse') then begin
if DevSend(devDimSrv,'@Browse '+arg+CRLF)=0 then WebBrowser(arg);
end else
...
Смысл кода простой - если есть сервер devWebSrv, переслать сообщение ему, иначе выполнить самому.
Этот код хорошо работал на сервере - он честно пересылал сообщения серверу &WebSrv.
Однако на клиенте этого сервера нет, там devWebSrv равен 0, поэтому сообщение отсылалось
самому себе, так как нулеая ссылка в DevSend означает посылку в свою собственную консоль.
По этой причине возникала бесконечная рекурсия через посылку сообщений самому себе, при этом программа
подвисала. Вывод простой: надо проверять ссылки на устройства, чтобы точно знать, куда посылается сообщение.
Дураков (если они есть) поздравляю с Днем Дурака.
Остальным желаю трезвомыслия, доброго здравия и долгая лета.
21.03.2012 ... 22.03.2012
StdLibrary Tempate.pas Web4Daq HVSS
Опять (и надеюсь, в последний раз) довольно сильно изменен
шаблон
канонической прикладной программы.
Изменение состоит в том, что шаблон теперь не просто рекомендует, а уже жестко навязывает
тело основной программы (Main) путем включения "канонического" тела программы директивой
{$I _std_main}.
То есть тело основной программы как бы становится обязательной частью библиотеки.
По моему мнению, такая строгая дисциплина оставляет прикладным программистам вполне достаточно свободы
(в рамках пользовательских процедур), но гарантирует самосогласованность программы - ведь тело основной
программы (Main) должно всегда соответствовать версии библиотеки (а вдруг в ней что-то изменится).
Теперь реализация стандартной библиотеки и шаблона прикладной программы приобрела логическую завершенность,
и приведена в соответсвие с принципами модульного программирования.
Имена прикладных пользовательских процедур ClearApplication, InitApplication,
FreeApplication, PollApplication, StdIn_Processor - теперь тоже жестко фиксируются,
поскольку основная программа на них ссылается.
Это последнее изменения шаблона, по моему мнению, устраняет последнюю помеху на пути внедрения стандартной библиотеки.
Вся битва, в сущности, шла за то, чтобы любые внутренние изменения в библиотеке никак не влияли на работоспособность
прикладных программ при обновлении версии пакета (как это у нас всегда было). А для этого как раз и пришлось
долго экспериментировать и возиться с шаблоном. Кажется, теперь все в полном порядке.
Ну, по крайней мере, я надеюсь на это.
Для проверки обновленной стандартной библиотеки StdLibrary, обновлены в соответствии с шаблоном,
и проверены демо-конфигурации DEMO_WEB4DAQ,
DEMO_RDMS и DEMO_HVSS.
Проблем во время тестирования не найдено.
Стандартная библиотека претерпела небольшие внутренние
доработки, касающиеся повышения производительности и мелких улучшений.
По моему мнению стандартная библиотека готова к широкому внедрению.
Разумеется, сначала надо пройти период бета-тестирования (в лаборатории), прежде чем использовать
ее на опасных установках.
Разумеется, никто насильно не будет заставлять переводить все программы под шаблон.
Можно продолжать писать программы в старом стиле, все будет работать как раньше.
Однако внедрение шаблона и стандартной библиотеки имеет очень много преимуществ.
Начиная с шаблона, мы начинаем со сразу же полностью работающей программы, в которой
доступен большой набор функций, снабженных описанием (по Ctrl-F1).
Сильно сократится объем прикладного кода.
Будут сразу доступны удобные средства отладки (команда @CpuProfiler). И так далее.
Со своей стороны я беру обязательства поддерживать совместимость версий библиотеки.
Для этого достаточно, чтобы не менялся интерфейс (названия переменных и функций и их аргументы).
То есть функции, однажды попавшие в библиотеку, уже не должны никогда менять названия и синтаксис
(тип, число аргументов и т.д.). При этом их внутреннее содержание может меняться (ускоряться работа,
устраняться ошибки, появляться дополнительные возможности и т.д.).
Рассчитываю на поддержку DaqGroup в бета-тестировании и внедрении стандартной библиотеки.
В ближайшее время надо собрать серию семинаров и поговорить об этом подробнее.
Отныне стандартная библиотека StdLibrary (см. ниже) должна рассматриваться как штатная часть компилятора Daq Pascal.
Использовать ее, разумеется, не обязательно, но крайне рекомендуется.
Стандартная библиотека существенно расширена.
Добавлены функции профайлера (см. ниже), много новых функций для упрощения разработки Web - приложений,
особенно с использовением технологии AJAX.
Добавлено много новых строковых функций.
Сделана контекстная справка
по функциям стандартной библиотеки, доступная по Ctrl-F1 в редакторе DAQ Pascal.
Это позволяет быстро найти информацию по интересующей функции, и описание и исходный текст.
Довольно сильно изменен шаблон,
канонической прикладной программы. Предприняты усилия для того, чтобы все создаваемые в будущем программы,
использующие стандартную библиотеку, имели жесткую, неизменную структуру - это сократит число ошибок.
Приношу извинения за то, что шаблон в последних версиях несколько раз изменялся - сейчас идет период
интенсивной разработки, сразу принять верное решение бывает нелегко.
Надеюсь, по завершении этого периода крупных изменений в шаблоне больше не будет.
Новый шаблон развивает идею инкапсуляции
модулей и супермодулей, доведя его до
логического конца: на верхнем уровне прикладной программы всегда присутствует условный супермодуль
Application, в который включаются все другие используемые модули, кроме системной библиотеки
StdLibrary, вызываемой непосредственно в теле основной программы.
Это позволяет унифицировать вид основного тела программы, сделав его одинаковым практически для всех случаев.
Предполагается, что основное тело программы (Main) меняться в будущем не будет, кроме редких исключений.
Основное тело программы должно копироваться из шаблона "один в один". Это гарантирует правильное использование
стандартной библиотеки StdLibrary, которая в шаблоне вызывается корректным образом.
Задачей прикладного программиста теперь становится заполнение своим кодом пяти процедур с фиксированными именами:
ClearApplication, InitApplication, FreeApplication, PollApplication, StdIn_Processor.
Процедура ClearStrings, ранее присутствовавшая в многих прикладных программах, теперь ликвидирована,
так как часть ее функций перенесена в тело основной программы, которая теперь зафиксирована, а другая часть
функций реализуется процедурой ClearApplication, которая используется для очистки строк, определенных
в прикладной программе. Очищать строки стандартной библиотеки и проверять утечку строк в прикладном коде
теперь не надо - это делается в теле основной программы.
Обращаю также внимание, что в теле StdIn_Processor обязательно вызывается StdIn_DefaultHandler,
который обеспечивает обработку некоторого набора стандартных команд. Этот набор, вероятно, будет пополняться,
а в настоящее время в него входят следующие команды:
@Help Показать справку. Справка прикладной программы находится в [@Help].
@DebugFlags n Установить режим отладочного вывода n=1+2+4+8, где флаги разрешают:
1 = Success(информационные сообщения);
2 = Trouble(выводится сообщение и генерируется ошибка), Problem(только сообщение);
4 = ViewExp(сообщения о выводе=экспорте, например, в канал или порт);
8 = ViewImp(сообщения о вводе=импорте, например, из канала или порта).
@Eval e Вычислить выражение e, например, @Eval 2+2
Для вычисления используется экземпляр калькулятора текущей программы DaqPascal,
то есть доступны все переменные и функции, которые доступны для функции Eval().
Например, @Eval @echo Привет выведет Привет в системную консоль.
Это очень мощная функция, но пользоваться ей надо весьма осторожно.
@CpuProfiler Показать Help по команде @CpuProfiler для вывода ститистики о производительности.
@CpuProfiler Start p v m s Стартовать профайлер с параметрами p v m s, по умолчанию 1 60 7 0
p - период опроса профайлера, секунд, по умолчанию 1
v - период вывода отчетов, секунд, по умолчанию 60
после вывода отчета счетчики зануляются, стартует новый цикл набора
нулевой период подавляет вывод и соответсвенно рестарт профайлера
m - режим вывода отчетов профайлера, по умолчанию 7=1+2+4
1=заголовок, 2=статистика загрузки, 4=счетчики
нулевой режим подавляет вывод отчетов и рестарт профайлера
s - тестовый режим стресс-нагрузки, %, по умолчанию 0 %
создает искусственную нагрузку потока программы s %
используется только для стресс-тестирования программы
при различных загрузках CPU
@CpuProfiler View Досрочный вывод отчета, не дожидаясь очередного периода отчетов.
Можно задать нулевой период отчетов, подавив его периодический вывод
с рестартом, а статистику смотреть командой View.
@CpuProfiler Stop Останавливает профайлер, чтобы он не отнимал время процессора.
По умолчанию профайлер остановлен, его можно стартовать только
консольной командой.
Прикладные программы должны обязательно использовать StdIn_DefaultHandler, это сократит и объем
прикладного кода, и даст всем программам, построенным по шаблону, мощные средства, входящие в стандартную
библиотеку. Пока в нее входят в основном отладочные функции, однако со временем этот набор может
существенно увеличиться.
Итак, весь пользовательский код прикладной программы теперь предлагается помещать в специальные процедуры
со строго фиксированными именами:
ClearApplication - очистка всех строк, определенных в прикладной программе.
Ничего лишнего эта процедура делать не должна - все, кроме очистки строк, делает InitApplication.
InitApplication - инициализация пользовательских переменных, тегов, кривых, устройств
прикладной программы и т.д. Надо помнить, что при возникновении в процессе инициализации
критических ошибок надо сделать вызов Trouble или инкрементировать Errors.
При этом генерируется ошибка, инициализация считается неудачной, а цикл опроса программы блокируется.
Для вывода сообщений о некритических ошибках вместо Trouble надо вызывать Problem.
FreeApplication - освобождение всех созданных переменных и занятых ресурсов - файлов, текстов,
созданных процессов (задач), открытых каналов, портов и т.д.
Системная библиотека освобождается в теле основной программы, поэтому позаботиться надо только
о тех ресурсах, которые явно выделяла сама прикладная программа.
PollApplication - процедура обработки данных в цикле опроса.
Здесь, собственно, происходит основная обработка данных, кроме обработки консольных команд.
Раньше эта обработка помещалась в основном теле программы.
Унификация программ требует отказа от этой практики - тело основной программы должно быть минимальным,
крайне желательно чтобы оно было шаблонным.
А вот процедуру опроса каждый пишет как ему надо.
StdIn_Processor - процедура обработки данных (в основном команд) из консоли StdIn.
Эта процедура должна брать команды с помощью GotCommand (это обязательно), обрабатывать
полученные команды, проверяя их с помощью IsSameText(cmd,'@CommandName'), а затем вызвать
StdIn_DefaultHandler для обработки стандартных команд.
Команды разделяются символами разделителя строк (CR,LF), начинаются с символа "собаки" (@)
и идентифицируются первым словом, например, @Help, за которым идет знак равенства (=) или пробел ( ),
после которого идут необязательные аргументы, смысл которых определяется именем команды.
Следует помнить, что вызов DevSend(cmd1+CRLF+cmd2+CRLF+..+cmdN+CRLF) гарантированно передает
пачку команд cmd1,cmd2,cmdN как единый атомарный (неделимый) блок.
Если, например, надо одновременно указать несколько параметров, которые задаются разными командами,
либо выполнить последовательность команд в фиксированном порядке, то их надо послать одним вызовом
DevSend. При этом, хотя команды будут выполняться порознь, гарантируется их одновременный
приход и строгий порядок их поступления. Если же было несколько вызовов DevSend,
то между ними может "вклиниться" посылка из другого потока, программа ведь работает параллельно с
многими другими. Все это надо учитывать при создании прикладных программ на основе сообщений.
При использовании включаемых библиотек и супермодулей
их процедуры Clear, Init, Free, Pollинкапсулируются
(включаются) в основную программу по принципу "матрёшки" - один в другой.
Это гарантирует корректную работу программы при большом числе включаемых модулей.
Для проверки обновленной стандартной библиотеки StdLibrary, а также для демонстрации
и прототипирования Web серверов на основе технологии AJAX, а также с использованием
GnuPlot, обновлена демо-конфигурация DEMO_WEB4DAQ,
в ней переделана программа WebCgi.pas,
в соответствии с шаблоном. Проблем во время тестирования не найдено.
Получился вполне полноценный Web сервер, содержащий прототипы основных технологий, которые
планируется развивать в будущем.
Эта конфигурация может служить хорошим прототипом для создания Web - серверов.
Программа WebCgi.pas помещена также в шаблоны редактора, так что ее всегда можно быстро вытащить
для извлечения из нее нужных фрагментов.
Для проверки обновленной стандартной библиотеки StdLibrary обновлена демо-конфигурация
DEMO_HVSS в соответствии с шаблоном.
Перевод программы под шаблон занял около часа, объем прикладного кода при этом существенно сократился.
Проблем во время тестирования (на симуляторе) не найдено.
Обновлены библиотеки скриптов JavaScript, нужные для создания динамических
WEB-страниц. В настощее время в RDMS весьма интенсивно используется библиотека flot, а
также jquery, которая существует как отдельно, так и входит в состав flot как её компонент.
Библиотека jquery содержит базовые функции, необходимые для использовения технологии AJAX
(Asynchronous Javascript and XML), на которой в будущем будет строиться все что касается Web.
Библиотека flot содержит функции, необходимые для рисования красивых графиков в Web-обозревателе.
Эти две библиотеки более-менее освоены и точно будут использоваться у нас.
Причем в качестве основной будет использоваться библиотека flot, запомните это название на будущее.
Другие библиотеки включены на всякий случай - на них тоже часто ссылаются в Сети.
У нас они пока они не используются.
Введены библиотеки стилей StyleSheet, нужные для задания стиля WEB страниц.
Эти стили задают оформление документов - фона, цветов, шрифтов и т.д.
В настоящее время заведена одна библиотека alex, созданная мной первоначально для RDMS, а теперь
предлагаемая для всех случаев. Возможно, библиотека будет расширяться.
Введение библиотек скриптов и стилей совершенно необходимо для решения поставленной задачи - широкого внедрения
WEB технологий в практику создания наших измерительных систем. Уже сделаны стандартные библиотеки,
которые копируют скрипты и стили из системной области в локальную папку измерительной системы. Например, вызов
WEB_CopyJsLibrary('flot'); // Копирует в ..\Utility\JavaScript\flot, ссылка /Utility/JavaScript/flot
WEB_CopyCssLibrary('alex'); // Копирует в ..\Utility\StyleSheet\alex, ссылка /Utility/StyleSheet/alex
копирует скрипты и стили в локальную папку, доступную для Web-сервера.
Так будет обеспечиваться унификация и поддержка Web серверов (а их планируется много).
Сделаны изменения в сервере &WebSrv, необходимые для использовения технологии AJAX.
Эта технология предназначена для динамического обновления Web-страниц "по требованию", без
полной прорисовки. При этом возможен период обновления данных на странице порядка секунды
(и даже 100 мс), то есть Web-интерфейс начинает работать практически в реальном времени.
При использовании AJAX страница обновляется "мягко", без "моргания".
В будущем планируется строить на этой технологии Web-интерфейсы для всех распределенных систем.
В настоящее время используется в основном в RDMS.
Добавлена консольная команда управления кэшированием конфигурационных файлов.
--Размер кэш-буфера (CfgCacheSize) конфигурационных файлов:
m=@Memory CfgCacheSize Прочитать в переменную m.
+@Memory CfgCacheSize Вывести на экран, в Байтах.
1/1024/1024*@Memory CfgCacheSize Вывести на экран, в мегаБайтах.
+@Memory CfgCacheSize 1024*1024*2 Оставить кэш не более 2 МБ и вывести на экран.
@Memory CfgCacheSize 0 Очистить кэш полностью.
--Предел (CfgCacheLim) кэш-буфера конфигурационных файлов:
@Memory CfgCacheLim 1024*1024*8 Задать предел размера кэша не более 8 МБ.
+@Memory CfgCacheLim Вывести предел размера кэша на экран.
--Период проверки (CfgCachePoll) кэш-буфера конфигурационных файлов:
@Memory CfgCachePoll 1000 Задать период проверки размера кэша 1000 ms.
+@Memory CfgCachePoll Вывести период проверки размера кэша на экран, ms.
Для справки: При чтении конфигурационных файлов они кэшируются, для ускорения чтения.
Чтобы кэш не возрастал слишком сильно, размер кэша (CfgCacheSize) периодически
(CfgCachePoll ms) проверяется и происходит его очистка,
чтобы он не превышал заданный предел (CfgCacheLim).
Кэширование, ускоряя процесс загрузки конфигураций, может иметь и негативные последствия.
Во-первых, кэш занимает память. Во-вторых, в кэше могут сохраняться "следы" удаленных файлов.
Вообще, при чтении (ReadIni) проверяется размер и дата модификации читаемых файлов,
при необходимости делается их перезагрузка. Однако если файл был удален после чтения,
то при повторном чтении в кэше может остаться его образ, и тогда чтение будет неверным.
Эта ситуация не типична для нормально работающей системы, однако в процессе отладки удаление
конфигурационных файлов - обычное дело. Очистка кэша позволяет устранить проблему без
перезагрузки пакета. Наконец, в начале работы прикладной программы очистка ненужного
уже кэша может освободить память для других нужд. По завершении работы конфигурации
тоже полезно освобождать кэш.
Так или иначе, теперь кэшированием можно управлять. Из программы это можно сделать
примерно так:
Этот релиз устраняет мелкие недостатки, обнаруженные в предыдущем.
Все изменения касаются [Compiler.Options].
Причиной послужило то, что после введения опций "по умолчанию" некоторые DEMO примеры стали давать
ошибку компиляции, т.к. значения "по умолчанию" изменились по сравнению с прошлыми версиями,
где эти значения были жестко "зашиты" в программе, а не задавались в Crw32.ini.
Блок [Compiler.Options] удален из шаблона
template.pas,
канонической прикладной программы.
Предполагается, что для подавляющего большинства программ настройки компилятора будут браться
из системной конфигурации Crw32.ini, где будут содержать разумные
значения, согласованные с текущей версией стандартной включаемой библиотеки StdLibrary
и подходящие для большинства прикладных программ.
В обычных прикладных программах использовать [Compiler.Options] теперь не рекомендуется,
чтобы в будущем при изменении стандартной библиотеки и системных настроек не возникало несовместимостей.
Лишь в исключительных случаях (когда используются большие массивы) нужно использовать [Compiler.Options].
Блок [Compiler.Options] удален из большинства DEMO примеров. Работа этих примеров проверена.
Добавлена альтернативная консольная утилита речевого синтезатора.
Доступна через вызов
@run /hide Speak Russian "Привет, мой друг."
@run /hide Speak English "Hello, my friend."
Альтернативная утилита добавлена потому, что позволяет вставлять речевые сообщения независимо от того,
запущен ли &SpeakSrv. Кроме того, это позволяет выводить речевые сообщения в командных
файлах, например, в препроцессоре или постпроцессоре.
01.01.2012 ... 22.02.2012
rusconv makescut saferun DIM itab, btab, atab rtab, ctab StdLibrary
Обновлена сборка Total Commander XP.
Приложены большие усилия для того, чтобы Командир нормально работал под Windows-7,x64.
В сборке также несколько новшеств - обновлена программа просмотра PDF, обновлен Firefox
до последней версии 10.0.1, добавлена написанная мной (по мотивам встреченной в Сети статьи) программа
для запуска программ с ограниченными привилегиями SafeRun, программа пакетной конвертации изображений
Photo Resizer, обновлены программы из набора SysInternals (диагностические утилиты).
Появился также Центр Управления Windows (кнопка с логотипом Windows) - в нем собраны
все основные функции для настройки и управления операционной системой.
Это удобно само по себе, а также может пригодиться в случае, когда альтернативные возможности доступа
к этим функциям отключены. Например, когда стандартные интерфейсные элементы (меню и кнопка Пуск)
заблокированы из соображений безопасности. Запуск Total Commander XP в этом случае позволит
легко получить доступ ко всем возможностям системы, даже если стандартное меню недоступно.
Утилита convert.exe заменена на rusconv для совместимости с Windows-7,x64.
Добавлена утилита makescut.exe для создания ярлыков .LNK из командной строки.
В меню Инструменты\Консольные утилиты в CRW32 также добавлена консольная утилита
Windows Control Center для вызова функций управления операционной системой.
Это позволит настраивать систему прямо из CRW, например, в случае, когда система запущена
под ограниченным пользователем, а пакет - под администратором.
Центр управления проверен на WinXP и Win7x64.
Существенно доработана стандартная библиотека
включаемых файлов для прикладных программ DAQ PASCAL.
Теперь вместо длинного списка включаемых модулей достаточно включать всего один
супермодуль, названный
библиотекой - StdLibrary.
Супермодуль назван так потому что он включает в себя кучу других модулей,
список которых со временем может быть расширен. Однако с внешней точки зрения использование супермодуля при добавлении
внутри него новых модулей не изменится. Стандартная библиотека будет расширяться без потери обратной совместимости.
Введение супермодуля оправдано потому, что компиляция идет достаточно быстро (сначала это было не так уж очевидно).
Как показала практика, компиляция модулей библиотеки требует не более 50 мс, поэтому нет особого смысла терять
время программистов на сокращении набора используемых модулей, а для унификации лучше включать сразу всю библиотеку.
Хотя при этом, конечно, в каждой программе будет куча невостребованных процедур и функций, которые никогда
не вызываются. Кроме незначительной потери памяти это не создаст других проблем, однако выигрыш
за счет унификации и облегчения разработки программ будет, я полагаю, весьма существенным.
Также изменен шаблон,
задающий канонический вид прикладной программы.
Настоятельно рекомендуется вести разработку всех будущих программ на основании этого шаблона.
Обращаю также внимание, что в шаблоне используются библиотечные функции Starting, Stopping,
Polling, GotCommand, CheckStdErrors, CheckStringLeaks, а также InitStdLibrary,
FreeStdLibrary, PollStdLibrary, использование которых улучшает структуру программы.
Смысл функций достаточно понятен по названию и контексту.
Используйте шаблон - будет меньше ошибок, сократится объем кода, улучшится структура программ.
Сняты ограничения на размер кода, числа переменных, процедур и функций для прикладных программ
DAQ PASCAL.
Это значит, что отныне опции [Compiler.Options] Compiler.itabmax - идентификаторы,
Compiler.btabmax - процедуры и функции,
Compiler.atabmax - массивы и записи,
Compiler.rtabmax - константы Real,
Compiler.ctabmax - сегмент программного кода
будут задавать лишь начальные значения таблиц, которые теперь будут расти по мере надобности,
если в большой программе возникнет необходимость их расширения. Фактически это означает, что конфигурировать
эти таблицы больше не требуется - они будут автоматически увеличены по мере необходимости.
Это решение снять ограничение было связано с тем, что при использовании стандартной библиотеки часто
возникала проблема переполнения таблиц компилятора из-за большого числа функций и идентификаторов.
Теперь эта проблема исчезает, даже если стандартная библиотека будет сильно расти. При этом, поскольку
все эти таблицы могут расти лишь в момент компиляции, их динамический рост не может снизить общую надежность
и отказоустойчивость системы во время работы прикладной программы.
В то же время сегмент данных Compiler.dtabmax и таблица строк Compiler.stabmax остаются
по-прежнему статическими. Это связано с тем, что нельзя сделать их динамическими без потери общей
надежности и отказоустойчивости системы - ведь при динамических таблицах прикладная программа
получит возможность неограниченно захватывать ресурсы, пока не исчерпает всю доступную память.
Статические таблицы препятствуют этому неограниченному захвату ресурсов, но требуют разумной конфигурации.
Во всяком случае, конфигурировать программы теперь станет легче - надо следить лишь за размером
сегмента данных Compiler.dtabmax и таблицы строк Compiler.stabmax.
При этом надо ориентироваться на показания функций StackAvail и MaxAvail, которые показывают
доступные (свободные) ресурсы в соответствующей таблице (данных и строк).
Изменена процедура чтения опций [Compiler.Options].
Раньше они читались только из текста программы в *.PAS файле. Теперь, если опции не найдены там,
система будет продолжать их поиск сначала в *.CFG файле конфигурации, а затем в системном файле
настроек программы CRW32.INI. То есть появилась возможность задавать опции "по умолчанию" для
всех программ, где опции не описаны явно. Это либо можно сделать в загружаемой конфигурации,
либо можно использовать значения, помещенные в CRW32.INI. Для большинства простых программ это
означает, что от описания опций компилятора в тексте программы можно, видимо, отказаться вовсе.
Разумные значения опций будут взяты из системного файла CRW32.INI.
Выработаны рекомендации по созданию с помощью включаемых файлов прикладных
модулей, а также правила правильной
инкапсуляции (объединения) этих
модулей в супермодули.
Соблюдение этих правил позволит в будущем облегчить создание больших проектов с большим числом
включаемых модулей и библиотек.
Для проверки стандартной библиотеки обновлена конфигурация DEMO_RDMS,
в ней переделаны программы rdms_cgi.pas и
rdms_gui.pas, в соответствии с шаблоном.
Проблем во время тестирования не найдено.
Устранена ошибка переполнения буфера, из-за которой не работали функции рисования при большом числе вызовов
WinDraw. Теперь буфер сделан динамическим - он будет расти при необходимости большого объема прорисовок.
В процессе эксплуатации измерительных систем выяснилось, что обычная цветовая палитра
окон с графиками и спектрами не всегда удобна, особенно при необходимости вывода на печать
или копирования графиков в документы или статьи. Возникла идея задавать цветовую палитру окон
через файл конфигурации, чтобы была возможность задавать вид окон, исходя из потребностей решаемых задач.
Были введены палитры для окон кривых и
спектрометрических окон.
Палитры задают начальный вид всех создаваемых окон соответствующего типа.
При указании палитры окон используются цвета либо с мнемоническими названиями из
палитры Delphi, либо цвета,
заданные в виде шестнадцатеричного числа.
Для проверки можно запустить конфигурации DEMO_RFA
и DEMO_DIM_GUI. В обоих случаях палитры заданы
в файле palette.cfg, включаемом в конфигурацию DAQ.
Заданные в конфигурации палитры влияют на вид всех окон данного типа с момента загрузки
текущей конфигурации DAQ. После её завершения восстанавливается палитра, принятая
по умолчанию (она описана в файле Crw32.ini).
Для проверки стандартной библиотеки обновлена конфигурация DEMO_WEB4DAQ,
в ней переделана программа WebCgi.pas,
в соответствии с шаблоном. Проблем во время тестирования не найдено.
Эта конфигурация может служить хорошим прототипом для создания Web - серверов.
В библиотеку устройств добавились модули
7045, 70517058, 7059. Эти модули добавлены формально,
по описаниям, а на реальном железе не проверялись. Просьба оказать содействие в такой проверке.
По случаю 23 февраля
- мое почтение всем родам войск, защищающим наш покой:
Пехота
Авиация
Связисты
Танкисты
Ракетчики
Артиллерия
Хим.защита
Радиотехники
Стретегические
Космические
Противовоздушные
Воздушно-десантные
Автомобильные
Железнодорожные
Музыканты
Топографисты
Юристы
Медики
Ветеринары
Инженеры
И не будем забывать азбучные истины:
У России есть только два союзника: армия и флот.Александр III Романов
Народ, который не хочет кормить свою армию, будет кормить чужую.Наполеон Бонопарт
18.10.2011 ... 30.10.2011
Preprocessor PostProcessor CMD BAT FontReg ttf-crw ttf-tot
Если не будет неожиданностей, этот релиз должен стать "рабочей лошадкой" на ближайшее полугодие.
В этой версии устранялись мелкие "косметические" погрешности предыдущей.
Немного изменена работа препроцессора и постпроцессора: устранена возможность
сбоя при перезагрузке DAQ-конфигурации.
В разделе "Общие свойства DAQ" в окне панели управления устройствами DAQ
в секцию DAQ добавлены параметры
препроцессора и постпроцессора (это надо было сделать сразу, но я забыл).
Добавлен еще один справочный файл cmd/allhelp.htm
по командам CMD, в котором приведены все справки,
которые выдаются встроенной командой HELP. Удобно, чтобы не открывать всякий раз консоль.
Изменены скрипты, регистрирующие фонты в системе (при инсталляции программа регистрирует нужные ей фонты).
Про фонты стоит поговорить отдельно. С ними есть проблемы.
Как известно, фонты хранятся в каталоге %SystemRoot%\Fonts.
Но кроме того, информация о фонтах находится в реестре (в разделе
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts).
Регистрация в реестре обеспечивает обращение к фонту по имени. Например, фонт Courier New
может ссылаться на файл cour.ttf. Именно этот метод использует большинство программ.
Причем возможны ситуации, когда фонт присутствует в каталоге Fonts,
но не зарегистрирован в реестре, или наоборот, зарегистрирован несуществующий файл.
В обоих случаях программа не сможет найти нужный фонт.
Для регистрации фонтов и устранения несоответствия реестра и каталога Fonts
в пакет добавлена утилита fontreg.
Она умеет регистрировать все шрифты из Windows\Fonts в реестре,
удалять из реестра все ссылки на несуществующие файлы, а также копировать
в системный каталог и регистрировать фонты из текущего каталога.
fontreg.exe - зарегистрировать в реестре все фонты из Windows\Fonts,
удалить из реестра несуществующие фонты
fontreg.exe /copy - скопировать все фонты (ttf,fon,otf) из текущего каталога
в Windows\Fonts, затем зарегистрировать и почистить реестр
@run fontreg.exe - так можно вызвать программу из консоли CRW32
@run ttf-crw.bat - (пере)установить фонты, входящие в дистрибутив CRW-DAQ
@run ttf-tot.bat - (пере)установить фонты, входящие в дистрибутив Tot-Cmd
Утилита доступна и для программ Daq Pascal, если прикладной программе надо регистрировать свой шрифт.
Хочется надеется, что теперь проблема с "кракозябрами" из-за отсутствия нужных фонтов будет решена
на всех платформах. Набор нужных шрифтов будет пополняться по мере обнаружения проблем.
Часть фонтов входит в сборку Total Commander, поэтому, чтобы не дублировать одинаковые файлы,
предполагается, что на рабочих машинах будет установлен также и он, чтобы были доступны все нужные шрифты.
Обновлена сборка Total Commander XP.
Теперь, после изрядной доработки, Командир должен выглядеть
одинаково во всех системах (проверено под WinXP и Ubuntu Linux\Wine).
В сборке также много новшеств - установка специальных шрифтов при инсталляции,
новая программа просмотра PDF, большое число новых плагинов.
Мной приложены все усилия к тому, чтобы эта сборка Командира стала удобной "средой обитания",
содержащей под рукой все нужные инструменты.
Настоятельно рекомендую освоить эти инструменты - это сильно ускоряет разработку прикладных систем.
07.10.2011 ... 17.10.2011
DaqConsoleFifoSize Preprocessor PostProcessor CMD BAT
Введена переменная Crw32.ini [DaqSys] DaqConsoleFifoSize=256,
задающая размер консоли при работе DAQ-системы, кб.
Раньше он был константой (64 kb), теперь его можно регулировать через CRW32.INI файл.
В секцию DAQ введен
препроцессор,
вызываемый перед загрузкой конфигурации, а также
постпроцессор,
вызываемый после завершения и выгрузки конфигурации.
Не буду повторять довольно подробное описание, скажу только о целях:
Препроцессор может служить для динамической генерации конфигураций при загрузке.
Это актуально для больших систем, содержащих много одинаковых подсистем.
Чтобы не приходилось многократно править кучу одинаковых файлов, вводится
один файл-генератор (*.gen), в котором вместо имен конкретных подсистем
стоят "заглушки". Препроцессор путем замены строк генерирует конфигурационные
файлы при загрузке. В результате надо редактировать только один файл,
остальные будут автоматически созданы. Это позволит резко сократить
объем ручной работы и сократить время и число ошибок по невнимательности
при редактировании большого числа похожих файлов.
Препроцессор может служить также для подготовки "среды обитания" загружаемой
конфигурации: создания каталогов, проверки и копирования нужных файлов и т.д.
Препроцессор может служить также для интерактивной (диалоговой) загрузки.
Например, можно спрашивать при загрузке "Загрузить клиент или сервер?"
и генерировать соответствующий конфигурационный файл по результатам
ответа оператора. Можно при загрузке запрашивать некие параметры,
например, имя DNS сервера DIM, и так далее.
Постпроцессор может служить для очистки каталогов DAQ системы от
ненужных временных файлов или для выполнения других действий, которые
требуются при завершении работы DAQ. Например, можно завершать
работу DNS сервера (dns.exe).
@echo off
Title PreProcessor.cmd
SetLocal EnableExtensions EnableDelayedExpansion
for %%i in (ReplaceStr.exe) do (path %%~dp$CRW_DAQ_SYS_PATH:i;%path%)
type demo.cfg.gen ^
| ReplaceStr "$DemoDevice$" "&DemoDevice1" ^
| ReplaceStr "$DemoTag$" "DemoTag1" ^
> demo.cfg
type demo.cfg.gen ^
| ReplaceStr "$DemoDevice$" "&DemoDevice2" ^
| ReplaceStr "$DemoTag$" "DemoTag2" ^
>> demo.cfg
В этом сценарии
Дается заголовок окну,
Устанавливаются опции интерпретатора,
Путь утилиты ReplaceStr.exe включается в путь поиска, чтобы потом писать ReplaceStr без пути,
Из файла demo.cfg.gen путем двух строковых замен генерируется файл demo.cfg для двух "подсистем".
При генерации первой файл перезаписывается, для второй - записывается в конец файла.
Для удобства используется многострочный оператор.
Обращаю особое внимание: a)аргументы для замены надо "комментировать", 2)для переноса строк
в длинных командах в конце строки ставится шляпка ^, после которой не должно быть пробелов.
Раз уж введен препроцессор и командные сценарии становятся частью пакета, то надо иметь их описание.
Поэтому добавлена справка по командам CMD.
Ссылка на неё находится в справочном файле Содержание - Top-20.
Программирование сценариев на cmd - довольно малоприятное дело, в силу запутанности синтаксиса
его языка, в котором плохо документированные мелочи играют большую роль. Но разобраться можно,
а выигрыш от использования скриптов все же может быть значительным.
Небольшие изменения в переменных окружения.
Добавлена переменная CRW_DAQ_CONFIG_BASE_TIME и CRW_DAQ_CONFIG_TEMP_PATH.
Это может пригодиться в сценариях препроцессора и постпроцессора.
Небольшие изменения в [DAQ] BaseTime.
Теперь допустимо указывать символ-заменитель * для обозначения текущего времени. Например:
BaseTime = *.*.*-00:00:00 ; Отсчет времени от начала текущих суток
BaseTime = 01.*.*-00:00:00 ; Отсчет времени от начала текущего месяца
BaseTime = 01.01.*-00:00:00 ; Отсчет времени от начала текущего года
Это удобно для установок, работающих в режиме рабочих смен. Если указать BaseTime = *.*.*-00:00:00 от начала
суток и TimeUnits = 3600 - часы, то время будет указано в календарных часах.
Внесенные изменения проиллюстрированы в демо-конфигурации
DEMO_PREPROCESS.
Тут есть PreProcessor.cmdPostProcessor.cmd,
генератор Demo.cfg.gen.
Конфигурация практически пустая - она лишь иллюстрирует правильное использование препроцессора,
постпроцессора и BaseTime.
// Примеры способов включения файлов в программы DAQ PASCAL:
{$I c:\demo\full.inc} // Включить файл с полным именем
{$I Lib\relative.inc} // Включить файл с путем относительно текущего файла
{$I find_me.inc} // Включить файл с поиском в списке известных путей
{$I find_me} // Включить файл с поиском и расширением по умолчанию .INC
В подавляющем большинтве случаев рекомендуется включать файлы БЕЗ ПУТИ, чтобы система
сама нашла нужный файл. Это позволяет безболезненно переносить библиотечные файлы в
удобное место, а также перекрывать системные библиотеки их локальными версиями,
если вдруг возникнет такая надобность.
Правила поиска файлов, для которых не указан путь, подробно описаны в документации.
Система допускает рекурсивное включение файлов до 9 уровня вложенности.
Для контроля включаемых файлов в окно отображения свойств устройств DaqPascal
выводится содержимое отладочного файла. В нем можно увидеть полный текст программы,
который компонует компилятор, с учетом директив включения файлов. Там также
можно узнать время компиляции каждого файла в конце текста.
Для облегчения поиска ошибок в включаемых файлах при компиляции программ DaqPascal
из встроенного редактора в случае ошибки во включаемом файле будет открыт полный "стек"
включаемых файлов, одно над другим.
В каждом из окон курсор установится в место ошибки. Окна редактирования для включаемых
файлов после этого не контролируются, они могут остаться открытыми после завершения прикладной
программы, и их придется закрывать "ручками". Это маленькое неудобство возникает только на этапе
отладки и касается только разработчиков. Зато не придется искать включаемые файлы с ошибками
- они сами "вылезут" в случае надобности.
Для сохранности библиотек при открытии вложенных файлов по ошибке устанавливается запрет редактирования,
если включаемый файл найден в каталоге, отличном от каталога компилируемой программы. То есть вложенный
файл встроенными средствами пакета можно редактиравать, если поместить его в каталог основной программы
(обычно DaqPas), но после того, как он отлажен, его можно переместить в каталог поиска - и он станет
защищенным от непреднамеренной модификации. Таким образом, по мере отладки включаемые файлы можно
постепенно убирать из текущего каталога в защищенную библиотеку, так что отлаженные включаемые файлы
и путаться под ногами не будут, и случайно испортить их будет нельзя.
Создана стандартная библиотека
включаемых файлов для прикладных программ DAQ PASCAL.
Есть описание и
шаблон программы,
поясняющий, как правильно ее использовать.
Обращаю внимание на новшества в шаблоне, касающиеся инициализации\завершения
(Init/Free, CheckStdErrors) и цикла опроса (GotCommand).
В будущем рекомендую придерживаться стиля, приведенного в шаблоне.
Философское отступление.
Стандартная библиотека обобщает многолетний опыт прикладного программирования и построена путем выборки
из реальных работающих уже давно прикладных систем удачных процедур и функций,
часто повторяющихся от одной системы к другой.
Предполагается, что постепенно большинство прикладных программ будут создаваться на основе этой
библиотеки путем включения в программу нужных библиотек.
Это поможет резко (в 2-3 раза) сократить объем прикладного кода, а также сильно понизит вероятность
случайных ошибок в прикладных программах за счет отделения стандартного, хорошо провереного кода
от прикладного, специфичного для данной задачи.
Предполагается, что "жизненный цикл" прикладного кода будут таким:
Прикладной программист решает частную задачу, располагая свой код в главном файле программы.
Постепенно становится ясно, что часть процедур и функций уже не меняются и могут быть
вынесены в включаемый файл в каталоге основной программы, чтобы сократить объем кода программы.
На следующем этапе становится ясно, что часть включаемых файлов являются общими для нескольких
программ. Их можно переместить в локальную библиотеку, включаемую в список каталогов поиска,
где они будут лежать, не мешая дальнейшей разработке и в определенной мере имея защиту
от непреднамеренного изменения. В качестве стандартного хранилища локальных библиотек
предлагается использовать каталог Utility\Include в каталоге текущей DAQ системы.
Наконец, библиотеки, часто используемые в многих проектах, могут быть перенесены в системный
каталог, расположенный в дистрибутиве CRW-DAQ, получив статус стандартной библиотеки.
Таким образом каждый прикладной программист может внести вклад в разработку пакета, создав
полезную прикладную библиотеку.
Стандартные библиотеки особенно важны в связи с планами активного внедрения Web - технологий.
Прикладной код Web - сервера довольно громоздкий. Теперь это уже неважно - большая часть этого
кода уйдет в библиотеки. Прикладному программисту будет достаточно освоить использование
набора готовых функций.
Практически невозможно "за один присест" вытащить из огромного числа прикладных систем все полезные
функции для стандартной библиотеки. Поэтому библиотека будет расширяться постепенно, этот процесс
требует обсуждения со всеми разработчиками. Надо учитывать, что чрезмерное раздувание библиотеки
приведет к замедлению загрузки за счет компиляции большого числа неиспользуемых процедур.
Правда, избыточность кода можно сократить, если включать в программу только нужные библиотеки.
Но это усложняет проблему ее конфигурирования.
В настоящее время компиляция всей библиотеки занимает около 500 мс на CPU 2.5 GHz.
Время сильно сокращается, если включать в программу только нужные файлы,
ведь в каждой задаче используется только часть функций.
Проще всего скопировать полный список всех включений из шаблона, а затем закомментировать (//)
то что не нужно в данной задаче.
Если, конечно, время загрузки критично.
Справедливости ради надо сказать, что время компиляции программ составляет лишь небольшую часть
времени загрузки, так как основное время уходит на чтение когнфигураций, создание окон и объектов и т.д.
При использовании стандартной библиотеки модули Errors, Strings, Console,
Devices, Tags можно считать обязательными - они нужны почти всегда.
Прочие модули - зависит от задачи. С учетом зависимостей между модулями,
порядок включения нарушать не следует - придерживайтесь шаблона.
При использовании включаемых файлов надо быть особенно внимательным в процессе разработки.
Изменение включаемого файла может изменить поведение сразу нескольких программ, причем
пока вы работаете с одной программой (перекомпилируете), остальные программы все еще используют
старый код. Только перезагрузка конфигурации (или перекомпиляция всех работающих прикладных программ)
гарантирует, что внесенные изменения коснулись всех программ. Это надо помнить и придерживаться
определенной дисциплины при разработке. Изменил включаемый файл - перезагрузи конфигурацию.
В качестве испытательного полигона для проверки стандартной библиотеки взята
конфигурация DEMO_RDMS, в ней переделаны CGI и GUI.
Процесс замены шел просто: берем из шаблона блоки включаемого кода, копируем в прикладную программу.
Потом компилируем. Программа выдает сообщение об ошибке (попытка повторного определения имен).
Вычищаем ставшие "лишними" константы, переменные и функции, пока компиляция не пройдет успешно.
Не забываем включить Init/Free в нужных местах. Это все. После замены все должно работать как раньше.
Для оптимизации времени загрузки можно поудалять ненужные модули (проще всего путем комментирования).
Вся процедура занимает несколько минут.
Исправлена небольшая ошибка в &CronSrv (в команде @cron.del).
В сервере также реализован режим непотопляемости.
Это для систем повышенной надежности - программа управления автоматом перезапустится, если внезапно "упадет".
Надо только правильно сконфигурировать DAQ-систему: включить автозагрузку и автостарт измерительной
конфигурации и правильно запустить "сторож" через стартовую секцию &CronSrv. Конфигурация же
для случая "непотопляемой" программы должна автоматом загружать требуемый режим работы и параметры
из своего INI - файла. То есть непотопляемая программа должна помнить свое последнее рабочее
состояние. Работающий пример такого рода - AliPhosCool.
Добавлена свободно распространяемая утилитаnconvert.
В рамках пакета может применяться для формирования изображений для &WebSrv сервера,
сжатия изображений для посылки почтой через &EmlSrv и т.д.
Пример:
nconvert.exe -out gif demo.bmp - преобразовать demo.bmp в demo.gif
Добавлен сервер &CronSrv для планирования
периодических и календарных событий и создания заданий, работающих "по расписанию".
Этот мощнейший по своим возможностям сервер имеет весьма большие перспективы - предполагается,
что он будет работать в составе практически ВСЕХ систем, как стандартный компонент, позволяющий
унифицировать прикладные программы. В частности, унифицируется генерация событий в календарном и
линейном времени, создание стартовых и завершающих скриптов, работа с окнами, завершение работы
системы (shutdown), обслуживание дисков и файловых массивов данных (резервное копирование, чистка, сжатие).
Одной из целей создание сервера является подготовка инструментария для создания "умных" систем, которые
сами себя обслуживают - дефрагментируют и чистят диски, копируют файлы данных на сервер и сжимают их,
завершают работу или генерируют автоматические отчеты в заданное время суток, и так далее.
Имеется подробное описание &CronSrv.htm
и примеры 1,
2.
Поэтому здесь только маленький пример для иллюстрации:
;---Включить сервер &CronSrv в конфигурацию. Всего одна строчка!
[ConfigFileList]
ConfigFile = ~~\Resource\DaqSite\CronServer\CronSrv.cfg
[]
;---В стартовой секции сервера можно поместить описание заданий.
[&CronSrv.StartupScript]
;--- При старте спрятать ToolBar
@ShowMainToolBar 0
;--- При старте показать окно ГЛАВНАЯ КОНСОЛЬ и задать его положение
@WinShow ГЛАВНАЯ КОНСОЛЬ
@WinDraw ГЛАВНАЯ КОНСОЛЬ|Left=167|Top=0|Width=600|Height=317
@WinSelect ГЛАВНАЯ КОНСОЛЬ
;--- Каждое утро в 8:00 ударять в гонг и говорить приветствие
@Cron.tab DailyMorning 0 8
@Cron.job DaylyMorning @Voice Gong
@Cron.job DailyMorning @Speak Доброе утро, сейчас 8:00.
;--- В полдень каждое воскресенье запускать дефрагментацию системного диска
;--- в скрытом окне, с низким приоритетом, стандартной утилитой CronDefrag.bat
@Cron.tab Defrag 0 12 * * Sun
@Cron.job Defrag @IfNotProcessExists defrag.exe @Run /hide /lower CronDefrag.bat
;--- Создать задание, работающее в "импульсном" режиме (Pulser)
;--- Каждую секунду посылать сообщение @Update устройству &GUI
@Cron.tab UpdateGui 0 0 0
@Cron.pul UpdateGui 1000
@Cron.job UpdateGui @DevMsg &GUI @Update
;--- Создать задание, работающее 10 раз, с периодом 10 секунд
;--- Каждый раз посылать сообщение @Execute устройству &DEMO
@Cron.tab TenTimes 0 0 0
@Cron.pul TenTimes 10000 10
@Cron.job TenTimes @DevSend &DEMO @Execute
[]
;--- Завершающая секция сервера вызывается при остановке системы.
[&CronSrv.FinallyScript]
;--- При завершении работы снова показать ToolBar
@ShowMainToolBar 1
;--- При завершении работы показать окно ГЛАВНАЯ КОНСОЛЬ и задать его положение
@WinShow ГЛАВНАЯ КОНСОЛЬ
@WinDraw ГЛАВНАЯ КОНСОЛЬ|Left=367|Top=0|Width=600|Height=317
@WinSelect ГЛАВНАЯ КОНСОЛЬ
;--- При завершении работы убить процесс сервера имен DIM - DNS.EXE
@Pid kill dns.exe
[]
Добавлена демо конфигурация DEMO_CRON, чтобы проиллюстрировать
работу сервера &CronSrv.
Несмотря на трудности с изучением работы сервера, основным членам группы автоматизации настоятельно
рекомендуется изучить работу сервера - он, как предполагается, будет очень активно использоваться
при создании практически ВСЕХ новых систем, поскольку одной из главных его целей являнется унификация
действий, связанных с
временем,
календарем,
стартом и
завершением работы - а это будет
востребовано всегда.
К сожалению, приведенные в демо-конфигурации примеры
не очень "наглядны", в том смысле, что на экране мало что происходит.
Большинство действий происходит в фоновом режиме - как и должны происходить автоматические действия
по обслуживанию систем на реальных установках.
По этой причине примеры достаточно сложны и требуют для их понимания кропотливого изучения
текста конфигурации, а также консольного вывода и в ряде примеров - журнальных *.log файлов.
Вся работа по изучению примера и сервера &CronSrv может делаться в консольном режиме,
команды для проверки и изучения работы сервера подаются (при желании) через консоль &CronSrv,
там же отображается результат.
Часть сообщений можно увидеть в главной консоли - например, при работе команды @run.
Поскольку в демо-расписании есть достаточно редкие события (например, дефрагментация - раз в неделю),
то эти задания при тестировании (не ждать же неделю!) запускаются через команду @cron.run:
@cron.run defrag - запуск задания на дефрагментацию дисков
@cron.run backup - запуск задания на резервное копирование файлов данных
@cron.run packer - запуск задания на архивацию файлов данных через GZIP
@cron.run dimdns - запуск задания на запуск сервера имен DIM - DNS.EXE
@cron.run purger - запуск задания на чистку устаревших файлов данных
Большинство утилит и действий по обслуживанию системы являются "скрытыми" - например,
при дефрагментации в скрытом окне запускается процесс defrag.exe.
Поэтому для анализа работы этих утилит надо смотреть вывод в консоль &CronSrv,
а также изучать журнальные файлы, создаваемые в каталоге Crw32exe\Temp.
Расширен набор шаблонов редактирования для DaqPascal.
Добавлена демо конфигурация DEMO_HVSS, чтобы проиллюстрировать
и зафиксировать некоторые новые приемы создания систем. Одной из особенностей этой системы является
продвинутый симулятор, который эмулирует работу с высоковольтными источниками Spellman.
За счет перенаправления COM-порта в канал (pipe) удалось выполнить симулятор как имитатор реального
устройства, подключенного к COM-порту. Драйвер устройства запускается как в рабочем режиме, так и в
режиме симуляции, и он "не знает", с чем он работает - с реальным устройством, или с имитатором.
Систему также отличает довольно тщательная проработка интерфейса - можно использовать как шаблон.
Имеется краткое описание - hvss.htm.
21.12.2010 ... 25.12.2010
ParamStr ToolBarKey DEMO_GNUPLOT
Добавлено множество новых возможностей в функцию ParamStr.
Наиболее важные для практики добавления:
ParamStr('System Process ID') - идентификатор текущего процесса
ParamStr('System Process ParentID') - идентификатор родительского процесса
ParamStr('System Process ParentExe') - имя файла родительского процесса
ParamStr('System Process AllocMemCount') - счетчик числа захваченных блоков памяти
ParamStr('System Process AllocMemSize') - счетчик объема захваченной памяти, байт
ParamStr('System Process GdiObjects') - счетчик ресурсов GDI (графические объекты - картинки, кисти, фонты и т.д.)
ParamStr('System Process UserObjects') - счетчик ресурсов USER (окна, курсоры, меню и т.д.)
ParamStr('System Process KernelObjects') - счетчик объектов ядра KERNEL (файлы, потоки, мютексы и т.д.)
ParamStr('System Process GdiObjectsQuota') - квота на число ресурсов GDI, которые можно захватить
ParamStr('System Process UserObjectsQuota') - квота на число ресурсов USER, которые можно захватить
ParamStr('System Process KernelObjectsQuota') - квота на число объектов ядра KERNEL, которые можно захватить
ParamStr('System Process Times') - список временных параметров процесса и потока
Эти добавления позволят следить за использованием ресурсов и работать с процессами.
В монитор ресурсов добавлено отображение счетчиков ресурсов GDI, USER, KERNEL.
Эти счетчики после загрузки конфигурации должны застабилизироваться.
Постоянный рост счетчиков коворит об "утечке ресурсов", что является серьезной проблемой программы.
Контроль ресурсов поможет сделать работу программы еще стабильнее, особенно при длительной круглосуточной эксплуатации,
так как позволит диагностировать трудно поддающиеся анализу ошибки работы с ресурсами,.
Сенсорные кнопки ToolBarKey сделаны динамическими,
то есть они теперь отображают состояние ассоциированного тега или кривой.
Сенсорные кнопки по прежнему имеют ряд ограничений.
Но теперь есть возможность индикации логических состояний прямо в ToolBar.
Модифицирована демо конфигурация DEMO_GNUPLOT, чтобы проиллюстрировать новые введенные возможности.
Видимо, это последняя версия в этом году. А потому: Всех с Новым 2011 Годом. И с Рождеством Христовым!
Долгожданное событие - "выход из подполья".
Подготовка и защита кандидатской диссертации заняла почти 2 года.
На это время развитие проекта было "заморожено". Сейчас работы по его развитию возобновляются.
Добавлена конфигурация DEMO_OPC, содержащая OPC-клиент общего назначения.
Этот клиент позволяет использовать драйверы фирменных устройств, поставляемых с различным оборудованием, выполненные
в виде OPC серверов. Конечно, клиентская программа должна будет объявить теги, сконфигурировать OPC-клиент и т.д.
Но все же это не потребует написания специального OPC-клиента. Это позволяет, в принципе, подключать к пакету
огромный перечень устройств, имеющих фирменные OPC-сервера, что значительно расширяет возможности пакета.
К недостатку данной версии OPC-клиента следует отнести его невысокую производительность - он не позволяет
"прокачать" больше нескольких тысяч OPC-тегов в секунду.
По драйверной программе есть подробный Help.
Следует учесть, что для работы демонстрационной версии OPC-клиента требуется установка тестового
OPC-сервера GrayBox, расположенного в DEMO_OPC/Utility.
Добавлена конфигурация DEMO_E140 с драйвером 16/32-канального,
14-битного, 100 кГц-вого АЦП типа E14-140
производства L CARD.
По драйверной программе есть подробный Help.
Есть также черновик статьи с описанием принципов работы
построения отказоустойчивых программ быстрого сбора данных на основе каналов и общей памяти.
Предполагается, что эта программа послужит прототипом для целого класса систем быстрого сбора данных.
Следует заметить, что для тестирования этой программы без реального оборудования имеется режим симулятора.
Добавлено множество новых возможностей в функцию ParamStr.
Наиболее важные для практики добавления:
ParamStr('System Metrics SM_CXSCREEN') - ширина экрана
ParamStr('System Metrics SM_CYSCREEN') - высота экрана
ParamStr('System Metrics SM_CXFULLSCREEN') - ширина окна в полноэкранном режиме
ParamStr('System Metrics SM_CYFULLSCREEN') - высота окна в полноэкранном режиме
ParamStr('System Metrics SM_CXMINIMIZED') - ширина минимизированного окна
ParamStr('System Metrics SM_CYMINIMIZED') - высота минимизированного окна
ParamStr('System Metrics SM_CXMAXIMIZED') - ширина максимизированного окна
ParamStr('System Metrics SM_CYMAXIMIZED') - высота максимизированного окна
ParamStr('System Metrics SM_XVIRTUALSCREEN') - координата X Рабочего Стола
ParamStr('System Metrics SM_YVIRTUALSCREEN') - координата Y Рабочего Стола
ParamStr('System Metrics SM_CXVIRTUALSCREEN') - ширина Рабочего Стола
ParamStr('System Metrics SM_CYVIRTUALSCREEN') - высота Рабочего Стола
ParamStr('System Metrics SM_CMOUSEBUTTONS') - число кнопок мыши или 0 если нет мыши
Эти добавления позволят правильно вычислять требуемые размеры окон при организации интерфейса пользователя.
Добавлено множество новых возможностей в функцию WinDraw.
Наиболее важные для практики добавления: фиксация положения окон, скроллинг мнемосхем,
работа с панелью команд ToolBar.
Краткая сводка новых возможностей:
// Фиксация положения окон:
b:=windraw('DemoPlot|Left=0|Options=-Left'); // Задать и зафиксировать горизонтальное положение окна
b:=windraw('DemoPlot|Top=50|Options=-Top'); // Задать и зафиксировать вертикальное положение окна
// Скроллинг мнемосхем:
b:=windraw('DemoPlot|Scroll=100;*'); // Установить горизонтальный сдвиг 100, вертикальный не менять
b:=windraw('DemoPlot|Scroll=*;150'); // Установить вертикальный сдвиг 150, горизонтальный не менять
b:=windraw('DemoPlot|Scroll=100;50'); // Установить горизонтальный сдвиг 100, вертикальный 150
b:=windraw('DemoPlot|Scroll=xmin;ymin'); // Сдвинуться в левый верхний угол (это начальное положение)
b:=windraw('DemoPlot|Scroll=xmin;ymax'); // Сдвинуться в левый нижний угол (пролистать вниз до конца)
b:=windraw('DemoPlot|Scroll=xmax;ymin'); // Сдвинуться в правый верхний угол (пролистать вправо до конца)
b:=windraw('DemoPlot|Scroll=xmax;ymax'); // Сдвинуться в правый нижний угол (пролистать вниз и вправо)
b:=windraw('DemoPlot|Scroll=xpos+10;ypos+20'); // Сдвинуться на 10 пикселей вправо и на 20 вниз
// Панель кнопок мнемосхем:
b:=windraw('DemoPlot|ToolBarHeight=0'); // Спрятать панель команд ToolBar
b:=windraw('DemoPlot|ToolBarHeight=1'); // Показать панель команд ToolBar стандартной высоты
b:=windraw('DemoPlot|ToolBarHeight=2'); // Показать панель команд ToolBar двойной высоты
b:=windraw('DemoPlot|ToolBarHeight=3'); // Показать панель команд ToolBar тройной высоты
b:=windraw('DemoPlot|ToolBarHeight=4'); // Показать панель команд ToolBar четверной высоты
b:=windraw('DemoPlot|ToolBarHeight=64'); // Показать панель команд ToolBar заданной высоты в пикселях
В меню Вид (View) для всех окон добавлены команды для фиксации положения и размера окон
(Ctrl+Alt+L, Ctrl+Alt+T, Ctrl+Alt+W, Ctrl+Alt+H).
В меню Вид (View) окон мнемосхем добавлены команды для прокрутки изображения (Shift+Стрелка),
а также показа и скрытия скроллеров (Ctrl+Alt+Z, Ctrl+Alt+V).
Добавлены новые возможности в мнемосхемы, связанные с панелью команд ToolBar в верхней части окна.
Эти возможности ориентированы на сенсорные экраны и экраны небольшого размера, на которых большие мнемосхемы не умещаются.
Чтобы работать с мнемосхемами в этих условиях, необходимо либо "разбивать" большую мнемосхему на несколько малых,
либо обеспечить удобный "скроллинг" с крупными кнопками и небольшим числом действий для достижения требуемого обзора.
Кроме того, при скроллинге часть наиболее важных команд должна быть доступна всегда, иначе требуемые команды придется постоянно искать.
Панель команд ToolBar снимает эти проблемы, по крайней мере частично.
Для сохранения обратной совместимости панель команд ToolBar по умолчанию спрятана и не видна на экране.
Её можно активизировать несколькими способами:
Переменной ToolBarHeight в секции [Circuit] в файле *.CRC описания мнемосхемы.
Переменной ToolBarHeight в секции описания мнемосхемы в файле *.CFG.
Во всех случаях переменная ToolBarHeight задает высоту панели команд, причем при значении 0 панель скрывается,
при значении 1..4 высота задается в единицах стандартной высоты (составляющей около 30 пикселей), а при других значениях высота задается в пикселях.
При этом высота панели команд не может быть меньше стандартной.
На панели всегда присутствует по меньшей мере четыре кнопки:
,
,
,
.
Они служат для быстрого сдвига изображения (скроллинга) в окне.
Эти кнопки, соответствующие также клавиатурным макросам Shift+Стрелка, работают даже если в окне спрятаны полосы прокрутки ScrollBar.
При этом сдвиг происходит примерно на 3/4 размера окна, так что для поиска нужного места мнемосхемы требуется немного операций перемещения.
Например, если размер изображения не на много больше размера окна, в любое место изображения можно попасть не более чем за две операции скроллинга.
Эти кнопки перемещения полезны потому, что полосы прокрутки плохо приспособлены к работе с сенсорным экраном.
Полосы прокрутки слишком малы и в них трудно попасть пальцем. Кнопки стрелок с помощью ToolBarHeight могут быть сделаны весьма крупными,
что удобно для работы с помощью сенсорных экранов. Заметим, к слову, что управление размером панели команд можно делать также с помощью
клавиатурных макросов Ctrl+Alt+0, Ctrl+Alt+1, Ctrl+Alt+2, Ctrl+Alt+3, Ctrl+Alt+4.
Панель команд очень хорошо дополняется вызовами ParamStr('System Metrics SM_CXSCREEN'), ParamStr('System Metrics SM_CYSCREEN')
для определения размера экрана. С их помощью можно, например, сделать программу, которая автоматически адаптируется к размеру экрана.
Если, например, экран имеет большой размер, мнемосхема "распахивается полностью", а панель команд прячется, так как скроллинг в этом случае не нужен.
Если экран маленький, устанавливается небольшой размер окна и мнемосхема отображается не полностью, а "кусками", при этом кнопки перемещения
на панели команд позволяют с помощью небольшого числа сенсорных операций показывать любую часть мнемосхемы.
Таким образом, скроллинг с помощью панели команд решает проблему больших мнемосхем на малых экранах.
Другим новшеством, связанным с панелью команд ToolBar, являются сенсорные кнопки.
Это делается с помощью переменной ToolBarKey при описании сенсора.
Ненулевое значение ToolBarKey помещает сенсор в кнопку на панели команд ToolBar, а при нажатии на кнопку
генерируется нажатие этого сенсора с заданным кодом ClickButton.
Полезным свойством сенсорных кнопок является то, что они имеют постоянное положение и видны всегда, независимо от скроллинга.
Более того, иногда есть смысл делать сенсорные кнопки видными только на панели команд.
Для этого достаточно задать координаты Pos за пределами экрана.
В настоящее время сенсорные кнопки имеют ряд ограничений.
Например, они статичны (не зависят от состояния тега), не могут иметь большой размер изображения, и так далее.
Это несколько ограничивает их применимость, но, в конце концов, панель ToolBar все же ориентируется на статические команды, а не на индикаторы.
[Circuit] ; Описание основного поля мнемосхемы
GeneralMap = ..\BITMAPS\SINWAVE.BMP ; Ссылка на основное изображение
Hint = Демонстрационный пример ; Подсказка при наведении мыши
ToolBarHeight = 3 ; Установка размера ToolBar, в данном случае тройной размер
[SensorList] ; Описание сенсоров:
Sensor = TOOL_START ; Объявление сенсора - кнопки на панели команд ToolBar
[TOOL_START] ; Секция описания сенсора
Pos = 10000, 10000 ; Pos задан за пределами экрана, поэтому кнопку видно только в ToolBar
Tag#1 = 0, ..\BITMAPS\TOOL_START.BMP ; Изображение кнопки
Hint = Кнопка СТАРТ на панели ToolBar ; Подсказка при наведении мыши
ToolBarKey = 1 ; Помещает сенсор в ToolBar и имитирует нажатие левой кнопки мыши
[]
Хочется надеется, что введенные средства окажутся полезными и решат проблему больших мнемосхем на небольших сенсорных экранах раз и навсегда.
Модифицирована демо конфигурация DEMO_GNUPLOT, чтобы проиллюстрировать новые введенные возможности.
Например, вызов demoplot.pas
иллюстрируют фиксацию положения окон и задание размера панели команд ToolBar.
Процедура PrintMostParamStr, занесенная, кстати, в библиотеку шаблонов, иллюстрирует работу функции ParamStr.
Файлы demoplot.cfg,
demoplot.crc
иллюстрируют создание мнемосхем с панелью команд и сенсорных кнопок на ней.
Добавлена конфигурация DEMO_EC3X32 - драйвер для контроллера терморегулирующего вентиля EC3X32 фирмы ALCO.
Этот драйвер может служить прототипом устройств со связью по TCP\IP.
Все вопросы Алексею Курякину.
Добавлена конфигурация DEMO_BSPP - драйвер для регистраторов НТП "Доза" с протоколом DiBUS на RS-232.
Все вопросы Алексею Вьюшину.
Добавлена конфигурация DEMO_BUK - драйвер для БУК (блока управления клапанами) на RS-232.
Все вопросы Виноградову Ю.И..
Добавлена конфигурация DEMO_TV551 - драйвер для турбомолекулярного насоса фирмы VARIAN.
Все вопросы Алексею Вьюшину.
Существенно переработан инсталлятор.
Пункты компонентов идут не одним списком, а сгруппирован по темам.
В дистрибутив добавлен свободный компилятор Tiny C Compiler,
взятый с сайта http://www.bellard.org/tcc/, есть документация.
Это очень простой, очень маленький и очень быстрый компилятор C c открытым кодом, который, возможно,
будет использован для создания мелких консольных утилит и драйверов.
Он поддерживается для Windows и Linux.
Экстремально высокая скорость компиляции и специальные средства в стиле Sha-Bang позволяют использовать компилятор как скриптовый интерпретатор языка C,
так как можно после компиляции сразу запускать программу:
Файл demo.bat:
@tcc\tcc -Itcc\include -Ltcc\lib -run demo.c "Hello world 1." "Hello world 2."
Файл demo.с:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int i;
for (i=0; i < argc; i++ ) printf("%s\n",argv[i]);
return 0;
}
Результат:
demo.c
Hello world 1.
Hello world 2.
При этом компилятор "на лету" создает программный код и сразу же исполняет его.
В таком стиле можно создавать довольно сложные скрипты, сочетая возможности командного интерпретатора и языка C,
если, например, в скрипте требуются вызовы специальных функций WinApi.
В будущем планируется добавление языка C в число стандартных средств CRW-DAQ, включая редактор и компилятор.
В дистрибутив добавлены библиотеки JavaScript, которые будут использоваться для создания
динамических WEB страниц.
В дистрибутив добавлен симпатичный конвертер физических единиц UnitConverter,
который доступен через команду @run UnitConverter.htm.
Конвертер работает через Web, реализован на JaveScript, что делает его доступным для редактирования и расширения.
Что я и проверил, добавив перевод единиц радиоактивности.
Так что по просьбе трудящихся можно будет добавить в конвертер часто используемые единицы.
Добавлена программа sendEmail для посылки писем по электронной почте.
Описание здесь.
Её можно использовать в главной консоли примерно в таком духе:
@run sendemail -f admilink@mail.ru -t akuryaki@cern.ch -u "Test subject" -s smtp.mail.ru:25 -xu admilink -xp *** -m "Hello, it is test."
Добавлен сервер почтовых рассылок &EmlSrv
для посылки писем по электронной почте из программ DaqPascal.
Это может оказаться полезным для круглосуточно работающих установок, чтобы оповещать экспертов
о критических событиях в системе управления по почте.
Обновлена демо конфигурация DEMO_ALIPHOSCOOL.
Фактически это конфиграция реального модуля на 2009, только с симулятором и без документации.
Рассылка email в коде присутствует, но отключена.
В набор утилит введен gnuplot,
домашний сайт gnuplot.sourceforge.net
(смотри также 1,
2,
3,
4).
Это утилита для постоения графиков для научных приложений, многоплатформенная и позволяющая
работать в пакетном режиме.
Это одна из широко распространенных в Unix утилит, распространяемая с исходными кодами.
Для нас важно то, что она позволяет строить графики "вслепую", то есть без мелькания лишних
окошек на экране.
Поэтому она может применяться в следующих случаях:
Для генерации отчетов. По кнопке генерируется HTML, со ссылкой на график в GIF-файле,
который генерируется вызовом gnuplot.
Для реализации графики в WEB сервере. Принцип тот же - прямая генерация графиков в файл.
Рисование графиков прямо на мнемосхемах. График генерирует gnuplot и записывает в файл,
а мнемосхема обновляется вызовом WinDraw('window|Reload=sensor').
Добавлен новый сервер &PlotSrv
(тут).
Он позволяет рисовать с помощью GNUPLOT из-под DaqPascal.
Работает это так.
В конфигурационный файл заносим:
;****************************************************************
;*** Standard &PlotSrv - GNUPLOT based server for science drawing
;****************************************************************
[ConfigFileList]
ConfigFile = ~~\Resource\DaqSite\PlotServer\PlotSrv.cfg
[]
Клиентский вызов со стороны устройства &Client для рисования кривых
с именами Curve1, Curve2 в файл Plot.bmp
будет выглядеть примено так:
b:=PlotSend('@Clear'+CRLF+'@TimeOut 5000'+CRLF+'@HomeDir ..\Temp'+CRLF
+'@DoneMsg &Client @Done ..\Bitmaps\plot.bmp'+CRLF
+'@FailMsg &Client @Fail ..\Bitmaps\plot.bmp'+CRLF
+'@CurveList Curve1, Curve2'+CRLF
+'@> set encoding koi8r; set grid; set key left top'+CRLF
+'@> set terminal gif small size 500,400 font "luconk,8"; set output "plot.gif"'+CRLF
+'@> set title "'+Win2Koi('Заголовок')+'" font "luconk,8"'+CRLF
+'@> set xlabel "'+Win2Koi('Надпись на оси Х')+'" font "luconk,8"'+CRLF
+'@> set ylabel "'+Win2Koi('Надпись на оси Y')+'" font "luconk,8"'+CRLF
+'@> plot "plot.dat" index 0 using 1:2 with linespoints ti "Легенда Curve1",\'+CRLF
+'@> "plot.dat" index 1 using 1:2 with linespoints ti "Легенда Curve2"'+CRLF
+'@! call gif2bmp plot.gif ..\Bitmaps\plot.bmp'+CRLF
+'@run plot.job plot.dat plot.bat'+CRLF)>0;
Важно, что все задание передается серверу одной длинной строкой, разделенной на строки CRLF.
Это гарантирует, что сообщение будет помещено в очередь сервера целиком, а не по частям.
Это обеспечивает корректную работу в многопоточной среде, где клиенты могут одновременно
присылать задания. Если разбивать задание на несколько вызовов PlotSend,
то части разных клиентских заданий могут перемешаться.
Сначала делается очистка (@Clear), задается ограничение по времени выполнения (@TimeOut)
и указывается рабочий каталог (@HomeDir), в котором запускается GNUPLOT и где создаются
в процессе работы временные файлы plot.gif, plot.job, plot.dat, plot.bat.
Затем задаются сообщения, которые сервер пошлет клиенту после выполнения рисования для уведомления
клиента об успешном рисовании (@DoneMsg) или об ошибке (@FailMsg).
Затем серверу передается список кривых для рисования @CurveList.
Затем в конструкциях "@> text" передается текст задания для GNUPLOT.
Операторы в одной строке разделяются точкой с запятой ;,
а длинные операторы продолжаются на другой строке с помощью обратного слеша \.
Команда set encoding koi8r задает русскую кодировку. Потом задаются разные опции рисования.
Команда set terminal gif ... определяет, что рисование будет делаться в GIF файл
(заданного размера, заданным фонтом).
Протом задается заголовок set title и метки set xlabel, set ylabel по осям.
При этом используется функция Win2Koi для преобразования русского текста в нужную кодировку.
Потом вызывается рисование графика plot "plot.dat" index 0 ....
Оператору рисования сообщается, что для рисования используется временный файл plot.dat,
index задает номер кривой, как в списке @CurveList.
Конструкция @! call gif2bmp plot.gif ..\Bitmaps\plot.bmp задает фильтр,
то есть командный файл, запускаемый после завершения GNUPLOT.
В данном случае фильтр преобразует файл GIF в формат BMP.
Оператор @run plot.job plot.dat plot.bat запускает задание на исполнение.
Перед запуском текст задания сохраняется во временный файл plot.job,
кривые сохраняются во временный файл plot.dat, а команды фильтра - в файл plot.bat.
Результатом работы является файл ..\Bitmaps\plot.bmp.
В конце работы сервер посылает клиенту уведомление (@DoneMsg или @FailMsg).
После получения уведомления "@Done ..\Bitmaps\plot.bmp" клиент может использовать
полученный файл для дальнейшей работы.
Например, файл может использоваться для перерисовки сенсора мнемосхемы с помощью
функции WinDraw('WindowName|Reload=SensorName').
Предполагается, что сенсор использует для отображения данный файл (..\Bitmaps\plot.bmp).
Или, например, можно использовать данный файл для генерации HTML - отчета,
или для динамической WEB-страницы.
Добавлена демо конфигурация DEMO_GNUPLOT
(тут).
Она собственно иллюстрирует возможности сервера &PlotSrv и GNUPLOT.
Расширен список консольных команд, доступных через меню Инструменты\Консольные утилиты.
Введена команда Инструменты\GNUPLOT для быстрого вызова пакета
GNUPLOT.
Добавилось несколько функций в библиотеку шаблонов редактора:
Win2Koi (преобразование русских кодировок),
GetMidnight (вычисление полуночи),
PlotSend (посылка задания серверу &PlotSrv),
RunStartupScript (выполнение команд при старте устройства).
Внесенная в шаблон функция RunStartupScript требует комментария.
Часто бывает необходимо выполнять какие-то команды при старте системы.
Иногда это бывает возможно сделать с помощью посылки сообщений устройствам.
Функция это и делает. Ее надо вставить в стартовую часть программы.
В секцию устройства надо вставить что-то вроде
[DeviceList]
&Demo = device software program
[&Demo]
...
StartupScript=[&Demo.StartupScript]
...
[]
[&Demo.StartupScript]
@Command 1 ; Посылка команды самому себе (признак - 1-й символ @)
@Command 2
&SpeakSrv @Speak Привет ; Посылка команды другому устройству (признак - 1-й символ &)
...
[]
Поскольку программа может сама генерировать ini-файлы, ссылку на которые можно включить
в конфигурацию, можно таким образом делать динамическую настройку старта программы.
Например, через стартовые сообщения можно приводить систему в заранее сохраненное состояние.
Обновлен DimServer. Суть изменений в том, что теперь список тегов и сервисов индексируется,
сортируется и для доступа к тегам применяется быстрый двоичный поиск.
С пользовательской точки зрения это должно дать значительное снижение загрузки процессора
при большом числе публикуемых DIM тегов.
Отключить сортировку и быстрый поиск можно переменной NoUseSorting=1.
Использование переменных NoCheckSort=1, NoCheckFind=1 отключает проверку сортировки
и поиска при старте и может ускорить загрузку конфигурации DIM на слабых машинах.
На примере RDMS с большим чмслом каналов показано, что загрузка процессора действительно
существенно снижается (в 5-10 раз).
В пакет добавлена библиотека, включающая большое число консольных утилит на всякий полезный случай.
Список наиболее полезных утилит находится здесь.
Штатный набор утилит может использоваться двумя путями: через консольную команду @run,
а также путем вызова из программ DaqPascal. Это позволяет решать множество проблем
без ввода новых функций языка программирования, за счет вызова утилит в виде отдельных
исполняемых файлов.
Поскольку утилит много и набор их будет расширяться, предприняты меры для облегчения использования
утилит, заключающиеся в первую очередь в функциях поиска. Во-первых, наиболее значимые утилиты
внесены в секцию [@run] основного конфигурационного файла и могут быть найдены через нее.
Однако это не очень удобно и к тому же мало пригодно для использования в дочерних процессах,
запускаемых из-под CRW-DAQ. Поэтому все каталоги утилит вносятся в переменную окружения
CRW_DAQ_SYS_PATH и используются в функциях поиска, как описано далее.
В список переменных окружения при запуске пакета,
а также при запуске конфигурации DAQ-системы добавлены, кроме прочих, две полезные переменные:
CRW_DAQ_SYS_PATH - содержит большой список каталогов, содержащих
консольные утилиты (смотри подробности ниже).
Этот список составляется при запуске пакета из путей всех утилит,
прописанных в секции [@run] основного конфигурационного файла.
CRW_DAQ_CONFIG_PATH - содержит список каталогов, создаваемый при загрузке
конфигурации DAQ-системы и включающий путь основного конфигурационного файла,
а также путей из списка SearchPath,
заданных в секции [DAQ].
Следует учитывать, что при завершении конфигурации переменная CRW_DAQ_CONFIG_PATH очищается.
Указанные переменные можно использовать несколькими путями:
Через команду @run.
Переменные окружения CRW_DAQ_CONFIG_PATH, CRW_DAQ_SYS_PATH, Path
используются для поиска программ при выполнении команды @run,
если для исполняемого файла не указан полный путь,
поэтому можно выполнять программы через короткие команды, например:
--Создание общего каталога командой rmtshare.exe:
@run rmtshare.exe \\.\postbox=c:\Postbox /REMARK "Почтовый ящик" /GRANT Все:"FULL CONTROL"
--Вызов утилиты DIMTree.exe:
@run dimtree
Команда @run находит требуемый исполняемый файл, используя указанные выше переменные окружения.
Команда @run описана подробнее ниже.
s:=ParamStr('FileSearch rmtshare.exe'); // Поиск в Path,CRW_DAQ_SYS_PATH,CRW_DAQ_CONFIG_PATH
s:=ParamStr('FileSearch rmtshare.exe CRW_DAQ_SYS_PATH'); // Поиск только в пути CRW_DAQ_SYS_PATH
Найденный файл затем запускается функциями типа task_run.
Через использование в дочерних процессах, запускаемых из-под CRW_DAQ.
Например, для поиска программы arj.exe в дочернем командном файле
можно использовать такие конструкции:
set arj=
rem -- Поиск утилиты arj.exe в CRW_DAQ_CONFIG_PATH
if "%arj%" == "" (for %%i in (arj.exe) do ( set arj=%%~CRW_DAQ_CONFIG_PATH:i))
rem -- Поиск утилиты arj.exe в CRW_DAQ_SYS_PATH, если не найдена
if "%arj%" == "" (for %%i in (arj.exe) do ( set arj=%%~CRW_DAQ_SYS_PATH:i))
rem -- Поиск утилиты arj.exe в Path, если не найдена
if "%arj%" == "" (for %%i in (arj.exe) do ( set arj=%%~Path:i))
rem -- Выполнение найденной команды
if "%arj%" == "" (echo ARJ.EXE не найдена) else (%arj%)
Другой вариант:
rem -- Включение списков каталогов в путь поиска
set path=%CRW_DAQ_CONFIG_PATH%;%CRW_DAQ_SYS_PATH%;%path%;
rem -- Выполнение команды
arj.exe
В секцию [DAQ] добавлен список путей поиска SearchPath,
например:
Эти пути добавляются в переменную окруженияCRW_DAQ_CONFIG_PATH, что делает файлы в этих каталогах доступными для команды
@run и функции ParamStr('FileSearch ...').
Добавление каталога dir в список поиска SearchPath эквивалентно вызову
функции ParamStr('AddSearchPath CRW_DAQ_CONFIG_PATH dir').
Изменилось поведение консольной команды @run.
Начальным каталогом запуска программ по умолчанию теперь является домашний каталог Crw32.exe.
Раньше это могло быть не так, ведь каталог запуска мог изменяться при смене текущего каталога
в диалогах открытия файлов. Это приводило к непредсказуемому поведению выполняемых команд.
Теперь можно быть уверенным, что запускаемые программы стартуют в домашнем каталоге.
Добавилась опция @run /cd dir cmd чтобы можно было изменять каталог dir
запуска программы cmd.
Если не указано полное имя исполняемого файла, происходит поиск исполняемого файла в каталогах,
указанных в переменных окружения CRW_DAQ_CONFIG_PATH, CRW_DAQ_SYS_PATH, Path.
То есть фактически все включенные в пакет утилиты можно вызывать по короткому имени, без указания пути.
Добавилась опция @run /path path cmd чтобы можно было изменять список переменных окружения
path, в которых заданы списки путей поиска программы cmd.
Элементы списка надо разделять плюсом.
По умолчанию используется список CRW_DAQ_CONFIG_PATH+CRW_DAQ_SYS_PATH+Path.
Если не указано расширение имени файла, оно ищется в соответствии со списком расширений, указанных
в переменной окружения PathExt. Обычно это что-то вроде .COM;.EXE;.BAT;.CMD;...
Опция @run /Idle cmd позволяет установить приоритет Idle запуска программы cmd.
Опция @run /Lower cmd позволяет установить приоритет Lower запуска программы cmd.
Опция @run /Normal cmd позволяет установить приоритет Normal запуска программы cmd.
Опция @run /High cmd позволяет установить приоритет High запуска программы cmd.
Опция @run /RealTime cmd позволяет установить приоритет RealTime запуска программы cmd.
Опция @run /Hide cmd позволяет установить скрытый (без окна) режим запуска программы cmd.
Опция @run /Term:opt cmd позволяет выполнять запуск программы cmd в режиме терминала
с опциями opt, такими же как в команде @term. В этом режиме стандартные потоки ввода-вывода
программы переназначаются в каналы и перенаправляются в консольное окно CRW-DAQ. Обычно бывают
нужны опции a (преобразование кодировок) и c (автоматическое закрытие окна консоли
после завершения программы).
Примеры:
@run c:\root\bin\root.exe --Запуск программы root.exe с полным путем
@run root.exe --Запуск с поиском в Path,CRW_DAQ_SYS_PATH,CRW_DAQ_CONFIG_PATH
@run /Path Path root.exe --Запуск с поиском в Path
@run root --Запуск программы с поиском в путях и расширениях
@run /cd c:\temp root --Запуск программы с указанием начального каталога
@run /Term:a cmd /c dir c:\ --Запуск команды DIR c:\ в терминальном окне
ParamStr('FileSearch file path') - поиск файла file в каталогах,
заданных списком path разделенных плюсом переменных окружения,
каждая из которых содержит список каталогов, разделенных точкой с запятой.
Имя файла должно быть коротким (без полного пути).
Если расширение файла не указано, то используются расширения из списка,
заданного в переменной окружения PathExt, в котором обычно содержится
что-то вроде PathExt=.COM;.EXE;.BAT;.CMD;.
Если список path не указан, то используется список по умолчанию, что эквивалентно
указанию path=CRW_DAQ_CONFIG_PATH+CRW_DAQ_SYS_PATH+Path.
ParamStr('AddSearchPath path dir') - добавление каталога dir в список путей,
содержащихся в переменной окружения path.
Например, вместо указания списка
SearchPath = c:\MyDirectory
в секции [DAQ] можно напрямую добавить нужный путь в программе вызовом типа ParamStr('AddSearchPath CRW_DAQ_CONFIG_PATH c:\MyDirectory').
ParamStr('RemSearchPath path dir') - удаление каталога dir из списка путей,
содержащихся в переменной окружения path.
Лучше всего объяснить на примерах:
s:=ParamStr('FileSearch root.exe'); --Поиск root.exe в CRW_DAQ_CONFIG_PATH,CRW_DAQ_SYS_PATH,Path
s:=ParamStr('FileSearch root.exe Path'); --Поиск root.exe в Path
s:=ParamStr('FileSearch root.exe CRW_DAQ_SYS_PATH+Path'); --Поиск root.exe в CRW_DAQ_SYS_PATH,Path
s:=ParamStr('AddSearchPath CRW_DAQ_CONFIG_PATH ..\Temp'); --Добавление каталога в список путей поиска
s:=ParamStr('RemSearchPath CRW_DAQ_CONFIG_PATH ..\Temp'); --Удаление каталога из списка путей поиска
Значительно изменен инсталлятор, он теперь включает красивое меню, которое появляется при вставке
CD-диска в привод компьютера.
Этот инсталлятор может также служить прототипом других инсталляторов для измерительных систем,
поставляемых заказчикам.
Добавилось несколько функций в библиотеку шаблонов редактора:
StrComp, StrIComp (сравнение строк),
Problem (отображение сообщений при нефатальных ошибках),
RmtShareExe (создание и удаление общих сетевых каталогов).
Внесены исправления в индексатор файлов.
Исправлена неточность, из-за которой файлы не показывали изображения в FireFox.
Теперь все должно работать, кажется.
Обновлены демо конфигурации
DEMO_RDMS,
DEMO_ASKRO33_RDMS.
Введена децимация (прореживание данных), генератор отчетов на базе Web-сервера,
решены вопросы автоматической публикации каталога данных в сети (утилита RmtShare.Exe).
Генератор отчетов сделан с использованием EXE-файла (написан на Delphi),
который читает *.DAT-файлы, что позволяет на его базе делать другие утилиты
анализа DAT-архивов.
Обновлен AdmiLink.
Устранена проблема с localhost в доменах. Раньше при указании в качестве домена
точки или localhost программа запускалась только если компьютер в рабочей группе,
а в домене надо было обязательно указывать или имя домена (для входа под пользователем домена)
или конкретное имя компьютера (для входа под локальным пользователем компьютера).
Теперь точка и localhost должны работать также и в домене. Это позволяет делать
переносимые ярлыки для одинаковых локальных пользователей на компьютерах, находящихся в домене.
Введены опции AdmiRun для
использования AdmiRun в пакетном режиме.
Введены дополнительные опции -d0, -d1, ... -d10 запуска приложения в различных
состояниях окна, например спрятанном (Hide=-d0), нормальном (Show=-d1),
свернутом (Minimize=-d2) и распахнутом (Maximize=-d3) виде, и т.д.
Эти опции доступны в AdmiLink в поле "Способ отображения (Режим ShowWindow)".
Введена команда Инструменты\ROOT (CERN) для вызова пакета ROOT.
Этот пакет разработан в CERN и служит для обработки данных, в первую очередь в области
ядерной физики и физики элементарных частиц. В дальнейшем планируется более полная интеграция
CRW-DAQ и ROOT, чтобы можно было обрабатывать измеренные в CRW-DAQ данные
с помощью пакета ROOT.
А пока сделана только простая связка - вызов ROOT из среды CRW-DAQ.
Обновлен DimServer. Суть изменений в том, что теперь dns.exe копируется и запускается
в общем каталоге %CommonProgramFiles%\CRW-DAQ\.... Поэтому каталог программы не блокируется,
даже если dns.exe остается работающим после завершения программы.
На работе DIM это проявляться не должно, просто теперь можно не "убивать" dns.exe
(а это можно сделать только вручную, так как dns.exe запускается без окна)
когда требуется переинсталляция пакета CRW-DAQ.
Добавлен сервер &VkbdSrv.
Это мнемосхема для редактирования тегов в случае использования сенсорных экранов,
когда клавиатура и мышь отсутствует, а точность попадания пальцем в экран ограничена
толщиной пальца и точностью калибровки сенсорного экрана.
Поэтому в диалоге большие кнопки и ориентация на мышь, так как сенсорные экраны проецируются
на мышь - при нажатии экрана в месте нажатия эмулируется щелчек мыши.
Добавлена демо конфигурация DEMO_VKBD.
Она содержит пример использования виртуальной клавиатуры для редактирования
тегов с использованием сенсорных экранов.
Добавилось несколько шаблонов функций DaqPascal в редакторе.
Например, SkipWords, TagAsText, VkbdSend, VkbdEditTag,
ReverseString, XorCheckSum.
Обновлена демо конфигурация DEMO_ALIPHOSCOOL.
Фактически это конфиграция реального модуля на 20080923, только с симулятором и без документации.
Добавлена демо конфигурация DEMO_HART.
Это прототип драйвера для устройств с протоколом обмена HART.
Имеется краткое описание.
Свободный файловый менеджер хорош тем, что будет всегда под рукой, если установлен CRW-DAQ.
Значительная часть документации переведена в более компактный формат djvu.
Кроме того, убрана часть ненужной документации по Delphi.
Это позволило освободить значительное место для программ и конфигураций.
В сборку TotalCommanderExtra добавлено много свободных программных пакетов, в частности
FireFox - рекомендуемый Web браузер с набором дополнений
WinDjvu - рекомендуемый обозреватель файлов .djvu, доступен в ToolBar
Burn4Free - рекомендуемый прожигатель CD\DVD
XP Tweaker - рекомендуемый настройщик параметров системы, доступен в дополнительном ToolBar
Из-за низкой защищенности Internet Explorer рекомендуется переход на FireFox.
Однако FireFox имеет некоторые особенности, общепринятые в Unix, но непривычные для Windows.
Дело в том, что FireFox более строго следует стандартам HTML.
В частности, усиливаются требования к именам и ссылкам.
Ссылки на локальные файлы при вызове из DAQ-программ и скриптов рекомендуется передавать
с префиксом file:///, подобно тому как ссылки Internet записываются
с префиксом http://.
Например, вместо c:\crw32exe\resource\manual\crw-daq.htm лучше написать
file:///c:\crw32exe\resource\manual\crw-daq.htm.
Кстати, Internet Explorer тоже прекрасно понимает такую запись.
Однако для FireFox, в отличие от IE, это правило следует считать обязательным,
особенно если ссылка указывает не только файл, но и раздел, например,
file:///c:\crw32exe\resource\manual\DaqPascalApi.htm#runcount.
При указании относительных ссылок на разделы документов типа file#chapter
регистр раздела #chapter играет роль.
Например, ссылка file:///c:\crw32exe\resource\manual\DaqPascalApi.htm#RunCount
не сработает, правильной ссылкой будет
file:///c:\crw32exe\resource\manual\DaqPascalApi.htm#runcount.
Для Internet Explorer регистр не играет роли ни в именах файлов, ни в ссылках.
Возможно, при переходе на FireFox появятся неработающие ссылки, так как
при создании документов правильность регистра ссылок специально не проверялась.
Просьба сообщать о таких ссылках, будем исправлять...
Изменения в команде @open:
добавлены возможности редактирования свойств DAQ-устройств.
Например:
1) Вызвать диалог калибровки номер 0 устройства &Mv2Pu:
@open DAQ:\DeviceList\&Mv2Pu\Calibration#0
2) Вызвать текстовый редактор для калибровки номер 0 устройства &Mv2Pu:
@open /e DAQ:\DeviceList\&Mv2Pu\Calibration#0
3) Вызвать диалог свойств и общих свойств устройства &Mv2Pu:
@open DAQ:\DeviceList\&Mv2Pu\PropertyDialog
@open DAQ:\DeviceList\&Mv2Pu\CommonPropertyDialog
Теперь можно делать кнопки, по которым пользователи самостоятельно смогут
редактировать калибровки через диалог калибровок.
Значительные изменения в диалоге редактора калибровок.
В заголовке диалога теперь отображается имя файла калибровки.
Сам диалог стал многостраничным, за счет чего размер его сильно уменьшился.
Дополнительные параметры калибровки (степень, масштаб, центр и т.д.) скрыты
во вкладке и не бросаются в глаза (и это хорошо - оператору они редко нужны).
Более продуманной стала работа кнопок загрузки и сохранения калибровок.
Теперь при редактировании обычных калибровок имя файла можно менять при загрузке\сохранении,
а при редактировании калибровок DAQ-устройств имя файла фиксировано.
Кроме того, в диалоге операторы не смогут изменить имена переменных и тип шкалы.
Это позволяет сравнительно безопасно поручить редактирование калибровок операторам.
Новая переменная SolidCrw32Logo в файле Crw32.ini - режим заставки
при загрузке системы.
Если SolidCrw32Logo=0, то все работает как раньше - при загрузке и завершении
показывается диалог приветствия CRW32 LOGO.
Этот режим оставлен для обратной совместимости с предыдущими версиями.
Если SolidCrw32Logo=1, то вместо диалога приветствия CRW32 LOGO
при загрузке и завершении показывается заставка в основном окне CRW32,
которая скрывает за собой все безобразие, которое там внутри творится.
Это полезно для того, чтобы скрыть мелькание большого числа окон, которые
раздражают при загрузке и завершении программы, а также при старте и остановке
DAQ-системы.
По умолчанию режим заставки включен.
Если с ним возникли проблемы, надо отключить режим заставки и вернуться к старому
диалогу приветствия.
Обновлена демо конфигурация DEMO_ALIPHOSCOOL.
Фактически это конфиграция реального модуля, который сейчас стоит в шахте в CERN,
только включен симулятор и удалена документация.
Изменения в команде @open:
добавлен флаг блокировки команды /l и разблокировки u.
Это сделано из соображений безопасности: при запуске конфигураций на ответственных установках
команда @open блокируется, чтобы предотвратить запуск
посторонних программ методом перетаскивания файлов
на ярлык программы CRW-DAQ (то есть через Drag & Drop).
Блокировать\разблокировать команду @open
можно только изнутри CRW-DAQ.
Например:
@open /l заблокировать команду @open
... теперь перетаскивание НЕ работает
@open /u /l /e c:\index.htm разблокировать, открыть файл и снова заблокировать
... перетаскивание по-прежнему НЕ работает
@open /u разблокировать команду @open
... теперь перетаскивание работает
Обновлен AdmiLink.
В нем добавлены функции настройки параметров безопасности Windows,
которые позволяют значительно улучшить защищенность системы.
Все описано в справочном файле AdmiLink.
Сделана программа CrwGo.exe.
Она умеет только одно: выполнять запуск Crw32.exe,
передавая ей все полученные параметры командной строки.
Целью программы CrwGo.exe является ее использование совместно с AdmiLink.
Дело в том, что при каждой смене версии Crw32.exe ярлыки AdmiLink перестают
работать, так как эти ярлыки привязаны к содержимому исполняемого файла.
Однако если сделать ярлыки AdmiLink с указанием CrwGo.exe,
которая не будет меняться от одной версии Crw32.exe к другой,
то ярлыки AdmiLink при смене версий Crw32.exe менять уже не придется.
Это сократит потери времени на администрирование защищенных систем.
Поэтому отныне рекомендуется делать все ярлыки на CrwGo.exe (а не на Crw32.exe),
чтобы потом не пришлось менять ярлыки с каждой новой версией пакета.
В состав пакета включен ряд свободно распространяемых маленьких консольных утилит
(mkisofs, cdrecord, cmdow, nircmd).
Эти утилиты пока явно не используются (кроме mkisofs,
которая теперь генерирует ISO-образ дистрибутива пакета),
но их планируется использовать в будущих проектах.
Добавлена
Virtual Russian/English Keyboard123.
Она пригодится:
Когда под рукой нет русской клавиатуры.
Для работы со специальными символами Unicode.
При использовании сенсорных экранов (в будущем).
Приветствие "Привет" при старте программы и прощание "До свидания" при выходе
теперь настраиваемые в Crw32.ini и по умолчанию теперь отключены.
Точнее,
в файле Resource\Crw32.ini определено:
[SysVoice]
Greeting = привет ; звук при старте программы
Farewell = досвидан ; звук при завершении программы
[]
а в файле Temp\Crw32.ini определено:
[SysVoice]
Greeting = -привет ; no sound on program enter
Farewell = -досвидан ; no sound on program exit
[]
Поскольку файл Temp\Crw32.ini, если таковой существует, разбирается первым, то он и работает.
То есть если закомментировать переменные в файле Temp\Crw32.ini, то сообщения появятся снова.
А можно задать и другие сообщения...
Введена консольная команда @open.
Это команда открывает файлы, примерно как меню File\Open, но ее функциональность шире.
Кроме того, теперь обработка параметров командной строки
в конечном счете сводится к вызову этой команды. Уже поэтому ее стоит изучить...
Открывать и запускать файлы разных типов в различных режимах через командную строку.
Открывать файлы на редактирование и запускать DAQ конфигурации методом
перетаскивания файлов на ярлык программы
CRW-DAQ.
Открывать и запускать файлы разных типов через функцию eval
и команду @open,
через вызов типа eval('@system @async @open ...').
Менять на ходу картинку программы (отображаемую в заголовке окна и в области уведомлений).
Это можно использовать для различения систем, если их несколько, а также для индикации
состояния измерительной системы. Смена картинки идет через вызов типа
eval('@system @async @open /Icon=2').
Ну, например:
Хватаете файл _LED20.BMP и кидаете на ярлык Crw
- запускается Paint для редактирования этого файла.
Хватаете файл !RDMS_SERVER.CFG и кидаете на ярлык Crw
- запускается DAQ система для этой конфигурации.
Заметьте - файл запускается, потому что это основной конфиг-файл
(имя начинается с !, а также есть секция [DAQ]).
Хватаете файл RDMS_SERVER.CFG и кидаете на ярлык Crw
- открывается окно для редактирования этой конфигурации.
Заметьте - файл редактируется, потому что это НЕ основной конфиг-файл
(имя НЕ начинается с !, а также НЕТ секции [DAQ]).
Хватаете файл RDMS_SERVER.CFG и кидаете на ярлык Crw при нажатой кнопке CTRL
- принудительно запускается DAQ система для этой конфигурации.
Хватаете файл !RDMS_SERVER.CFG и кидаете на ярлык Crw при нажатой кнопке ALT
- принудительно запускается редактирование этой конфигурации.
Вызываете eval('@async @open /r c:\Daq32\Demo\RDMS_CTRL.CFG') из программы
DaqPascal для редактирования этой конфигурации.
Обратите внимание - в команде @open сформулированы
условия для определения основного конфиг-файла:
имя начинается с !, как !demo.cfg (обычная практика)
имя начинается с #, как #demo.cfg (не рекомендуется, устарело)
файл содержит секцию [DAQ] (обычно эта секция в основном конфиге)
Следует придерживаться этих соглашений, чтобы правильно работал режим
запуска программы
и перетаскивания файлов.
Изменено поведение меню File\Open для *.CFG файлов.
Теперь через это общее меню можно не только открывать редактор конфигов, но и запускать их.
Точнее:
Если DAQ система уже запущена, конфиги всегда открываются на редактирование, как и ранее.
Это разумно, так как прежде запуска измерительной системы надо остановить работающую.
Если DAQ система не запущена, то открывается диалог с вопросом - что делать
(открыть текст для редактирования или запустить на исполнение).
Так что теперь практически все файловые операции можно делать единым образом - через File\Open,
а также методом перетаскивания файлов на ярлык программы.
Добавлены следующие демо конфигурации:
DEMO_TDS - демонстрация работы с осциллографами TDS.
Драйвер TDS переработан (все вопросы к Алексею Вьюшину).
Демо версия включает в себя также симулятор TDS (именованный канал симулирует COM-порт).
DEMO_ISKRA - система управляемого нагрева с контролем
по заданному графику давления (все вопросы к Виноградову Ю.И.).
Демо версия включает в себя симулятор и PID-регулятор, а также пример использования
новой команды @open, которая используется для загрузки
кривой из *.CRW-файла.
DEMO_HPI - система управления для установки высокого давления
(все вопросы к Виноградову Ю.И.).
Демо версия включает в себя симулятор и ключевой регулятор для нагревателей.
DEMO_CLRM - система управления для микрокалориметра
(все вопросы к Виноградову Ю.И.).
Демо версия включает в себя симулятор и PID-регулятор.
DEMO_AHIT и DEMO_THIT
- две версии систем управления для проверки химических источников энергии
(все вопросы к Виноградову Ю.И.).
Демо версия включает в себя симулятор и генератор отчетов.
DEMO_BOX - система трехканального терморегулятора
(все вопросы к Виноградову Ю.И.).
Демо версия включает в себя симулятор и PID-регулятор.
Обновлен драйвер 7080.
Теперь он откликается на сообщения
r:=devmsg('Adam7080 ResetCounter 0'); if r=0 then {Error} else {Ok}; // Reset counter 0
r:=devmsg('Adam7080 ResetCounter 1'); if r=0 then {Error} else {Ok}; // Reset counter 1
Исполняемый файл CRW32 в этой версии не изменялся.
Ставилась цель зафиксировать полезные новшества в прикладной части DAQ систем,
не касаясь ядра пакета, а также улучшить инсталлятор и справочную систему.
Обновлен основной справочный файл CRW-DAQ (также см. далее).
С целью ускорения разработки DAQ систем в инсталлятор добавлена опция создания
HTML - индексов для всех типов файлов.
Идея тут такая. При разработке новых систем наблюдается очень высокий процент
повторного использования программных кодов, картинок и конфигураций.
Другими словами, системы строятся из кубиков, созданных при разработке предыдущих систем.
Чтобы облегчить поиск конфигураций, картинок, звуков, программных кодов и документов,
создаются индексы, то есть списки всех файлов разных типов.
Хотите найти программу? Кликаете список всех *.pas файлов и быстро находите то что надо.
Обратите внимание, что картинки присутствуют в 2-х видах - как список (List)
и как черепица (Tile).
Первая форма удобна для получения ссылок на картинки,
а вторая - для быстрого поиска и последующего копирования в буфер обмена.
Обратите внимание, что звуки присутствуют в 2-х видах - как список (HTML List)
и как список воспроизведения (Play List).
Первая форма удобна для получения ссылок на звуки,
а вторая - для воспроизведени всего списка, для быстрого поиска нужного звука.
Обратите внимание, что опция создания индексов по умолчанию отключена
в инсталляторе InstallCrw32.exe и по умолчанию включена
в инсталляторе InstallCrw32Extra.exe.
Дело в том, что индексные файлы нужны в основном при разработке новых систем.
На измерительных машинах конечных пользователей устанавливается только основной пакет
InstallCrw32.exe, а создавать индексы зачастую необязательно.
На рабочих станциях разработчиков обычно устанавливается основной пакет InstallCrw32.exe,
а затем дополнительный пакет InstallCrw32Extra.exe со справками и примерами.
Целесообразно создавать индексы уже после инсталляции обоих пакетов, поэтому по умолчанию
выбраны такие значения флагов.
Обратите внимание, что индексатор запускается как командный файл в консольном окне,
который продолжает работу и после завершения основного инсталлятора.
Дело в том, что индексация может занимать много времени (до нескольких минут при полной
инсталляции Crw32 и Crw32 Extra Kit). Поэтому индексатор должен
работать в фоне, не мешая оператору продолжать работу.
В конце индексации выдается сообщение о ее завершении, а консольное окно индексатора
автоматически закрывается.
При желании индексацию можно прервать в процессе работы, закрыв консольное окно индексатора.
При необходимости можно запустить индексацию позже вызовом меню
"Инструменты\Консольные утилиты\Make Crw32 HTML indexes"
или консольной командой:
При необходимости можно запустить также индексацию Daq32 вызовом меню
"Инструменты\Консольные утилиты\Make Daq32 HTML indexes"
или консольной командой:
Надеюсь, что индексатор поможет всем разработчикам повысить скорость разработки систем
и облегчить их поддержку.
Добавлено много новых функций в шаблоны редактора, что должно облегчить разработку программ
в редакторе Daq Pascal.
В консольные драйверы введен "анти-зомби" контроль.
Напомню, что "зомби" называют подвисшие дочерние процессы, которые остаются после
(аварийного) завершения родительского процесса, который должен взаимодействовать с этими
дочерними процессами и завершать их при выходе из программы.
Например, если выполняется программа CRW32.exe, которая запустила
DIM сервер DimSrv.exe для связи по сети,
а затем вдруг программа CRW32.exe аварийно завершается, то процесс DimSrv.exe
остается в списке процессов и ждет ввода со стороны не существующей уже CRW32.exe
(вернее, так было раньше).
Более того, "зомби"-процессы могут препятствовать запуску нового экземпляра программы,
так как могут захватить критически важные ресурсы (порты, каналы связи и т.д.).
Таким образом, "зомби" мешают работе и должны устаняться.
Анти-зомби контроль заключается в том, что теперь дочерние программы (например, DimSrv.exe)
отслеживают состояние родительского процесса и завершают работу, если видят, что основная
программа уже завершена. Это в свою очередь гарантирует возможность корректного перезапуска
системы даже после ее аварийного завершения.
Инсталлятор сделан более "строгим". Теперь он не позволит провести инсталляцию,
если каталог Crw32exe или Crw32exe.old содержит заблокированные
файлы. Причиной блокировки чаще всего является следующее:
Запущена программа Crw32.exe в этом каталоге (забыли закрыть).
Надо закрыть ее.
Запущена программа dns.exe в этом каталоге.
Это бывает после запуска DIM сервера, который запускает DNS сервер.
При этом в списке процессов есть процесс с именем dns.exe, хотя у него нет
видимого на экране окна.
Надо убить программу dns.exe либо "ручками" через Task Manager,
либо командой:
TaskKill /F /IM dns.exe
Открыт какой-нибудь *.doc, *.ppt, *.htm файл при помощи
Word, PowerPoint или InternetExplorer.
Надо закрыть все лишние программы.
В общем, если инсталлятор ругается, надо закрыть все лишние программы, которые
могут блокировать файлы в каталоге Crw32exe или Crw32exe.old,
и повторить инсталляцию.
Добавлена демо конфигурация DEMO_ALIPHOSCOOL.
В ней присутствуют все новые возможности - DIM, WEB, SPEAK и т.д.
Кроме того, система полностью распределенная, то есть практически все можно делать
удаленно, включая перезагрузку удаленного компьютера и т.д.
Поэтому ее можно брать как экземпляр для клонирования при создании будущих распределенных
систем управления.
Демо версия отличается от рабочей только тем, что в ней изменено имя (AliPhosCoolDemo)
и удален громоздкий HELP.
Кстати, довольно реалистичный симулятор позволяет наглядно представить работу реальной системы.
Добавлена демо конфигурация DEMO_P48 (в InstallCrw32Extra).
Демо версия отличается от рабочей только тем, что в ней удален громоздкий HELP.
Все вопросы и замечания - Сергею Фильчагину.
Специально для Саши - в шаблонах есть процедура PcSound,
которая включает - выключает звук PC, то есть "пищалку" внутри системного блока компьютера.
Полезно, когда на машине нет звуковой карты или динамиков.
paramstr('UserList') список пользователей
paramstr('HostList') список серверов в сети
paramstr('DomainList') список сетевых доменов
Исправления в консольных командах @list users,@list hosts.
Эти команды теперь выполняются в фоне, в отдельном потоке,
сразу освобождая консоль, так как сетевые функции могут выполняться долго.
Новая консольная команда @list domains.
Пример:
@list domains
Список доменов:
.
kouriakine
abbey
rnphi
В Total Commander добавилось несколько полезных утилит.
nnCron - мощный планировщик заданий. Вставлен в инсталлятор.
NetView - мощный набор сетевых утилит. Вставлен в инсталлятор.
NetFind - поиск файлов в сети. Вставлен в панель инструментов Total Commander.
WinHardLink - умеет создавать жесткие ссылки на файлы, папки и диски. Вставлен в инсталлятор.
Обновлена документация по CRW-DAQ.
16.07.2007 ... 19.07.2007
Tag#n = .. URL_Packed @list users @list hosts
Добавлено новое поле (текст) в переменные Tag#n в описание сенсора мнемосхемы.
Целью добавления является желание сократить число *.bmp картинок для кнопок.
Часто кнопки отличаются друг от друга только надписями, поэтому логично ввести одно
*.bmp изображение, а текст задавать как параметр.
Подробнее см. описание *.crc-файлов.
Важно не забывать, что текст передается в виде URL
строки, в которой CRLF заменяется на %0d%0a,
пробел - на + или %20, символ + на %2b,
символ % на %% или %25.
Пример:
[Circuit]
GeneralMap = .\Control.bmp
Name = Control
[]
[SensorList]
Sensor = BTN_START
[BTN_START]
Pos = 248, 10
Tag = 0
LED = 0, 0, 0, *, [LedFont]
Tag#1 = 0, .\BUTTON_0.BMP, Start+Measurements
Tag#2 = 1, .\BUTTON_1.BMP, Stop%20Measurements
Hint = Кнопка старта%0d%0aПредназначена для старта измерений
[]
[SensorList]
Sensor = BTN_POWER
[BTN_POWER]
Pos = 248, 10
Tag = 0
LED = 0, 0, 0, *, [LedFont]
Tag#1 = 0, .\BUTTON_0.BMP, Power+On
Tag#2 = 1, .\BUTTON_1.BMP, Power+Off
Hint = Кнопка включения питания%0d%0aПредназначена для включения реле питания
[]
[LedFont]
CharSet = 204 ; кодировка фонта RUSSIAN_CHARSET=204
Color = $0000FF ; цвет фонта, RGB
Height = -19 ; высота фонта
Name = Courier New ; название фонта
Pitch = Fixed ; ширина символов фонта Default/Fixed/Variable
Style = [Bold] ; [Bold, Italic, Underline, StrikeOut]
[]
Обратите внимание, как задается фонт для кнопок.
Имена файлов в мнемосхемах теперь задаются в URL кодировке.
На существующие конфигурации это повлиять не должно,
так как URL_Decode не меняет строк, в которых нет
символов + и % (а мы их обычно в именах файлов не использовали).
Однако теперь появилась возможность ссылаться на имена файлов,
содержащих пробелы и другие нехорошие символы.
Подробнее см. описание *.crc-файлов.
Список параметров функций
paramstr,
filerename,
filecopy
теперь также использует URL-кодировку.
Все старенькое должно работать как раньше, так как в именах не было пробелов, + и %.
Но теперь можно работать и с именами, содержащими пробелы...
Например
filerename('c:\demo\a.txt d:\demo\b.txt')
- работает как раньше
filerename(URL_Packed('c:\demo\a.txt')+' '+URL_Packed('d:\demo\b.txt'))
- новый стиль вызова
filerename('c:\Program Files\a.txt d:\demo\b.txt')
- не работает, пробел в имени
filerename('c:\Program+Files\a.txt d:\demo\b.txt')
- работает, хотя есть пробел в имени
filerename(URL_Packed('c:\Program Files\a.txt')+' d:\demo\b.txt')
- работает, хотя есть пробел в имени
Добавлены шаблоны процедур/функций, в частности StrReplace.
Добавлена функция URL_Packed.
Она используется для URL-кодировки строк.
Вообще URL-кодировка удобна при приеме списков имен файлов, так как URL-декодер
вообще не меняет строки, если в них нет символов + и %, которые редко встречаются в именах файлов.
Поэтому можно передавать имена файлов "как есть", без изменений, если нет необходимости
их кодировать (нет пробелов в имени файла).
Поэтому многие функции будут переводиться на URL-кодировку (см. далее).
Список пользователей:
paramstr('UserList') - простой список локальных пользователей
paramstr('UserList .') - простой список локальных пользователей (точка = локальный комп)
paramstr('UserList crwbox') - простой список локальных пользователей (на сервере crwbox)
paramstr('UserList crwbox 1') - список пользователей на crwbow (в виде 3 столбцов Name Group On/Off)
Чтение реестра (каталог Рабочий Стол текущего пользователя)
paramstr('Registry HKCU Software\Microsoft\Windows\CurrentVersion\Explorer\Shell+Folders Desktop')
Запись в реестр
paramstr('Registry HKCU Control+Panel\Desktop\WindowMetrics MinAnimate 0')
Новая консольная команда @list users.
Пример:
@list users
Список пользователей:
root
HelpAssistant
test
Администратор
Гость
@list users crwbox 1
Список пользователей:
Alex Root On
test User On
Администратор Root On
Гость Guest Off
Новая консольная команда @list hosts - список компьютеров в сети.
Обновлена демо конфигурация DEMO_STRINGS.
В ней демонстрируются и тестируются новые возможности строковых функций.
Обновлена демо конфигурация DEMO_TASK_PKK4.
В ней демонстрируются новые возможности мнемосхем (кнопки с надписями, см. пункт 1).
Обновлена демо конфигурация DEMO_AK_TARG_XP (АКУЛИНА).
В частности там присутствует Web server и RDMS.
Обновлена демо конфигурация DEMO_PROMETHEUS (ПРОМЕТЕЙ).
В частности там присутствует Web server.
Обновлен AdmiLink.
Там теперь список компьютеров и пользователей вводится через список.
Обновлена документация по CRW-DAQ.
22.05.2007 ... 22.05.2007
Hint AdmiLink DIM RDMS
Добавлена переменная Hint в описание как главного поля,
так и сенсора мнемосхемы. Hint - это текст справки (комментарий) для данного сенсора
или мнемосхемы.
Подробнее см. описание переменной Hint в разделе описания
*.crc-файлов.
Здесь важно, что
Hint передается в виде URL-encoded строки,
в которой CRLF заменяется на %0d%0a,
+ на %2b, % на %% или %25.
Первая строка текста Hint отображается в строке статуса
мнемосхемы, если мышь над сенсором.
Исправлена ошибка связанная с неправильным центрированием текста при рисовании сенсоров
с увеличенными шрифтами в окнах мнемосхем.
Частично исправлена ошибка, связанная с некорректным закрытием TCP соединений
при наличии дочерних программ со связью по анонимным каналам.
Обновлена документация по CRW-DAQ.
25.02.2007 ... 28.02.2007
DEMO_PIPE_BENCH
Новая команда меню Инструменты\Консольные команды.
Среди них особенно обращаю внимание на "View log file statistics" (статистика сеансов и сбоев).
Добавлена демонстрационная конфигурация DEMO_PIPE_BENCH
для измерения скорости передачи данных по каналу при помощи функций
pipe_xxxx.
При "чистой" передаче (без обработки) у меня получилось около 3 Mbyte/sec,
при включении обработки (выделение строк, слов, преобразование в числа и т.д.)
- намного ниже (100 kbyte/sec), что видимо связано с медленными функциями
обработки строк (типа pos,extractword,val и т.д.).
Небольшие улучшения в речевом синтезаторе SpeakSrv (перезапуск сервера при сбое синтезатора).
Обновлена документация по CRW-DAQ.
04.02.2007 ... 24.02.2007
@term @compile pipe_xxxx strconv dump2f dumpf DIM
Юрия Ивановича - с Днем Рождения, всех остальных - с 23 февраля!
Добавлена консольная команда @term для открытия терминальных консолей,
связанных с каналами. Под каналом понимается консольная программа,
именованный сетевой канал, сокет TCP или COM порт - то есть нечто,
с чем можно обмениваться данными с дисциплиной FIFO (first in, first out).
Терминальные окна - мощное средство наблюдения и отладки при программировании
систем, использующих те или иные каналы.
Общий формат команды такой:
@term /optlist arglist
Аргументы arglist описывают тип канала
(подробнее см. pipe_init).
В качестве каналов могут выступать:
task c - задача, запускаемая через командную строку
c в фоновом режиме с переназначением ввода-вывода
в анонимный канал.
pipe n - серверный именованный канал с именем n.
pipe h\n - клиентский именованный канал
с именем n, который подключается к серверу h.
tcp port n server m - TCP сервер, порт n,
рассчитанный на m клиентов.
tcp port n client h - TCP клиент, порт n,
подключаемый к серверу по имени или IP адресу h.
com port n baudrate b - последовательный COM порт
номер n, на скорости b.
Опции /optlist описывают свойства терминала (консольного окна).
В качестве опций можно указать:
a - преобразование символов ANSI/OEM.
Применяется при вызове программ командной строки, так как
обычно консольные программы выводят символы в кодировке DOS.
c - автоматически закрывать окно если прошло некоторое
время (3 секунды) после разрыва связи.
d - отображать окно программы (в случае task).
По умолчанию программа выполняется в фоновом режиме, без окна.
x - выводить данные в окно в виде HEX-дампа, т.е.
в шестнадцатеричном формате.
h - интерпретировать входные данные как заданные в HEX-формате,
то есть посылать в канал hex_decode(data).
u - интерпретировать входные данные как заданные в URL-формате,
то есть посылать в канал url_decode(data).
s - добавлять перед CR контрольную сумму ADAM,
применяется для работы с устройствами ADAM.
@term /ca cmd
Запустить консоль с командным процессором.
Автоматически закрывать окно после exit.
@term /a ping crwbox
Пропинговать сервер, окно автоматически не закрывать.
@term pipe test
Консоль сервера канала test.
@term pipe .\test
Консоль клиента канала test на локальном компьютере.
@term pipe crwbox\test
Консоль клиента канала test на компьютере по имени crwbow.
@term tcp port 1234 server 2
Консоль сервера канала TCP порта 1234 на два клиента.
@term tcp port 1234 client crwbow
Консоль клиента канала TCP порта 1234 с поключением к серверу crwbow.
@term tcp port 1234 client 192.168.0.1
Консоль клиента канала TCP порта 1234 с поключением к серверу 192.168.0.1.
@term com port 2 baudrate 115200
Консоль порта COM2 на скорости 115200.
@term /s com port 2 baudrate 115200
Консоль порта COM2 на скорости 115200, с контрольной суммой.
@term /shx com port 2 baudrate 115200
Консоль порта COM2 на скорости 115200.
Ввод и вывод делается в HEX-формате, перед CR добавляется контрольная сумма.
Для получения справки можно просто выполнить команду
@term
Введена группа функций pipe_xxxx.
Она служит для работы с каналами, в качестве которых могут выступать
задачи task, именованные каналы pipe, сокеты tcp,
а также com порты.
Унификация способов работы с каналами и устройствами последовательной связи - факт,
безусловно, положительный. Позже функции pipe_xxxx должны, по замыслу,
вытеснить функции task_xxxx и comxxxx.
В шаблонах также добавлен ряд специальных функций для работы с каналами,
например, Pipe_Readln. Это также позволит со временем унифицировать
прикладные программы ориентированные на канальные устройства.
Добавлена демонстрационная конфигурация DEMO_PIPE
для проверки и демонстрации новых функций pipe_xxxx.
Введена функция strconv для преобразования
строк, например:
s:=strconv('Oem2Ansi','user string'); // Convert from DOS to Windows code page
s:=strconv('Ansi2Oem','user string'); // Convert from Windows to DOS code page
Введены функции dump2f,
dumpf для работы с типом float.
Добавлено много шаблонов, например, объявление сервисов DIM.
Полезные функции - Pipe_Readln/Writeln, DIM_UpdateTag.
Обновлена документация по CRW-DAQ.
11.01.2007 ... 15.01.2007
NSIS Installer
Обновлен инсталлятор. Теперь он двуязычный, с выбором языка, при этом язык CRW-DAQ
также устанавливается по выбранному языку инсталлятора.
Поддержка создания инсталляторов для DAQ-систем включена в ядро CRW-DAQ.
Делается примерно так:
Инсталлируется NSIS (входит в дистрибутив TotalCommander).
Создается новое пустое текстовое окно.
В него из шаблонов редактора вставляется шаблон Daq-Nsi\InstallDaq32-XXXX.nsi.
При этом надо указать название установки Facility.
Окно сохраняется как InstallDaq32-XXXX.nsi файл в домашнем
каталоге интересующей Daq-системы.
Окно закрывается, а затем открывается снова, но уже как *.nsi
скрипт через общий File\Open.
Если открыт файл *.nsi, в нем появляется кнопка компиляции
и справки
,
как в окне редактора программ.
Надо еще написать два файла лицензии Help\License\license_rus.txt
и Help\License\license_eng.txt, в которых дается краткое описание
и условия распространения данной системы.
Шаблоны лицензий есть в Daq-Nsi\license_rus/eng.
Надо еще написать файл Clear.bat, который будет очищать
временные файлы перед созданием дистрибутива.
Шаблон тоже имеется.
После этого становится возможной компиляция скрипта (надо только
разрешить его редактирование командой
).
По умолчанию скрипт создает ярлыки для запуска конфигурации
Daq32\XXXX\Config\!XXXX.cfg (где XXXX-имя установки).
Этот файл должен содержать ссылку на основной файл конфигурации,
например,
[ConfigFileList]
ConfigFile = XXXX_Ctrl.cfg
[]
Обновлена система RDMS.
В ней появился инсталлятор и конфигуратор.
Скомпилируйте файл InstallDaq32-RDMS.nsi
(можно из пакета CRW-DAQ).
Запустите его - и все увидите.
Обновлена документация по CRW-DAQ.
24.12.2006 ... 27.12.2006
windraw // comment LED format LED fonts
Финальная версия 2006 года!
Надеюсь, успешная.
С Новым Годом и Рождеством!
В Extra пакете обновлен пример DEMO_PLC_ICPDAS.
Там текущая версия написанного Алексеем Вьюшиным софта для контроллеров ICP-DAS,
включая радиометрический канал. Все вопросы - автору.
Добавлены новые возможности в функции windraw.
Введен атрибут Options. Он позволяет придавать окнам новые свойства:
b:=WinDraw('Demo|Options=-Min,-Max,-Close'); - запретить кнопки минимизации\максимизации\закрытия окна
b:=WinDraw('Demo|Options=+Min,+Max,+Close'); - разрешить кнопки минимизации\максимизации\закрытия окна
b:=WinDraw('Demo|Options=-Width,-Height'); - запретить менять ширину\высоту окна
b:=WinDraw('Demo|Options=+Width,+Height'); - разрешить менять ширину\высоту окна
b:=WinDraw('Demo|Options=-HScroll,-VScroll'); - запретить горизонтальный\вертикальный скроллинг окна
b:=WinDraw('Demo|Options=+HScroll,+VScroll'); - разрешить горизонтальный\вертикальный скроллинг окна
b:=WinDraw('Demo|Options=-StatusBar'); - запретить статусную строку в нижней части окна
b:=WinDraw('Demo|Options=+StatusBar'); - разрешить статусную строку в нижней части окна
b:=WinDraw('Demo|Options=-ToolBar'); - запретить статусную строку в нижней части окна
b:=WinDraw('Demo|Options=+ToolBar'); - разрешить статусную строку в нижней части окна
Таким образом, теперь можно создавать окна, которые пользователь не может случайно испортить
(закрыть, минимизировать, изменить размер).
В Daq Pascal добавлены комментарии в стиле C++ или Delphi.
А именно, если в тексте присутствует два слеша //, то оставшийся до конца строки текст считается
комментарием. Теперь можно писать:
//
// Демо-Комментарий
//
procedure Demo; // Это комментарий
begin { и другой комментарий }
end; (* и еще комментарий *)
Изменения в формате *.crc файла.
Теперь можно задавать формат отображения числового поля LED, а также его фонт:
[SensorList]
Sensor = Demo
[Demo]
...
LED = 9, 4, 0 - как раньше (формат что-то типа %9.4g, системный фонт)
LED = 9, 4, 0, %9.4f - формат с фиксированной точкой, ширина 9, 4 символа после точки
LED = 9, 4, 0, %9.4e - формат с экспонентой, ширина 9, 4 значащих цифры мантиссы
LED = 9, 4, 0, %9.4g - свободный формат, ширина 9, 4 значащих цифры
LED = 9, 4, 0, *, [LedFont] - формат не задан, фонт задан в секции [LedFont]
LED = 9, 4, 0, %9.4g, [LedFont] - свободный формат, фонт задан в секции [LedFont]
[]
[LedFont] ; секция описания фонта
CharSet = 204 ; кодировка фонта RUSSIAN_CHARSET=204
Color = $000000 ; цвет фонта, RGB
Height = -19 ; высота фонта
Name = Courier New ; название фонта
Pitch = Fixed ; ширина символов фонта Default/Fixed/Variable
Style = [Bold] ; [Bold, Italic, Underline, StrikeOut]
[]
Обратите внимание - высота фонта отрицательна.
Это указывает на то, что высота берется без учета межстрочных пробелов.
Стандартным для мнемосхем является фонт по умолчанию:
[DefaultCircuitFont]
CharSet = 204
Color = $000000
Height = -13
Name = Fixedsys
Pitch = Fixed
Style = []
[]
Для облегчения выбора параметров фонтов можно открыть текстовое окно
(кнопка )
и поменять в нем фонт
(кнопка ).
При этом параметры выбранного фонта отобразятся в Главной Консоли, а в Буфер Обмена будет скопирован
готовый текст с описанием фонта. Останется только вставить его в *.crc файл.
Из панели инструментов убраны не нужные команды
и
.
В меню инструментов добавлены нужные команды
и
.
Команда
к тому же отображает загрузку процессора в панели инструментов.
Обновлена документация по CRW-DAQ.
12.12.2006 ... 18.12.2006
cpu_clock pidaffinity
Добавлены новые функции
cpu_count,
cpu_start,
cpu_clock,
cpu_mhz,
devaffinity,
pidaffinity.
Они позволяют определять число процессоров, их частоту, считывать счетчик
тактов процессора, а также делать привязку процессов и потоков (устройств)
к процессорам. Все это нацелено на многоядерные процессоры, за которыми будущее...
Например, можно критические процессы и потоки засадить на один процессор,
а все остальные - на другой, чтоб не мешали.
Добавлен пример demo_benchmark.
Он использует новые функции (см.выше) и позволяет измерять
производительность компилятора Daq Pascal.
paramstr('ComPortList') теперь возвращает список
существующих COM-портов.
В окнах DAQ-системы теперь отображается календарное время при движении мыши над окном.
Предполагается, что в окнах находятся кривые, в которых в координате X записано время
time по часам DAQ-системы.
Если это не так, календарное время будет неверным.
Отображение календарного времени отсутствует в окнах, созданных вне DAQ-системы,
так как там нет ясной привязки к реальному времени.
Календарное время отображается также в окнах, прочитанных из *.dat файлов штатной утилитой
чтения файлов.
Привязка к календарному времени сохраняется вместе с окном в файле, сохраняется при клонировании
окна, однако при любой обработке теряется, так как обработка может изменить привязку кривых
к шкале времени.
Теперь *.dat файлы можно открывать через стандартный диалог открытия файлов, так же как
файлы *.crw, *.daq.
Усилена "защита от дурака".
Теперь текстовые окна по умолчанию открываются в режиме ReadOnly.
То есть программы и конфигурации открываются первоначально в безопасном режиме
"только для чтения". Это предохранит файлы от непреднамеренного повреждения.
Если будет раздражать, надо отредактировать переменную OpenTextAsReadOnly в файле
Temp\Crw32.ini.
Устранена очень старая ошибка в компиляторе
Daq Pascal, из-за которой нельзя было
использовать функции, возвращающие строковое значение.
Теперь все работает корректно.
Однако не лишним будет напомнить еще раз, что каждую строку
перед использованием надо инициализировать (присвоить ей что-нибудь),
так как в начале работы все строки не инициализированы и обращение
к ним считается ошибкой.
Кроме того, в теле функции ей обязательно что-то надо присвоить,
иначе результат функции будет не определен и возникнет ошибка.
Например,
function GetAccount:String;
var s:String;
begin
s:=ParamStr('UserName');
s:=s+'@'+ParamStr('ComputerName');
GetAccount:=s;
s:='';
end;
Очистка строк (присвоение пустой строки) локально объявленным строкам
перед выходом из процедур и функций не обязательно (все вроде и так
работает правильно), но рекомендуется.
Пример demo_strings может служить
для иллюстрации и тестирования строковых функций.
Собственно, этот тест и служил для отладки и проверки корректности
работы строковых функций.
С этим связано довольно странное на первый взгляд содержимое теста -
оно ставит целью всестороннюю проверку компилятора, поэтому содержит
весьма сложные конструкции, лишенные какого-либо иного смысла,
кроме создания для компилятора различных головоломок с заранее
известным ответом.
Значительно переработан DimServer.
В нем используются новые возможности компилятора (увеличен сегмент данных, снят ряд ограничений).
В меню новая команда Web\~~\Temp\Crw32.ini.
Она служит для настройки параметров запуска CRW32.EXE.
Сейчас файл настроек программы разделен на три файла.
Основной файл Crw32.ini содержит ссылку на два других файла, редактировать его не надо.
Файл Resource\Crw32.ini содержит настройки по умолчанию и редактировать его тоже не надо.
Файл Temp\Crw32.ini содержит настройки пользователя, его и надо редактировать для указания
параметров, которые будут установлены при каждом запуске программы.
Обновлена документация по CRW-DAQ, в соответствии с изменениями в пакете.
22.11.2006
WebSrv RDMS
Основной файл ядра CRW32.EXE не изменился, этот релиз фиксирует
только изменения в Web сервере и РДМС.
Обновлен Web сервер: устранено несколько мелких багов, из-за которых
сервер не мог обслуживать одновременно много запросов.
Теперь, по результатам тестов, возможно устойчивое обслуживание HTTP
запросов, следующих с частотой 10-20 Герц при загрузке (по CRW-DAQ)
порядка 5-10%.
Обновлена документация по CRW-DAQ, добавлена по DaqScript.
Пример demo_keygen может служить
для генерации защищенных паролей для Web сервера.
Пароль подставляется в поле Password в секции [TrustedUsers].
Пример demo_Ak_targ_xp
- АКУЛИНА (мишень) на 28.10.2006.
Включен в Extra пакет.
Пример test_rta
- тестовая версия РДМС для проверки РТА-4
для поставки на МАЯК.
Включен в Extra пакет.
Пример demo_rdms
- основная референсная версия РДМС для генерации из нее
конфигураций для конкретных установок.
Генерация делается через файл !RDMS_Make.bat, в котором надо
задать таблицу адресов, портов, названий и т.д. После заполнения
таблицы надо запустить файл на исполнение - все конфигурационные
файлы будут созданы.
10.10.2006
WWW Web4Daq WebSrv
Добро пожаловать в мир Web технологий.
В CRW-DAQ появилась возможность написания полноценных распределенных
клиент-серверных систем с Web-интерфейсом.
Пример такой системы помещен в DEMO_WEB4DAQ,
см. описание в web4daq.htm.
Так что изучайте HTML, CGI, HTTP...
см. также WebSrv.
Главным достоинством Web-технологий является то, что клиентскую часть
писать не надо - есть готовый Internet Explorer.
Задача создания системы сводится таким образом к созданию сервера.
Поскольку клиентов зачастую много, а сервер один, это делает задачу проще,
несмотря на усложнение сервера.
Новые функции Daq Pascal:
url_encode, url_decode.
Нужны для анализа HTTP запросов
и при написании CGI скриптов.
Устранен маленький баг - при разрыве связи по именованному каналу
при отключении клиента фиксировалась ошибка, хотя в принципе это
нормальная ситуация. Теперь ошибка не регистрируется.
Добавлена документация по HTTP, CGI etc.
В шаблоны редактора добавлено несколько ставших стандартными процедур
и пример web4daq.pas как прототип CGI-скрипта.
24.09.2006
DIM Help Install
Благодаря усилиям Дарьи Дроздовой обновлен Help.
Существенно обновлен Help по ADAM (доступна при установке Crw32Extra).
Опять обновление DIM Server: добавлена опция UsePadding.
Теперь по умолчанию Padding (выравнивание полей по 8-байтной границе) отключено.
Раньше этой опции не было и выравнивание было всегда включено.
Это порождало проблемы при использовании формата DIM (см. комментарии к прошлому релизу).
Проблема в том, что при включении опций UsePadding=1, UseFormat=1DIM сервер часто падает.
Похоже, это проблема самого DIM.
[&DimSrv]
...
UsePadding = 0 ; Использовать выравнивание DIM сервисов?
...
Существенно обновлены инсталляторы. Фейс сделан английский (чтобы не было проблем при установке на англоязычной версии Windows).
14.09.2006
DIM tinyWeb
Прошлое обновление DIM Server оказалось небезопасным: DIM стал падать
при многократных перезагрузках DIM сервера (замечено Ю.И.Виноградовым).
Было решено сделать новую возможность (использование строки формата в сервисах DIM)
опциональной и по умолчанию отключенной (то есть по умолчанию DIM теперь работает по-старому).
Новая возможность включается только при явном указании
[&DimSrv]
...
UseFormat = 1 ; Использовать формат DIM сервисов
...
В каталог Resource\DaqSite добавлен (пока чисто формально)
tinyWeb
- очень маленький, но вполне функциональный Web-сервер, который свободно распространяется
в исходных кодах, написан под Delphi, компиллируется под CRW-DAQ, поддерживает CGI и т.д.
На основе этого Web-сервера в будущем планируется строить DAQ-системы с поддержкой Web-интерфейсов.
Обновлен DIM Server по результатам командировки в CERN.
Теперь он корректно работает с другими пакетами (DimTree, PVSS и т.д.)
Изменение состоит в том, что теперь сервер публикует корректную строку формата.
Например, при публикации сервиса [a,b,c,d] с тегами типа [integer,integer,real,string]
строка формата будет "I:2;D:1;C".
Очень рекомендую пользоваться консольной командой:
@run dimtree
Она позволяет видеть все опубликованные DIM сервисы в реальном времени.
Новые функции Daq Pascal:
getclockres, setclockres.
Они служат для определения и задания разрешения (кванта времени) системного таймера.
Это альтернатива использованию @mmtimer, имеющая больше возможностей.
Однако обе функции не работают под Win-9x (возвращают всегда ноль).
Правда, под Win-9x они и не имеют смысла...
Пример demo_fast_poll_nt иллюстрирует работу с новыми функциями.
Строка "_nt" в названии подчеркивает, что пример работает для ядра NT
(WinNT,Win2k,WinXp).
В команду @speak добавлена поддержка тегов.
Теги позволяют легко управлять голосом (громкость, скорость, тембр, интонация и т.д.)
Вот примеры основных тегов:
@speak \Rst\Сброс всех тегов на значения по умолчанию.
@speak Пауза \Pau=1000\в речи на 1000 миллисекунд.
@speak Громкость речи \Vol=65535\по максимуму \Vol=0\по нулям.
@speak \Spd=100\Скорость речи 100 слов в минуту.
@speak Тон (тембр) речи в герцах \Pit=100\низкий \Pit=200\высокий.
@speak Читать \Pro=1\с интонацией или \Pro=0\без интонации (монотонно).
@speak Читать слова \RmS=1\по буквам \rms=0\нормальными словами.
@speak Подчеркнуть интонацией выражение \Emp\СЛЕДУЮЩЕГО слова.
@speak Не надо подчеркивать интонацией \Dem\СЛЕДУЮЩЕЕ слово.
Соответственно обновлено описание @help @speak в консоли и в eval.
Обновлен также SpeakServer.
Изменения в команде @speech: теперь можно задавать речевой движок @speech engine по имени,
а не только по номеру (который может меняться при установке новых движков).
Делать надо так:
@speech engine 1 Установили первый движок
@speech engines Прочитали список установленных в системе речевых движков
SpeechEngine[1] = Adult Female #1 Russian (L&H)
SpeechEngine[2] = Adult Male #1 Russian (L&H)
@speech engine Adult Female #1 Russian (L&H) Теперь, зная имя, можно прописать его при вызове @speech engine
Имя речевого движка не меняется, поэтому по имени можно надежно его идентифицировать.
Соответственно обновлены примеры DEMO_SPEAK1,
DEMO_SPEAK2 и SpeakServer.
Теперь есть возможность при нажатии на кнопку закрытия окна прятать окно (делать невидимым),
вместо того чтобы сворачивать их в значек.
Эта возможность управляется кнопкой меню "Окна\Прятать свернутые окна" или Ctrl+Alt+H.
При нажатой кнопке окна будут прятаться с экрана (становиться невидимыми) при закрытии или свертывании окна.
При не нажатой кнопке все будет как раньше - окна будут сворачиваться в значек.
Начальное значение кнопки задается в переменной HideMdiIconicChildren=0/1 в секции [System]
в файле Crw32.ini.
Устранил баг в процедуре чтения конфиг-файлов (например, readini).
Он заключался в неверной интерпретации пустых строк из-за игнорирования символа конца строки.
Это приводило, например, к такой ошибке:
[Section] [Section]
X = one X =
Y = two Y = two
[] []
Читается правильно: Читается неправильно:
X=ONE X=Y (должна быть пустая строка!)
Y=TWO Y = TWO
Теперь оба случая читаются правильно.
Баг, конечно, не очень вредный, но все же...
Он был известен давно, да вот руки не доходили (или ноги).
Устранил сразу два (тоже не очень вредных) бага в процедуре чтения калибровок.
Первый баг заметил Сергей Фильчагин: при обратном порядке объявлений
Calibration#n некоторые калибровки не читались.
Второй баг состоит в том, что вопреки обычной практике, выражение
Calibration#n было чувствительным к регистру символов, поэтому при
замене, например, на CALIBRATION#n калибровка не читалась.
1)Читалось верно:
Calibration#1 = ..\Calibr\_HrCn.cal U(mV) T Tc Line HrAl 0 10
...
Calibration#14 = ..\Calibr\_HrAl.cal U(mV) T Tc Line HrAl 0 10
2)Читалось не верно (калибровка 1 не читалась):
Calibration#14 = ..\Calibr\_HrAl.cal U(mV) T Tc Line HrAl 0 10
...
Calibration#1 = ..\Calibr\_HrCn.cal U(mV) T Tc Line HrAl 0 10
3)Читалось не верно (калибровка 1 не читалась):
CALIBRATION#1 = ..\Calibr\_HrCn.cal U(mV) T Tc Line HrAl 0 10
...
Calibration#14 = ..\Calibr\_HrAl.cal U(mV) T Tc Line HrAl 0 10
Теперь все читается корректно.
В драйвер устройств ADAM-4000,7000,87000 введены новые команды:
StartCommand = s - задает список команд, которые модуль посылает при старте.
StopCommand = s - задает список команд, которые модуль посылает при остановке.
При этом в командах работает замена макроса "??" на HEX-адрес модуля.
Пример:
[DeviceList]
i7018 = device adam adam-7018
[i7018]
Port = 2
Address = 1
....
StartCommand = $??M ; Чтение имени модуля
StartCommand = $??F ; Чтение версии модуля
StartCommand = ~??C0 ; Отключение компенсации холодного спая
StopCommand = #??
При этом модуль подаст команды $01M, $01F, ~01C0 при старте и команду #01 при завершении работы.
см. также тут.
Введение старт/стоповых команд несколько расширяет возможности конфигурирования без серьезной переделки драйвера.
Начата работа по полной переработке справочного файла. Теперь это файл crw-daq.htm в HTML.
Старый файл справки пока остается, но меняться больше не будет.
Пока успел сделать только часть. Работа будет продолжена в следующих версиях...
23.03.2006 ... 27.03.2006
@async @speak @speach
В интерпретатор введена команда @async.
Ранее она присутствовала только в системном калькуляторе, теперь стала доступна везде.
См. описание eval.
Эта команда служит для асинхронного выполнения команд в основном потоке программы,
через задержанный вызов системного калькулятора, связанного с основной консолью.
Если точнее, вызов @async помещает следующую далее строку в очередь FIFO и возвращает
длину помещенной в очередь строки.
Команды извлекаются из очереди по таймеру и выполняются с периодом примерно 55 ms.
Вызов @async, в отличие от @system и @global является абсолютно безопасным.
Это связано с тем, что @async ничего не делает, кроме как помещает сообщение в очередь,
а это очень короткая операция.
То есть блокировки вызывающего потока при вызове @async не происходит.
В отличие от этого, при вызове @system или @global вызывается системный калькулятор.
Если системный калькулятор в момент вызова был занят длительными вычислениями,
вызывающий поток блокируется до завершения вычислений.
По указанной причине вызовов @system и @global надо по возможности избегать.
У нас же RealTime кругом!
Причиной вызова @system может служить желание прочитать переменную из системного калькулятора
(@async не позволяет это сделать) или задать переменную в системном калькуляторе непосредственно,
без задержки.
В остальных случаях вызов @async предпочтительнее.
Вызовы @system, @global стали безопаснее.
Если точнее, вызов @system @async стал эквивалентен безопасному вызову @async,
а вызов @global @async тоже стал безопасным в смысле блокировки потоков.
В интерпретатор введена команда @speak и @speech.
Эти команды вводят в оборот речевой синтезатор.
Для справки по параметрам можно ввести имя команд без аргументов.
Команды синтезатора могут выполняться только в основном потоке, поэтому должны вызываться
из Daq Pascal только асинхнонно. При неверном вызове они игнорируются.
Например:
b:=eval('@async @speech engine 1'); {включить синтезатор, движок номер 1}
b:=eval('@async @speech engines'); {показать список доступных движков}
b:=eval('@async @speak Привет, Мир.'); {сказать классическую фразу}
b:=eval('@async @speak Температура '+Str(Round(temp))); {сказать значение темрературы}
b:=eval('@async @speech engine 0'); {отключить синтезатор}
По умолчанию речевой синтезатор отключен, чтобы введение речевого синтезатора не влияло
на стабильность основной программы.
Для его активизации надо задать положительный номер речевого движка (@speech engine).
Задание нулевого номера движка приводит к отключению синтезатора.
Команды синтезатора становятся доступными только после установки двух Freeware компонентов
spchapi.exe и lhttsrur.exe, которые можно найти в меню Web\Home.
Если указанные компоненты не установлены, то вызов @speech engine выдаст сообщение
об ошибке (типа нет такого-то интерфейса) в консольном окне.
Пример demo_speak1 иллюстрирует работу с речевым синтезатором
через вызов @speak, @speach.
Пример demo_speak2 иллюстрирует работу с речевым синтезатором
через речевой сервер &SpeakSrv.
Настоятельно рекомендуется использовать сервер &SpeakSrv и не использовать @speak, @speech,
так как при запуске звукового синтезатора в отдельном процессе надежность работы будет выше.
В пример demo_dim_gui добавлен речевой синтезатор &SpeakSrv.
Просто для тестирования и иллюстраций.
В шаблоны добавлено несколько конфигураций (например, [&DimSrv], [&SpeakSrv]),
и программ (procedure Speak).
В многие DEMO примеры добавлен инсталлятор типа InstallDaq32-xxx.nsi, где xxx - имя установки.
Например, в demo_elmb.
Из указанного инсталлятора в считанные минуты можно сделать удобный дистрибутив для большинства наших измерительных систем.
Для этого надо в "шапке" файла заменить несколько констант.
Найден и устранен (надеюсь) очень хитрый баг.
В случае запуска двух консольных программ-серверов с обменом по анонимному каналу при остановке конфигурации DAQ
возникал классический DeadLock (взаимная блокировка потоков).
Взаимная блокировка возникала при попытке завершения потоков ввода-вывода, обслуживающих анонимные каналы.
Проблема устранена за счет отсоединения потоков ввода-вывода, при этом ожидается, что они "умрут" сами.
Точнее, потоки уведомляются о необходимости "умереть" и отсоединяются, предоставленные своей грустной судьбе.
Здесь есть некоторый риск, что потоки не умрут, а будут "болтаться" без дела, ничего полезного не выполняя.
Во всяком случае, тестирование показало, что все вроде нормально. Время покажет.
Теперь потоки ввода-вывода по анонимным каналам видны в списке потоков при вызове монитора ресурсов.
Эти потоки обозначаются как StdIn#Pid, StdOut#Pid.
StdIn#128 - поток, обслуживающий StdIn процесса с идентификатором Pid=128.
StdOut#128 - поток, обслуживающий StdOut процесса с идентификатором Pid=128.
Это позволяет видеть, какие процессы с каналами связи запущены и как они работают.
Устранен (надеюсь) не принципиальный баг, связанный с тем, что иногда значек программы оставался в строке задач
(TaskBar) и одновременно присутствовал в строке уведомлений SysTray.
12.03.2006 ... 19.03.2006
DIM read AdmiLink @mmTimer RealTime 1 kHz
DEMO_DIM_GUI DEMO_FAST_POLL
Реальное время становится все
реальнее и
реальнее.
В систему введен мультимедийный таймер, который позволяет организовывать опрос потоков с частотой до 1 kHz.
По умолчанию таймер НЕ АКТИВИЗИРОВАН, все работает как обычно.
Для его активизации используется новая консольная команда @mmtimer.
@mmtimer - новая консольная команда:
В консоли или программе на Daq Script это выглядит так:
t=@mmtimer ; Чтение периода таймера, [ms]
@mmtimer 1 ; Разрешение таймера
@mmtimer 0 ; Запрещение таймера
В программе на Daq Pascal это будет выглядеть как
b:=eval('@system @mmtimer 1'); {Enable timer}
b:=eval('@system @mmtimer 0'); {Disable timer}
После включения таймера все начинает крутиться в 10 раз быстрее.
Если точнее, переключение потоков начинает работать с частотой около 1000 Hz.
По крайней мере, это верно для потоков с приоритетом tpTimeCritical.
Появление быстрого таймера имеет такие любопытные последствия:
Обмен по COM-порту теперь может иметь частоту до 1000 Hz.
Для этого, помимо включения таймера, надо прописать
Это специальные значения, по умолчанию быстрый опрос устройств отключен.
Значение InquiryPeriod=0 - наиболее критично, ненулевое значение приведет
к снижению частоты опроса устройства до обычных 100 Hz.
DevicePolling может иметь, в принципе, другие значения, при этом первый параметр
задает период в миллисекундах с квантом 1 ms.
Следует участь также, что при снижении приоритета ниже tpTimeCritical
стабильность частоты опроса резко падает.
При программировании устройств с быстрым опросом следует учесть, что все функции времени
(time, msecnow,
tm_event ...) кроме mksecnow
по-прежнему имеют квант времени порядка 10 ms, поэтому опрос таких устройств следует организовывать
особым образом.
Кроме того, обычно применяемая конструкция записи в кривые
putao(n,time,data)
работать будет
не совсем верно. Дело в том, что вызов time при опросе с частотой 1000 Hz вернет 9 раз
одно и то же время и только в 10 раз время изменится.
Это приведет к тому, что 9 из 10 вызовов потеряются (будут проигнорированы),
так как запись в кривую делается только при обновлении времени.
Добавлен пример DEMO_FAST_POLL, который иллюстрирует
процедуру создания быстрых систем с частотой опроса до 1000 Hz.
Почитайте описание fast_poll.htm.
Снято ограничение Length(s)<255 на строки в функциях sGetTag, sSetTag,
а также в процедуре Read, Readln.
Это позволяет передавать через DIM строки длинной до 32768.
Вызов DevSend(0,s) теперь посылает сообщение самому себе.
Раньше это выглядело бы как DevSend(RefFind('Device '+DevName),s).
Обновлен AdmiLink до версии 1.1.
Добавлена привязка к командной строке, IP и MAC адресу.
Добавлено меню Web с некоторыми ссылками.
Добавлен пример DEMO_DIM_GUI, который иллюстрирует
процедуру создания распределенных в сети систем клиент-сервер на основе технологии DIM.
Почитайте описание sin_client.htm.
В текстовых и консольных окнах добавилось "выпадающее" меню по правой кнопке мыши.
Если будет удобно, со временем и в окна с кривыми добавим...
Введена поправка, которая в основном снимает проблему при чтении\сохранении данных *.dat.
Раньше при открытии диалога "Выбор кривой" при чтении *.dat файла,
файл оставался открытым и потому надолго (на время диалога) блокировал запись в файл.
Если DAQ программа пытается записывать в заблокированный файл, возникает коллизия.
Данные при этом не обязательно пропадают (они могут быть сохранены позже),
но DAQ система фиксирует ошибку.
Теперь файл на время диалога закрывается, что снижает риск возникновения коллизий.
Вероятность коллизии остается, так как в момент чтения файла программа записи может
попытаться записать данные в файл, однако она резко снижена, так как файл при чтении
блокируется лишь на короткое время.
В интерпретаторе DAQ SCRIPT существенные изменения:
Раньше входная строка всегда приводилась к нижнему регистру, теперь регистр строки не меняется.
Например:
x=1
@echo "Переменная X=%x"
В старой версии выведет
"переменная x=1"
а в новой версии выведет
"Переменная X=1"
Команды (которые начинаются с символа @) теперь могут возвращать результат
и использоваться в командах присвоения.
Например, для запуска процесса и затем его уничтожения можно написать:
p=@run mspaint.exe
@echo Запущен процесс mspaint.exe, PID=%p
n=@pid kill %p
if n then @echo Процесс успешно убит!
В системную консоль добавлен ряд новых команд. Вот перечень наиболее полезных команд:
@help, @list, @run, @pid, @polling, @system,
@async, @menu, @view, @memory, @echo, @guard,
@sleep.
Для получения справки наберите в консоли
@help
Чтобы узнать список доступных переменных, констант, команд и функций, наберите в консоли
@list
Вообще большинство команд при вызове без параметров выдают справку.
В совокупности команды консоли позволяют делать из Daq Script или Daq Pascal
например такие вещи:
Управлять правами доступа Guard
Выполнять команды меню из программы
Завершать работу конфигурацию DAQ, CRW и Windows
Перезапускать конфигурацию, загружать другую конфигурацию DAQ
Скрывать главное меню, панель иструментов, статусную строку в целях упрощения внешнего вида и защиты
... и многое другое (все не перечислить)...
Доступ к системному интерпретатору возможен из программ через функции
eval, global.
Эти функции содержат более детельное описание новых возможностей и массу примеров.
Например:
--Скрипт, который завершает работу DAQ конфигурации, выходит из программы
--и завершает работу Windows через 15 секунд
r:=eval('@system @async @guard root');
r:=eval('@system @async _Daq_Force_Stop_=1');
r:=eval('@system @async _Daq_Force_Exit_=1');
r:=eval('@system @async _Crw_Force_Exit_=1');
r:=eval('@system @async @view max FormCrw32');
r:=eval('@system @async @view norm FormDaqControlDialog');
r:=eval('@system @async @menu run FormDaqControlDialog.ActionDaqStop');
r:=eval('@system @async @menu run FormDaqControlDialog.ActionDaqDone');
r:=eval('@system @async @run /Hide %ComSpec% /c shutdown -s -t15');
r:=eval('@system @async @menu run FormCrw32.ActionFileExit');
Весьма содержательные примеры на эту тему помещены в конфигурации DEMO_EDIT.
Там показано, как останавливать\перезапускать DAQ, CRW, Windows, работать с меню,
панелью инструментов и статусной строкой.
Предпринята попытка упорядочить горячие клавиши программы.
За образец был взят стандартный Notepad и AkelPad (редактор в составе Total Commander).
По крайней мере, команды текстового редактора теперь практически совпадают с AkelPad.
Просьба пользователям - попробовать и высказать мнение.
Кстати, список всех клавиш доступен по команде
@list keys
Устранена одна из дыр в защите Guard. Эта дыра связана с файловым диалогом.
Если пользователь запускал CRW32 с правами Администратора
(например, через ярлык AdmiLink), а затем открывал любой диалог ввода-вывода имени файла,
он мог получить права Администратора, просто нажав правую кнопку мыши и вызвав в выпадающем меню
любой файл на выполнение.
Теперь, если текущий уровень доступа ниже чем Root, файловый диалог имеет "устаревший" вид,
в котором меню по правой кнопке не работает.
То есть диалог файлового ввода больше не является дырой в защите.
Устранено несколько мелких интерфейсных неточностей.
В функции ParamStr добавилось определение параметров:
HostName, UserDomain, IPAddress, MACAddress.
В текстовом редакторе добавилась кнопка
разрешения\запрета редактирования.
Большое количество DEMO примеров вынесена в дополнительный дистрибутив.
Основной дистрибутив становится все меньше...
21.02.2006 22.02.2006
ELMB LA1.5 LA2USB
С Днем Защитника Отечества!
Обновлен инсталлятор, благодаря чему размер дистрибутивов существенно уменьшился
(за счет улучшения алгоритма сжатия).
Инсталлятор теперь проверяет права пользователя и выдает сообщение,
если пользователь не имеет прав Администратора.
Добавлены утилиты (Small CD Writer, NetLab, GNU архиваторы и т.д)
Исправлена ошибка в модуле _OPCC.PAS, из-за которой OPC клиент ELMB мог подвисать.
В Extra пакет добавлен пример DEMO_PLC_ICPDAS.
Там текущая версия написанного Алексеем Вьюшиным софта для контроллеров ICP-DAS,
включая радиометрический канал. Все вопросы - автору.
Изменились стили линий при рисовании кривых. Теперь:
0 - нет линии
1..7 - сплошная линия данной толщины
8..15 - разные варианты пунктирной линии
Введение толстых линий позволяет делать "жирные" графики, которые видно издалека.
Пересмотрены библиотеки измерения времени _rtc.pas и запуска задач _task.pas.
Для пользователя ничего не изменилось, но будьте внимательны, сообщайте о глюках.
Обновлен DIM сервер, в соответствии с новым каноном (см.далее).
Введены канонические правила для создания консольных драйверов.
Собственно, это библиотека _ascio.pas, плюс набор правил и шаблонов для написания консольных
программ, которые могут работать как подключаемые к CRW-DAQ драйверы, как DIM сервер, например.
Добавлена поддержка технологии OPC.
Это означает несколько вещей:
В дистрибутив (в инсталлятор) добавлены OPC компоненты
(OPC Core Components 2.00 Redistributable),
которые нужно установить на машину, если есть желание использовать какой-то OPC сервер.
Некоторые пакеты автоматически устанавливают поддержку OPC, однако на "голой" машине
OPC работать не будет, поэтому иметь компоненты под рукой не помешает.
В Delphi библиотеку добавлены модули _OPC.PAS, _OPCc.PAS.
Эти модули доступны при написании консольных драйверов.
Модуль _OPC.PAS содержит общие определения, необходимые для работы с OPC,
фактически это основная библиотека OPC (она не изменится).
Модуль _OPCc.PAS содержит объекты, облегчающие написание OPC клиентов.
В принципе, можно писать клиенты и без нее, но технология OPC настолько громоздкая,
что без соответствующей надстройки это будет просто мучением.
Добавлен пример DEMO_ELMB, в котором данные АЦП
считываются через OPC клиента.
Этот пример может служить прототипом для других OPC клиентов.
К сожалению, из экономии места пришлось удалить почти всю документацию по ELMB,
больно уж она громоздкая.
В Extra пакет внесены основнополагающие спецификации OPC.
К сожалению, в полном объеме спецификации весят слишком много и в дистрибутив не попали.
Добавлен пример DEMO_PHOS_COOLING.
Это слегка урезанный вариант системы охлаждения первого модуля PHOS.
В дистрибутив внесена таблица RelNi100.ini
для никелевых датчиков температуры (Ni-100 RTD).
Обновлена таблица RelPt100.ini
для платиновых датчиков температуры (Pt-100 RTD).
Старая таблица сохранена в файле RelPt100.ini.OLD.
Добавлены стандартные калибровки
~~\Resource\DaqSite\StdLib\Calibr\_Ni100.cal,
~~\Resource\DaqSite\StdLib\Calibr\_Pt100.cal
для никелевых и платиновых датчиков температуры (Ni-100, Pt-100 RTD).
Они могут применяться, как обычно, в случае стандартных датчиков, если высокая точность
(лучше 1°С) не требуется.
В случае нестандартных датчиков или для достижения высокой точности требуется индивидуальная калибровка.
17.09.2005 18.09.2005 19.09.2005
DIM
Обновлен справочный файл DaqPascalApi.
Вроде бы формально там есть теперь все функции Daq Pascal, кроме CAMAC.
Не все справки сделаны хорошо, но хоть так...
Обновлен дистрибутив Crw32 Extra Kit. Там добавлены ресурсы и DEMO.
Дистрибутив теперь поставляется в виде ISO файла.
TotalCommander поможет вытащить из него InstallCrw32, если надо.
Обновлен DIM с версии 15.19 до 15.21.
Ничего нового для нас там нет, ребята просто фиксят баги и ловят глюки. Как и мы.
Пойман глюк и зафиксен баг в стандартной программе _DATSAVE.PAS.
Он проявлялся в том, что неверно работали ссылки типа CurveList = [Section].
Теперь все работает как надо.
В стандартную библиотеку добавлен _DIO144.PAS.
Вроде бы удалось устранить проблему с неопределенным состоянием DIO при включении программы.
Для этого карта включается с задержкой и программируется непосредственно перед началом вывода.
Пример конфигурации _DIO144-PAS.CFG.
[DeviceList]
DIO = device software program
[DIO]
Comment = DIO-144
InquiryPeriod = 1
DevicePolling = 10, tpTimeCritical
ProgramSource = ~~\Resource\DaqSite\StdLib\DaqPas\_DIO144.pas
DigitalInputs = 144
DigitalOutputs = 6
DelayRunCount = 1000 ; подключать карту с задержкой
tagPolling = DIO.Polling ; тег разрешения опроса
; Аппаратная конфигурация DIO-144 задает какие порты работают на ввод, какие на вывод.
; Для DIO-24/48 надо закомментировать лишние чипы.
Base = $2C0 ; базовый адрес
; 8255 * A B CL CH - порт чипа,0=запись,1=чтение
i8255#0 = 1 1 1 1 ; чип 0 запрограммирован на ввод по всем портам
i8255#1 = 1 1 1 1 ; чип 1 запрограммирован на ввод по всем портам
i8255#2 = 1 1 1 1 ; чип 2 запрограммирован на ввод по всем портам
i8255#3 = 1 1 1 1 ; чип 3 запрограммирован на ввод по всем портам
i8255#4 = 1 1 1 1 ; чип 4 запрограммирован на ввод по всем портам
i8255#5 = 0 0 0 0 ; чип 5 запрограммирован на вывод по всем портам
Link DigitalInput ...
Link DigitalOutput ...
Много нового в каталоге DEMO.
Несколько новых и старых примеров драйверов устройств (LA2USB,UPS-420,PISO).
Сюда также включены некоторые работающие (но не обязательно самые свежие) версии некоторых установок,
таких как Prometheus, Straus, Phos и т.д.
Надо понимать, что установки продолжают развиваться независимо, поэтому демо-версии могут отличаться
от программ на этих установках.
Демо версии включены в дистрибутив как примеры для обучения и как шаблоны для будущих разработок.
Демо конфигурации крупных систем включены в Crw32 Extra Kit, мелких - в основной дистрибутив.
Добавлено еще несколько описаний в DAQ PASCAL API HELP.
23.08.2005
*.dat
Проведен большой объем тестов. Устранялись мелкие недочеты.
В стандартной утилите чтения *.dat добавлена возможность сжатия данных.
Это позволяет сильно сокращать объем данных, исходя требуемого из баланса точность/объем.
Алгоритм сжатия примерно такой же, как online сжатие в процессе сбора данных DAQ,
но теперь он доступен offline.
В DIM Server добавлены переменные StdInPipe, StdOutPipe для задания размера анонимного
канала связи при запуске DimSrv.Exe.
Это позволяет избежать потерь данных при больших объемах прикачиваемых через DIM данных.
22.08.2005
*.dat _crwsave.pas _datsave.pas
Переведен в HTML еще кусок Help.
Теперь уже больше половины Daq Pascal Api имеет HTML HELP.
Напоминаю, по Ctrl+F1 над словом в окне редактора можно быстро получать справку
по функциям DAQ PASCAL.
В меню "Печать" окон - кривых и окон-поверхностей добавился пункт
"Скопировать как таблицу в буфер обмена".
Это позволяет очень быстро копировать данные, например, из CRW-DAQ в Excel
или другой пакет для математической обработки.
Раньше для этого надо было создавать текстовое окно с таблицей, копировать данные из окна.
Теперь все стало проще.
Новая стандартная программа _crwsave.pas
для сохранения данных в *.crw.
В основном эта утилита нужна для "быстрых" систем, в которых надо сохранять одноразовые
порции данных, обычно без привязки к календарному времени, когда либо играет роль только локальное
время, либо вообще по оси абсцисс отложено не время, а что-то еще.
Формат *.dat для этого не пригоден.
Новая утилита очень похожа на старую _savecrw.pas, но немного по-другому конфигурируется:
Пример конфигурации:
[DeviceList]
&QMS_CRWSAVE = device software program
[&QMS_CRWSAVE]
Comment = Program to save data to *.CRW files
InquiryPeriod = 1
DevicePolling = 50, tpNormal
ProgramSource = ..\daqpas\_crwsave
OpenConsole = 0 ; Открывать консольное окно
DebugFlags = 15 ; Флаги для отладочных сообщений
FilePrefix = QMS_ ; Префикс имени файла, любой длины
DataPath = ..\data ; Каталог данных
WinCaptionTag = QMS_CrwCaption ; String Тег имени окна
WinTitleTag = QMS_CrwTitle ; String Тег заголовка окна
WinLabelTag = QMS_CrwLable ; String Тег легенды окна
WriteEnableTag = QMS_CRWSAVE ; Integer Тег кнопки сохранения
WriteErrorsTag = QMS_IoErrors ; Real Тег счетчика ошибок
CurveList = QMS_CH0, QMS_CH1 ; Список сохраняемых кривых
CurveList = [QMS_Curves] ; Допустимы также ссылки на секции
Несколько комментариев:
CurveList - список сохраняемых кривых, задается так же, как в секции описания окон, в виде списка.
Кроме того, список файлов может включать имя секции в квадратных скобках [], содержащей список кривых.
Обычно это секция описания окна с кривыми.
Указание секций в списке кривых во-первых позволяет сократить объем описания, если секции окон уже есть,
а во-вторых позволяет преодолеть ограничение длины списка из-за использования коротких строк (255 символов).
Поэтому рекомендуется всегда использовать ссылки на списки кривых, а не сами кривые.
Другое отличие новой утилиты состоит в том, что сохранение теперь можно делать не только через тег,
но и посылкой сообщения, например:
Пример посылки сообщений:
r:=devmsg('&QMS_CRWSAVE Save Windows QMS_Curves'+CRLF);
r:=devmsg('&QMS_CRWSAVE Save CurveList QMS_CH0,QMS_CH1'+CRLF);
Сообщение "Save Windows Window1,Window2,.." приводит к сохранению в файл списка окон с кривыми.
Сохраняемые окна должны быть описаны в секции [Windows].
Сообщение "Save CurveList Curve1,Curve2,.." приводит к сохранению в файл окона со списком перечисленных кривых.
Список кривых может содержать секции, как и в конфигурационном файле.
Новая стандартная программа _datsave.pas
для сохранения данных в *.dat.
Эта утилита нацелена на сохранение "медленных" данных, которые измеряются непрерывно длительное время
и должны быть "привязаны" к календарному времени.
Утилита не пригодна для сохранения данных, у которых по оси абсцисс отложено не реальное время, а что-то еще.
То есть координата x сохраняемых кривых должна получаться из функции time.
Новая утилита очень похожа на старую _savedat.pas, но записывает данные в другом формате и по-другому
конфигурируется:
Пример конфигурации:
[DeviceList]
&QMS_DATSAVE = device software program
[&QMS_DATSAVE]
Comment = Program to save data to *.dat files
InquiryPeriod = 1
DevicePolling = 1000, tpNormal
ProgramSource = ..\daqpas\_datsave
OpenConsole = 0 ; Открывать консольное окно
DebugFlags = 15 ; Флаги для отладочных сообщений
SavePeriod = 60 ; Период сохранения, секунд
TimeQuota = 100 ; Квота времени, миллисекунд
FilePrefix = QMS_ ; Префикс имени файла, любой длины
DataPath = ..\data ; Каталог данных
DataFormat = XY:BASE64 ; Формат из списка XY:ASCII, XY:HEX, XY:BASE64
WriteEnableTag = QMS_DATSAVE ; Integer Тег кнопки разрешения сохранения
WriteErrorsTag = QMS_IoErrors ; Real Тег счетчика ошибок
CurveList = QMS_CH0, QMS_CH1 ; Список сохраняемых кривых
CurveList = [QMS_Curves] ; Допустимы также ссылки на секции
Несколько комментариев:
CurveList - список сохраняемых кривых, задается так же, как в секции описания окон, в виде списка.
Кроме того, список файлов может включать имя секции в квадратных скобках [], содержащей список кривых.
Обычно это секция описания окна с кривыми.
Указание секций в списке кривых позволяет сократить описания, если секции окон уже есть.
Список может иметь до 1024 элементов.
SavePeriod задает, как и раньше, период сохранения в секундах, но теперь он имеет типичное значение
в несколько минут.
Дело в том, что теперь программа отслеживает содержимое кривых и сохраняет не только текущее значение,
но и всю историю.
Поэтому редкое сохранение не приводит к потере данных в новом формате.
Напротив, редкое сохранение приводит к сокращению объема файла, так как при записи событий в медленно
меняющуюся кривую с учетом округления происходит сжатие данных.
Но для сжатия данных надо, чтобы данные накапливались достаточное время.
Нельзя сжимать текущее значение, так как следующее значение еще неизвестно.
Вот когда при следующем опросе значение не изменится, станет возможным "выбросить" промежуточную точку
с таким же значением.
Если же сделать сохранение достаточно редким, то есть сохранять данные с запозданием, то сохраняться будут уже
сжатые данные.
Надо только помнить, что у кривых может быть конечная история, так что длина истории и период сохранения должны быть
согласованы.
История должна быть такой, чтобы за период сохранения данные не пропали раньше времени.
TimeQuota задает ограничение по времени на выполнение программы сохранения в одном кванте времени.
Это ограничение введено, чтобы программа не "подвисала" в длительных циклах, не блокировала доступ
к общим ресурсам.
Если программа сохранения не успела сделать все сохранение в одном кванте времени,
она посылает самой себе сообщение, чтобы "проснуться" досрочно на следующем кванте времени и продолжить
работу.
То есть, допустим, программа активизируется раз в минуту и в течение нескольких квантов времени
сохраняет появившиеся новые данные.
DataFormat - формат сохранения данных, один из следующих:
XY:ASCII - данные сохраняются в виде десятичных чисел.
XY:HEX - двоичные данные сохраняются в виде hex_encode.
XY:BASE64 - двоичные данные сохраняются в виде mime_encode.
В начале файла помещается заголовок - секция [CRW-DAQ DATA FILE].
В этой секции перечисляются кривые, сохраненные в файле.
Далее вперемежку идут порции данных из кривых, помещенные в секции с именем кривой.
В начале каждой порции указан формат @Format=.. из набора XY:ASCII, XY:HEX, XY:BASE64.
В каталоге Demo_Dim_Server/Config находится пример QMS_SERVER
и QMS_CLIENT,
который помимо сетевого обмена через DIM также иллюстрирует использование утилит сохранения данных.
Штатная команда чтения *.dat файлов
модифицирована, она теперь "понимает" и старый и новый формат *.dat,
а также позволяет выбирать время начала отсчета, чего не было раньше.
Утилита существенно полагается на то, что 6 последних знаков содержат дату в формате YYMMDD,
YY-год,MM-месяц,DD-день.
По этой причине записанные *.dat файлы переименовывать надо осторожно, не нарушая даты в имени файла.
20.08.2005
paramstr
В диалоге "Общие свойства устройства Dev" теперь можно на ходу менять
частоту и приоритет потока устройства.
Эта возможность доступна только на уровне доступа Root.
В основном это нужно для отладки.
Новые возможности paramstr:
paramstr('Консоль '+devname) или paramstr('Console '+devname)
возвращает имя окна консоли для данного устройства.
19.08.2005
crvlock crvunlock DaqFileRef
Сделана защита от несбалансированного вызова функций
crvlock/crvunlock.
Раньше это приводило бы к подвисанию всей программы, теперь просто к генерации ошибки DAQ.
Вызов crvins(c,maxint,x,y) теперь можно использовать
для добавления точки x,y в кривую c.
Новая функция daqfileref служит для разрешения (расшифровки)
файловых ссылок.
Например:
В конфигурации:
DataFile = ..\data\demo.txt
TempFile = ~~\temp\demo.tmp
В программе:
DataFile:=DaqFileRef(ReadIni('DataFile'),'.txt');
TempFile:=DaqFileRef(ReadIni('TempFile'),'');
Введены новые правила файловых ссылок в конфигурациях, см. описание функции
daqfileref.
Все как было, но:
Если имя файла начинается на ~~, подставляется домашний каталог CRW-DAQ,
где расположен Crw32.exe.
Если имя файла начинается на ~, подставляется домашний каталог пользователя,
где расположены Мои Документы и т.д.
Например:
~\demo.txt c:\Documents and Settings\User\demo.txt
~~\demo.txt c:\Crw32exe\demo.txt
Новые правила файловых ссылок в конфигурациях, позволяют размещать общие стандартные файлы
CRW-DAQ в дистрибутиве CRW-DAQ, а не в каждой DAQ системе по отдельности.
Введены следующие стандартные каталоги:
~~\Resource\DaqSite\DimServer - расположение DIM сервера.
~~\Resource\DaqSite\StdLib\Bitmaps - расположение стандартных картинок.
~~\Resource\DaqSite\StdLib\Calibr - расположение стандартных калибровок.
~~\Resource\DaqSite\StdLib\DaqPas - расположение стандартных программ Daq Pascal.
Отныне все стандартные программы и ресурсы должны располагаться там, а прикладные программы должны
ссылаться на них, чтобы избежать лишнего дублирования одинаковых файлов и облегчить техническую поддержку.
Стандартные программы из каталога ~~\Resource\DaqSite редактировать средствами DAQ Pascal
запрещено - редактор открывается в режиме ReadOnly.
Это сделано из соображений защиты проверенного кода от внесения ошибок.
Если стандартная утилита чем-то не устраивает и хочется внести изменения, надо завести ее локальную
копию и работать с ней.
Для этого надо скопировать стандартную программу в локальный ..\DaqPas каталог
и изменить ссылку ProgramSource.
А стандартные программы в каталоге CRW-DAQ менять запрещено.
15.08.2005
Watchdog.log timebase enumerate
Новая функция timebase возвращает момент времени,
соответствующий нулю по часам DAQ. То есть
ms = timebase + t * timeunits;
ms - астрономическое время в миллисекундах, по вызову msecnow
t - время по часам DAQ, то есть полученное по вызову time
Функция используется для перевода локального времени DAQ в астрономическое (например,
для записи в файл).
Конечно, время начала отсчета можно вычислять и записывать в константу, как делалось ранее,
но это не так удобно, как использование готовой функции.
Обновлен DIM с версии 15.09 до 15.19.
Ничего нового для нас там нет, но версия на сайте обновилась, пусть и у нас будет.
Введено ограничение на размер журнальных файлов в файле Crw32.ini, секции [System],
переменная DebugOutLimit, по умолчанию 32 MB.
При достижении предела file.log переименовывается в file.log.old с удалением
предыдущего file.log.old.
Это чтобы диск не переполнить при длительной работе.
Новая функция enumerate
(перечислить) позволяет получить в тексте список имен всех DAQ объектов данного типа.
Например, перечисление всех устройств DAQ выглядит так:
t:=enumerate(new_text,'Device');
for i:=0 to text_numln(t) do writeln(text_getln(t,i));
b:=text_free(t);
Злая собака
по кличке Watchdog стала полезнее.
Теперь в файл Temp\Watchdog.log c периодом около 5 секунд по умолчанию
(а вообще период задается в диалоге) пишется что-то вроде:
2005.08.15-15:48:15 : ++ Alex@crwbox
2005.08.15-15:51:23 : 0 hanging threads found
2005.08.15-15:51:28 : 1 hanging threads found
2005.08.15-16:15:25 : 0 hanging threads found
2005.08.15-16:15:30 : -- Alex@crwbox
То есть записывается:
Факт успешного входа в систему DATE-TIME : ++ User@Host
Факт успешного завершения системы DATE-TIME : -- User@Host
Текущий счетчик зависших потоков - каждые 5 секунд.
Чтобы не раздувать размер файла, сообщение
DATE-TIME : 0 hanging threads found
перезаписывается на месте предыдущей записи,
так что при успешной работе, то есть если не было подвисаний и работа завершена успешно,
а не аварийно, в файле останется только три записи, типа:
А вот если в файле осталось две записи (запись DATE-TIME : -- User@Host отсутствует),
это значит, что работа завершилась аварийно, причем по последней записи можно с точностью
около 5 секунд сказать, когда это случилось.
Таким образом, файл Temp\Watchdog.log позволяет анализировать работу установки
за длительный период (сколько раз запускалась программа, сколько раз "падала",
сколько времени отработала и т.д.).
Для такого анализа со временем планируется сделать специальную утилиту, а пока и глазками можно
много увидеть...
Чтобы файлы типа Temp\Watchdog.log не терялись при переустановке дистрибутива, в инсталяторе
введен пункт "Crw32 - Copy TEMP files", который позволяет копировать журнальные файлы
из предыдущей инсталяции в новый каталог.
По умолчанию опция включена.
14.08.2005
logo @run @env
Предприняты усилия для того, чтобы картинка - заставка CRW32 LOGO,
появляющаяся при загрузке системы, не "застревала" на экране. Надеюсь, это поможет...
Новая консольная команда @env в окне ГЛАВНАЯ КОНСОЛЬ.
Позволяет прочитать/записать переменную окружения данного процесса.
При вызове @env без аргументов выдается справка по команде.
Новая консольная команда @run в окне ГЛАВНАЯ КОНСОЛЬ.
Позволяет запускать внешние программы командной строкой.
При вызове @run без аргументов выдается справка по команде.
Некоторые программы, входящие в дистрибутив CRW-DAQ,
можно вызвать командой @run по псевдониму - короткому имени,
заменяющему полное имя файла.
В настоящее время работают псевдонимы:
dns, dns.exe - сервер имен DIM (DNS = Distributed Name Server).
did, did.exe - утилита для просмотра DIM сервисов
(DID = Distributed Information Display), одна из штатных утилит DIM.
Перед запуском DID надо задать переменную окружения dim_dns_node
- имя DNS сервера.
dimtree, dimtree.exe - - другая утилита для просмотра DIM сервисов в виде дерева,
одна из штатных утилит DIM.
Перед запуском DIMTREE надо задать переменную окружения dim_dns_node
- имя DNS сервера.
Команды @run, @pid, @env позволяют выполнять довольно осмысленные
пакеты команд, например:
@env dim_dns_node=Prometheus-kro - задать имя DNS сервера
@run /hide /high dns.exe - запустить DNS сервер, спрятанным, с высоким приоритетом
@run did - запустить просмотр сервисов DIM
@run cmd - вызвать командный процессор
@run control - вызвать Контрольную Панель
@run control userpasswords2 - вызвать панель управления пользователями
@pid kill dns.exe - убить сервер имен DIM
Все это имеет такие цели:
Облегчить работу по администрированию DIM.
Дать возможность быстро запускать программы с короткими именами.
Дать возможность вообще запускать программы в случае, если настройка текущего пользователя
не позволяет вызвать командную оболочку (такое тоже бывает).
Следует иметь в виду, что ГЛАВНАЯ КОНСОЛЬ доступна только для уровня доступа Root.
13.08.2005
DimServer _dimcrvio @adam @pid /icon=
Новый параметр командной строки /icon=xxx, где xxx - или имя *.ico файла с картинкой,
или номер стандартной картинки: 0=,
1=,
2=,
3=,
4=,
5=.
При указании имени файла картинки можно указывать или полный путь файла, или короткий путь относительно
домашнего каталога, где расположен исполняемый файл Crw32.exe.
Например:
Следует также заметить, что теперь номер картинки по умолчанию, если он не указан в командной строке,
вычисляется по полному имени исполняемого файла Crw32.exe.
Вычисление идет по формуле xxx=(d+n-2)%6, где d - номер диска (0=C:,1=D:...),
n - число символов "\" в имени файла (уровень подкаталога).
Поэтому при запуске экземпляров пакета с разных дисков или из каталогов разного уровня картинки будут
по умолчанию разные.
Новая консольная команда @pid в окне ГЛАВНАЯ КОНСОЛЬ.
Миниатюрный Task Manager, позволяет смотреть список процессов и убивать процессы
по номеру или по имени исполняемого файла.
При вызове @pid без аргументов выдается справка по команде.
Новая консольная команда @adam в окне ГЛАВНАЯ КОНСОЛЬ.
Позволяет включать/выключать режим отладки и открывать консоль ADAM DEBUG CONSOLE
для отладок (например, чтобы посмотреть протокол или выяснить, каков период опроса устройств).
При вызове @adam без аргументов выдается справка по команде.
Изменения в DimServer (файл dimsrv.pas),
связанные с установлением приоритетов потоков обслуживания обмена данными по каналу.
Это сделает связь более стабильной в смысле возможных задержек приемо-передачи в реальном времени.
В состав DimServer добавлена
программа _dimcrvio как стандартная утилита для передачи кривых в реальном времени.
Предполагается, что данные в кривую сервера поступают в реальном времени, не более одной точке за квант времени.
При этом данные, если они появляются, передаются клиенту и записываются в кривую клиента.
Таким образом, утилита не рассчитана на блочную передачу данных, когда в кривую сервера данные поступают
редко, но большими пачками (типа быстрых однократных измерений), так как в этом случае будет передана только
последняя точка кривой, а промежуточные пропадут.
Блочные данные лучше записать в файл и передать как имя файла (это на будущее).
Достоинство утилиты _dimcrvio в простоте и сравнительно несложном конфигурировании -
писать программу не надо, надо только создать теги и кривые и правильно все подключить.
Пара новых демонстрационных конфигураций QMS_SERVER.CFG, QMS_CLIENT.CFG в каталоге
DEMO_DIM_SERVER иллюстрируют использование стандартной
программы _dimcrvio.
Измерения с указанными конфигурациями показывают, что:
Задержка приемо-передачи в реальном времени составляет примерно 30 … 50ms.
Дисперсия задержки приемо-передачи в реальном времени составляет примерно ±10ms.
Задержка и дисперсия примерно сохраняются при загрузке сети до 25% (просмотр видеофильма по сети).
При более сильных загрузках дисперсия увеличивается.
Задержка измерялась как разность локальных времен по часам сервера в момент передачи и клиента в момент приема.
Из-за сдвига двух независимых часов существует постоянная константа, не имеющая отношения к задержке.
Даже после синхронизации командой типа
net time \\crwbox /set
разность показаний часов составила
порядка 150ms. Устранить ее сложно, поэтому величина задержки оценена по измерениям
задержки, возникающей при запуске клиента и сервера на одной машине (по одним часам).
А вот дисперсия измерялась "честно", на реальной сети.
Обе системы, клиент и сервер, были под Windows-XP.
12.08.2005
wdt_reset guard_check dirlist pidlist pidkill
Изменения в примере DEMO_TASK.
Этот пример можно использовать как иллюстрацию для новых функций
pidlist, pidkill, dirlist.
Новая функция pidkill позволяет
убивать процессы, которые выполняются на машине, по идентификатору процесса.
В сочетании с pidlist это позволяет делать следящие системы, препятствующие
запуску нежелательных процессов во время измерений.
Новая функция pidlist позволяет
узнать, какие процессы выполняются на машине.
Например:
writeln('Running process list:');
t:=pidlist(text_new);
for i:=0 to text_numln(t)-1 do writeln(text_getln(t,i));
b:=text_free(t);
В функции task_ctrl появилась
возможность задавать приоритеты потоков, обслуживающих каналы Stdin, Stdout,
что влияет на время задержки при работе с внешними программами через канал (например,
на Dim Server).
Также появилась возможность задавать класс приоритета запускаемого процесса и приоритет
основного потока этого процесса.
Например:
Измерение периода опроса:
writeln('Текущий период опроса = ',msecnow-wdt_reset(false),' ms');
Длинный цикл с подавлением предупреждения Watchdog:
while msecnow-wdt_reset(true)<10000 do begin
writeln('Прошло ',msecnow-wdt_reset(false),' ms, а злой собаки все нет...');
Sleep(1000);
end;
Новая функция guard_check позволяет
определять текущий уровень доступа и на основе этого строить защищенные интерфейсы пользователя
средствами Daq Pascal.
Например, анимация мнемосхем может выглядеть так:
if clickbutton=1 then begin
if clicksensor='START' then
if guard_check('Root')<0 then AccessDenied else ExecuteStart;
end;
Новая функция dirlist позволяет читать
список файлов, каталогов, искать файлы по имени или по шаблону.
Например, печать списка *.cfg файлов в каталоге c:\daq и его подкаталогах может выглядеть так:
t:=dirlist(text_new,maxint,'c:\daq','*.cfg');
for i:=0 to text_numln(t)-1 do writeln(text_getln(t,i));
b:=text_free(t);
10.08.2005
Guard
Усовершенствована система безопасности CRW-DAQ. А именно:
Введен уровень доступа Lock - программа заблокирована, все команды,
кроме смены уровня доступа, запрещены.
Введен список разрешенных к запуску конфигурационных файлов.
Если список пуст, разрешен запуск любых конфигураций (низкая степень защиты).
Если список не пуст, пользователю разрешен запуск только указанных в списке конфигураций.
Изменено действие кнопки .
Теперь при отсутствии описания [Daq] Navigator = ...
выдается список доступных окон мнемосхем.
26.07.2005
Guard
Введена система безопасности CRW-DAQ, именуемая Guard, доступная через кнопки
F11
- вызов диалога авторизации (изменения уровня доступа).
F12
- понижение уровня доступа на единицу.
Система безопасности работает так:
Есть уровни безопасности, Guest=Гость, User=Оператор, Root=Администратор.
Текущий уровень безопасности определяет, что можно и нельзя делать.
Каждая критическая операция проверяет уровень доступа и выдает в консоль или в диалог
сообщение, если текущий уровень доступа недостаточен.
Уровень Guest не требует пароля, а User и Root могут быть защищены паролем
(но могут и не быть).
Root - это уровень администратора DAQ системы.
Администратор имеет полные права на все операции.
Это уровень, на котором создаются и редактируются DAQ системы.
Уровень User - это уровень оператора, выполняющего измерения в DAQ системе.
Оператор имеет право на загрузку/завершение и большинство других функций DAQ системы,
но не имеет прав на операции, которые связаны с редактированием программ, конфигураций,
запуск внешних программ и командных файлов.
Это связано с тем, что в защищенной системе оператор работает под пользователем с ограниченными
правами, в то время как CRW-DAQ запускается с правами Администратора (при помощи
пакета AdmiLink).
То есть оператор не может редактировать файлы DAQ-системы средствами Windows,
так как эти файлы созданы под Администратором.
Единственным способом редактировать файлы DAQ-системы остается сама DAQ-система.
Поэтому на уровне пользователя запрещены операции, связанные с запуском программ
и редактированием программ и конфигураций.
Guest - уровень, на котором запрещены также операции запуска/останова
DAQ-системы, выхода из программы и т.д.
Разрешенными остаются операции, не критичные с точки зрения защиты DAQ-системы,
например, печать, манипуляции с окнами и т.д.
Уровень Guest применяется, если система оставляется без присмотра,
чтобы посторонние люди что-то не испортили.
Работать надо с минимально возможным для данной задачи уровнем доступа.
Как только критическая работа выполена, надо сразу понижать уровень доступа.
Особенно это касается уровня Root.
Уровень доступа можно понизить быстро - одним нажатием
F12,
и пароля для этого не надо.
Уровень доступа можно повысить только командой
F11,
при этом требуется пароль.
При загрузке пакета CRW-DAQ уровень доступа устанавливается как максимальный уровень,
имеющий пустой пароль.
То есть если пароль User и Root не был установлен,
то при загрузке установится уровень Root.
Если пароль User не был установлен, а пароль Root установлен,
то при загрузке установится уровень User.
Если пароль User и Root установлен,
то при загрузке установится уровень Guest.
Пароли устанавливаются на машину, то есть все экземпляры CRW-DAQ на одной машине
используют одни пароли.
По умолчанию на "голой" машине пароли отсутствуют (и уровень доступа по умолчанию Root).
Уровни доступа CRW-DAQ надо использовать совместно с службой безопасности Windows.
При этом пользователь запускается с ограниченными правами, CRW-DAQ - под администратором
при помощи ярлыка AdmiLink, а сам CRW-DAQ защищен уровнями доступа.
Система безопасности Windows гарантирует, что пользователь не сможет изменять файлы
CRW-DAQ - он ведь под администратором.
25.07.2005
InstallCrw32
Установка CRW-DAQ теперь делается через дистрибутив InstallCrw32.Exe.
Дополнительные ресурсы устанавливаются через InstallCrw32Extra.Exe.
Дополнительные утилиты устанавливаются через InstallTotalCommanderExtra.Exe.
Новая демо-конфигурация demo_crw2nio
иллюстрирует (на примере утилиты для ячейки Курдюмова на установке Прометей)
как создавать вычислительные утилиты в Daq Pascal.
16.06.2005
DIM
Обновлена версия DIM с v15r9 на v15r16
(с сайта http://dim.web.cern.ch).
В новой версии устранена ошибка с утечкой памяти,
которую я обнаружил и о которой написал разработчикам DIM.
Вроде бы устранена также и ошибка с падением сервера DIM
при кратковременном разрыве связи. Поглядим...
В _DIM.PAS добавлена поддержка чтения-записи приоритетов
потоков DIM, см. dim_test.
Обновлен DIM сервер DimSrv (добавлена поддержка приоритетов
потоков DIM, увеличены размеры FIFO), см.
demo_dim_server.
13.06.2005
Help
Добавлено еще несколько описаний функций в
Daq Pascal API.
Теперь, наверное, около половины функций переведено в HTML.
В секции описания устройств program появились новые переменные:
StdinFifo = n - задает размер n (в килобайтах)
буфера FIFO стандартной консоли ввода для данного устройства.
Стандартный размер по умолчанию StdinFifo=16.
Размер StdInFifo можно уменьшить для экономии памяти,
если данное устройство не использует консоль ввода, то есть никогда
не делает чтения консоли вызовом read или readln.
Размер StdInFifo можно увеличить, если программа интенсивно
использует консоль ввода, например, если другие программы присылают
данной программе сообщения через devsend или devmsg,
а программа читает консоль вызовом read или readln.
StdoutFifo = n - задает размер n (в килобайтах)
буфера FIFO стандартной консоли вывода для данного устройства.
Стандартный размер по умолчанию StdoutFifo=32.
Размер StdoutFifo можно уменьшить для экономии памяти,
если данное устройство не использует консоль вывода, то есть никогда
не делает записи консоли вызовом write или writeln.
Размер StdOutFifo можно увеличить, если программа интенсивно
использует консоль вывода, например, для отображения отладочных
сообщений в консоль вызовом write или writeln.
10.06.2005
7000
В спектрометрических окнах добавлено 5 новых параметров в статусной строке.
Пример в папке
Demo/Demo_Task_Pkk4
показывает как конфигурировать окно.
Здесь надо отметить, что конкретное имя параметра не играет роли, оно используется
для отображения, а для вычисления важен только порядковый номер.
Надо также отметить, что любой параметр можно исключить подстановкой в качестве
имени параметра звездочки *. Например:
И еще - по двойному щелчку на статусной строке появляется диалог, через который
можно задать параметры MarkerLabel "на лету", без перезагрузки конфигурации.
В стандартных программах _SaveCrw,_SaveDat в папке
Demo/ExSavers/DaqPas
снято ограничение на длину префикса (наследие DOS).
Появилась кнопка Go to line № в окне редактора.
Кроме того, при активизации диалогов Find/Replace текущее слово под курсором
автоматически попадает в поле ввода, как принято в современных редакторах.
Цикл опроса ADAM оптимизирован для повышения частоты опроса.
Теперь частота опроса в среднем 20 ms на запрос/ответ, раньше было более 30 ms.
Для повышения частоты опроса надо также правильно указывать таймауты:
[DAQ]
AdamTimeOut = t1, t2, t3
t1 - время ожидания команд с ответом ( пример: #01 )
t2 - время ожидания команд без ответа ( пример: ~** )
t3 - время ожидания для длительных команд ( пример: калибровка )
Параметр t2 используется, например, для команды ~** сброса Watchdog.
Эта команда не имеет ответа, поэтому таймаут для нее должен быть короткий.
Раньше по умолчанию он был 50 ms (наследство CRW16, где квант времени 55 ms).
Теперь имеет смысл делать его меньше.
Рекомендуемое значение:
[DAQ]
AdamTimeOut = 100, 10, 10000
Добавлен выбор формата данных и быстрое чтение многоканальных ADC.
Это делается так:
[DeviceList]
&7018 = device adam adam-7018
[&7018]
Port = 1
....
DataFormat = 0 -> формат Engineering, физ. единицы, например >+150.00
DataFormat = 1 -> формат Percent FSR, % всей шкалы, например >+050.00
DataFormat = 2 -> формат Hexadecimal, 16-ричный вид, например >7FFF
DataFormat = 3 -> формат Resist.Ohms, сопротивление, например >+100.00
FastRead = 0 -> чтение как раньше, командами #AA0,#AA1,..#AA7
FastRead = 1 -> чтение всех каналов командой #AA
Для старых версий модулей FastRead=1 может не работать (команда ранее не поддерживалась).
Формат DataFormat=3 работает, разумеется, только для модулей
RTD (резистивных термодатчиков).
За счет оптимизации цикла опроса и быстрого чтения ADC общая скорость опроса устройств
может быть значительно повышена. Скорость опроса многоканальных ADC в режиме быстрого
чтения в HEX формате близка к теоретически достижимой
(около 8*50=400 каналов в секунду).
Включение Watchdog снижает скорость опроса практически в 2 раза,
так как в цикле теперь опрашивается статус Watchdog.
Кроме того, необходимость чтения температуры холодного спая 7018,7011 также снижает
скорость из опроса по сравнению с 7012,7017.
Одноканальные ADC и DIO могут опрашиваться с частотой 50 каналов в секунду.
Включение Watchdog и в этом случае снижает скорость опроса практически в 2 раза.
Разумеется, при подключении на один порт нескольких устройств максимальная частота опроса
отдельного устройства падает пропорционально числу устройств, так как цикл опроса
общий.
Для анализа и профилирования (измерения временнных параметров) опроса модулей можно применять
[DAQ]
AdamDebugMode = 15
При этом в файл TEMP\DEBUG.OUT сбрасывается весь протокол обмена с указанием времени,
так что все будет хорошо видно.
Только не забудьте в конце отладки сделать
[DAQ]
AdamDebugMode = 0
Иначе диск быстренько заполнится отладочной информацией...
Мелкие улучшения в UART-терминале.
Соответственно обновлен AdmiLink, который тоже использует этот терминал.
В журнальном файле TEMP\CONSOLE.OUT сохраняется эхо вывода в главную консоль.
Режим задается в переменной Crw32.ini [System] ConsoleEchoMode:
ConsoleEchoMode=0 - не надо вести журнал.
ConsoleEchoMode=1 - продолжать журнал, если он уже существует.
ConsoleEchoMode=2 - создавать журнал заново при каждом старте системы.
Максимальный размер файла задается в Crw32.ini [System] ConsoleFileLimit.
При достижении этого размера файл переименовывается в TEMP\CONSOLE.OLD.
Этот файл может помочь при анализе - какие конфигурации и когда запускались и т.д.
20.05.2005
AdmiLink
Исправлено несколько мелких недочетов в AdmiLink.
19.05.2005
AdmiLink winKeyLock
В состав пакета введена специально разработанная мной утилита
AdmiLink.
Эта утилита находится в папке
Resource/Tools.
Эта утилита позволяет делать запуск программ от имени другого пользователя
при помощи ярлыков, создаваемых специальной программой.
Замечу сразу, что запуск программ от имени другого пользователя
работает в W2K/XP, но не в W95/98/NT.
Там же лежит winKeyLock - утилита для быстрой блокировки кливиатуры и мыши
по клавиатурному макросу. Она тоже имеет отношение к защите.
Эта утилита взята из Интернета.
16.05.2005
Bug fixed
Устранена маленькая ошибочка из-за которой запуск программ
от имени другого пользователя не работал под Windows-2000.
Замечу сразу, что запуск программ от имени другого пользователя
работает в W2K/XP, но не в W95/98/NT.
15.05.2005
Secret service
Появилась служба безопасности CRW-DAQ.
Здесь будут собраны все вещи, связанные с паролями, правами доступа и т.д.
Пока просто сделан генератор ключей
task_ctrl
для запуска программ от имени другого пользователя.
task_ctrl('Account='+Key)
- вызов используется для запуска программы из под другого аккаунта,
заданного зашифрованным ключем.
task_ctrl('Encrypt='+'User'+CRLF+'Domain'+CRLF+'Password')
- вызов используется для генерации зашифрованного ключа для запуска
программы от имени другого пользователя, из под другого аккаунта.
Ключ есть некая абракадабра, которую можно использовать только для
запуска конкретного файла под конкретным аккаунтом и никак иначе.
Только система знает, как превратить ключ обратно в аккаунт,
что необходимо для запуска файла.
task_ctrl('ExeName') - вызов возвращает имя исполняемого файла,
как его распознает программа.
Имя исполняемого файла задается вызовами
task_ctrl('AppName='...),task_ctrl('CmdLine='...).
Имя файла должно быть задано до момента генерации ключа, причем имя
должно быть полным, включая путь и расширение.
Данные вызовы позволяют, работая под пользовательским аккаунтом, запускать
измерительные задачи под аккаунтом администратора, практически не снижая
безопасности системы, так как пользователь не сможет запустить от имени
администратора ничего кроме разрешенных программ и не сможет узнать
пароль администратора.
Подробности читайте в справке по
task_ctrl.
Новые функции для кодирования/аутентификации
hex_encode,
hex_decode,
crypt_ctrl,
crypt_encode,
crypt_decode,
getmd5fromstr,
getmd5fromfile,
getmd5fromtext.
Функции hex_encode,hex_decode могут использоваться для хранения двоичных
данных в конфиг-файлах, так как они не боятся преобразования регистра символов,
в отличие от mime_encode,mime_decode.
Функции вычисления контрольной суммы MD5 могут использоваться для
идентификации/аутентификации файлов/текстов, то есть для выяснения,
был ли файл/текст изменен.
Для этого вычисляется контрольная сумма MD5 и сохраняется в журнальном файле.
Если кто-то изменил интересующий файл, этот факт можно будет установить,
сверив контрольную сумму проверяемого файла с сохраненной в журнальном файле...
28.04.2005
@polling @sysinfo PriorityClass
Краткая статья о системе приоритетовWindows.
Ее надо почитать, чтобы стало ясно, что такое класс приоритета и т.д.
В консольной командe @sysinfo изменился набор и форма печати параметров системы.
Выглядит новый фрагмент примерно так:
Login : Alex on MAIN, with root privileges
Process : PID 2780, with RealTime priority (24)
Здесь
root privileges означает наличие прав администратора,
user privileges - отсутствие прав администратора.
В консольной командe @polling появилась возможность узнать/задать
класс приоритета программы, что имеет важнейшее значение для временных параметров
DAQ-системы. Работает примерно так:
@polling PriorityClass - просмотр приоритета
@polling PriorityClass RealTime 100 - задание приоритета и периода его проверки
Появилась новая переменная ProcessPriorityClass в конфигурационных файлах:
Формат такой:
ProcessPriorityClass = P, T
Здесь
P - класс приоритета процесса:
Idle (4)
Lower (6)
Normal (8)
Higher (10)
High (13)
RealTime (24)
Класс приоритета задается в символьном виде или цифрой, например,
Normal или 8.
T - период проверки приоритета процесса, в миллисекундах.
Ненулевой период проверки означает, что класс приоритета процесса
будет периодически проверяться и устанавливаться в заданное значение.
Это означает, что сторонними программами приоритет процесса изменить не удастся.
Нулевое значение или отсутствие параметра отключает проверку,
то есть установка приоритета будет делаться только один раз, при загрузке.
Переменная ProcessPriorityClass задается в следующих местах:
В секции [DAQ] файла конфигурации DAQ-системы.
В секции [DaqSys] файла Crw32.ini.
В секции [System] файла Crw32.ini.
Порядок чтения ProcessPriorityClass такой:
При старте программы Crw32.exe читается [System].
При загрузке файла конфигурации DAQ-системы читается [DAQ],
а если там переменной нет - читается [DaqSys].
При завершении работы DAQ-системы восстанавливается значение,
которое было на момент загрузки.
Конфигурация Demo_Smooth
иллюстирирует возможности новых стандартных программ
_mvtopu,_mvtotc, которые по замыслу должны заменить
_mv2pu,_mv2tc.
Эта конфигурация также является полигоном для алгоритмов online сглаживания.
Есть Help.
Новый тип шкалы калибровки SubZ позволяет делать вычитание нуля АЦП
также через программу _mv2tc или _mvtotc, что позволит использовать
все возможности сглаживания, заложенные в них и унифицировать конфигурации.
Шкала SubZ означает преобразование x'=x-z,
где x-основной сигнал (АЦП), z-параметр (ноль АЦП).
Далее значение калибровки y вычисляется как полином y=p(x').
Для вычитания нуля:
Сигнал АЦП заводится как термопара,
ноль АЦП - как холодный спай.
Впрочем, полином и точки калибровки могут быть другими, например, для вычитания нуля
и затем перевода милливольт в вольты надо указать {(0,0),(1000,1)}.
Главное, чтобы шкала калибровки была правильной, а сигнал нуля заведен на нужный вход.
Пример в Demo_Smooth.
Новая функция vdpm_opcount
для измерения временных параметров DAQ-программ.
Новая консольная команда @polling позволяет получать список потоков
программы, а также таблицы и гистограммы периодов опроса потоков программы.
Опять же для выяснения временных параметров при длительной работе DAQ-системы.
Введена переменная DIM_SECTION.
Это имя секции, где теперь определяются сервисы.
Изменение сделано для того, чтобы можно было менять имя задачи,
не затрагивая описаний сервисов.
Введена переменная StatPeriod.
Это период обновления статистической информации о потоке данных DIM.
На аналоговые выходы 0..11 выводится статистичекая информация о потоке данных DIM.
Подстановка %**,%01,%02... позволяет передавать значения
данных (вся запись) и тегов (по номеру в записи) клиентам.
Например, для сериализации обработки принятых сообщений.
Серверу можно слать сообщения типа devmsg('&DimSrv ##'+str(tag)+'='+dump(i)).
Например, для сериализации посылки сообщений.
DIM_TASK теперь может иметь любое значение, если сервер содержит только клиентские сервисы.
Это облегчает тиражирование клиентов.
В DIM обнаружена утечка памяти.
Это в случае, если клиент посылает команду, а сервер не запущен.
Я выслал указание на ошибку в CERN, авторам DIM.
Может, исправят?
Тестировалась производительность сервера.
Получилось примерно 40 тыс. тегов в секунду (300 KB/sec) при загрузке 30% на P4-2000.
Грубо говоря, 1% на 1000 тегов в секунду.
03.04.2005
task_send task_recv
Функции
task_send,
task_recv
теперь могут работать со строками длиннее 255 символов.
Из-за ограничений task_send,task_recv общий размер сервиса
DIM-сервера
имел ограничение 190 байт.
Теперь ограничение снято.
Остается только ограничение 100 сервисов по 50 тегов, как описано в хелпе.
31.03.2005
refxxx DimServer
Функции ссылок теперь возвращают тип integer:
refai,
refdi,
refao,
refdo,
refcalibr,
tm_new.
Вроде, это совместимости не мешает, а по факту точнее будет.
Вышел первый вариант DIM-сервера.
Можно делать его обкатку...
Устранены последние неувязки с идентификаторами объектов.
То есть если раньше одно и то же число могло описывать задачу (task_init),
тег (findtag) или кривую (crvfind), то теперь пространство идентификаторов едино.
Если, скажем, есть задача с идентификатором 10, то никакой другой объект не имеет такого
значения идентификатора.
Любой идентификатор теперь можно использовать в refinfo.
В силу единого пространства ссылок (идентификаторов) ошибка в контексте вызова
(например, подстановка ссылки на тег вместо ссылки на кривую) становится практически
безопасной, так как тип ссылки проверяется при вызове.
Теперь система регистрирует ошибки типа тегов.
Например если real тег используется в igettag, появится красная морда.
28.02.2005
issametext defaultextension forceextension trim extractXXX fexpand etc
Изменен механизм работы менеджера строк DaqPascal по тому же принципу,
как реализован единый реестр объектов (таблица со стеком свободных ячеек).
Результатом должно стать повышение производительности всех строковых операций,
особенно для сравнительно больших DAQ-программ, так как таблица со стеком
имеет порядок O(1) для всех операций (доступ, вставка, удаление).
Значимая длина имен идентификаторов DaqPascal увеличена до 16.
Введены функции
reffind,
refinfo,
devsend.
Эти функции позволяют более эффективно организовать обмен сообщениями через консоль.
Введен единый реестр всех объектов CRW-DAQ, которым теперь пользуются функции
Daq Pascal для доступа к объектам. Это, по замыслу, должно повысить надежность
Daq-программ, так как теперь ссылки являются не указателями, а индексами в реестре,
корректность которых можно проверять. Это значит, вызовы типа crvx стали безопаснее.
Даже неверная ссылка почти наверняка не приведет к краху системы...
А как на деле - увидим.
В монитор ресурсов заведена информация о реестре объектов (ObjectRegistry).
В драйвер COM-порта добавлена поддержка разной экзотики вроде контроля приемо-передачи
по сигналам CTS/RTS/DTR/DSR.
Эти опции включаются флагами DcbFlags, как описано в справке по
comopen.
В функции windraw появился атрибут SaveBmp.
Это дает возможность сохранять окно в виде изображения в *.bmp файле.
Соответственно, имея возможность создавать файлы изображения, можно автоматически генерировать
файлы отчетов в формате HTML.
Просмотр и печать созданных отчетов можно также автоматизировать при помощи shellexecute.
Разумеется, перед печатью надо той же функцией windraw правильно нарисовать окно,
которое будет печататься, то есть выделить нужную кривую, масштабировать и т.д.
Пример:
В функции paramstr появился параметр GetExeByFile.
Это дает возможность узнать имя исполняемого файла по имени документа, например,
узнать расположение Internet Explorer, Word и т.д.
Совместно с функциями task_XXX это открывает большие возможности.
Пример:
Часть документации (по ADAM, CRW16.doc, CRW-DAQ.doc) вынесена из основного
дистрибутива Crw32exe.zip в файл дополнительных ресурсов Crw32exe-ExtraResourceKit.zip.
Это продиктовано желанием сохранить основной дистрибутив пакета небольшим.
Таким образом, полная установка пакета требует распаковки основного пакета Crw32exe.zip,
а затем сверху Crw32exe-ExtraResourceKit.zip (но он нужен только для разработчиков).
Добавлена функция awakeflag,
которая показывает, что поток программы был разбужен досрочно внешним событием, таким как посылка сообщения
или щелчек сенсора.
21.02.2005
scheduling Context help
Теперь справка в DaqPascal контекстная.
Это значит, что при нажатии
команды вызова справки Ctrl+F1 будет активизирована справка по ключевому слову,
которое находится по курсором.
Если это слово не найдено в списке тем, отображается список доступных тем.
Так что теперь достаточно щелкнуть мышкой на интересующую функцию и нажать кнопку
,
чтобы получить справку по этой функции.
Изменился алгоритм опроса устройств.
Если в двух словах, теперь при щелчке сенсора или при посылке сообщения устройству devmsg
это устройство будет активизировано досрочно, то есть даже если время опроса не подошло.
Можно теперь делать опрос устройств, которые выполняют обработку пользовательского ввода,
достаточно редким, скажем, раз в секунду.
Но при этом устройство будет все равно быстро откликаться на внешние события.
Это особенно удобно при реализации программ, построенных как интерпретатор консольного ввода.
Добавлена справка о планировании измерительных
программ, то есть о временах опроса, потоках, приоритетах и т.д.
Добавил функции
crvgetln,
crvputln,
crvinsln,
crvaddln,
crvdelln,
crvnumln.
Напоминаю, что каждая кривая содержит помимо данных также паспорт, то есть текст для
хранения разной сопроводительной информации. В паспорте можно хранить в текстовом виде
разные дополнительные переменные в виде "Name=Value".
Перечисленные функции дают полный доступ к паспорту кривой и позволяют организовать сохранение
в паспорте различной дополнительной информации о кривой, условиях измерений и т.д.
Добавился атрибут рисования SaveCrw в
windraw.
Это альтернативный путь сохранения данных вместо использования функции savecrw,
для случая, когда нужные данные уже собраны в окне и их надо просто сохранить.
Не хотелось вводить новую функцию, поэтому сохранение окна сделано как атрибут функции рисования.
Отличия от savecrw состоят в том, что:
Перед сохранением данные в окне перерисовываются.
Нет возможности сохранять данные,не размещенные в окне.
Пример ExSavers модифицирован с учетом новых возможностей savecrw.
Теперь вместо
; Список кривых для сохранения
DataCurve#1 = HRM_CAM
DataCurve#2 = HRM_KAT
можно писать
DataCurve#1 = [CAM_Curves]
DataCurve#2 = [KAT_Curves]
то есть ставить ссылку на секцию со списком кривых.
Потребовалось небольшое изменение _savecrw.pas.
Появились клавиатурные макросы:
F9 -
- вызов DAQ.
F6 -
- выбор окна.
Alt+F6 -
- выбор следующего окна.
Shift+F6 -
- выбор предыдущего окна.
Alt+F1 -
- справка по Delphi (требует Crw32ExtraResourceKit).
Shift+F1 -
- справка по Win32 (требует Crw32ExtraResourceKit).
Ctrl+F1 -
- справка по DaqPascalApi (в окне редактора программы Daq Pascal).
Начата работа по созданию Daq Pascal Api Help.
Постепенно вся справка по Daq Pascal будет в ней. Пока буду заносить туда информацию по новым функциям.
Добавились атрибуты рисования в
windraw
относящиеся к plot3d.
Добавлены переменные Pixel,Value,Bitmap в
clickparams
Функция plot3d(nx,ny,x1,y1,x2,y2,opt) теперь работает быстрее.
Напомню, что при помощи вызовов add3d(x,y,z) в программу в произвольном порядке
заносится массив данных.
В общем случае точки массива расположены произвольно и для этого случая все осталось по-прежнему.
Однако значительное ускорение будет в случае, если:
Массив (x,y,z) после сортировки расположен на регулярной прямоугольной сетке (x,y).
Область рисования (x1,y1,x2,y2) не выходит из прямоугольника сетки (x,y).
Поскольку этот специальный случай массива данных наиболее распространен, сначала делается попытка
использовать быстрый алгоритм рисования.
Для этого массив данных автоматически сортируется, затем определяется факт наличия регулярной сетки,
автоматически распознается размерность и шаг.
Если сетка регулярная, применяется быстрый алгоритм интерполяции.
Ускорение при этом достигается в несколько десятков раз.
В случае нерегулярной сетки используется более медленный случай интерполяции на произвольной сетке.
В функции WinDraw появился атрибут Reload=SensorName, который действует на мнемосхемы
и заставляет перезагрузить изображения для указанного сенсора (имя SensorName=All перезагружает все).
Это сделано для работы с сенсорами, изображения которых могут формироваться автоматически из программы.
Например:
b:=windraw('Ip4.Viewer|Reload=Ip4.Bitmap');
Появилась 2 новые функции:
str2shortcut(s:string):integer - возвращает клавишу по имени.
shortcut2str(i:integer):string - возвращает имя клавиши.
В качестве имен можно применять, например:
Scroll_Lock Caps_Lock Right_Shift Sys_Req BkSp Tab
Num_5 Enter Shift Ctrl Alt Esc Space PgUp PgDn End
Home Left Up Right Down Ins Del
0 1 2 3 4 5 6 7 8 9
A B C D E F G H I J
K L M N O P Q R S T
U V W X Y Z Num_* Num_+ Num_- Num_Del
F1 F2 F3 F4 F5 F6 F7 F8 F9 F10
F11 F12 F13 F14 F15 F16 F17 F18 F19 F20
F21 F22 F23 F24 Pause ; = , - .
` ' [ ] / \
в комбинации с Alt+, Ctrl+, Shift+.
Надо заметить, что с мышью связаны специальные виртуальные коды, возвращаемые clickbutton,
которые также поддерживаются функциями str2shortcut,shortcut2str,
хотя они и не являются клавиатурными клавишами.
Это такие виртуальные коды:
LButton = 1 - левая кнопка мыши
RButton = 2 - правая кнопка мыши
MButton = 4 - средняя кнопка мыши
а также их производные с регистрами Alt+, Ctrl+, Shift+.
Например:
if clickbutton>0 then begin
writeln(shortcut2str(clickbutton));
if clickbutton=str2shortcut('LButton') then LeftMouseButtonClick;
if clickbutton=str2shortcut('RButton') then RightMouseButtonClick;
if clickbutton=str2shortcut('Alt+F1') then Help;
...
end;
Появилась новая функция:
clickparams(s:string):string - возвращает разнообразные параметры события
щелчка сенсора:
clickparams('') - вернет все параметры одной длинной строкой.
clickparams('What') - что произошло: NOTHING,MOUSEDOWN,KEYDOWN
clickparams('Key') - код клавиши без учета регистровых клавиш
clickparams('Button') - виртуальный код клавиши, см. str2shortcut
clickparams('Window') - имя окна мнемосхемы
clickparams('Sensor') - имя сенсора
clickparams('Tag') - имя присоединенного тега
clickparams('Curve') - имя присоединенной кривой
clickparams('Bounds') - границы сенсора: left,top,right,bottom
clickparams('ShortCut') - код горячей клавиши
У сенсоров появился атрибут ShortCut. Это горячая клавиша, эквивалентная щелчку на сенсоре.
Задаются горячие клавиши выражением shortcut в секции описания мнемосхемы.
Link sensor SENSOR_NAME with device DEVICE_NAME tag TAG_NAME shortcut SHORTCUT_NAME
В качестве имени горячей клавиши используются выражения типа F1,Alt+F1,Ctrl+F1,Shift+F1,
смотри описание str2shortcut, shortcut2str.
При нажатии горячей клавиши clickbutton вернет виртуальный код этой клавиши,
а функции clicksensor, clicktag вернут имя сенсора и тег.
Поскольку обработчики обычно содержали код типа:
if clickbutton=1 then begin
if clicktag=tagSomething then DoSomething; {обработка щелчка мыши}
end;
то есть были ориентированы на мышиный щелчек, для использования горячих клавиш код надо изменить:
if clickbutton>0 then begin
if clicktag=tagSomething then DoSomething; {обработка щелчка мыши или горячей клавиши}
end;
Использование горячих клавиш позволит ускорить доступ к функциям мнемосхемы, а также позволит делать
мнемосхемы, работающие даже в случае отсутствия мыши.
10.01.2005
[Windows] Name clickparams shortcut2str str2shortcut windraw
Теперь переменная Tag в секции описания сенсора задает не просто стартовое значение тега,
но определяет значение тега по умолчанию. Дело в том, что ранее, если указывалось значение тега,
не входящее в список тегов, сенсор исчезал с экрана. Теперь при задании недопустимого тега отображается
тег по умолчанию.
Например, пусть есть сенсор:
Теперь переменная Name в секции описания окна мнемосхемы также НЕОБЯЗАТЕЛЬНА.
Правило чтения конфигурации такое:
По умолчанию имя окна мнемосхемы совпадает с именем секции описания окна в файле *.CFG.
Если переменная Name присутствует в секции [Circuit] файла *.CRC,
она замещает имя окна своим значением.
Если переменная Name присутствует в секции описания окна мнемосхемы файла *.CFG,
она замещает имя окна своим значением.
Таким образом, если переменная Name отсутствует в обоих секциях, имя окна будет совпадать
с именем секции описания окна в файле *.CFG.
Пример описания окна мнемосхемы:
[Windows]
Ip4.Ring.Viewer = Circuit_Window
[Ip4.Ring.Viewer]
Circuit = ..\circuits\Ip4_RingView.crc
Link sensor Ip4.Ring.BtnEye with device &Ip4 tag &Ip4.Ring.BtnEye
...
В этом примере окно получит имя Ip4.Ring.Viewer.
Предполагается, что имя мнемосхемы не задано ни в *.CRC, ни в *.CFG файле.
09.01.2005
Sensor Name
Теперь переменная Name в секции описания сенсора мнемосхемы НЕОБЯЗАТЕЛЬНА.
Если переменная Name отсутствует, имя сенсора будет совпадать с именем секции.
Пример описания сенсора:
В этом примере сенсор получит имя Ip4.Ring.BtnEye.
04.01.2005
DeviceMessage FIFO savecrw
Исправлена не фатальная но неприятная ошибка в _CrwApi.DeviceMessage.
Увеличены буферы FIFO для консольного ввода-вывода и консольных окон.
Весьма важная для практики возможность - новый формат функции
savecrw.
В чем тут была проблема?
Из-за ограничения на длину строки (255 символов) функция не позволяла
сохранять произвольное число кривых и имела ограничения
на длину описания имени окна и прочих параметров.
Для некоторых задач это не подходит, так как иногда надо сохранять
очень много кривых.
Новый формат функции позволяет обойти эту проблему, в то же время сохраняя
полную совместимость с прежней версией.
Напомню что функция имеет вид:
savecrw(args:string):boolean
Список аргументов имеет вид:
args='FileName Name AxisY AxisX CurveList'.
FileName - имя *.CRW файла.
В новой версии вместо имени файла можно (но не обязательно)
подставить имя секции, помещенное в квадратные скобки.
Секция должна содержать переменную FileName
с указанием имени файла.
Name,AxisY,AxisX - соответственно имя окна,
надпись к оси Y (сверху) и надпись к оси X (снизу).
В новой версии вместо имени окна или надписей можно (но не обязательно)
подставить имя секции, помещенное в квадратные скобки.
Секция должна содержать переменные Name,AxisY,AxisX
с указанием имени окна или надписей.
CurveList - список кривых для сохранения.
В новой версии вместо имени кривой в списке можно (но не обязательно)
подставить имя секции, помещенное в квадратные скобки.
Секция должна содержать список переменных CurveList
с указанием имен кривых.
Надо иметь в виду следующее:
Элемент списка аргументов, помещенный в квадратные скобки, теперь интерпретируется
как имя секции. При этом из секции читается переменная с известным именем и ее значение
подставляется в список вместо имени секции. Разумеется, имена объектов в квадратных
скобках запрещены, чтобы не путать их с именами секций.
Для описания Name,AxisY,AxisX,CurveList можно подставлять имена секций с описанием
окон Curve_Window, так как такие переменные там уже есть.
В списке CurveList в качестве элементов можно подставлять как имена отдельных кривых,
так и имена секций в квадратных скобках. Очень удобно использовать уже готовые
списки кривых из секций с описанием окон Curve_Window.
Списки кривых могут пересекаться, при этом кривая, которая упоминается в суммарном списке
многократно, включаются в окно только один раз.
Пример:
Пусть конфигурация содержит окна:
[Windows]
Win-P = Curve_Window
[Win-P]
Name = Win-P
AxisX = ^R{sec}___^N^CTime, 0, 1
AxisY = ^CPressure^N^L___{Bar}, 0, 1
CurveList = P1,P2,P3
[Windows]
Win-T = Curve_Window
[Win-T]
Name = Win-P
AxisX = ^R{sec}___^N^CTime, 0, 1
AxisY = ^CTemperature^N^L___{C}, 0, 1
CurveList = T1,T2,T3
Тогда вызов типа
savecrw('..\data\PT.CRW, Win-P+T, [Win-T], [Win-T], [Win-P], [Win-T]')
позволяет сохранить в файл ..\data\PT.CRW окно с именем Win-P+T,
взяв AxisY, AxisX, из окна Win-T, а также совместный список кривых
P1,P2,P3,T1,T2,T3.
30.12.2004
DaqScript format @SysInfo LockedXXX
Финальный релиз 2004 года. С Новым Годом, c Рождеством!
Внутренние изменения для корректной работы на многопроцессорных системах.
В CrwApi (модуль _CrwApi.pas) добавлено 10 функций LockedXXX.
Эти функции выполняют атомарные (неделимые) операции с целыми переменными и могут применяться
для синхронизации потоков или процессов через общую память.
Например:
const Locker:Integer=0;
begin
if LockedInc(Locker)=1 then DoExclusively;
LockedDec(Locker);
end;
Процедура DoExclusively может быть захвачена только одним потоком,
остальные будут проскакивать мимо, пока процедура не закончит выполнение.
Функции добавлены для получения возможности высокоскоростного взаимодействия
с консольными драйверми через общую память, на будущее.
При старте выдается более подробная информация о системе, чем раньше.
Информация о системе также доступна через команду @sysinfo в окне Системная консоль.
Внутренние изменения для более корректной работы с модальными окнами (которые забирают управление).
В файле Crw32.ini появилась также переменная MaxNumberOfModalForms=3,
которая регулирует максимальное возможное число открытых модальных форм. Введена для защиты.
Просьба сообщить, если будут найдены ошибки.
В интерпретаторе DaqPascal появились усовершенствованные возможности форматирования строк.
Правила форматирования строк интерпретатора:
Интерпретатор DaqScript в настоящее время не имеет строковых переменных.
Однако частично этот недостаток компенсируется тем, что строковые константы и функции форматирования
строк можно использовать во всех командах (или @-функциях) интерпретатора, таких как
@echo, @voice и т.д.
Здесь описываются правила и возможности такого форматирования.
Надо иметь в виду, что интерпретатор всегда переводит все строки в нижний регистр,
поэтому для отображения символа в верхнем регистре надо использовать форматирование.
Чтобы перевести символ в верхний регистр, после него поставить символ обратной кавычки `.
Например, выражение @print м`осква напечатает слово Москва.
После преобразования регистра символов все символы обратной кавычки из результирующей строки
удаляются. Надо заметить, что некоторые функции при пустых аргументах могут делать очистку
(например, очистку окна). Если же надо напечатать пустую строку, следует использовать запись типа:
@echo `
Все незначащие пробелы сначала и с конца строки удаляются.
Если надо начать строку с пробела или табуляции, опять же можно использовать символ обратной кавычки.
Например: @echo ` строка с пробелом слева и справа `
Есть возможность подставлять в строку значения переменных интерпретатора.
Для подстановки значения переменной с именем SomeVariable надо написать перед именем символ процента,
то есть %SomeVariable.
Переменные можно вставлять одну за другой без пробелов, знак процента отделяет одну переменную
от другой. Чтобы отделить переменную от текста в случае слитного написания, можно использовать
символ обратной кавычки `, так как эти символы из строки удаляются.
Например, %x%y`и%z напечатает значения переменных x,y и z
без пробела между ними.
По умолчанию переменная подставляется в свободном формате %.15g с 15 значащими цифрами
(см. далее).
Перед подставляемой переменной можно поставить спецификатор формата в виде
%w.df, %w.dg или %w.de. Здесь:
w-минимальная ширина поля для отображения числа.
Если число получается шире, ширина поля игнорируется (то есть усечения не делается).
d-спецификатор точности, смысл которого зависит от спецификатора формата.
f,g,e – спецификаторы формата.
f - формат с фиксированной точкой.
В этом случае d - число точек после запятой.
g - свободный формат, наиболее удобный для чтения, выбираемый автоматически
на усмотрение компьютера. В этом случае d – число значащих цифр результата.
e - научный формат с мантиссой и порядком, типа 1.23e+2.
В этом случае d – число значащих цифр мантиссы.
В связи с ошибкой при закрытии максимизированных окон под Win-95/98,
максимизация окон в этих системах теперь запрещена.
Поскольку Win-95/98 уходят, плакать долго не будем :).
Изменена внутренняя реализация msecnow.
Это уже не первый вариант, однако ввиду исключительной важности функции
(это основная функция времени в CRW-DAQ) изменения весьма полезны.
Функция стала быстрее, введен контроль монотонности, устранен потенциально возможный разрыв
во времени после 49.7 суток работы Windows (из-за переполнения 32 битного счетчика).
Добавлен контроль монотонности показаний времени:
каждый вызов msecnow должен давать значение не меньше предыдущего.
При нарушении монотонности появится окно службы системного времени.
Диалог контроля устройств CRW_DAQ
теперь не будет торчать на экране и заслонять другие окна. Постепенно от окон типа
StayOnTop будем избавляться...
22.11.2004
синхронизация часов LA1_5PCI TDS-3034
Появилась служба системного времени (меню Окно|Служба времени).
Время может измеряться по-разному: по прерыванию таймера (локальное время с момента старта системы),
по энергонезависимым часам (календарное или астрономическое время) и т.д.
К тому же есть еще часовые пояса, зимнее/летнее время, назойливые пользователи
и прочие вирусы.
Локальное время непрерывно, но использовать его не всегда удобно, так как оно
определено только в рамках данного сеанса работы системы и не привязано
к календарному времени.
Календарное время тоже не лишено недостатков - в нем есть разрывы, например,
переход на зимнее/летнее время.
Системное время по часам Windows может к тому же измениться скачком
по нескольким причинам:
Пользователь изменил системное время или часовой пояс
Произошел переход на летнее/зимнее время
Вирусная программа или служба сетевой синхронизации времени
изменила системное время
Во всех этих случаях время по системным часам Windows изменяется скачком
на некоторую константу и далее меняется параллельно с локальным временем.
Такое поведение времени для измерительных систем совершенно недопустимо,
так как может повлечь сбой в алгоритмах управления реальными объектами.
Поэтому для измерения времени CRW-DAQ и выбран другой алгоритм, который гарантирует
непрерывность времени, но при этом дает астрономическое время.
Функция msecnow, которая является основной функцией
измерения времени CRW-DAQ, измеряет локальное время, прошедшее с момента старта
CRW-DAQ, затем прибавляет к нему календарное (астрономическое) время этого самого
момента старта CRW-DAQ по системным часам Windows.
Это время меняется непрерывно в пределах данного сеанса CRW-DAQ,
однако оно может не совпадать с системными часами Windows.
Конечно, в нормальном состоянии часы CRW-DAQ и Windows идут синхронно.
Однако при изменении системного времени Windows появляется разница,
так как часы CRW-DAQ продолжают идти по-старому.
Хотя алгоритмы управления CRW-DAQ будут работать правильно, несоответствие
локального и системного времени может повлечь другие непредвиденные эффекты.
Служба времени CRW-DAQ отслеживает соответствие времени по часам CRW-DAQ
и по часам Windows. При обнаружении существенной разницы активизируется диалог,
извещающий оператора о рассинхронизации часов CRW-DAQ и Windows.
[System]
MistimingService = 1 ; Сервис времени 0=off, 1=on
Сделан пример драйвера карты быстрого сбора данных LA-1.5-PCIDEMO_LA15_PCI.
Этот драйвер использует DLL и фирменные драйверы производителя
www.rudshel.ru.
Сделан пример драйвера цифрового осциллографа для быстрого сбора данных Tektronix TDS-3034DEMO_TDS-3034, к нему также приложен симулятор
DEMO_TDS-3034-simulator для отладки.
Этот драйвер использует Daq Pascal программу и не требует фирменных драйверов производителя.
Две вышеприведенные системы также могут служить эталонным примером оформления документации
и справочной системы измерительных систем.
Справки
LA15_PCI и
TDS
реализованы в виде HTML файлов.
Это гораздо лучше Word/PDF/PS etc, так как весьма компактно, ведь все картинки
вставляются как ссылки на уже готовые элементы мнемосхем.
Так что срочно осваиваем HTML.
14.08.2004
Dcc32 PKK4 CAMAC
Предложение терминологического характера.
Для краткости будем отныне называть автономные программы,
вызываемые из среды Daq Pascal как подчиненные процессы,
взаимодействующие с CRW-DAQ через анонимный канал связи,
консольными драйверами CRW-DAQ.
Если консольный драйвер запускается как невидимый на экране
консольный процесс, будем называть его
консольным демоном CRW-DAQ.
Это направление развития CRW-DAQ систем представляется весьма перспективным.
Добавил в системные библиотеки модуль _PKK4.PAS.
В тело основной программы CRW32 он не входит и не будет входить.
Однако как компонент для создания консольных драйверов CRW-DAQ
для CAMAC систем - будет использован.
Модуль _PKK4.PAS должен быть протестирован на железе.
Надеюсь на помощь команды.
Сделан пример консольного драйвера CRW-DAQ:
DEMO_TASK_PKK4.
Это модель спектрометрической системы, в которой отображение и интерфейс
реализованы в CRW-DAQ на Daq Pascal,
а сбор данных в системе CAMAC на PKK4
реализован как консольный драйвер, запускаемыйая из-под Daq Pascal.
Обмен данными идет по анонимному каналу, а программа сбора данных запускается
как демон.
Этот пример можно использовать как шаблон для построения других консольных драйверов
сбора данных под управлением CRW-DAQ, а также как
пример использования функций _PKK4.PAS.
Мелкие поправки в встроенном компиляторе Delphi. Расширен список встроенных системных *.dcu.
Для создания консольных драйверов CRW-DAQ сделаны доступными
системные библиотеки CRW32. Это часть исходного кода CRW32, которую
теперь можно использовать для создания консольных драйверов,
как в приведенном выше примере.
Системные модули CRW32, по сложившемуся соглашению, начинаются
со знака подчеркивания, например, _MIME.PAS.
Среди особенностей библиотеки надо отметить ее ориентацию на многопоточный
и асинхронный стиль программирования и высокую степень защиты кода от сбоев.
По кнопке справки
в окне редактора *.DPR проектов теперь выдается список всех доступных модулей,
плюс основная часть системных библиотек Delphi. Это нацелено на то, чтобы
можно было вести разработку консольных драйверов CRW-DAQ встроенными средствами
CRW-DAQ.
Раньше по кнопке выдавался только один файл - _CRWAPI.PAS.
Теперь это только один из многих доступных модулей.
Но надо иметь в виду следующее. При написании DLL драйверов для
DAQ - систем, из библиотек CRW32 можно использовать ТОЛЬКО
_CRWAPI.PAS.
Напротив, при написании консольных драйверов, то есть EXE приложений,
можно использовать ВСЕ модули КРОМЕ _CRWAPI.PAS.
Добавлено несколько новых шаблонов редактирования.
Поправил task_kill(1/2). Теперь перед тем как
послать окну сообщение WM_CLOSE/WM_QUIT, окно убиваемой программы
активизируется. Это на случай если она напоследок хочет что-то сказать,
например, спросить, надо ли сохранить результаты редактирования и т.д.
Мелкие поправки в встроенном компиляторе Delphi.
Расширен список встроенных системных *.dcu.
При старте CRW32.EXE устанавливает набор переменных окружения, содержащих
сведения о себе, любимом. Это нужно для того, чтобы программы, вызываемые через
функции task_xxx, могли легче взаимодействовать с
основным процессом.
CRW_DAQ_SYS_HOME_DIR - каталог запуска CRW32.EXE.
CRW_DAQ_SYS_EXE_FILE - полное имя файла CRW32.EXE.
CRW_DAQ_SYS_INI_FILE - полное имя файла CRW32.INI.
Зная имя файла настроек, можно использовать файлы ресурсов,
входящие в состав CRW.
CRW_DAQ_SYS_EXE_PID - идентификатор процесса CRW32.EXE.
Например, автономная программа, вызванная через task_run,
может узнать, используя PID (Process ID), жив ли еще родительский процесс и завершить работу,
если родительский процесс уже завершен.
CRW_DAQ_SYS_EXE_TID - идентификатор основного потока CRW32.EXE.
Например, автономная программа, вызванная через task_run,
может посылать, используя TID (Thread ID), сообщения родительскому процессу.
CRW_DAQ_SYS_MESSAGE - уникальное сообщение MsgId, связанное
с данным экземпляром CRW32.EXE.
При посылке этого сообщения через вызов типа:
var BSMR:DWORDS;
BSMR:=BSM_APPLICATIONS;
BroadCastSystemMessage(BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE, @BSMR, MsgId, 0, 0);
приложение CRW32.EXE активизируется.
Это чтобы дочерняя программа могла активизировать родительское приложение.
CRW_DAQ_CONFIG_FILE - полное имя текущего конфигурационного файла CRW-DAQ.
CRW_DAQ_CONFIG_DATA_PATH - полный путь текущего каталога данных CRW-DAQ.
CRW_DAQ_CONFIG_LOAD_TIME - время загрузки текущей конфигурации CRW-DAQ
в миллисекундах.
CRW_DAQ_CONFIG_START_TIME - время запуска текущей конфигурации CRW-DAQ
в миллисекундах.
Изменения в примере DEMO_TASK. Этот пример можно использовать
как шаблон для автономных консольных программ под управлением CRW-DAQ.
В Daq Pascal добавились две функции:
mime_encode(s:string):string - закодировать строку в MIME, Base64.
mime_decode(s:string):string - раскодировать строку из MIME, Base64.
Эти функции сделаны на случай обмена двоичными данными через текстовый канал связи.
Канал может быть представлен в виде COM-порта, анонимного или именованного канала.
При канальном обмене удобно использовать функции типа readln/writeln или вроде того.
Однако двоичные данные так передавать нельзя - ведь в данных присутствуют спецсимволы
типа возврата каретки, которые при приемо\передаче потеряются.
Можно передавать данные в виде чисел, но тогда могут быть ошибки округления.
Для передачи по текстовому каналу двоичные данные лучше закодировать в MIME,
чтобы там были только печатные символы, а при приеме раскодировать.
При кодировании-раскодировании можно также использовать функции
dump,dump2i,dump2r для получения данных в двоичном виде и обратно.
Например:
program writer;
var x,y,z:real; i:integer; s:string;
begin
s:=dump(x)+dump(y)+dump(z)+dump(i); {binary dump of (x,y,z,i) record}
s:=mime_encode(s); {now dump converted to MIME}
writeln(s); {write it to ...}
end;
program reader;
var x,y,z:real; i:integer; s:string;
begin
readln(s); {read data from ...}
s:=mime_decode(s); {decode data from MIME to binary}
x:=dump2r(copy(s,1,8)); {extract x}
y:=dump2r(copy(s,9,8)); {extract y}
z:=dump2r(copy(s,17,8)); {extract z}
i:=dump2i(copy(s,25,4)); {extract i}
end;
Надо не забывать, что длина данных при кодировании возрастает примерно в 4/3 раз,
поэтому не следует кодировать слишком длинные строки - желательно чтобы длина исходной
строки не превышала 190 символов.
01.08.2004
task_kill
Изменился арсенал способов убиения процесса в task_kill.
Напомню синтаксис:
task_kill(tid,how,exit_code,timeout:Integer):Boolean
- убивает процесс tid.
Метод how теперь может быть таким:
0 = TerminateProcess - безусловно убить процесс.
Процесс никак не уведомляется о завершении и не может ничего предпринять
перед завершением.
Этот метод рекомендуется для убиения GUI процесса, если нормальное убиение
через task_kill(1,2) не сработало и если не было переназначения стандартного
ввода-вывода в канал или файл.
1 = послать окну сообщение WM_CLOSE. Это самый мягкий способ завершения
GUI программ. Обычно GUI программа при этом нормально завершается,
как если бы мы щелкнули мышью на кнопке закрытия окна программы.
Однако программа может и отказаться завершиться, например, спросить,
следует ли сохранить отредактированный файл.
2 = послать окну сообщение WM_QUIT. Это более жесткий способ завершения
GUI программ. Обычно GUI программа при этом безусловно завершается,
хотя может и отказаться, если в ней специально предусмотрен перехват
этого сообщения.
3 = TerminateProcessTree - безусловно убить не только сам процесс,
но и всех его потомков (все дочерние процессы).
Метод работает под Win-95/98/2000/XP, но не под Win-NT3/NT4.
Можно дать такие рекомендации:
Для GUI (графического) приложения, запущенного обычным способом (без командного
процесора и без переназначения ввода-вывода):
Cначала попробовать kill(1) для нормального завершения.
Если не сработало - попробовать kill(2).
Если опять не умер - последний аргумент kill(0).
Для CUI (консольного) приложения, запущенного без переназначения ввода-вывода,
применять kill(0). Для CUI методы, основанные на
сообщениях kill(1,2) не работают.
При запуске программ через командный процессор (типа "command.com /c program.exe")
с переназначением стандартного ввода-вывода в файл или в канал обмена,
надежным является толко kill(3).
При написании консольных программ следует предусматривать команду нормального выхода,
передаваемую по каналу, чтобы не приходилось эту программу грубо убивать.
29.07.2004
TASK task_xxx
В ходе работ по включению DIM в CRW создана библиотека куда более
широкого применения. Это набор функций task_xxx,
позволяющий запускать процессы, управлять ими и обмениваться с ними данными
по анонимному каналу. Это позволяет строить измерительные системы из набора
отдельных экзешников.
Библиотека включает 16 функций:
task_init(cmdline:String):Integer
- создает задачу, инициализирует ее командную строку,
возвращает индекс задачи (task index, далее tid).
Возвращает ноль, если таблица задач переполнена. Созданная задача
не связана ни с каким процессом, пока не вызван task_run.
task_free(tid:Integer):Boolean
- уничтожает задачу и освобождает элемент в таблице задач.
Уничтожение задачи не обязательно означает уничтожение запущенного процесса.
Процесс можно оставить в живых, если не вызывать task_kill.
Однако, если делалось переназначение стандартного ввода-вывода в файл
или анонимный канал связи, процесс убивается даже без вызова
task_kill. Это связано с тем, что канал или файл
закрываются, процесс уже все равно не имел бы к ним доступа и завершился бы
по ошибке ввода-вывода.
task_ref(tid:Integer):Integer
- возвращает ссылку задачи по ее индексу tid.
Ненулевая ссылка означает, что задача с таким индексом существует,
то есть индекс корректен.
task_pid(tid:Integer):Integer
- возвращает идентификатор задачи pid.
Если индекс tid задачи некорректен
или задача еще не создала процесс вызовом
task_run, возвращается 0.
task_run(tid:Integer):Boolean
- запускает задачу на исполнение. При успешном завершении задача связывается
с процессом и получает свой pid.
Связь остается даже после завершения процесса, пока не вызван
task_free для уничтожения задачи.
Перед запуском надо задать параметры задачи вызовом task_ctrl.
task_wait(tid,timeout:Integer):Boolean
- Служит для ожидания завершения процесса. Возвращает true, если после таймаута
процесс все еще жив. Вызов task_wait(tid,0) служит для
проверки статуса процесса - работает ли он еще - без ожидания.
task_send(tid:Integer; data:String):Integer
- посылка данных в канал stdin процесса.
Возвращает число переданных байт.
task_recv(tid,maxlen:Integer):String
- чтение данных из канала stdout процесса.
task_txcount(tid:Integer):Integer
- возвращает счетчик данных в канале stdin процесса.
task_rxcount(tid:Integer):Integer
- возвращает счетчик данных в канале stdout процесса.
task_txspace(tid:Integer):Integer
- свободное место в буфере для посылки в канал stdin процесса.
task_rxspace(tid:Integer):Integer
- свободное место в буфере для посылки в канал stdout процесса.
task_result(tid:Integer):Integer
- возвращает код завершения процесса. Пока процесс выполняется, возвращает
специальный код 259 = STILL_ACTIVE.
task_kill(tid,how,exit_code,timeout:Integer):Boolean
- убивает процесс. Метод how может быть таким:
0 = TerminateProcess - убить молча и жестоко
1 = послать окну сообщение WM_CLOSE
2 = послать потоку сообщение WM_CLOSE
3 = послать окну сообщение WM_QUIT
4 = послать потоку сообщение WM_QUIT
kill(tid,0...) - наиболее надежный способ убить задачу,
однако это аварийное завершение. Посылка сообщений позволяет убить задачу
более корректно (путем принуждения к самоубийству), но работает не всегда.
task_ctrl(tid:Integer; param:String):String
- задание и чтение параметров задачи. Работает, только пока не вызван
task_run, до создания процесса. После создания процесса
параметры можно только читать.
Вызов task_ctrl('name=value') задает, а вызов
task_ctrl('name') - читает параметры.
AppName - имя файла программы. Параметр необязателен,
если указана командная строка.
CmdLine - командная строка. Если имя программы не указано,
первое слово командной строки должно содержать это имя.
HomeDir - стартовый каталог при запуске процесса.
Display - режим отображения 0=SW_HIDE, 1=SW_SHOWNORMAL,
SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED и т.д.
StdInPipeSize - ненулевое значение приводит к переназначению
stdin на чтение канала и задает размер канала.
Теперь можно вызывать task_send.
StdInFileName - переназначает stdin
на чтение файла.
StdOutPipeSize - ненулевое значение приводит к переназначению
stdout на запись в канал и задает размер канала.
Теперь можно вызывать task_recv.
StdOutFileName - переназначает stdout
на запись файла.
GetComSpec:String - имя командного процессора
cmd.exe или command.com.
1)Вызвать программу и пусть ее живет...
tid:=task_init(getcomspec+' /c example.bat');
b:=task_run(tid);
b:=task_free(tid);
2)Вызвать программу, ждать 10 секунд и убить, если не завершилась сама.
tid:=task_init(getcomspec+' /c example.bat');
b:=task_run(tid);
if task_wait(tid,10000) then task_kill(tid,0,0,1000);
b:=task_free(tid);
1)Вызвать программу c переназначением каналов и обмен данными...
tid:=task_init('');
s:=task_ctrl('CmdLine=c:\example.exe');
s:=task_ctrl('HomeDir=c:\');
s:=task_ctrl('StdInPipeSize=1000');
s:=task_ctrl('StdOutPipeSize=1000');
b:=task_run(tid);
if task_rxcount>0 then writeln('Received:',task_recv(tid,100));
if task_txspace>100 then writeln('Sent:',task_send(tid,s),' bytes');
b:=task_free(tid);
Теперь включение DIM в CRW видится как создание DIM-сервера,
консольного приложения, общающегося с CRW через канал.
Если сервер будет падать - на здоровье, перезапустим.
Это дело будущего.
19.07.2004
DIM
DIM.DLL,MSVCRTD.DLL,dim_work.bat,dim_stub.bat
удалены из дистрибутива CRW32. Это штраф за нестабильность, которая была
обнаружена при тестировании. DIM остался
в дистрибутиве, но будет включен в пакет иначе (вероятно, через запуск отдельного
процесса - сервера DIM).
Устранена ошибка, которая приводила к утечке ресурсов (незакрытый handle процесса
и потока) при компиляции при помощи встроенного DELPHI. Теперь все Ok.
Теперь возможна компиляция *.DPR проектов также в *.exe файлы, а не только в *.dll.
Добавление этой возможности связано с проектом построения многопроцессных DAQ систем.
19.07.2004
DIM
В CRW32 добавлен автономный пример
обмена данными через
DIM в виде консольного приложения.
Это пример на случай, если надо обеспечивать связь CRW с другими программами.
Состоит из двух консольных программ:
client и
server.
Все сделанное нуждается в тестировании. Надеюсь на помощь команды...
18.07.2004
DIM mmTimer
В CRW32 добавлен пример обмена данными через DIM.
Состоит из двух систем:
DemoDimOne и
DemoDimTwo.
Они запускаются из разных экземпляров CRW, на той же или на разных машинах.
Надо только не забыть поправить переменную
[DIM] DIM_DNS_NODE = ... .
Реализовано через DLL.
После массированного тестирования этих DLL планируется интеграция
DIM также и в DaqPascal.
Обнаружен и устранен небольшой баг в реализации интерфейсного класса DaqApi.
С этим багом функции DaqApi работают только в потоке устройства, а при
асинхронном callback вызове из других потоков глючат (хоть и не фатально).
Demo_mmTimer - пример
DLL программы, которая реализует сбор данных по мультимедийному таймеру.
Этот таймер позволяет увеличить среднюю частоту опроса до примерно 1 кHz.
Драйвер LA15 теперь также реализован через
мультимедийный таймер. Переменная UsesMmTimer = 1 включает эту опцию.
12.07.2004
DIM
В CRW добавлен дистрибутив DIM.
Это Distributed Information Manager,
распределенная информационная система, разработанная в
CERN для создания распределенных
измерительных систем.
Дистрибутив DIM со всеми
исходниками находится в resource\DimSite\dim.
Для доступа к DIM из Pascal написан модуль
_dim.pas.
Планируется интеграция DIM в DaqPascal.
Пока интеграция DIM чисто номинальная.
В силу этого библиотеки MSVCRTD.DLL,dim.dll должны быть
в домашнем каталоге CRW32. Для отката сделан модуль-заглушка dim.dll,
который ничего не делает и нужен на случай, если с рабочей версией dim.dll
будут проблемы. Командные файлы dim_work.bat,dim_stub.bat помещают
рабочую версию dim.dll или заглушку соответственно.
11.07.2004
add3d plot3d
Функции для рисования трехмерных (3D) графиков доступны теперь и в CRW16.
Также как и задание имени окна мнемосхемы в секции описания окна.
Обновлены справочные файлы. Проведено тестирование.
10.07.2004
add3d plot3d
Добавлены две функции для рисования трехмерных (3D) графиков.
add3d(x,y,z:real):boolean - функция служит для добавления
точек, по которым будет строится график, во внутренний буфер.
Точки могут идти в произвольном порядке,причем они не обязаны лежать на регулярной
сетке и могут располагаться случайно в плоскости (x,y).
Точки, содержащие _nan,_inf в буфер не заносятся.
Надо иметь в виду, что внутренний буфер недоступен, пока не завершена предыдущая операция
рисования трехмерного графика. В этом случае функция вернет false, а точка добавлена
не будет. Чтобы узнать, свободен ли буфер, не занося в него точек, можно сделать так:
if add3d(_nan,0,0) then {буфер свободен}.
plot3d(nx,ny:integer;x1,y1,x2,y2:real;opt:string):boolean
- выполняет рисование трехмерного графика, заданного набором точек из внутреннего буфера,
занесенных туда функцией add3d.
При построении графика выполняется интерполяция набора точек (в общем случае случайного)
из буфера на регулярную (прямоугольную) сетку в плоскости (x,y).
Интерполяция делается с использованием триангуляции по методу Делоне (Delaunay).
Вызов plot3d также очищает буфер. Чтобы очистить буфер без рисования,
можно вызвать plot3d(0,0,0,0,0,0,'').
Если предыдущая операция рисования не завершена, функция вернет false,
не производя никаких действий.
nx,ny - задает число точек на графике по x,y.
x1,y1,x2,y2 - задает прямоугольную область рисования.
opt - задает разные опциональные параметры в строке
в виде выражений 'имя1=значение1|имя2=значение2|...'. Допустимые опции такие:
Caption,Title,Legend - заголовок и надписи.
top,left,width,height - положение и размеры окна в пикселях.
phi,psi - угол зрения в градусах.
scalex,scaley,scalez - масштабирующие факторы.
replace - 0/1 для того чтобы не/замещать окно графика,
если окно с таким заголовком уже есть. То есть при новой прорисовке предыдущее окно
уничтожается, если replace=1. Это чтобы не плодить много окон.
Пример программы, рисующей график поверхности:
procedure show3d(nx,ny:integer; x1,y1,x2,y2:real; formula:string);
var ix,iy:integer; x,y,z:real;
begin
for ix:=0 to nx-1 do
for iy:=0 to ny-1 do begin
x:=x1+(x2-x1)*ix/(nx-1);
y:=y1+(y2-y1)*iy/(ny-1);
b:=evar('x',x);
b:=evar('y',y);
z:=eval(formula);
b:=add3d(x,y,z);
end;
b:=plot3d(nx,ny,x1,y1,x2,y2,
'Caption=Plot3d'+
'|Title=Заголовок|Legend=Легенда'+
'|top=100|left=100|width=600|height=400'+
'|phi=60|psi=85'+
'|replace=1');
b:=plot3d(0,0,0,0,0,0,'');
end;
Также смотри демонстрационную конфигурацию _plot3d.
09.07.2004
UART Circuits
Устранена проблема, обнаруженная Алексеем Вьюшиным
(честь и слава героям :). Суть в том, что для доступа к
COM порту n использовалось имя
COMn, а надо \\.\COMn.
Из-за этого COM порты с номером > 9 не открывались.
Терерь проблема устранена.
Теперь в секции описания окна мнемосхемы можно указывать имя окна.
Имя, указанное в crc-файле при этом игнорируется. Зачем это надо?
Это позволяет иметь один crc-файл описания мнемосхемы на несколько однотипных окон,
структура которых идентична, а различия только в подключаемых тегах. Такие окна должны
иметь разные имена, поэтому приходилось делать несколько crc-файлов, отличающихся только
именем. Теперь это не требуется - crc файл может быть один, а имена задаются в секции
описания окна мремосхемы, там же, где подключение тегов.
Они могут ссылаться на один crc-файл, а имя окна задается в секции описания мнемосхемы.
Старый способ описания, разумеется, работает: если имени в секции описания окна нет,
оно берется из crc-файла.
Например:
[Windows]
Example.Win = Circuit_Window
[Example.Win]
Circuit = ..\circuits\example.crc
Name = MyWindow
Link sensor ... etc.
03.05.2004
Bugs
Обнаружилась тут одна проблема.
Как вы уже знаете, часть окон имеет свойство быть всегда "наверху".
Назовем такие окна "всплывающими". Они-то и создают проблемы.
Если активизируется модальное окно, которое берет управление на себя, то может
возникнуть такая ситуация, что модальное окно будет закрыто этими всплывающими окнами.
Это, конечно, не страшно - устраняется нажатием Escape, но неприятно для пользователя.
Чтобы избежать этого, я ввел в файл Crw32.ini переменную - флаг
SmartWindowLocation. Если этот флаг взведен, то всплывающие
окна автоматически сдвигаются так, чтобы заголовок модального окна был всегда виден
на экране. За этот заголовок его можно перетащить в удобное место.
В каталог Demo добавлены две полезные конфигурации.
_pipe.cfg - терминал для сетевой связи.
usrdrv.cfg - типовой шаблон
для создания DLL библиотек пользователя.
01.05.2004
Sound
Усовершенствовал звуковую подсистему.
Теперь при высокой загрузке процессора звуковой поток не приводит
к срабатыванию таймера
WatchDog, как было раньше.
Для управление звуковой подсистемой появилась меню
Инструменты/Контроль звука или кнопка
.
Изменил процедуру запуска CRW32.
Теперь при повторном запуске CRW32 ругательный диалог не появляется,
а вместо этого активизируется уже запущенная копия и ей передается
командная строка от запускаемой копии. Если командная строка содержит
ссылку на конфиг-файл и DAQ-система не загружена, конфиг файл загружается.
Что это дает? А то, что можно понаделать ярлыков на одну CRW32,
но с разными конфигами в командной строке. Нажимаешь - запускается нужная
конфигурация.
В файле CRW32.INI появился ключик UsesSysTray.
Если он равен 1 (по умолчанию), то CRW32 убирается из панели задач, при этом сажает свою
картинку в панели области уведомления (System Tray).
При щелчке на картинку программа раскрывается.
Использовать SystemTray вместо панели задач - более логично для системы сбора данных,
так как 1)не загромождает панель задач, 2)ее становится труднее "убить" по ошибке, так как
в списке задач ее нет.
В окне DAQ СИСТЕМА появилась кнопка "СТАТУС DAQ".
Когда все в порядке, нормальное состояние кнопки зеленое:
.
Если в DAQ системе возникает ошибка, состояние меняется на желтое:
.
Если новых ошибок не возникает, через секунду состояние будет красное:
.
Чтобы сбросить это состояние, надо нажать кнопку.
При этом она возвращается в зеленое состояние, а в консольное окно
помещается список ошибок.
Таким образом, зеленая кнопка означает, что со времени последнего нажатия
кнопки ошибок DAQ не было. Красная означает, что ошибки когда-то были.
Желтая означает что ошибки сыплются прямо сейчас.
В CRW16 тоже реализованы comclear,
comspace.
23.04.2004
pipe comspace comclear
function comspace:integer - возвращает свободное пространство
(число байтов) в FIFO передатчика. Теперь, когда идет запись данных в порт, можно проверить,
есть ли там место. Это особенно актуально для сетевых каналов, где траффик может быть
гораздо больше чем по RS-232.
Например,
if comspace>length(s) then b:=comwrite(s) else writeln('Overflow');
function comclear:boolean - очищает FIFO передатчика.
paramstr('UserName') - возвращает имя пользователя.
paramstr('ComputerName') - возвращает имя компьютера.
Ввел поддержку именованных каналов (pipe).
Правда, это работает только под NT/2K/XP.
Канал - это средство двустороннего сетевого обмена между двумя экземплярами
CRW-DAQ, очень похожий на RS-232, но идущий по Ethernet. Один экземпляр работает
как сервер (в том смысле что он "владеет" каналом), второй как клиент. Для связи
надо знать только две вещи - имя канала и имя компьютера, на котором запущен сервер.
Каналы целиком "накладываются" на функции работы с COM-портом:
comopen,
comclose,
comclear,
comcount,
comspace,
comwrite,
comread.
Фактически DAQ-программа даже не знает, с чем она работает - с каналом или с RS-232.
Чтобы открыть канал, надо просто в функции comopen сослаться
на секцию в конфиг-файле, в которой вместо COM-порта описан канал. Описание канала
выглядит так:
[PipeServer] ; секция описания сервера
PipeName = test ; имя канала
PipePolling = 10,tpNormal ; параметры потока
FifoSize = 16 ; размер FIFO,KБ
Timeout = 1000 ; тайм-аут,миллисекунд
[PipeClient] ; секция описания клиента
PipeName = alex\test ; компьютер\канал
PipePolling = 10,tpNormal ; параметры потока
FifoSize = 16 ; размер FIFO,KБ
Timeout = 1000 ; тайм-аут,миллисекунд
Как видно, описание клиента и сервера отличается только тем, что у сервера
не указано имя компьютера. Параметр PipeName обязан быть
(фактически его наличие и определяет, что это канал, а не порт). Все остальные
параметры можно опустить, будут приняты значения по умолчанию. Тайм-ауты, если указаны,
должны совпадать.
Выбор, кто будет клиентом, кто сервером, отчасти произволен. Однако надо учитывать,
что сервер создает канал и ждет подключения, не генерируя ошибок, даже если клиент не подключен,
в то время как клиент периодически пытается открыть канал, генерируя ошибку, если сервер не
отвечает. В типичной ситуации сервер - машина, которая работает всегда (измерительная),
а клиент - машина, которая может выключаться (наблюдательная).
Установление связи происходит автоматически, это забота системы.
Внимание!
Каналы задуманы как средство оперативного обмена командами или небольшими
(несколько килобайт) пакетами, траффик может составлять десятки килобайт в секунду.
Не следует использовать каналы для прокачки больших объемов данных (более 500 КБ в секунду).
Для этого больше подходят обычные сетевые файлы.
При посылке сообщений желательно проверять comspace и приостанавливать
вывод, если передатчик переполнен.
Если связи нет или возникают сбои, будет инкрементироваться ошибки с кодами 11,12.
Чтобы увидеть тип ошибки, включить режим отладки и открыть консоль программы.
При чтении, чтобы увеличить скорость "прокачки" и избежать потерь, надо использовать
что-то вроде while comcount>0 do s:=comread(128),
то есть выбирать из FIFO приемника все что там есть.
Для иллюстрации полезно сравнить две консольные программы:
_RS232.CFG
- консоль RS-232
_RS232_PIPE.CFG
- две консоли (клиент и сервер), связанные по именованному каналу на одной машине.
Заметьте, что программа одна и та же:
_RS232.PAS.
17.03.2004
HTML CRW16 CRW32
Добавил еще 3 документа - справки по HTML - в справочник.
В Crw32 устранил пару ошибок в шаблонах редактора.
В Crw16 устранил пару мелких недочетов (интерфейсного характера).
В Crw16 дополнил HELP с учетом последних новшеств.
30.01.2004
edit in CRW16
Теперь можно указывать текущий пункт меню
... edit(')MenuList Ident n'); .
Это надо, чтобы можно было показать при редактировании
текущее состояние переменной.
В Crw16 добавлена поддержка функции edit.
Есть ряд отличий-ограничений:
SelectionList работает как MenuList (выбор только одного пункта)
StringGrid изображается всегда в один столбец.
Для больших таблиц это не подходит.
FileOpenDialog умеет выбирать только один файл.
В Crw16 добавлена возможность указать конфиг-файл в командной строке,
что позволяет делать автозагрузку конфигурации при старте.
30.01.2004
BUG in pos(..)
Найдена и устранена ошибка в функции pos(s1,s2).
Она проявляется в случае, если s1=char ,
а s2=temporary string , например, при вызове
pos('?',edit(...)). Проявляется в том, что использованная временная строка
не уничтожается, что ведет к постепенной "утечке памяти".
В результате через какое-то время программа начнет давать сбои из-за
исчерпания таблицы строк.
В связи с этим все версии CRW16 и CRW32 подлежат
обязательной замене на всех установках.
29.01.2004
Cmd line HelpFile Text-Shift File-Open HTML
Теперь можно передавать в командной строке CRW32 имя *.CFG файла
чтобы автоматом запускать измерения. Это удобно, теперь можно наделать несколько
*.LNK или *.BAT файлов на разные конфигурации
и быстро запускать их. Кроме того, теперь при обновлении версии можно не заботиться о настройке
CRW32.INI.
Теперь в секции [Daq] HelpFile = ... можно указать имя справочного файла
*.DOC, *.RTF, *.PDF, *.HTM, *.HTML, *.PPT, он будет открыт по нажатию кнопки
вызова справки DAQ .
Это значит, справочную документацию по измерительным системам теперь спокойно можно писать
в Word,HTML,PowerPoint и т.д.
Появилось полезное средство форматирования. Это команды сдвига текста
влево и
вправо .
Это полезно для правильного форматирования программ и на практике часто используется.
Допустим, какой-то кусок программы зависит от некоторого условия.
Мы пишем: if Condition then КУСОК ПРОГРАММЫ end.
Все хорошо, но КУСОК надо сдвинуть вправо на один пробел,
а это иногда солидный объем текста. Теперь нет проблем. Замечу, что правильные отступы - не
блажь, знаю по опыту. Хорошая структура программы сильно облегчает ее понимание и сопровождение.
Пишите программы с хорошей структурой - сэкономите время и себе и другим.
Теперь в меню Файл | Открыть
можно открывать много чего - HTML, документы, звуки, фильмы, программы.
Обычно при создании измерительной системы интерес сосредоточен в одном каталоге, так что удобно
через одну и ту же команду вызывать, например, редактор для правки мнемосхемы,
графический редактор для правки картинок и т.д.
В зависимости от расширения файл открывается в CRW или средствами Windows.
Заметьте, что:
При открытии DPR файлов их можно редактировать и компилировать. Это надо для создания
DLL-программ на Delphi.
При открытии PAS файлов их можно редактировать, но компиляция не доступна.
Для компиляции DAQ-программ надо загрузить DAQ-систему.
Можно редактировать калибровки CAL в текстовом виде или в специальном редакторе калибровок.
Можно редактировать мнемосхемы CRC в текстовом виде и затем загружать в графическом для
просмотра их вида.
Можно редактировать тексты HTML в текстовом виде и затем смотреть через Explorer.
Вообще операции чтения/записи подверглись внутренним изменениям, с целью получить больше
удобства в работе. Скажем, при открытии диалога ввода файла имя файла запоминается,
чтобы при следующем открытии файла оказаться в том же каталоге. Ведь обычно редактируемые
файлы расположены недалеко.
По предложению Олега при нажатии кнопки "Редактировать DAQ программу" окно свойств программы
и управления DAQ-устройствами закрывается. В самом деле удобно.
Добавлен справочник по HTML 4.0 . Это связано с тем, что
теперь возможно делать справочную систему и документацию для DAQ-систем в HTML и вызывать по
. Возможно, что со временем CRW32 вообще будет
сильно интегрироваться с HTML, например, для создания интерфейсов можно делать их в виде
HTML, который взаимодействует с CRW32.
По этой же причине в редактор введены некоторые шаблоны HTML.
Все желающие приглашаются для расширения библиотеки шаблонов.
Шаблоны расположены в Crw32exe\Resource\EditorTemplates, это просто текстовые файлы.
Если будут наработки, передавайте их мне, я включу их в очередной дистрибутив.
27.01.2004
Help
В меню добавились
Справка по Delphi ,
Справка по Win32 .
Из-за большого объема сами справочные файлы в дистрибутив CRW32 не входят.
Они доступны только если установить дополнительный пакет
Crw32exe-ExtraResourceKit.zip .
Для этого надо просто скопировать каталог
resource в каталог
Crw32exe.
Эти справочные средства нужны на случай, если вы соберетесь писать DLL программы в CRW32.
27.01.2004
Ctrl+Shift
Теперь, если включить меню Инструменты|Rus/Eng=Ctrl+Shift,
то переключение языка ввода (Русский\Английский) в CRW32 будет
происходить только при нажатии Ctrl+Shift независимо от того, как настроен Windows.
Других программ это не касается. Начальное состояние меню задается в переменной
Crw32.ini,[System],KeyBoardLayoutControl.
Кроме того, при включенном контроле языка устраняется ошибка, связанная с
неправильным переключением клавиатуры в текстовом редакторе под Windows-95/98.
В связи с этим настоятельно рекомендуется отказаться от
Notepad и других редакторов при работе в пакете CRW32, особенно при редактировании
конфигураций, программ, мнемосхем и т.д.
Использование посторонних программ для редактирования текста имеет ряд
отрицательных эффектов. В пакете отслеживается, например, чтобы файл был открыт
только в одном окне, а при использовании Notepad можно открыть файл дважды,
так что потом при закрытии редактора можно потерять отредактированный файл.
Это я по опыту знаю.
19.01.2004
Templates
Сделаны некоторые внутренние изменения в надежде повысить надежность пакета.
Расширена библиотека шаблонов редактора. Пользуйтесь, сообщайте о недочетах и пожеланиях.
15.01.2004
Text Edit
В текстовом редакторе появились шаблоны -
.
Библиотека шаблонов пока чисто номинальная, она будет пополняться со временем.
Все могут принять в этом участие. Примеры - в каталоге resource/DaqEditorTemplates.
Там все понятно.
15.01.2004
winshow
Теперь программа может открыть консольное окно устройства-программы вызовом winshow('Консоль name'),
где name - имя устройства.
Пример программы, открывающей свою консоль:
b:=winshow('Консоль '+devname);
b:=windraw('Консоль '+devname+'|Top=100|Left=200');
.
14.01.2004
windraw
Теперь при прорисовке окон после имени окна можно указывать различные параметры рисования,
разделяя их символом вертикальной черты |.
Чтобы уменьшить число прорисовок, рекомендуется все параметры передавать в одном вызове.
Параметр рисования имеет вид Имя=Значение.
Для всех окон можно указывать такие параметры:
Top=y - координата y верхнего левого угла окна.
Left=x - координата x верхнего левого угла окна.
Width=w - ширина окна w.
Height=h - высота окна h.
Для окон-графиков можно также задавать:
LegendX=s - надпись s в нижней части окна.
LegendY=s - надпись s в верхней части окна.
При указании надписи используются символы форматирования:
^L=Left
^R=Right
^C=Center
^N=NewLine.
Range=ex1;ey1;ex2;ey2 - диапазон ex1<=x<=ex2,ey1<=y<=ey2 окна.
Roi=ex1;ey1;ex2;ey2 - маркеры ex1,ey1 и ex2,ey2 области интереса ROI.
Для отмены ROI надо задать значение _nan.
Формульные выражения ex1,ey1,ex2,ey2, разделенные точкой с запятой, могут ссылаться на следующие переменные:
x1,y1,x2,y2 - текущий диапазон окна.
xmin,ymin,xmax,ymax - диапазон данных в окне.
roix1,roiy1,roix2,roiy2 - диапазон ROI в окне.
SelectCurve=s - выбор в окне кривой с именем s.
Если нет такой кривой или указана пустая строка, выбор кривой отменяется, то есть отображаются все кривые.
Напоминаю всем еще раз, что все строки Daq-Pascal - динамические.
Все используемые строки должны инициализироваиться (присвоением пустой строки)
в начале программы (или подпрограммы), а также сбрасываться (присвоением пустой строки)
в конце программы (или подпрограммы).
program example;
var s1:string;
procedure DoSomething;
var s2:string;
begin
s2:=''; {initialize s2}
s2:='xxx'; {use s2}
s2:=''; {finalize s2}
end;
begin
if runcount=1 then begin
s1:='' {initialize s1}
end else
if isinf(runcount) then begin
s1:=''; {finalize s1}
end else begin
s1:='yyy'; {use s1}
end;
end.
11.01.2004
edit editstate
CRW32! (В CRW16 функции присутствуют но не работают).
Давно есть необходимость в функциях редактирования из-под CRW-DAQ. Извольте.
Чтобы не плодить много функций, я все засунул в две, но довольно сложных.
Проблема в том, что программа Daq Pascal выполняется в своем потоке и не может напрямую вызывать какие-либо
диалоги. Кроме того, неправильно приостанавливать поток daq-программы во время редактирования.
Поэтому логика работы такая - в цикле опроса анализируем статус редактора.
Когда редактор освободился (статус=0), инициируем диалог.
При инициировании с диалогом связывается некий идентификатор, который мы сами для себя придумываем для
облегчения интерпретации. После инициирования через некоторое время появится статус готовности ответа (1).
По этому статусу можно читать результат. При чтении результата считывается идентификатор завершившегося диалога,
что позволяет легко разобраться, даже если в программе несколько диалогов.
function editstate:integer - возвращает статус редактирования. Это комбинация флагов:
0 - редактор свободен, можно инициировать новое редактирование.
1 - редакторование успешно закончено, можно читать результат.
2 - редактор находится в состоянии редактирования,окно открыто.
4 - редактор находится в состоянии подготовки к редактированию.
8 - редактор обнаружил ошибку редактирования. Это либо ошибочные
аргументы, либо в момент исполнения в программе уже открыто какое-то модальное окно. Чтобы не
возникало проблем с множеством модальных окон, запрещено открывать более одного модального окна.
Временно могут возникать суммарные комбинации этих флагов, но не надолго.
Ориентироваться в основном надо на 0(можно открывать диалог), 1(можно брать результат), 8(ошибка).
function edit(arg:string):string - основная функция редактирования.
Редактирование получается за счет многократного вызова этой функции с разными аргументами.
Перед вызовом edit надо проверять editstate.
Если arg='', происходит сброс флагов 1,4,8 редактора,
флаг 2 сбрасывается только самим редактором.
Если arg<>'', работа функции определяется первым символом arg.
( - начать подготовку задания для редактирования.
После открывающей скобки идет строка, добавляемая в задание для редактора.
Возвращается статус editstate или ? при ошибке.
- (пробел) продолжить подготовку задания для редактирования.
После пробела идет строка, добавляемая в задание для редактора.
Возвращается статус editstate или ? при ошибке.
) - закончить подготовку задания для редактирования и послать задание редактору.
После закрывающей скобки идет тип диалога и его идентификатор, который служит потом для того,
чтобы верно интерпретировать результат редактирования. Если идентификатора нет, его заменяет тип диалога.
Возвращается статус editstate или ? при ошибке.
? - прочитать данные. Дальше идет уточнение, что именно прочитать.
? - прочитать статус.
?ans count - прочитать число строк в буфере результата редактирования.
?ans n - прочитать строку результата номер n.
Аналогично читаются inp(буфер подготовки задания для редактора) и
ask(буфер редактируемного задания).
В нулевой строке результата всегда идет строка Name=Result,
где Name - идентификатор диалога, который был указан при создании диалога,
Result - статус редактирования, это одна из констант:
1 - Ok.
2 - Cancel.
6 - Yes.
7 - No.
Другие строки результата (если они нужны) определяются типом диалога.
Типы диалога:
Warning - диалог-предупреждение.
На входе - отображаемый текст, на выходе - статус (Ok/Cancel).
YesNo - диалог-подтверждение.
На входе - отображаемый текст, на выходе - статус (Yes/No).
YesNoCancel - диалог-подтверждение
На входе - отображаемый текст, на выходе - статус (Yes/No/Cancel).
Information - диалог-справка
На входе - отображаемый текст, на выходе - статус (Ok/Cancel).
Error - диалог-сообщение об ошибке.
На входе - отображаемый текст, на выходе - статус (Ok/Cancel).
MenuList - меню выбора.
На входе - строка#1=Заголовок, строка#2=Комментарий, дальше список пунктов меню.
На выходе - статус (Ok/Cancel). Если статус=Ok, дальше идет строка с номером выбранного пункта.
SelectionList - список выбора.
На входе - строка#1=Заголовок, строка#2=Комментарий, дальше список пунктов меню.
На выходе - статус (Ok/Cancel). Если статус=Ok, дальше идут строки с номерами выбранных пунктов.
TextEdit - редактор текста.
На входе - строка#1=Заголовок, дальше редактируемый текст.
На выходе - статус (Ok/Cancel). Если статус=Ok, дальше идут строки отредактированного текста.
StringGridEdit - редактор таблиц.
На входе - строка#1=Заголовок, дальше идут строки с описанием таблицы, элементы которой разделены
символом-разделителем |.
Например, Row1|1.23|10|20.
Первый столбец таблицы всегда нередактируемый, служит для комментария.
Первая строка нередактируемая, если число столбцов > 2.
На выходе - статус (Ok/Cancel). Если статус=Ok, дальше идет строка с номером выбранного пункта.
FileOpenDialog - диалог выбора файла или файлов.
На входе - строка#1=Заголовок, строка#2=имя файла, дальше список пунктов фильтра.
Элементы фильтра типа Все файлы (*.*)|*.*|.
На выходе - статус (Ok/Cancel). Если статус=Ok, дальше идет список выбранных файлов.
Пример программы редактирования строки:
program editstr;
var s:string; x:real;
begin
{инициирование диалога при нажатии сенсора EDIT_X}
if (clickbutton=1) and (clicksensor='EDIT_X') then
if editstate=0 then begin
if pos('?',edit('(Отредактируйте переменную:')
+edit(' X=|10')
+edit(')StringGridEdit EDIT_X'))>0
then writeln('Не могу инициировать диалог!');
end;
{анализ результата}
if editstate=1 then begin
if extractword(1,edit('?ans 0'))='EDIT_X' then begin
if extractword(2,edit('?ans 0'))='1' then x:=rval(copy(edit('?ans 1'),4,255));
s:=edit(''); {сброс}
end;
end;
{сброс по ошибке};
if editstate=8 then s:=edit('');
end;
Теперь строковые теги можно отображать в мнемосхемах. Радуйтесь.
11.01.2004
echo eval evar
Несколько функций общего применения.
function echo(msg:string):boolean - выводит сообщение msg в главную консоль.
То же самое делает writeln(msg), если предварительно сделать rewrite('con:').
function eval(expr:string):real - вычисляет выражение expr,
используя интерпретатор. При ошибке интерпретации возвращает NaN.
function evar(x:string;v:real):boolean - установка переменной x=v.
Установка переменной через evar('x',v) нужна потому, что при этом не возникает
ошибок округления, в отличие от выражения типа x=eval('x='+str(v)), которое тоже
устанавливает значение x.Возвращает true, если операция удалась.
Пример:
program test;
var x:real; b:boolean;
begin
x:=1.2345;
if evar('x',x) then writeln('Set x :',x);
writeln('Get x :',eval('x'));
writeln('Evaluate x^2 :',eval('x^2'));
b:=echo('Ok');
end;
03.01.2004
crlf progname devname paramstr
Новая группа строковых функций:
crlf:string - разделитель строк, CR=#13,LF=#10.
progname:string - имя текущей программы Daq-Pascal.
devname:string - имя устройства, которому принадлежит текущая программа.
Кроме того, новые возможности paramstr:
paramstr('ProgName') - полное имя CRW32.EXE - файла.
paramstr('DaqProgram') - имя текущей программы Daq-Pascal.
Следующие возможности paramstr служат для доступа к базе данных CRW-DAQ,
позволяя узнать, какие в текущей конфигурации есть кривые, устройства, окна и т.д.:
paramstr('DeviceName n') - имя устройства n.
paramstr('DeviceModel n') - модель устройства n.
paramstr('DeviceFamily n') - семейство устройства n.
paramstr('CurveName n') - имя кривой n.
paramstr('CurWinName n') - имя окна кривых n.
paramstr('CirWinName n') - имя окна мнемосхем n.
paramstr('TabWinName n') - имя окна таблиц n.
paramstr('SpeWinName n') - имя окна спектров n.
Везде номер n объекта меняется от нуля до тех пор, пока не вернется пустая строка.
Например, для перечисления всех устройств DAQ можно писать:
i:=0;
while length(paramstr('DeviceName '+str(i)))>0 do begin
writeln(paramstr('DeviceName '+str(i)));
i:=i+1;
end;
Новая группа функций работы с кривыми:
crvname(c:real):string - имя кривой, данной ссылкой c.
crvlock(c:real):boolean - блокировка доступа к кривой, данной ссылкой c.
crvunlock(c:real):boolean - снятие блокировки доступа к кривой, данной ссылкой c.
crvins(c,i,x,y:real):real - вставка точки (x,y) в i-й элемент кривой,
данной ссылкой c. Индекс i меняется от 1 до crvlen(c)+1.
Функция возвращает число вставленных точек - 0 (при ошибке) или 1 (при успехе).
crvdel(c,i,n:real):real - удаление n точек начиная с i-й в кривой, данной ссылкой c.
Индекс i меняется от 1 до crvlen(c).
Функция возвращает число удаленных точек - 0 (при ошибке или если кривая пустая) или >0 (при успехе).
Все перечисленные выше функции используют для доступа к кривой ссылку.
Для получения этой ссылки можно испльзовать такие функции как refao,refdo,refai,refdi,crvfind.
Будьте внимательны, неверная ссылка может, в принципе, свалить программу! Защита есть, но она не всесильна.
Функции crvlock,crvunlock требуют пояснений.
Они всегда используются в паре - сначала кривая блокируется, потом ОБЯЗАТЕЛЬНО разблокируется.
Блокировка обеспечивает, что никакой другой поток не модифицирует кривую между вызовами crvlock и crvunlock.
Например, если надо извлечь последнюю точку (x,y) кривой с именем data, это можно делать так:
c:=crvfind('data');
b:=crvlock(c);
x:=crvx(c,crvlen(c));
y:=crvy(c,crvlen(c));
b:=crvunlock(c);
Блокировка обеспечивает, что кривая не будет модифицирована другим потоком, пока выполняется нужная
последовательность операций с кривой.
Однако надо иметь в виду следующее:
1) Если заблокировали и забыли разблокировать - программа может повиснуть.
2) Фрагмент внутри заблоктрованной секции должен быть как можно более коротким.
Блокировка на длительной время недопустима, другие потоки могут приостановиться.
3) Желательно не блокировать две и более кривых одновременно.
Лучше скопировать данные в локальные переменные, блокируя/разблокируя кривые по очереди.
Если это все же необходимо, блокировка-разблокировка должна идти по принципу стека
(порядок разблокировки обратен порядку блокировки).
В принципе, все программы Daq Pascal должны быть переписаны с использованием блокировок.
Поскольку это трудно сразу сделать, надо писать новые программы с использованием этих функций.
Постепенно все заменится на новые функции.
Новые возможности функции devmsg и консоли устройств program.
Как вы знаете, при вызове reset(''), стандартный файл ввода-вывода программы
подключается к FIFO, к которому с другого конца подключено окно консоли ввода-вывода.
Когда вы делаете вызов readln/writeln, ввод-вывод делается
в консольном окне. Для иллюстрации смотри _console.cfg
и _con.cfg.
Так вот, теперь функция devmsg позволяет помещать в FIFO сообщения так же, как будто они
поступают из консольного окна. Допустим, имеется программное устройство с именем &Rx.
При вызове r:=devmsg('&Rx Hello!'+crlf) во входное FIFO устройства
&Rx помещается строка Hello!, а функция возвращает длину
r помещенной в FIFO строки или 0, если буфер FIFO переполнен или устройство с данным
именем не найдено. Теперь при очередном вызове readln(s) в программе
&Rx будет прочитана строка s='Hello!'.
Ну и что из этого следует?
А то, что теперь появилось новое средство коммуникации между программами на DAQ-Pascal, кроме кривых и тегов.
Например, программа-драйвер может теперь не записывать измеряемые данные в кривую, а непосредственно передавать
программе обработки через сообщения. Программа обработки может брать данные из консоли, обрабатывать их и передавать
управляющие воздействия также через сообщения. Это удобно, при отладке все можно эмулировать с консоли,
а потом заменить на сообщения.
Правда, надо учитывать несколько обстоятельств.
1) Буфер FIFO порядка 4 килобайт, для высокоскоростного ввода может оказаться маловато.
2) На функции ввода-вывода и преобразования число-текст тратится время процессора.
При высокой скорости ввода на слабых машинах могут быть проблемы.
3) Приостановки и ожидания программы-писателя при переполнении FIFO приемника не предусмотрено.
Анализируйте результат вызова devmsg и организуйте задержку сами, если надо.
4) Не забывайте CRLF в конце сообщения, чтобы разделять разные сообщения.
5) Сообщения могут передаваться от кого угодно, кому угодно, могут поступать от нескольких
разных устройств одновременно. Приемник не знает, откуда пришло сообщение.
Если это надо знать, само сообщение должно содержать эту информацию явно.
6) Содержание сообщений есть предмет договоренности передатчика и приемника.
Системой оно не контролируется.
7) При старте и остановке системы CRW-DAQ возможна потеря сообщений, так как устройства стартуют
независимо, в разное время, а при старте устройства буфер FIFO очищается.
Сообщения работают надежно после старта всех устройств.
8) Обработка посланного сообщения, естественно, происходит с задержкой.
Передатчик просто записывает строку в FIFO и продолжает свои дела.
Обработку сообщения приемник делает, когда ему будет выделен очередной квант времени.
Cмотри пример _conmsg.cfg.
Там программа &Tx посылает сообщения, а программа &Rx их
анализирует.
02.01.2004
LA15_DRV RFA-1229 CRW32-Plug-In
Несколько новых конфигов в разделе CRW32EXE\DEMO.
_conmsg.cfg - новые возможности _devmsg.
LA15_CTRL.CFG - драйвер
для карты ЛА-1.5 Руднева-Шиляева, еще один пример использования технологии Crw32-Plug-In.
LA15_DRV.DOC - отчет по драйверу ЛА-1.5.
RFA-1229.CFG - обработка спектрометрических данных
в методике РФА, еще один пример использования технологии Crw32-Plug-In.
RFA-1229.DOC - отчет по программе RFA-1229.
02.01.2004
RFA
Обновленная библиотека рентгеновских линий для РФА от Васина.
RFADATA.INI - новая библиотека RFA.
RFADATA.INI.OLD - старая библиотека RFA.
02.01.2004
crw-daq-news
Создан раздел crw-daq-news.
Здесь, по мере развития пакета CRW, будут помещаться новости, интересные для пользователей и разработчиков.