PDA

Просмотр полной версии : Архив типа shift mode средствами SysLibFile



Владимир Васильевич
08.04.2010, 16:15
Добрый день!
Очень нужено организовать архив типа "shift mode" средствами SysLibFile, а опыта работы с этой библиотекой и с файлами очень мало.
Прочитал почти все, что писалось об этом на форуме. Прочитав это:

http://www.owen.ru/forum/showthread.php?t=2114&page=4&highlight=SysLibFile
http://www.owen.ru/forum/showthread.php?t=4205&highlight=syslibfile

Кое что стало понятно, а воплотить это в жизнь, без подробного примера, не получается :(
Может кто-нибуть может поделится более менее подробным примером создания архива типа "shift mode" средствами SysLibFile с применением следующих приемов:

читаете последнюю половину файла в буфер, создаете новый файл, записываете буфер (не забудьте заголовок добавить к нему), удаляете старый файл, переименовываете.
лучше делить файл не побайтно, а по строкам.
Buffer:Array [0..1024] of byte;
Строки можно делать любой длинны, но работать с ними с помощью строковых функций - только до размера 256 байт.


Рекомендую не писать 20 раз в файл, а накапливать данные в буфере и сбрасывать на диск большими блоками. Каждое обращение к функции записи неизбежно затирает 1 блок Flash. Да и быстрее будет.

В программе архивации создаёте буфер на 1 (а лучше на 2-5) записей.
Архивируете в буфер и считаете число свободных блоков в буфере. Когда буфер заполнится - записываете его весь на диск и сбрасываете счётчик свободных блоков.

Архивировать нужно переменные типа REAL и WORD.
Если кто может таким поделиться, буду очень благодарен.

Gans
08.04.2010, 17:10
и не жалко пэ-эл-ка-шку так мучить!?
насчет архивирования лучше почитать про мсд100, уверен как раз то что нужно.

Филоненко Владислав
08.04.2010, 17:41
технология проста.
пишем в ретайн. после накопления пары кбайт сбрасываем на диск.
если размер на диске становится >критического, то:
создаем новый файл. копируем в него последнюю половину старого, стираем старый, переименовываем.

предусматриваем защиту от разных неожиданностей, например старый уже стерли, а новый не переименовали, а свет выключился. т.е. в зависимости от состояния транзакции либо её доигрываем, либо откатываем назад.

в ретайн храним состояния транзакции.

если соблюдать "умеренность" в записях - ресурса хватит на века.

Владимир Васильевич
09.04.2010, 06:35
Спасибо за ответы, с технологией все понятно, хотелось бы увидеть реализацию этих идей (пример именно с shift mode). В теме примеры программ и полезности уже есть примеры работы с SysLibFile, но с shift mode - нет. Этот пример был бы изюменкой:).

Филоненко Владислав
09.04.2010, 09:48
с нетерпением ждем поставок изюминок. нам просто некогда это делать.

Владимир Васильевич
09.04.2010, 10:42
я вас понимаю. вам действительно некогда, судя по активности переписок. но очень хотелось бы увидить грамотный пример работы с файлами (когда и в каких случаях отрывать и закрывать файлы и т.д. т.п.) ведь предстоит работа с памятью, увы не вечной. вдруг у вас появится свободная для этого минутка - другая и вы смогли бы накропать подобны примерчик, не только я - многие будут благодарны :).

Сергей71
14.04.2010, 21:01
в ретайн храним состояния транзакции.

если соблюдать "умеренность" в записях - ресурса хватит на века.

... и ретайн не сохранился. то-ли плк поймал глюка то-ли сдохла батарейка и ушло в небытие состояние транзакций.

Ps страшная штука архив в плк. сам их делаю но в них всеравно теряются записи (те самые транзакции глючат наверно).

Филоненко Владислав
14.04.2010, 23:03
без аппаратного резервирования говорить о надежности вообще нельзя. это другого класса задача. купите 2 плк, соедините сетевыми переменными, напишите разные по алгортму программы в них и обеспечьте независимым Ups - и будет счастье.
но, имхо, потеря в крайнем случае последнего десятка записей, не критична.

Владимир Васильевич
15.04.2010, 12:33
Уважаемый Сергей71!
Не могли бы Вы поделиться простым примерчиком создания архива с помощью SysLibFile в режиме shift mode? На сколько я понимаю, у Вас есть опыт создания таких архивов. У меня что-то до конца не клеится... За ранее благодарен.

Владимир Васильевич
15.04.2010, 18:33
Здравствуйте Владислав!
Попытался написать архивацию на SysLibFile в режиме shift mode, но где-то напутал - в результате есть проект - надеюсь кандидат в "примеры программ и полезности" но с ошибками. Сильно не ругайте, в этом деле я новичок :rolleyes: , только учусь. Если поможите мне разобрать в моих ошибках и немного доработать, буду благодарен и обязательно выложу рабочий вариант на форум. Если есть и други желающие помочь разобраться - пожалуйста, буду рад.
Проект прилогаю. ПЛК100-24 P-L прошивка 2.10.7 таргет 2.10

Моему земеле Gans отдельный большуший привет :) Если есть возможность - присоединяйся.

Филоненко Владислав
16.04.2010, 09:43
1. Не надо совершать 100500 операций с файлами в 1 цикле. Хотя ФС жестоко закеширована, но размеры кэшей ограничены. И если выйти за их пределы - начнется торможение, т.к. операция будет ждать реальной записи на Flash, а не помещения в кэш.
2. Вы используете текстовый тип архива, разделяя записи переводом строки. Поэтому при поиске 2/3 нужно не только математически рассчитать 1/3 от конца, но и найти начало след. записи, чтобы архив не был порезан посреди значения.
3. Желательно иметь для записей время (ну это на будущее)
4 . А так идея верна. Единственно не надо каждое значение класть во Flash сразу. Накапливайте несколько.

Gans
16.04.2010, 09:52
Посмотрел пример - прикольно, но я сторониик архивирования на компах.
Возникло пара коментариев. Почему таймер t персонально объявлен в глобальных переменных!? По тексту нет комментариев :-(
Из предложений вот что:
1) может быть для архивирования брать массив real (вот он должен быть глобальным) где первый элемент массива содержит количество чисел. Этот массив содержит текущие значения переменных (температуры давления и тд.)
2) символ разделения столбцов вынести в отдельную переменную (комуто двоетичие, а другим точка с запятой или символ табуляции).
3) на мой взгляд генерация события архивации должна производится примерно так
ton_Save(in:= not ton_Save.q, PT:=tmSave); где tmSave это периодичность записи в архив. Далее по условию if tmSave.q then …. Должно выполнятся архивирование и тд. Конечно можно и task к этому пристроить (см. Task configuration).
4) в архиве первым столбцом должно быть время .. наверное

К большому сожалению исправлять код и выкладывать пока не буду это получится совершенно другая программа, каждый пишет программы по-своему - это как отпечатки пальцев:-)

Владимир Васильевич
16.04.2010, 12:19
1. Не надо совершать 100500 операций с файлами в 1 цикле. Хотя ФС жестоко закеширована, но размеры кэшей ограничены. И если выйти за их пределы - начнется торможение, т.к. операция будет ждать реальной записи на Flash, а не помещения в кэш....да, я уже думал об этом, буду разносить по циклам, наверное с помощью типа такого: IF SysFileClose(f1) THEN ...

2. Вы используете текстовый тип архива, разделяя записи переводом строки. Поэтому при поиске 2/3 нужно не только математически рассчитать 1/3 от конца, но и найти начало след. записи, чтобы архив не был порезан посреди значения.... тоже согласен. Только как это делается? Как найти найти начало след. записи в файле?
3. Желательно иметь для записей время (ну это на будущее)... это я вставлю обязательно, когда архиватор правильно заработает :) .
4 . А так идея верна. Единственно не надо каждое значение класть во Flash сразу. Накапливайте несколько.... я так понимаю надо в RETAIN писать массив и по его заполнению сбрасывать его содержимое на диск (в фаил).


Посмотрел пример - прикольно, но я сторониик архивирования на компах.Да я не против бы, но стоит задача архивирования на объекте со съемом архива через GSM модем! Обязательно через модем... Фишка с МСД100 не проходит по причине невозможности снятия архивов с него через модем :( . По замечаниям 1,2,3,4 - учту.
К большому сожалению исправлять код и выкладывать пока не буду это получится совершенно другая программа, каждый пишет программы по-своему - это как отпечатки пальцев:-) ...ЁЛКИ-ИГОЛКИ, а я думал увижу как умные и опытные люди пишут программы. Исправляйте мою, я не обижусь. Может чему нибуть и научусь глядучи на примеры :rolleyes: .

Филоненко Владислав
16.04.2010, 13:16
2. по кодам конца строки.

Gans
16.04.2010, 13:17
Постараюсь на выходных начеркать свои мысли в кодесис ..... своим-то людям :-) правда с библиотекой SysLibFile я не работал может заодно и научусь. Хотя в целях наладки подумываю всё-таки приобрести МСД100.

Gans
16.04.2010, 15:11
вот что смог накрапать, правда там вообще нет записи на флеш зато все предварительное похоже сделано.

Владимир Васильевич
16.04.2010, 15:36
2. по кодам конца строки. ... а каким образом? Нужно наверное прочитать 2/3 файла в строковую переменную (или в массив?) и спомощью FIND искать код конца строки в конце считанного куска и посчитать длину строки до этого символа. Так узнаем куда ставить указать в файле (SysFilePos). Где я ошибаюсь?


Постараюсь на выходных начеркать свои мысли......Das ist fantastisch!!! Sehr gut!

...подумываю всё-таки приобрести МСД100...У нас уже есть такая штука. Лично мне нравится. Работает не плохо, если не замучаешь со сменой скорости обмена по порту с ПК. У некоторых бывает пролетает глюк (смотри http://www.owen.ru/forum/showthread.php?p=39085#post39085) и все... allas kaput :( прямая дорога в тех.центр. Жду новых версий с исправлениями и нововведениями.

Gans
17.04.2010, 10:55
привет вот накидал чуток побольше. у меня на руках нет плк100 для надругательств поэтому обкатывать придется самому. и времени пока маловато :-)

Владимир Васильевич
17.04.2010, 14:16
...обкатывать придется самомуНе вопрос! Для этой цели у меня есть все. В понедельник на работе запущу проект в работу. Результат обязательно сообщю. А вот SysLibFile без "железа" не работает! Проверенно. Спасиб за советы в коментах, очень помогает. Нравится мне твой ход мыслей. Все, до понедельника!

P.S. Смотрю, народ интересуется нашей темой. Только почемуто ни кто не высказывается и свои идеи не предлагает...

Владимир Васильевич
27.04.2010, 18:01
Всем привет!
Долго я мучил проект ARC_Y_10_04_17 и результаты странные:
Хороший результат:
1. Проект работает нормально - время и строки формируются
Плохохие результаты:
1. Фаил на запись не открывается (дискриптор всегда равен 0) и на диск не пишется
2. Размер файла полученный с помощью SysFileGetSize принимает странные значения (541212688, 537416024, 536991940) и раза два принял реальные значения (типа 128, 256) и файла естественно на диске нет...
Вечные вопросы: что делать? В чем причина?
Может нам Филоненко Владислав подскажет?
Использую ПЛК100-24 P-L прошивка 2.10.7 таргет 2.10

Логвиненко Андрей
27.04.2010, 21:02
Если на диске нет файла, SysFileGetSize возвращает случайные значения,
наличие файла надо проверять SysFileOpen (file,'r')<>0 и , если нужна запись, то SysFileClose и SysFileOpen (file,'w').
Если для файла открыто несколько дескрипторов, то для записи доступен только первый , если он создан SysFileOpen (file,'w').
Если дескриптор был утерян, то восстановить возможность записи помогает только RESET.
SysLibFile без железа работает на SP WINNT и SP RTE, но реализация несколько отличается от ОВЕН ПЛК.

Филоненко Владислав
27.04.2010, 22:07
если дескриптор был утерян - ну в принципе его можно восстановить. но как его можно потерять?

Логвиненко Андрей
28.04.2010, 06:54
если отключить питание при открытом файле

Филоненко Владислав
28.04.2010, 07:39
и? плк либо работает на батарейном питании и ничего не теряется, либо выключается и при включении все заново происходит.
пример (развернутый) можно?

Владимир Васильевич
28.04.2010, 08:16
Вот кусочек программы, все подробно выложенно выше в проекте ARC_Y_10_04_17

IF f1 = 0 THEN f1 := SysFileOpen('ARC_HUR.txt', 'rw'); END_IF (*откроем файло на чтение и запись*)
sizAR := SysFileGetSize('ARC_HUR.txt'); (*Получаем размер файла в байтах*)
SETP2 := SysFileSetPos(f1, sizAR); (*Выставляем указатель в конец файла*)
SYSW1 := SysFileWrite(f1, ADR(str2Send), LEN(str2Send)); (*Пишем строку в файл*)
btRecordCount:=0; (*Обнуляем счетчик строк*)
str2Send:=''; (*Очистим строчку (типа буфер для нескольких строк)*)

Gans
28.04.2010, 08:30
Ой :o я открывал файл сразу и на чтение и на запись "rw" может указать по старинке только "w". Мне показалось так будет круче:rolleyes:, хотя в документации указано, что можно.
Если в этом глюк зарание страшно извеняюсь

Логвиненко Андрей
28.04.2010, 08:53
О режима SysLibFile написано здесьhttp://www.owen.ru/forum/showthread.php?t=2114&highlight=Syslibfile
полностью библиотека не поддержана, в документации об этом ни слова.

Владимир Васильевич
28.04.2010, 12:20
Поменял строчку
IF f1 = 0 THEN f1 := SysFileOpen('ARC_HUR.txt', 'rw'); END_IF
на
IF f1 = 0 THEN f1 := SysFileOpen('ARC_HUR.txt', 'w'); END_IF
Запись заработала, файл создается, данные пишуться.
Люди! Человеки! Режимы "rw" и "a" в библиотеке SysLibFile НЕ РАБОТАЮТ.
Осталось сделать самое трудное - реализовать функцию "Shift mode".

Gans
28.04.2010, 12:58
тут уже не ёлки-иголки, а настоящий пипец!!! столько уважаемых мультперсонажей на ухи поставили. как-то надо прикладывать к библиотекам описание от овен (раз уж отправляете в библиотеку), где и примеры и характерные ошибки и ссылки на форум овен + ссылка на инет где можно взять последнюю версию документа. работы в этом направлении еще лет на пять!!!
зы ну вот свалил вину на других и с чувством глубокого удовлетворения пойду делом займусь :-) владимир, извините такая уж документация :-(в следующий раз сначала буду на форуме читать про библиотеку, а потом в бой)

Владимир Васильевич
28.04.2010, 13:11
Нет, проблем, я думаю тут никто не обиделся, наоборот - всем скопом разобрались. Теперь любой желающий прочитав нашу переписку уже меньше ошибок будет совершать... Да и документацию может быть поправят :-). Часть ошибок я нашел, часть уважаемый Gans - надеюсь нам еще кто нибуть поможет :-)...

Владимир Васильевич
28.05.2010, 10:58
Огромный привет Gans! Ну, вот, приехал с командировки и третий день пытаюсь разнести по циклам работу с файлами. Получается все что угодно, только не то что нужно... Может кто подскажет, как правильно и грамотно это сделать?
Какие операторы работы с файлами из SysLibFile требуют больше времени для завершения своих действий, а какие можно писать в программе подряд? Привожу часть кода из ARC_Y_10_04_17 который нужно разнести по циклам.

sizAR := SysFileGetSize('arc.txt'); (*Получаем размер файла в байтах*)
IF sizAR > 3072 THEN (*Если файл превысил лимит по объему в байтах, хотя придел надо уточнять*)

sizBUF := (sizAR / 3) *2; (*Вычисляем 2/3 размера файла*)
SysFileSetPos(f1, sizBUF); (*Выставляем указатель на 2/3 файла*)
SysFileRead(f1, ADR(BUFER), (siz - sizBUF)); (*Читаем в буфер последнюю треть файла*)
SysFileClose(f1);

IF f2 = 0 THEN f2 := SysFileOpen('temp.txt', 'w'); END_IF (*Открываю новый файл для записи*)
SysFileWrite(f2, ADR(BUFER), SIZEOF(BUFER));
FOR i := 0 TO 1024 DO BUFER [i] := 0; END_FOR (*Очищищаем буфер*)

SysFileClose(f2);
SysFileDelete('arc.txt');
SysFileRename('temp.txt', 'arc.txt');

END_IF;(*IF sizAR > 3072 THEN*)

Малышев Олег
28.05.2010, 12:24
Я бы сделал
case i of
1: i:=+1;
2: i:=+1;

n:

end_case

Gans
15.06.2010, 11:46
здравствуйте владимир. выложите последний вариант вашей программы и окружающие помогут. мне кажется что сам процесс переноса последних 30% в новый файл (с заменой старого) нужно делать отдельным функциональным блоком. вобщем выкладывай, посмотрим :-)

lazy
09.07.2010, 14:15
Рекомендую не писать 20 раз в файл, а накапливать данные в буфере и сбрасывать на диск большими блоками. Каждое обращение к функции записи неизбежно затирает 1 блок Flash. Да и быстрее будет..
Вопрос. Допустим, организовали буфер длинной в 1 блок Flash (хорошо бы еще длину знать) и пишем в файл по заполнению буфера. Допустим, каждая десятая запись начинается с начала файла и затирает "самую древнюю". Будет ли использовано только десять блоков на Flash? И еще, если, скажем, необходимо скинуть незаполненный буфер в файл, например, при выключении. Скинули. Теперь если при включении прочитать этот кусок в буфер, добить его(буфер) данными и записать в ту же позицию файла будет начат следующий блок Flash или запишется в прошлый( в тот куда записался "недобитый" кусок буфера в прошлый раз )? Заранее благодарен :)

Филоненко Владислав
09.07.2010, 22:20
первый блок 448 байт, остальные по 512.
Нет. Записи равномерно растираются по всей Flash для одинакового износа.
Но 1 запись = 1 запись на Flash. В любом случае. Дозаписи не бывает, весь блок во Flash при записи аппаратно стирается.
Дозапись бывает если использовать сегмент - но это для больших объемов требуется.

lazy
23.08.2010, 15:50
Добрый день! Предлагаю свой вариант "Шифт-архива". Строки архива формируется из "постоянной" и "переменной" частей подобно sprintf. Строки накапливаются в ретайн буфере равном двум записям в файл. В данном примере запись равна 512 байт. При достижении архивом "критического размера" каждая новая запись в архив затирает самую старую. Запись в файл разбита по циклам ПЛК. С помощью этой программы можно увидеть, что кнопка "Reset" генерирует только события "Start" и "Power_On". Поэтому, после сброса ПЛК кнопкой "Reset", архив начинает запись по предыдущему "Store". Что, естественно, идеологически неверно. ;) События "Before_Reset" и "After_Reset" генерируются только при команде "Сброс" из CoDeSys. Это моя вторая программа для "Овен" (первая была подобна "Hello Word") поэтому буду благодарен любому пинку. И все-таки интересно, какие события должны генерироваться при нажатии на кнопку "Reset"?

В предпоследней строчке fbArchiver нужно исправить строчку gr_anParam[_STEP] := 0; на:
gr_anParam[_STEP] := gr_anParam[_STEP] - WRITESIZE;

lazy
31.08.2010, 10:02
:) Так кто же все таки ответит? Почему невозможно перехватить нажатие на кнопку "Reset" на контроллере ПЛК100-24.К-М до того как он начнет "перезагружаться" (или сбрасываться)? А если возможно, то как? Заранее благодарю.

Филоненко Владислав
31.08.2010, 11:06
Потому что reset аппаратный

lazy
31.08.2010, 15:15
Я так понял даже "Power status" бессилен? Конечно, не мне решать, но правильно ли это? Господи, Нео, просто нажми "Reset" матрица об этом никогда не узнает... :)

Филоненко Владислав
31.08.2010, 17:07
Вот для этого Reset и утоплен в корпус. Типичный палец млекопитающего начиная с 1 кг весом не пролазит в дырку.