SIEMENS, DF&PD

Предыдущее посещение: Сб июл 02, 2016 4:17 Текущее время: Сб июл 02, 2016 4:17

Часовой пояс: UTC + 3 часа




 [ Сообщений: 50 ]  На страницу 1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: Step7-STL: косвенное обращение к элементу массива - КАК?
СообщениеДобавлено: Вт ноя 08, 2011 17:36 
Не в сети
Известный Писатель

Зарегистрирован: Чт мар 08, 2007 17:11
Сообщения: 336
Откуда: Киров - - Вятка - - Хлынов
Никак не могу разобраться, как сделать.... Если кто сможет помочь примером, буду признателен.
Итак, имеется FB, в шапке STAT которого объявлен массив из DINT;
во входных переменных FB задаётся переменная "К", значение которой задаётся из вне и может принимать значения от 0 до 10 - по размерности массива.
Задача: считать из массива на STL одно значение, индекс которого соответствует значению переменной "К"
Изображение
При задании индекса явно (например - "5") - всё работает, а с переменной напрямую в STL ничего не получается. Как-то можно ли сделать это, используя косвенную адресацию?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт ноя 08, 2011 19:33 
Не в сети
Известный Писатель

Зарегистрирован: Ср авг 08, 2007 14:00
Сообщения: 418
Откуда: Старый Оскол
к сожалению никак...
Цитата:
Доступ к элементу массива обеспечивается по имени массива и индексу в
квадратных скобках. Индекс имеет фиксированное значение в STL и не
может быть изменен во время выполнения программы
(не может быть
переменной).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт ноя 08, 2011 22:18 
Не в сети
Начинающий писатель

Зарегистрирован: Ср авг 10, 2011 21:56
Сообщения: 92
Если элементов в массиве не очень много то можно входное значение сравнивать с константой и если оно равно то считывать. Что то вроде вот так для 3 элементов
A(
L #K
L 1
==I
)
JNB _004
L #Mass[1]
T #OutInt

A(
L #K
L 2
==I
)
JNB _004
L #Mass[2]
T #OutInt
A(
L #K
L 3
==I
)
JNB _004
L #Mass[3]
T #OutInt


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт ноя 08, 2011 23:53 
Не в сети
Известный Писатель

Зарегистрирован: Ср фев 16, 2011 14:23
Сообщения: 434
Откуда: Санкт-Петербург, Москва
Почему же, все возможно :-)

#Value - переменная из локального стека, которому присваивается значение Mass[k].

У вас может иначе вычисляться смещение если Mass идет не первым в объявлении, обратите на это внимание.

Так же не вылезьте за пределы массива :-)

Код:
      L     #k
      ITD   
      L     L#1   // В случае если номер элемента начинается с единицы.
      -D   
      L     L#32  // Размер ячейки - dint
      *D   
      TAR2 
      +D   
      LAR1 
      L     DID [AR1,P#2.0]
      T     #Value


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср ноя 09, 2011 9:28 
Не в сети
Известный Писатель

Зарегистрирован: Чт мар 08, 2007 17:11
Сообщения: 336
Откуда: Киров - - Вятка - - Хлынов
Вроде бы как заработало!! Отдельное спасибо Alexey_Spb_82
Вот как в итоге получилось:
Код:
      L     P##Mаss                 //Загрузка адреса начала  массива в аккумулятор, тип POINTER
      LAR1                              // загрузка адреса начала  массива в регистр
      L     #K                      //загрузка номера элемента
      ITD                               // Преобразование в двойное целое
      L     L#32                        // Двойное целое=32 бита
      *D                                //умножение
      TAR2                              // Запоминание смещения в битах в адресном регистре-2
      +D                                // в АСС1 - адрес нужного элемента БЕЗ СМЕЩЕНИЯ!
      TAR1                              // Загрузка в аккумулятор адреса начала массива
      +D                                // Сложение со смещением
      LAR1                              // Загрузка адреса нужного элемента в AR1
      L     DID [AR1,P#0.0]             //считывание значения элемента
      T     #VVL                        // перенос во временную переменную
      T     MD   222                    // и в ячейку памяти для контроля


В комментариях могу ошибаться - не до конца ещё разобрался, но код рабочий!!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср ноя 09, 2011 10:14 
Не в сети
Новый писатель

Зарегистрирован: Ср ноя 09, 2011 8:47
Сообщения: 40
Кто мне скажет, что хранится в AR2 на момент вызова TAR2 в этом куске кода. В любом случае я бы оформил код как
Код:
L P##Mass
L #K
SLW 5
+D
TAR2
+D
LAR1
L DID [AR1,P#0.0]


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Чт ноя 10, 2011 10:04 
Не в сети
Известный Писатель

Зарегистрирован: Пт июл 06, 2007 6:41
Сообщения: 325
Откуда: г. Тюмень, Россия
Поаккуратнее с AR2 в функциональном блоке, товарищи!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт ноя 11, 2011 7:40 
Не в сети
Написал больше чем Вы читали

Зарегистрирован: Вс янв 25, 2009 22:05
Сообщения: 1906
Откуда: Киров
Мне кажется косвенную адресацию, в т.ч. по индексам в массиве, проще всего реализовать на SCL...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт ноя 11, 2011 8:35 
Не в сети
Известный Писатель

Зарегистрирован: Чт мар 08, 2007 17:11
Сообщения: 336
Откуда: Киров - - Вятка - - Хлынов
canada писал(а):
Мне кажется косвенную адресацию, в т.ч. по индексам в массиве, проще всего реализовать на SCL...

Так всегда и делал, например проверка блока данных с элементами типа BOOL на наличие хоть одной ячейки, установленной в "1" - удобно, когда признаки всех аварий пишутся в один DB - есть хоть одна авария - вырубаем установку
Изображение
Но в том конкретном случае сложилось так, что пришлось с STL связаться - кусок-то программы - часть большого (и почти готового)блока.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт ноя 11, 2011 12:30 
Не в сети
Известный Писатель

Зарегистрирован: Ср фев 16, 2011 14:23
Сообщения: 434
Откуда: Санкт-Петербург, Москва
mva-78,

Вместо побитовой проверки в вашем лучше проверять байты, слова, либо двойные слова (в зависимости от того как у вас группируются аварии) на неравенство нулю:

что-то типа (за 100% правильность синтаксиса не ручаюсь, важен принцип):

Alarm = Word_To_Block_DB(db_num_W).DB[bayt_num] <> #b#16#0;

Это гораздо быстрее и правильнее чем перебор по битам в цикле. Особенно учитывая что CPU Infineon, используемый в ПЛК Siemens, если не ошибаюсь, не поддерживает операций с битами на уровне инструкций процессора.

А еще неплохо бы пользоваться теми возможностями, которые дают представления данных (view).


Последний раз редактировалось Alexey_Spb_82 Пт ноя 11, 2011 12:34, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт ноя 11, 2011 12:33 
Не в сети
Известный Писатель

Зарегистрирован: Ср фев 16, 2011 14:23
Сообщения: 434
Откуда: Санкт-Петербург, Москва
canada, да, удобно. Но правда в SCL много ньюансов. Без понимания некоторых принципов того, по каким принципам это добро компилируется и увлекшись косвенной адресацией, можно получить очень неоптимальный код с точки зрения как времени выполнения, так и требований к рабочей памяти.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Сб ноя 12, 2011 21:21 
Не в сети
Известный Писатель

Зарегистрирован: Ср фев 16, 2011 14:23
Сообщения: 434
Откуда: Санкт-Петербург, Москва
Хочу опровергнуть сказанное мной ранее, а именно:

Цитата:
Особенно учитывая что CPU Infineon, используемый в ПЛК Siemens, если не ошибаюсь, не поддерживает операций с битами на уровне инструкций процессора.


На самом деле процессоры Infineon (по крайней мере 16-битные серии C166 - используются в S7-300, вероятно и другие серии тоже) поддерживают работу с битами на уровне инструкций процессора, что следует из Instruction Set Manual:

http://www.keil.com/dd/docs/datashts/in ... 166ism.pdf


Подобного документа для других процессоров Infineon (в том числе 32-битных) я не нашел. Если кто знает - поделитесь пожалуйста ссылкой.

Отдельное спасибо gre_m за поднятие этого вопроса.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн ноя 14, 2011 5:44 
Не в сети
Известный Писатель

Зарегистрирован: Пт июл 06, 2007 6:41
Сообщения: 325
Откуда: г. Тюмень, Россия
Цитата:
Подобного документа для других процессоров Infineon (в том числе 32-битных) я не нашел. Если кто знает - поделитесь пожалуйста ссылкой


Инструкции Infineon TriCore, которые по моим данным применяются в 400ой серии, я так же не видел.

Но по косвенным признакам могу предположить, что они уже не умеют напрямую адресовать биты.

Признак: время исполнения целочисленных инструкций аналогично времени битовых инструкций для S7-400. При этом для S7-300 битовые операции выполняются быстрее целочисленных.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн ноя 14, 2011 6:21 
Не в сети
Известный Писатель

Зарегистрирован: Вт июл 06, 2010 11:44
Сообщения: 315
Откуда: Газ-Система-Сервис Пермь
Alexey_Spb_82 писал(а):
Хочу опровергнуть сказанное мной ранее

Я бы не стал торопиться.
Скорее всего, что в С166 битовые операции поддерживаются только для операндов расположенных в специальной области памяти - например регистры и еще десяток байт в младших адресах ОЗУ (как в msc51). Таким образом, конструкциям типа
if (word_to_block_db(db_num).DX[byte_num, bit_num]) then
какая-либо аппаратная поддержка и оптимизация не грозит.

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

Кстати на счет косвенной адресации... Я тут обзавелся функцией о которой давно мечтал, но всё руки не доходили.
Код:
TYPE "UDT_ANY"
TITLE  ='структура ANY-указателя'
FAMILY : 'LIB_PTR'
AUTHOR : Mayasin
VERSION: 1.0
STRUCT
      id:     BYTE;       //код
      tp:     BYTE;       //тип
      sz:     INT;        //размер
      blk:    WORD;       //номер блока данных
      area:   DWORD;      //указатель на область
END_STRUCT
END_TYPE

FUNCTION MemCpy: INT 
TITLE = 'копирование массива данных из src в dst'
FAMILY: LIB_PTR
VERSION : '1.0'
AUTHOR : Mayasin
KNOW_HOW_PROTECT
VAR_INPUT
  dst:  ANY;      //назначение 
  src:  ANY;      //источник
  cnt:  INT;      //количество байт
  dx:   INT;      //смещение в назначении
  sx:   INT;      //смещение в источнике   
END_VAR
VAR_TEMP
  i, s, d:  INT;
  //укзатели в виде структур
  psrc: ANY;
  pdst: ANY;
  ps AT psrc: UDT_ANY;
  pd AT pdst: UDT_ANY;
END_VAR
BEGIN
    //переносим данные
    psrc:=src;
    pdst:=dst;
    s:= sx + DWORD_TO_INT(SHR(in:=SHL(in:=ps.area, n:=8),n:=11));
    d:= dx + DWORD_TO_INT(SHR(in:=SHL(in:=pd.area, n:=8),n:=11));
    i:=0;
    WHILE (i<cnt) DO
        WORD_TO_BLOCK_DB(pd.blk).db[d] := WORD_TO_BLOCK_DB(ps.blk).db[s];
        i:=i+1; d:=d+1; s:=s+1;
    END_WHILE;
    MemCpy:=cnt;
    OK:=true;
END_FUNCTION


Очередной "велосипед", на изобретение которых нас обрекли немцы :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн ноя 14, 2011 8:07 
Не в сети
Известный Писатель

Зарегистрирован: Ср фев 16, 2011 14:23
Сообщения: 434
Откуда: Санкт-Петербург, Москва
ВЕТЕР59,

imho, что меркеры, что DB, что L-стек - все одного поля ягоды, и все находятся в оперативной памяти. Вероятно, разница во времени доступа доступе вызвана вычислением смещения на уровне виртуальной машины (логично предположить что адрес для данных DB считается а пару тактов больше, чем для меркеров - возможно, есть таблица вида "Номер DB" - смещение). Впрочем, это все только наши предположения, не сильно влияющие на конечный результат, а именно разработку АСУ ТП.

P.S. А чем SFC20 (BLKMOV) вас не устраивает?? Собственно, она и есть аналог memcpy в Step7. Вдобавок, она умеет работать со многими областями памяти.

P.P.S. Тип any уже содержит в себе в том числе данные о количестве и типе данных (тем и отличается от pointer), поэтому нужны ли дополнительные входные переменные (например, размер)?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн ноя 14, 2011 12:03 
Не в сети
Известный Писатель

Зарегистрирован: Вт янв 20, 2009 13:44
Сообщения: 343
to BETEP59
Если пишите функцию копирования блоков данных целесообразнее использовать копирование слов, а не байтов, так как минимальный размер блока данных это – “слово”.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн ноя 14, 2011 13:41 
Не в сети
Известный Писатель

Зарегистрирован: Вт июл 06, 2010 11:44
Сообщения: 315
Откуда: Газ-Система-Сервис Пермь
To ProFan & Alexey_Spb_82
Согласен, что по сути - конечно "велосипед" трехколесный и деревянный :)
Я потому и написал "наконец обзавелся", что долго обходился без неё: то указатель перед вызовом BLKMOV "подшаманится" для ограничения размера, то смещение учитывается.

Я эту функцию использую для копирования буферов данных в модулях обмена (объявляются как array[] of byte).
Отличия от BLKMOV не большие, но весьма полезные:
1) копируется заданное количество байт;
2) размеры источника и назначения могут не совпадать;
3) имеется возможность указать смещения в буферах.

To Alexey_Spb_82 на счет "предположений":
Согласен, что размышления на этот счет носят абсолютно непрактичный и неконструктивный характер. Приходится привыкать иметь дело с "черным ящиком" в окружении придуманных терминов и понятий.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн ноя 14, 2011 18:19 
Не в сети
Это точно не человек

Зарегистрирован: Вт май 03, 2005 17:11
Сообщения: 3547
во всем этом главное процесс, то что SCL - функции будут неоптимальны, то это второстепенно по сравнению с великой универсализацией. Не хочу сказать, что против унификации, но к этому мероприятию отношусь с изрядным скепсисом. Для этого есть несколько причин.
1. Давно еще в начале 80-х годов мы начинали разработку одной системы. Эта система, к слову тоже позиционировалась как универсальная, но дело не в этом. Была разработана система построения модулей, куда входили и так называемые универсальные программы. На протяжении всей эволюции эти подпрограммы выродились во вставляемый внутрь модуля исходный код. Этому способствовали и ограничения на ресурсы процессора, и редкость их применения внутри системы,= хороший макрогенератор, встроенный в язык программирования. Хорошие тестовые редакторы также сделали легким размножение фрагментов кода.
2. Сейчас у меня нет современного материала для сравнения - процессора сильно изменились, но ранее специалисты из Siemens говорили, что даже стандартная функция , написанная на STL, работает дольше встроенной в контроллер функции. Что уж тогда говорить прo SCL. Куча косвенной адресации в функции никогда не добавляла быстродействия. Хотите того или нет, но операции вычисления адреса, указатели будут отнимать время. В этом и быстрота меркерных операций - прямая или непосредственная - тут, к сожалению, единообразия в терминах нет - адресация. Поэтому если работаете на слабых процессорах, будьте крайне осторожны, чтобы не пришлось бороться с ОВ80.

вообше, отвлекаясь, хочу сказать, что компиляторам Siemens не хватает хорощего макрогенератора, как например у MACRO-11, на котором можно было создать нечто близкое к языку высокого уровня.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт ноя 15, 2011 6:00 
Не в сети
Известный Писатель

Зарегистрирован: Вт янв 20, 2009 13:44
Сообщения: 343
gre_m писал(а):
.... но ранее специалисты из Siemens говорили, что даже стандартная функция , написанная на STL, работает дольше встроенной в контроллер функции. .....
Время выполнения функции можно определить, вызвав системный счётчик до и после функции и получить разницу. По поводу копирования переменных как-то встречал в одном проекте функцию копирования, где приводилось автором сравнение времени выполнения системной функции и само писанной. И системная функция была на втором месте, конечно речь шла о малом выигрыше, но все же.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт ноя 15, 2011 8:49 
Не в сети
Известный Писатель

Зарегистрирован: Вт июл 06, 2010 11:44
Сообщения: 315
Откуда: Газ-Система-Сервис Пермь
ProFan писал(а):
как-то встречал в одном проекте функцию копирования ...

Статистика вещь коварная :) Да и с случае с SCL чудес ожидать не приходиться....
Вот прогнал такой тест на PlcSim:
Код:
FUNCTION_BLOCK TST_FB
VAR_INPUT
    cnt: INT;
END_VAR
VAR
    sys_time: DINT;
    usr_time: DINT;
    man_time: DINT;
END_VAR
VAR_TEMP
    i,j,res: INT;
    start:  DINT;
END_VAR
BEGIN
  //копирование системной функцией 
  start:= TIME_TO_DINT(time_tck()); 
  FOR i:=1 TO cnt DO
    res:=BLKMOV(dstblk:=dst_db, srcblk:=src_db);
  END_FOR; 
  sys_time:=TIME_TO_DINT(time_tck()) - start;

  //копирование пользовательской scl-функцией 
  start:= TIME_TO_DINT(time_tck()); 
  FOR i:=1 TO cnt DO
    res:=memcpy(dst:=dst_db, src:=src_db, dx:=0, sx:=0, cnt:=1000);
  END_FOR; 
  usr_time:=TIME_TO_DINT(time_tck()) - start;
 
  //копирование по-байтно
  start:= TIME_TO_DINT(time_tck()); 
  FOR i:=1 TO cnt DO
    FOR j:=0 TO 999 DO
        dst_db.db[j]:=src_db.db[j];
    END_FOR;
  END_FOR; 
  man_time:=TIME_TO_DINT(time_tck()) - start;
END_FUNCTION_BLOCK


При копировании 1000раз по 1000байт Получилось примерно так:
системная функция: 10мс
пользовательская: 350мс
по-байтное: 700мс
В абсолютных цифрах, конечно, смысла немного - но соотношение 1:35:70 красноречиво.

При копировании 10000раз по 100байт:
системная функция: 70мс
пользовательская: 380мс
по-байтное: 700мс
Соотношение: 1:5.5:10

При копировании 10000раз по 10байт:
системная функция: 70мс
пользовательская: 70мс
по-байтное: 70мс
Соотношение: 1:1:1 - ничья?! :)

Видимо, у системной функции BLKMOV огромные "накладные расходы" на вызов. Оно и понятно - разбираются с типами данных (ворды-байты и т.п.), определяют области памяти - в общем, нескучно им.
У по-байтного копирования накладных расходов практически нет - время прямо пропорционально количеству копируемых данных.
У пользовательской функции накладные расходы незначительны на фоне затрат на копирование (по сути - так же по-байтное).
Непонятно почему пользовательская функция выигрывала у побайтного копирования в первых двух тестах? Единственное отличие - внутри неё цикл не FOR, а WHILE.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
 [ Сообщений: 50 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения

Перейти:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group