PDA

Просмотр полной версии : SysFileClose возвращает Invalid



Wanted
23.04.2013, 11:59
Добрый день. Реализовал запись и чтение рецептов в файлы на ПЛК. Часть кода чтения рецепта из файла:

(*Создаем или открываем новый файл с таким же именем, как номер рецепта*)
FileHandler:=SysFileOpen(WORD_TO_STRING(recipenumb er),'r');

(*Если файла с рецептом ещё не существует, присваиваем переменным рецепта нули*)
IF FileHandler=0 THEN
recfeed1:=recfeed2:=recfeed3:=recfeed4:=recfeed5:= recpowder:=recbitum:=0;
END_IF

(*Если файл существует, считываем оттуда значения и присваиваем их переменным рецепта*)
IF FileHandler<>0 THEN
FileRead:=SysFileRead(FileHandler,ADR(recipe),SIZE OF(recipe));
recfeed1:=recipe[1];
recfeed2:=recipe[2];
recfeed3:=recipe[3];
recfeed4:=recipe[4];
recfeed5:=recipe[5];
recpowder:=recipe[6];
recbitum:=recipe[7];
END_IF
FileClose:=SysFileClose(FileHandler);
END_IF

Суть проблемы: два рецепта с номерами, соответственно, 1 и 2 записались, значения считываются с помощью данного кода успешно. Когда переключаю на 3 рецепт или рецепт с любым другим номером, переменным рецепта присваиваются нули, как и должно быть, но SysFileClose возвращает Invalid, соотвественно, файл не сохраняется. В чём может быть проблема, куда смотреть?

capzap
23.04.2013, 12:04
что значит не сохраняется, Вы показываете код для чтения из файла

Wanted
23.04.2013, 12:13
Прошу прощения, не то написал. Файл не закрывается, а затем уже записать в него ничего не удается (код записи в файл приводить не стал, т.к. явно проблема не в нём), контроллер виснет и перезагружается.

Хм, порылся в русскоязычной документации к библиотеке, там написано, что SysFileOpen возвращает 0 в случае ошибки. Где-то я нашел пример, по которому всё, собственно, и сделал, где SysFileOpen как-будто бы возвращал 0 в случае, если файл не существовал и был создан только что, может быть в это и проблема вся? Файл просто не создается, не открывается, поэтому и закрывать-то и нечего? :)

capzap
23.04.2013, 12:28
loadReception : BOOL;
saveReception : BOOL;
hFile : DWORD; (* дескриптор файла рецептов *)
reception : ARRAY [0..9] OF PROD_RECEPT;


IF loadReception THEN (* при загрузке плк *)
hFile:=SysFileOpen('rcpt.bin', 'r'); (* получение дескриптора файла *)
IF hFile>0 THEN (* если файл существует *)
logFileSize := SysFileGetSize('rcpt.bin'); (* вычисляем размер файла *)
(* читаем данные по минимуму, либо размер файла, либо размер массива *)
IF SysFileRead(hFile, ADR(reception)
,MIN(UDINT_TO_DWORD(logFileSize)
,INT_TO_DWORD(SIZEOF(reception)))) <> 0 THEN (* если приняли соответствующее количество байт *)
SysFileClose(hFile); (* закрываем файл *)
loadReception:=FALSE;
ELSE SysFileClose(hFile);loadReception:=FALSE; END_IF;
ELSE loadReception:=FALSE; END_IF;
END_IF;
Такой код работает
Не понятно зачем Вы рецепты в разные файлы пишите, не забывайте что к каждому файлу пишется еще служебная информация, поэтому такой способ больше занимает место на флеш

Wanted
23.04.2013, 12:39
Такой код работает
Не понятно зачем Вы рецепты в разные файлы пишите, не забывайте что к каждому файлу пишется еще служебная информация, поэтому такой способ больше занимает место на флеш

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

В моем случае нашел ошибку: SysFileClose должно было быть на строчку выше )

lazy
27.04.2013, 11:50
успешнозавершенный SysFileClose возвращяет 0 - это стопудово. и (помоему) -1 в случае ошибки. а -1 это даже совсем не true. в смысле не BOOL )
:D