Данный CODESYS форум содержит архивную копию русской ветви только для чтения. Для создания сообщений пожалуйста используйте актуальную международную платформу CODESYS Forum. Close

SysLibFile библиотека

Общий
Safron
2011-03-18
2012-09-03
  • Safron

    Safron - 2011-03-18

    Где можно более подробно узнать как пользоваться библиотекой SysLibFile. Уж больно скупо описано в документации к библиотеке. Например:
    1) непонятно как определить закрылся файл или нет? Где -то проскользнуло, что на самом деле SysFileClose возвращает DWORD, а не BOOL. Но присваиваешь переменной типа DWORD результат этой функции-компилятор ругается.

    VA:=enc;
    trigger();
    IF VA =126 THEN
    trigger.CLK:=TRUE;
    IF trigger.Q THEN
    hf:= SysFileOpen ('k_weight','w');
    VAP:=SysFileWrite(hf, ADR(VA), SIZEOF(VA) );
    flag:=SysFileClose(hf);
    END_IF
    ELSE
    trigger.CLK:=FALSE;
    END_IF
    2) функция SysFileDELETE не работает, если переред этим файл не открыть. В документации об этом ни слова. Да и чувство такое, что удаляет только само содержимое, а сам файл.
    IF udalit THEN
    hf:= SysFileOpen ('k_weight','r');
    del:=SysFileDelete ('k_weight');
    END_IF ----удаляется дескриптор (вроде так и надо), но del не становится TRUE при этом.
    3) функция SysFileRead отрабатывает только при первой инициализации. Т.е. постоянно надо менять имя файла, а не содержимое, только тогда считывает
    IF chitat THEN SysFileOpen ('k_weight','r');
    r_d:= SysFileRead (hf, ADR(VN), Size );
    variab:=VN;
    SysFileClose(hf);
    END_IF
    В общем куча всяких вопросов возникает.

     
  • Avgur

    Avgur - 2011-03-18

    При работе с файлами лучше использовать принцип state machine, т.е. в 1 цикле программы выполнять только 1 операцию с файлом (пример в аттаче).
    По 2 вопросу: SysFileDelete не связана с другими файловыми функциями. Могу предположить, что операционная система ПЛК не даст удалить файл предварительно открытый функцией SysFileOpen. Если есть сомнения, попробуйте вызвать SysFileDelete сразу после старта ПЛК, не вызывая других файловых функций (чтобы не было открытых дескрипторов с предыдущих попыток).
    По 3 вопросу: ИМХО проблемы должны уйти при переходе на state machine.

    FileWriteExample.rar [6.46 КБ]

     
  • Safron

    Safron - 2011-03-18

    Спасибо. Возникло пару вопросов.
    1) ( Initialisieren )
    '\disk_mmc\TestDat.bin'; ??? О чём это? Директория файла? Где об этом прочитать?
    strMode := 'a'; - ??? почему ' '

    2) ADR(Buffer) - указатель на некий Buffer. Этот буфер надо где-то предварительно объявлять или система сама распознает что и зачем?

    Спасибо.

     
  • Avgur

    Avgur - 2011-03-18

    1) прочесть можно в справке по SysFileOpen>Цитата:
    SysFileOpen
    This function (see Library SysLibFile.lib) of type DWORD serves to open a file, which already exists or which should be created.
    The return value is a file number, which will be used in the functions SysFileWrite, SysFileRead, SysFileClose as an input ('File'). In case of an error '0' will be returned resp. (watch out this exception!) '-1' by target CoDeSys SP RTE.
    FileName
    STRING
    File name

    Mode
    STRING
    Access mode:
    w write (File will be updated or created newly)
    r read (File will only be opened for reading; if the file does not exist, an error will be returned)
    rw read and write (File will be updated; if the file does not exist, an error will be returned)
    a append (File will be opened like described for 'w', but the written data will be appended at the end of the file)

    полный путь к файлу, который открываете
    режим 'a' - открытие файла с добавление информации (append); если файла нет, то он будет создан
    2) в этом проекте буфер для чтения/записи объявлен глобально```

    VAR_GLOBAL
       xWriteDone: BOOL := TRUE;
       Buffer : ARRAY[1..20] OF BYTE := 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20;
       strFileName : STRING;
       strMode: STRING;
    END_VAR

    ```В общем случае, это необязательно. Можно объявить его в своей программе или функц. блоке.

     
  • Safron

    Safron - 2011-03-18

    ОК. Спасибо. Ещё вопрос. Планирую использовать массив из реал.
    Buffer : ARRAY[1..4] OF REAL := re,rt,rw,ru; -это коээффициэнты.
    Вопрос можно ли их каждый по отдельности записывать/перезаписывать в уже созданном файле не трогая других. Если я правильно понимаю нужно использовать указатель
    ADR (ARRAY.3) для переменной с индексом 3, например?

     
  • Avgur

    Avgur - 2011-03-18

    Не понял вопроса. Вы в переменную >Цитата:
    Buffer : ARRAY[1..4] OF REAL
    собираетесь считывать информацию из файла?

     
  • Safron

    Safron - 2011-03-18

    Постараюсь подробнее. Хочу попробовать различные конфигурационные переменные (коэф. пид-регулятора, данные энкодера, диапазон измерения, длину платформы и т.д). Записать в одном файле. Для меня важно, чтобы оставалась возможность их редактирования при (необходимости) и по отдельности. Но так, чтобы в этом файле перезаписывалась только редактируемая переменная, а не все скопом. А вот считывать их я собираюсь только после каждого включения питания и присваивать их переменным с которыми работает программа процесса. Я знаю про ретайн переменные и что у Овен154 есть батарейка, с помощью которой автоматически происходит запись в файловую систему после пропадания питания (если хватит батареи). Это всё очень просто.Вроде бы это решение проблемы. Но я наслышан про эти аккумуляторы и что-то не охота связываться с ретайн. Хочется чего-то наверняка

     
  • Aleksey Pshikov

    Aleksey Pshikov - 2011-03-21

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

    bufLF: ARRAY[0..255] OF REAL;    (*буфер с уставками*)
    fdR:=SysFileOpen('a:\sets.txt', 'r');
    stR:=SysFileRead(fdR, ADR(bufLF),  SIZEOF(bufLF));
    stRC:=SysFileClose(fdR);
    

    Естественно все делал в разных тактах контроллера и пока ОС не вернет значение функции.
    Аналогично и сохранение.

     
  • Safron

    Safron - 2011-03-26

    Для Avgur:
    Пример работы с файлами классный. Спасибо. Но есть три вопроса.
    1) Запись работает только в режиме 'w' , в режиме 'a' выдаёт ошибку 100.
    2) IF ( dwReturn <> SIZEOF(Buffer[x]) ) THEN необходимо установить знак равенства (=)вместо <>.
    3) Так и не ясно , что возвращает xReturn := SysFileClose(dwHandle) в случае ошибки и возвращает ли, что либо ещё кроме FALSE. Мои эксперименты показали, что в случае удачного закрытия файла возвращается FALSE, а не TRUE как в описании, и добиться момента когда произойдёт ошибка мне не удалось...Похоже дело в самой библиотеке.
    В общем, всё работает замечательно. Спасибо всем.

     
  • Avgur

    Avgur - 2011-03-28

    Очень рад, что удалось помочь.
    1) в примерах тоже могут быть ошибки))
    2) и 3) все вопросы по ошибкам и непонятной работе функций из библиотек Sys... лучше задать производителю контроллера. Может быть описанный в справке функционал реализован не в полной мере.
    Как вы определяете "удачное" закрытие файла? Если честно, в своих проектах никогда не анализировал результат работы SysFileClose.

     
  • Safron

    Safron - 2011-03-28

    Как определил удачно или нет прошло закрытие? Просто попытался прочитать файл сразу после записи и закрытия, предварительно не открывая его функцией SysFileOpen. В расчёте на то. что если он перед этим не закрылся, то должен продолжать оставаться открытым - и у меня не получилось его прочитать. Значит файл закрылся. После того как ввёл функцию открытия прочитать удалось.

     
  • Avgur

    Avgur - 2011-03-28

    Safron писал(а):
    Просто попытался прочитать файл сразу после записи и закрытия, предварительно не открывая его функцией SysFileOpen.
    Не уловил смысл сего действия...
    Обычный вариант работы с файлом: открыли для чтения, считали информацию, закрыли; обработали инфу из файла; при необходимости открыли для записи, записали и закрыли.
    Не поленился и скачал ваш проект на сайте Овен. Зачем такой алгоритм работы с файлами в реальном проекте??? Сделайте 2 условия входа в программе: xWrite и xRead. По первому условию только пишем, по второму - только читаем. В программе PLC_PRG оставить только постоянный и безусловный вызов WriteFile, все остальное выкинуть. Дальше в режиме отладки взводить условие xWrite или xRead (или на визуализацию кнопки приделать) и проверять работу.

     
  • Safron

    Safron - 2011-03-31

    Если вы имеете в виду проект "энкодер", то от этого варианта давно уже отказался, я за ваш вариант ухватился как за спасительную соломинку..Что касается как я проверял закрывается или нет, то, если ввести четвёртый шаг wStep и удалить выделенную строчку, то считать не получится - значит в третьем шаге файл всё-таки удачно закрылся, а если оставить , то в Buffer2 запишутся значения. В противном случае(если файл не закрылся в третьем шаге) не было бы нужды опять его открывать и всё считалось как обычно.
    Возможно я несколько наивно проверил, но другого способа не знаю...

    4:    (* FileOpen*)
               strMode:='r';
    

    dwHandle := SysFileOpen(strFileName,strMode);
    ( Success ??)
    IF dwHandle <> 0 THEN
    zReturn := SysFileRead(dwHandle,ADR(Buffer2[x]),SIZEOF(Buffer2[x]));
    SysFileClose(dwHandle);
    xWriteDone := TRUE;
    wStep := 0;
    ELSE
    wStep := 100; ( error without close and out )
    END_IF

     
  • Avgur

    Avgur - 2011-03-31

    Я скачал ваш измененный FileWriteExample.pro и не понял, зачем нужен шаг 4. ОС контроллера может физически не успеть записать информацию в файл и освободить ресурсы для повторного открытия этого же файла через промежуток времени = циклу программы.
    Сделайте эту проверку (чтение) по отдельному флагу.

     
  • SiMM

    SiMM - 2011-04-06

    А в режиме эмуляции пользоваться этой библиотекой нереально? SysFileOpen возвращает 0.

     
  • SiMM

    SiMM - 2011-04-12

    Спасибо, пока помогло

     
  • falvik

    falvik - 2012-09-03

    На основе примера получилось сделать и чтение и запись, и смещение задействовал.
    Но не понятно осталось почему если делать это все по циклам программы то выдается ошибка ватчдога, а через конфигуратор задач все нормально.
    Кто нибудь может разъяснить?