Simatic Step 7, STL, сглаживание (Smooth) сигнала аналогового входа 4-20mA.

PLC
  Simatic это абревиатура семейств PLC фирмы Siemens для общепромышленного применения (SIMATIC S7-300/S7-400/C7/WinAC). Сейчас есть и более новые SIMATIC S7-1200/S7-1500, программируются через TIA Portal.
  Siemens выпускает и узко специализированные линейки PLC (Sinumerik — для станков ЧПУ, Simadyn — линейка повышенной производительности, многие задачи решаются аппаратно, специализированными блоками). Так же широко распостранены абревиатуры, которые относятся к области применения, а не к линейке аппаратного обеспечения на котором оно собрано, естественно оно должно поддерживать стандарты фирмы Siemens (SIMATIC HMI — управление оборудованием с панели оператора, SIMATIС NET — все что связано с межблоковой связью, SIMOTION — моторизованные приводы, управляющие движением, SIMODRIVE — инверторы, управляемые через ProfiBus, и еще куча абревиатур на которые Siemens имеет товарные знаки).
  Step 7 это IDE для программирования всего этого хозяйства (кроме устаревшего S7-200, для него используется STEP 7-Micro/WIN, несмотря на схожее название, это отдельная программа и в IDE Step 7 не интегрируется). Составить представление можно почитав статью на Хабре Программирование ПЛК Siemens на Simatic Step7. Дополнительные языки программирования, драйвера оборудования и т.д. интегрируются в Step 7. Доступны драйверы для широкой номенклатуры стороннего оборудования (не Siemens).
  Инструментальные средства STEP 7 позволяют выполнять:
      Конфигурирование и определение параметров настройки аппаратуры;
      Конфигурирование систем промышленной связи и настройку параметров передачи данных;
      Программирование, тестирование, отладку и запуск программ отдельных систем автоматизации, а также их локальное или дистанционное обслуживание;
      Документирование и архивирование данных проекта;
      Функции оперативного управления и диагностирования аппаратуры.
  STL — один из МЭК (IEC) стандарта IEC61131-3 языков программирования (англ. Statement List, список операторов). Немцы зовут его AWL (нем. Anweisungsliste), это же расширение имеют и исходники, написанные на STL. Тут есть несоответствие в абревиатурах стандартных языков МЭК и фирмы Siemens. Дело в том, что по стандартам МЭК язык STL должен называться IL (Instruction List), а абревиатура ST (Structured Text) зарезервирована за Pascal-подобным языком, который у Siemens называется SCL (Structured Control Language).
  Кроме STL, Step 7 включает в дистрибутив поддержку МЭК языков LAD (Ladder Diagram, язык релейной (лестничной) логики) и FBD (Function Block Diagram, программирование функциональными блоками). При приобретении лицензии интегрируются языки SCL (Pascal-подобный язык), S7-GRAPH (позволяет выполнять конфигурирование и программирование систем графическими способами, стандарт DIN EN 6.1131-3), S7-HiGraph (позволяет разрабатывать программы систем автоматизации SIMATIC в виде графа состояния системы), S7-PDIAG (позволяет разрабатывать однородные процедуры диагностирования систем автоматизации SIMATIC), S7-PLCSIM (позволяет эмулировать работу систем автоматизации SIMATIC, предназначен для отладки программ указанных систем на программаторе/компьютере без использования реальных технических средств автоматизации).
  В настоящее время Siemens активно рекомендует переходить со Step 7 на TIA Portal. Это логическое развитие Step 7, но не всегда однозначное (IMXO, что-то теряем, что-то находим...).
  Представленный функциональный блок выполняет функции ограничителя аналогового сигнала (4..20mA) с индикацией выхода за диапазон (Limiter) и его сглаживания по алгоритму простого (арифметического) скользящего среднего (SMA).
  Алгоритмов скользящего среднего несколько, SMA (простой, Simple Moving Average), EMA (экспоненциальный, Exponential Moving Average), WMA (взвешенный, Weighted Moving Average). Последние еще и разновидности имеют. Здесь рассмотрен только первый.

  Код функционального блока был написан для контроллера семейства Simatic S7-300, конкретно для S7-313C.
  Как правило (за редким исключением, S7-313C как раз из них), входные аналоговые модули S7-300 имеют универсальные входы. У ранних ревизий переключателем на боковой стенке модуля можно перевести вход в режим работы с сигналами напряжения, тока, термометров сопротивления и резисторов, термопар (4 положения). Аналоговые модули не имеющие переключателя (новые ревизии), конфигурируются утилитой Hardware Configuration, входящей в состав пакета STEP7.
  Здесь рассмотрена работа с аналоговым входом, настроенным на измерение тока 4-20mA. Он преобразует входной ток в слово (16-разрядное HEX число).



  У различных модулей аналоговых входов Simatic разрешающая способность может быть от 9 до 15 бит + знак. Если разрешающая способность аналогового модуля составляет менее 16 бит, то аналоговая величина сохраняется в модуле с выравниванием влево. Младшие, не используемые, битовые разряды заполняются нулями.
  Из таблицы видно, что модуль с состоянии работать с входным током в диапазоне 1,185mA — 22,81mA. Ток не входящий в данный диапазон вызывает переполнение и показания являются недействительными. Нередкие в промышленности отказ датчика или обрыв провода приведут к выходу измеряемого тока из диапазона работы аналогового входа.
  Поэтому перед любой обработкой полученных данных от аналогового входа необходимо их нормализовать, т.е. отсечь недействительные значения. Один из вариантов такой функции на языке STL:

FUNCTION FC20: VOID	

TITLE = Ограничитель аналового сигнала 4-20mA

AUTHOR:   Anakost  
FAMILY:   SOHO	   
NAME:     LIMITER   
VERSION:  1.0	   

VAR_INPUT            
  INPUT: INT;	// входной ток
END_VAR

VAR_OUTPUT            
  OUTPUT: INT;	// выходной ток
  RANGE: BOOL;	// выход за диапазон   
END_VAR

BEGIN

NETWORK
TITLE = Ограничение аналогового сигнала

  L #INPUT;	// ACCU 1 <- INPUT, входной ток	
  L W#16#6C00;	// ACCU 1 <- константа 20mA, ACCU 2 <- ACCU 1
  >I;		// в RLO результат сравнения ACCU 2 > ACCU 1
  = #RANGE;	// RANGE <- RLO	   
  JC A00;	// в ACCU 1 верхняя граница диапазона
  L #INPUT;	// ACCU 1 <- INPUT, входной ток
  L W#16#0;	// константа 4mA
  <I;		// в RLO результат сравнения ACCU 2 < ACCU 1   
  = #RANGE;	// RANGE <- RLO	   
  JC A00;	// в ACCU 1 нижняя граница диапазона
  L #INPUT;	// ACCU 1 <- INPUT, входной ток
A00:
  T #OUTPUT;	// OUTPUT <- ACCU 1, результат на выход
	
END_FUNCTION

  Небольшое обьяснение к коду для тех, кто незнаком с промышленными контроллерами Siemens. Simatic S7-300 имеет два 32-х разрядных аккумулятора. При загрузке в первый, его предыдущее содержимое сдвигается во второй. Поэтому применение операции сравнения или математической операции требует двух предварительных операций загрузки. Результат сохраняется в первом аккумуляторе. Бит RLO — результат логической операции, применим и для операций сравнения. JC — переход при RLO=1, JCN — переход при RLO=0. W#16#6C00 расшифровывается как шестнадцатиричное (#16) представление слова (W) 6C00, его можно записать и в десятичном виде W#27648 или просто 27648.
  Ограничитель можно оформить в виде функции, т.к. статичной памяти для работы ему не требуется.
  Алгоритм же вычисления арифметического плавающего среднего должен хранить в статичной памяти результаты последних замеров (кольцевой буфер), указатель на последний замер и сумму замеров в буфере. Т.е. иметь статичную память, неизменную между вызовами функции. В Step 7 этим требованиям отвечает функциональный блок. Помимо функции он имеет жестко ассоциированный (экземплярный) блок данных для расчетов. Обращаться к этим данным изнутри функционального блока проще чем к глобальным. Доступ снаружи (не из функционального блока) запрещен и блокируется.
  На рисунке ниже представлена реакция функции простого скользящего среднего на скачок сигнала полного диапазона при буфере в 16 слов, функциональный блок вызывается из блока циклического прерывания ОВ35 с цикличностью 100mc.




FUNCTION_BLOCK FB30

TITLE =  Функция простого скользящего среднего

AUTHOR:   Anakost	//
FAMILY:   SOHO		//
NAME:     LIM_SMA	// Limiter + Simple Moving Average
VERSION:  1.0		//

VAR_INPUT
  INPUT: INT;		// входной ток (Iin)
END_VAR

VAR_OUTPUT
  OUTPUT: INT;		// выходной ток (Iout)
  RANGE: BOOL;		// ошибка диапазона
END_VAR

VAR
  VALUES: ARRAY[0..15] OF INT; // буфер
  STEPER: WORD;		// текущий указатель в буфере
  TOTAL: DWORD;		// сумма значений
END_VAR

VAR_TEMP
  TEMP_VAL: INT;	// временная внутренняя величина
END_VAR

BEGIN

NETWORK
TITLE = Ограничение и сглаживание 4..20mA
// Ограничение
  L #INPUT;		// ACCU 1 <- INPUT, входной ток
  T #TEMP_VAL;		// TEMP_VAL <-ACCU 1, во локальную переменную				
  L W#16#6C00;		// ACCU 1 <- константа 20mA, ACCU 2 <- ACCU 1, верхняя граница диапазона
  >I;			// в RLO результат сравнения ACCU 2 > ACCU 1, проверка на превышение
  = #RANGE;		// RANGE <- RLO
  JC A00;		// в ACCU 1 верхняя граница диапазона
  L #TEMP_VAL;		// ACCU 1 <- INPUT
  L W#16#0;		// ACCU 1 <- константа 4mA, нижняя граница диапазона
  <I;			// в RLO результат сравнения ACCU 2 < ACCU 1, проверка на превышение
  = #RANGE;		// RANGE <- RLO
  JCN A01;		// в ACCU 1 нижняя граница диапазона
A00:
  T #TEMP_VAL;		// TEMP_VAL <- INPUT(Limiter), ограничение входного тока
A01:
// Сглаживание
  L #STEPER;		// ACCU 1 <- STEPER, загрузка текущего указателя
  L P##VALUES;		// ACCU 1 <- @VALUES, загрузка указателя на начало массива
  +D;			// ACCU 1 <-  @VALUES + STEPER, сдвиг начального адреса на адрес слова
  LAR1;			// AR1 <- ACCU 1, регистр-указатель на нужное слово
  POP;			// ACCU 1 <- ACCU 2, ACCU 1 <- STEPER
  + 16;			// ACCU 1 <- STEPER + 16 (длина слова), на следующий адрес
  AW W#16#00FF;		// ACCU 1 <- ACCU 1 AND 00FF, адрес ограничен одним байтом (16х16)
  T #STEPER;		// STEPER <- ACCU 1, сохранить новый адрес
  L #TOTAL;		// ACCU 1 <- TOTAL, загрузить сумму
  L DIW [AR1,P#0.0]; 	// ACCU 1 <- VALUES[STEPER], чтение старого замера
  -D;		   	// ACCU 1 <- TOTAL - VALUES[STEPER], вычтем из суммы
  L #TEMP_VAL;	   	// ACCU 1 <- INPUT(Limiter), новый замер
  T DIW [AR1,P#0.0]; 	// VALUES[STEPER] <- ACCU 1, сохранение в буфере
  +D;		   	// ACCU 1 <- TOTAL + INPUT(Limiter), прибавим к сумме
  T #TOTAL;	   	// TOTAL <- ACCU 1, сохраним новую сумму
  SRD 4;		// ACCU 1 >>>> 4, деление на 16, среднее арифметическое
  T #OUTPUT;		// OUTPUT <- ACCU 1, результат на выход

END_FUNCTION_BLOCK


  Обычно при тестах я пользуюсь симулятором PLCSIM, т.к. не всегда можно собрать стенд, а тем более залезть в работающее оборудование. По словам Siemens PLCSIM позволяет выполнять отладку программы на ранних стадиях разработки проекта и предоставляет следующие преимущества:
  • Ускорение отладки программы и снижение затрат на проектирование.
  • Повышение качества разрабатываемого программного обеспечения.
И все было ничего, но на этом функциональном блоке PLCSIM меня подвел.
  По рускоязычному мануалу от Siemens второй аккумулятор после математической операции не изменяется. Я этим воспользовался в своем коде, но обнаружил что при запуске под PLCSIM второй аккумулятор обнуляется.



Это привело к тому, что адрес указателя в буфере не изменяется и программа постоянно стоит на первом слове.

Проверил на рабочем S7-300, нет, все работает как и должно быть.



И ревизия PLCSIM у меня вроде не старая (K5.4.5.2), раньше проблем не было, в общем не понял…
  Если хотите, чтобы FB нормально работал и в симуляторе, его нужно немного изменить. Не полагаться на то, что нужное число осталось в ACCU 2, а принудительно загрузить его в ACCU 1. Вырезаем следующие строки:

  POP;			// ACCU 1 <- ACCU 2, ACCU 1 <- STEPER
  + 16;			// ACCU 1 <- STEPER + 16 (длина слова), на следующий адрес
  AW W#16#00FF;		// ACCU 1 <- ACCU 1 AND 00FF, адрес ограничен одним байтом (16х16)
  T #STEPER;		// STEPER <- ACCU 1, сохранить новый адрес

и в самый конец блока (после T #OUTPUT) добавляем:

  L #STEPER;		// ACCU 1 <- STEPER, загрузка текущего указателя
  + 16;			// ACCU 1 <- STEPER + 16 (длина слова), на следующий адрес
  AW W#16#00FF;		// ACCU 1 <- ACCU 1 AND 00FF, адрес ограничен одним байтом (16х16)
  T #STEPER;		// STEPER <- ACCU 1, сохранить новый адрес

  Создавать блоки данных для функциональных блоков вручную нет необходимости и не рекомендуется. Лучше чтобы их создал STEP 7. Для этого нужно в месте вызова функционального блока вызвать его с номером требуемого блока данных. Примерно так:

  CALL FB30, DB30 <Enter>

При этом FB30 должен быть скомпилирован и находиться в папке Blocks, номер блока данных может быть любым, еще не используемым. После нажатия «Enter» STEP 7 предупредит, что данного блока не существует и спросит, надо ли его создать.



При нажатии «Yes» блок данных с необходимой внутренней структурой, правильным TimeStamp (отметка времени) и привязкой к FB30 будет создан:



Вызов блока также дополнится формальными обозначениями входов/выходов:



  Блок был опробован на измерении уровня воды в буферном баке (120 м3) датчиком давления. Уровень (0..6м) отслеживается с шагом изменения 0,01м. Ранее при медленном опорожнении бака происходило 4-6 переключений во время смены показаний. После подключения на выход датчика этого функционального блока показания сгладились, происходило 1-2 переключения. Хотелось бы еще плавнее. Это было достигнуто увеличением постоянной времени фильтра. Сделать это несложно, необходимо пропускать некоторые из вызовов фильтра.

  L DB5.Cycle_Counter	// Загрузка счетчика цикла
  LOOP M001		// Декремент и выход если ACCU1 > 0

  CALL FB30, DB30
    INPUT := PIW 754 
    OUTPUT:= MW 112
    RANGE := M 3.4

  L DB5.Division_Factor	// Коэффициент деления 
M001: 
  T DB5.Cycle_Counter	// Сохранение счетчика цикла

Коэффициент деления и счетчик цикла хранятся в глобальном блоке данных. Это сделано для удобной подстройки коэффициента сглаживания во время работы без подключения програматора.

DATA_BLOCK DB5 
 
TITLE = "Параметры сглаживания"
VERSION : 1.0

STRUCT
  Cycle_Counter   : BYTE := B#16#0;	// Счетчик цикла	
  Division_Factor : BYTE := B#16#4;	// Коэффициент деления	
END_STRUCT;

BEGIN
  Division_Factor  := B#16#4;
END_DATA_BLOCK

Коэффициент деления Division_Factor выведен как тег в операционной панели.
  И в заключение расскажу еще об одном эксперименте с этим функциональным блоком. Вход и выход блока имеют одинаковый тип данных. А что если включить два блока цепочкой, один за другим? Чтобы оставить только необходимое, был оформлен новый функциональный блок.

FUNCTION_BLOCK FB40

TITLE = Функция сдвоенного простого скользящего среднего

AUTHOR:   Anakost     	//
FAMILY:   SOHO		//
NAME:     LIM_DSMA	//Limiter + Double Simple Moving Average 
VERSION:  1.0		//

VAR_INPUT            
  INPUT: INT;		// входной ток (Iin)
END_VAR

VAR_OUTPUT            
  OUTPUT: INT;		// выходной ток (Iout)
  RANGE: BOOL;		// ошибка диапазона    
END_VAR

VAR                  
  VALUES_1: ARRAY[0..15] OF INT; // буфер 1 ступени
  VALUES_2: ARRAY[0..15] OF INT; // буфер 2 ступени
  STEPER_1: WORD; 	// текущий указатель в буфере 1 ступени
  STEPER_2: WORD; 	// текущий указатель в буфере 2 ступени
  TOTAL_1: DWORD ; 	// сумма значений 1 ступени
  TOTAL_2: DWORD ; 	// сумма значений 2 ступени
END_VAR

VAR_TEMP             
  TEMP_VAL: INT;	// временная внутренняя величина
END_VAR

BEGIN

NETWORK
TITLE =  Ограничение и двухступенчатое сглаживание 4..20mA
// Ограничение
  L #INPUT;		// ACCU 1 <- INPUT, входной ток			
  T #TEMP_VAL;		// TEMP_VAR <-ACCU 1, в локальную переменную	
  L 27648;		// ACCU 1 <- константа 20mA, ACCU 2 <- ACCU 1, верхняя граница диапазона
  >I;			// в RLO результат сравнения ACCU 2 > ACCU 1, проверка на превышение 
  = #RANGE;		// RANGE <- RLO	   
  JC A00;		// в ACCU 1 верхняя граница диапазона
  L #TEMP_VAL;		// ACCU 1 <- INPUT
  L 0;			// ACCU 1 <- константа 4mA, нижняя граница диапазона
  <I;			// в RLO результат сравнения ACCU 2 < ACCU 1, проверка на превышение    
  = #RANGE;		// RANGE <- RLO	   
  JCN A01;		// в ACCU 1 нижняя граница диапазона
A00:
  T #TEMP_VAL;		//ограничение входной величины
A01:
// Сглаживание 1 ступени
  L #STEPER_1;		// ACCU 1 <- STEPER_1, загрузка текущего указателя
  L P##VALUES_1;	// ACCU 1 <- @VALUES_1, загрузка указателя на начало массива
  +D;			// ACCU 1 <-  @VALUES_1 + STEPER_1, сдвиг начального адреса на адрес слова
  LAR1;			// AR1 <- ACCU 1, регистр-указатель на нужное слово
  POP;			// ACCU 1 <- ACCU 2,  ACCU 1 <- STEPER_1
  + 16;			// ACCU 1 <- STEPER + 16 (длина слова), на следующий адрес
  AW W#16#00FF;		// ACCU 1 <- ACCU 1 AND 00FF, адрес ограничен одним байтом (16х16)
  T #STEPER_1;		// STEPER <- ACCU 1, сохранить новый адрес
  L #TOTAL_1;		// ACCU 1 <- TOTAL_1, загрузить сумму
  L DIW [AR1,P#0.0];	// ACCU 1 <- VALUES_1[STEPER_1], чтение старого замера
  -D;			// ACCU 1 <- TOTAL_1 - VALUES_1[STEPER_1], вычтем из суммы
  L #TEMP_VAL;		// ACCU 1 <- INPUT(Limiter), новый замер
  T DIW [AR1,P#0.0];	// VALUES_1[STEPER_1] <- ACCU 1, сохранение в буфере
  +D;			// ACCU 1 <- TOTAL_1 + INPUT(Limiter), прибавим к сумме
  T #TOTAL_1;		// TOTAL_1 <- ACCU 1, сохраним новую сумму
  SRD 4;		// ACCU 1 >>>> 4, деление на 16, среднее арифметическое
  T #TEMP_VAL;		// OUTPUT <- ACCU 1, результат в локальную переменную
// Сглаживание 2 ступени
  L #STEPER_2;		// ACCU 1 <- STEPER_2, загрузка текущего указателя
  L P##VALUES_2;	// ACCU 1 <- @VALUES_2, загрузка указателя на начало массива
  +D;			// ACCU 1 <-  @VALUES_2 + STEPER_2, сдвиг начального адреса на адрес слова
  LAR1;			// AR1 <- ACCU 1, регистр-указатель на нужное слово
  POP;			// ACCU 1 <- ACCU 2,  ACCU 1 <- STEPER_2
  + 16;			// ACCU 1 <- STEPER + 16 (длина слова), на следующий адрес
  AW W#16#00FF;		// ACCU 1 <- ACCU 1 AND 00FF, адрес ограничен одним байтом (16х16)
  T #STEPER_2;		// STEPER <- ACCU 1, сохранить новый адрес
  L #TOTAL_2;		// ACCU 1 <- TOTAL_2, загрузить сумму
  L DIW [AR1,P#0.0];	// ACCU 1 <- VALUES_2[STEPER_2], чтение старого замера
  -D;			// ACCU 1 <- TOTAL_2 - VALUES_2[STEPER_2], вычтем из суммы
  L #TEMP_VAL;		// ACCU 1 <- INPUT(Limiter+SMA), новый замер
  T DIW [AR1,P#0.0];	// VALUES_2[STEPER_2] <- ACCU 1, сохранение в буфере
  +D;			// ACCU 1 <- TOTAL_2 + INPUT(Limiter), прибавим к сумме
  T #TOTAL_2;		// TOTAL_2 <- ACCU 1, сохраним новую сумму
  SRD 4;		// ACCU 1 >>>> 4, деление на 16, среднее арифметическое
  T #OUTPUT;		// OUTPUT <- ACCU 1, результат на выход

END_FUNCTION_BLOCK

Для сравнения график исходной функции FB30, постоянная времени фильтра 1,6 сек.



И график «тандемной» функции FB40, постоянная времени фильтра 3,2 сек. График из прямого стал S-образным.


Качественной рускоязычной документации по устройству и программированию Simatic очень много. Перевод как правило произведен фирмой Siemens, и самая полная подборка со свежими исправлениями лежит на официальном сайте. К сожалению для скачивания требуется регистрация. Вот неплохая подборка без регистрации.
P.S.Пособие "Введение в програмирование на LAD, FBD, STL".

Приложены:
  • Исходник функции FC20.awl в zip;
  • Исходник функционального блока FB30.awl в zip;
  • Исходник функционального блока FB40.awl в zip;
  • +2
  • 19 октября 2016, 18:46
  • anakost
  • 3
Файлы в топике: FB30.ZIP, FB40.ZIP, FC20.ZIP

Комментарии (79)

RSS свернуть / развернуть
Очепятка!
Siemens выпускает и узко специализированные линейки PLC (Sinymerik — для станков ЧПУ,
Правильно: SINUMERIK
0
Перепутал букву, бывает, эту линейку видел только на картинке…
0
Непонятны абстрактные рассуждения об сглаживании несглаживаемого и игнорирования реальных проблем… для чего сглаживать ток потребления двигателя и его момент?
Конечно можно сгладить реальные показания в одну прямую линию среднего благосостояния моего капитала и капитала абрамовича

данный реальный график показывает реальные механические особенности конкретного механического объекта управления.
0
Даже не знаю что ответить, попробую…
>> для чего сглаживать ток потребления двигателя и его момент?
Код явно для этого не предназначался, постоянная времени фильтра предполагает медленно меняющиеся во времени процессы.
>> линию среднего благосостояния моего капитала и капитала абрамовича
комментариев нет…
0
надо приводить конкретные примеры, а не писать о средней температуре за год и фильтровать летние и зимние максимо-минимумы температуры.
Игнорирование залётов сигналов с датчиков может привести к печальным последствиям — плавающий залёт за допустимые пределы может быть признаком повреждения кабельных прокладок и оборудования… ну да… залёт до 3-х недель можно игнорировать…
0
Есть специалист превращающий трудно понимаемый многими ассемблерный STL в неменее трудно понимаемыми некоторыми в симатиковый Паскаль SCL www.plc4good.org.ua/view_post.php?id=293
некоторые вещи неплохо бы иллюстрировать более понятными формулами
0
>> трудно понимаемый многими ассемблерный STL…
Непонимание сути обсуждения, STL ассемблером не является, ассемблер это мнемоническое представление системы команд определенного контроллера. STL на контроллер не проецируется, это МЭК стандарт, Siemens сменил в своих контроллерах уже две архитектуры (может и три)…
0
STL это Ассемблер виртуального процессора с Двумя Аккумуляторами (4 для S7-400-х)
регистром битов состояния типового процессора — чётность, нечётность, перенос…
парой адресных регистров для косвенной адресации
стеком…
и ты будешь «школьника без опыта» убеждать, что это не ассемблер? :)
у меня сейчас на столе несколько килоевров этих архитектур http://s7detali.narod.ru/
да… да… почитай документацию :)
0
Чтением документации я занимаюсь постоянно…
И не в коем случае не хотел никого намеренно задеть. Ваши слова «TL это Ассемблер виртуального процессора» только показывают, что это не ассемблер. Программы для Java называют промежуточным кодом, исполняемым на Java сервере. Параллель можно провести, только здесь система реального времени, пусть и не быстрая. А так все правильно…
0
Это значит условно-жумповый ассемблер для АТмеги
sbic pinc, 5 ;условный переход «кнопка режима»
jmp mode
sbic pinc, 4 ;условный переход «войти в настройки»
jmp settings
sbic pinc, 3 ;усл.пер. «спать»
jmp sleep_on

а этот условно-жумповый прыжок из твоего опуса на языке Высокого уровня :)
L #INPUT;     // ACCU 1 <- INPUT, входной ток
  L W#16#0;     // константа 4mA
  <I;           // в RLO результат сравнения ACCU 2 < ACCU 1   
  = #RANGE;     // RANGE <- RLO    
  JC A00;       // в ACCU 1 нижняя граница диапазона
  L #INPUT;     // ACCU 1 <- INPUT, входной ток
A00:
  T #OUTPUT;    // OUTPUT <- ACCU 1, результат на выход

а тогда что это? (кусок модбусы plc4good.org.ua/view_post.php?id=240 )
FOR i:=0 TO 16 BY 1 DO
   tALicenseKey[i]:=(sACODE[i] XOR sHoldingRegisterState[i]) XOR INT_TO_BYTE(i+1);
   tALicenseKey[i]:=INT_TO_BYTE(BYTE_TO_INT(tALicenseKey[i]) MOD 26 + 65); // 65='A'
END_FOR;                    
0
Вот честно, не понял, что нужно от меня?
Переписать код? Можно, например заменить второе включение «L #INPUT;» и «T #OUTPUT;» на POP.
Конкретней можно выразиться?
0
от тебя? Признать, что это STL команды это ассемблер :)
Язык ассемблера – это символическое представление машинного языка.
0
А он существует ли, этот машинный код, который представляет STL? Ассемблер достаточно точно соответствует командам машинного языка, фактически это машинный код, записанный мнемониками. Если он транслируется в другой машинный код — это уже компиляция, а не ассемблирование.
0
Ты просто наступил plcist у на правое яйцо больной мозоль))
Ишь ты… в ПЛК полезть вздумал… умничать там… лавры святейшества подвинуть вздумал?
З.Ы. Да прибудет святой холивар
0
Ох-хо-хо. Я этим вынужден заниматься на работе, святейшие лавры мне по барабану.
0
1. Есть заблуждающиеся из-за трёпа в трёпонете — их можно научить правильно мыслить…
2. Есть навязчивые коммерческие рекламисты постящие якобы технические опусы с ссылками на эстонские коммерческие ресурсы.
3. у некоторых проблемы с урологией… о чём они сообщают на весь трепонет в технической теме про ПЛК.
0
И насчет условного джампа, хелп, длинный:
JL: Распределенный переход 
Формат 
JL <метка> 

Адрес Описание 

<метка > Символьное имя метки перехода. 


Описание 
Инструкция JL <метка> (переход по списку) представляет собой распределитель переходов. 
За ней следует ряд безусловных переходов на метки (максимум 255 ) и заканчивается этот список перед меткой , указанной в самой инструкции JL<метка>. 
Все инструкции списка : JU инструкции. 
Номер выполняемого перехода (от 0 до 255) берется из ACCU 1-L-L. 
Инструкция JL передает управление одной из JU инструкций, если значение в аккумуляторе меньше общего количества безусловных переходов между инструкцией JL и меткой этой инструкции. 

Первая в списке инструкция JU будет выполнена при ACCU 1-L-L=0. 
Вторая в списке инструкция JU будет выполнена при ACCU 1-L-L=1, и так далее. Инструкция JL передает управление на метку за последней инструкцией JU в списке если число в аккумуляторе, определяющее номер перехода, больше или равно общему числу переходов в списке . 
Список инструкций распределенного перехода не должен содержать других инструкций кроме JU. 

Код:

Пример 

Комментарий 
L MB0 // Загрузка номера перехода в ACCU 1-L-L. 
JL LSTX // Переход выполняется при ACCU 1-L-L > 3. 
JU SEG0 // Переход выполняется при ACCU 1-L-L = 0. 
JU SEG1 // Переход выполняется при ACCU 1-L-L = 1. 
JU COMM // Переход выполняется при ACCU 1-L-L = 2. 
JU SEG3 // Переход выполняется при ACCU 1-L-L = 3. 
LSTX: JU COMM // Конец списка переходов 
SEG0: L 0 // Исполняемая инструкция 
T MB1 
JU COMM 
SEG1: L 1 // Исполняемая инструкция 
T MB1 
JU COMM 
SEG3: L 2 // Исполняемая инструкция 
T MB1 
JU COMM 
COMM: L 3 
T MB1 



В этом примере переменная MB0 содержит число, загружаемое в аккумулятор accumulator 1. Вслед за операцией загрузки следует распределитель переходов JL с меткой LSTX, указывающей на конец списка функций перехода JU. 
Номер перехода, который должен быть выполнен, содержится в правом байте аккумулятора accumulator 1. Если этот аккумулятор содержит 0, то выполняется первая функция перехода. Если этот аккумулятор содержит 1, то выполняется вторая функция перехода и так далее. 

Если число в аккумуляторе превышает размер списка операторов перехода, то происходит переход на конец списка (на первую инструкцию, следующую за набором функций перехода JU). 
JL не зависит ни от каких условий и не изменяет битов состояния. 
При этом только выражения с оператором JU, располагающиеся без пробелов, допускаются в списке операторов перехода функции JL. 
Назначая произвольные метки для этих операторов перехода, Вы должны придерживаться общих правил для меток.
0
Пример ...
Пример глупейший — показывающий тупой копипаст неразбирающегося в теме рекламного спаммера :)
Чтобы не было в таймерном меркере МВ0 (а ведь по умолчанию там таймерный меркер),
в МВ1 всегда будет 3 :)
COMM: L 3 
T MB1 
0
Ну да, ну да, уже в спамеры зачислили…
Это продолжение:

В общем виде, тело программы состоит из:
1) обнуление (сброс) команд, признаков и т.п., используемых в автомате, но не имеющих обнуления по условию;
2) определение текущего состояния;
3) проверка условий и действий в состоянии 0;
4) проверка условий и действий в состоянии N;
5) обработка ошибки распределенного перехода;
6) установка/сброс выходных переменных;
7) обработка вложенных таймеров.
Шаблон STL общего вида:

NETWORK
TITLE =Сброс промежуточных переменных и анализ слова состояния
      CLR   ; //сбросить в 0
      =     # Временная переменная 1; 
      =     # Временная переменная i; 
      L     #STATE_WORD; //загрузка слова состояния для перехода
      JL    GT_3; // метка перехода, которая указывает на конец списка
      JU    ST_0; //переход на начального состояния графа переходов
      JU    ST_1; // переход на 1 состояние графа перехода
      JU    ST_2; // переход на i состояние графа перехода
GT_3: JU    Err; // переход на метку обработок ошибок инструкции JL
NETWORK
TITLE =Обработка начального состояния
ST_0: A     #Входной параметр 1; // номер состояния автомата и условие 1
           A     #Входной параметр 2; //условие 2
           JCN   End; //если условие не выполнено уход на метку
           =     #Временная переменная 1; //Действие 1
           =     # Временная переменная 2; //Действие 2
           =     # Временная переменная i; //Действие i
           L     1; //переход по дуге графа в требуемое состояние
           T     #STATE_WORD; //загрузка номера следующего состояния
           JU    End; //Безусловный переход на конец блока
NETWORK
TITLE =Обработка состояния 1
ST_1:  A     # Входной параметр 1; // номер состояния автомата и условие 1
            AN    # Входной параметр 1; //условие 2
           JCN   Tr01; //если условие не выполнено уход на метку
           =     #Временная переменная 1; //Действие 1
           =     # Временная переменная 2; //Действие 2
           =     # Временная переменная i; //Действие i
            L     3; //переход по дуге графа в требуемое состояние
            T     #STATE_WORD; //загрузка номера следующего состояния
            JU    End; //Безусловный переход на конец блока
Tr01: A     # Входной параметр 1; // номер перехода (дуги) автомата и условие 1
          AN    # Входной параметр 1; //условие 2
          JCN   End; //если условие не выполнено уход на метку
          L     0; //переход по дуге графа в начальное состояние
          T     #STATE_WORD; //загрузка номера следующего состояния
          JU    End; //Безусловный переход на конец блока
И т.д.
NETWORK
TITLE =Обработка ошибки распределенного перехода
Err:  CLR
       =      Выходной параметр 1; 
        =      Выходной параметр 2; 
        =      Выходной параметр i; 
      L     0; //и загрузить число 0 начальное состояние
      T     #STATE_WORD; //в слово состояния
      JU    End; //выйти на конец блока
End:  NOP   0; // конец блока  
NETWORK
TITLE =Обработка выходных сигналов
      A     # Временная переменная 1; 
      S     # Выходной параметр 1; 
      A     # сброс Временная переменная 1; 
      R     # Выходной параметр 1; 
      NOP   0; 
NETWORK
TITLE =Обработка таймера

      A     #если есть команда на включение таймера, загрузить:; 
      L     #временную базу; 
      SS    #номер таймера; 
      A     #если есть команда на сброс таймера; 
      R     #сбросить таймер; 
      A     #если таймер отработал; 
      =     #установить внутреннюю перменную;

И для устранения "зависаний" выходных переменных, при некорректном выключении контроллера (бывает и такое), в ОВ100 (однократно, при запуске контроллера). в слово состояния загружаю большое число, больше чем кол-во состояний. При этом, после анализа слова управления, осуществляется переход на обработку ошибок распределенного перехода (JL) со сбросом выходных переменных и приведение алгоритма к начальному состоянию.

Ждем коментарии…
0
Кто то хочет от меня утверждения, что на этом могучем ассемблерном языке и его соратнике Языке релейно-контактной логики LAD нельзя построить управление уровнем большого металлургического прокатного стана?
Не дождётесь… я использую достоинства всех языков программирования
0
Ну и? Рукоплещем от «я использую достоинства всех языков программирования». По теме разродимся хоть чем то?
0
А вообще, хотелось бы получить комментарий на свой код. Чего то туго с этим…
0
Программы для Java называют промежуточным кодом, исполняемым на Java сервере.
Вообще говоря, промежуточный код JVM — это машинный код. И для него тоже существует ассемблер.
STL ассемблером является врядли (не потому, что выполняется виртуальным процессором — в конце концов, x86 тоже выполняется виртуальным процессором — но потому, что у него врядли имеется соответствующий ему машинный код), но что это ассемблероподобный язык — однозначно.
0
Согласен с определением ассемблероподобный язык, но STL явно не ассемблер. А вообще, о чем копья ломаем? Да какая разница как назвать?
0
Ассемблер это не сколько язык, а скорей парадигма. Так что STL вполне себе можно считать ассемблером. Никто не запрещает сделать некий процессор где каждой его команде будет четкая машинная инструкция. Собственно в ПЛК идет эмуляция такого процессора.
0
>> Ассемблер это не сколько язык, а скорей парадигма.
Ассе́мблер (от англ. assembler — сборщик) — транслятор исходного текста программы, написанной на языке ассемблера, в программу на машинном языке. Как и сам язык, ассемблеры, как правило, специфичны для конкретной архитектуры, операционной системы и варианта синтаксиса языка.
Парадигмой я бы назвал некий обобщенный язык высокого уровня на котором можно изложить любой алгоритм решения.
0
Какое значение имеет «я бы назвал», когда есть конкретная терминология?
Ассе́мблер (от англ. assembler — сборщик)
Ты не ту статью смотришь. В вики то, что здесь обычно называют «ассемблер» называется "язык ассемблера".
0
Надо применять правильные термины в правильных местах с правильным смыслом
и тогда будет понятно, как из написанного на Паскале SCL в контроллере оказывается условно-жумповый ассемблерный код с командами из 1-ой буквы на языке «высокого уровня» :)
0
Насколько я знаю, в контроллере оказывается не ассемблерный код, а машинный. Впрочем, лично не изучал.
0
>> Надо применять правильные термины…
Кто то с этим спорит? У меня такое чувство, что вы не совсем в теме. Любой нестандартный блок на FBD и LAD, если его исходник отсутствует в папке Source будет отображен на языке STL. Это основа для команд внутренней виртуально машины. Но STL от этого ассемблером (языком ассемблера) не стал. Это стандарт МЕК (IEC).
0
Ты как-то странно выбираешь, кому отвечать. Надо использовать ссылку «ответить» под тем комментарием, на который отвечаешь.
Это стандарт МЕК (IEC).
Как будто это мешает ему быть ассемблером.

А вообще, немного ковырявший тему знакомый говорит, что STL действительно ассемблируется в как минимум весьма близкий ему машинный код. Если так — то таки ассемблер.
0
>> Ты как-то странно выбираешь, кому отвечать.
Уж как умею, а то начнешь отвечать, окажешься за 100500 ответов от вопроса.
STL дизасемблировался в близкий (не идентичный) машинный код когда в качестве ЦП контроллера применялся 16-разрядный С166, лет 6-8 назад.
0
Уж как умею, а то начнешь отвечать, окажешься за 100500 ответов от вопроса.
Не страшно. Для выстраивания цепочек есть стрелочки под комментарием. А вот при нарушенной структуре ответов приходится угадывать, кому на самом деле ответ предназначен. К тому же, по мере добавления ответов твой ответ все равно может оторваться от комментария, на который он отвечает — но стрелочка уже не поможет.
когда в качестве ЦП контроллера применялся 16-разрядный С166, лет 6-8 назад.
Какая разница, какой процессор применяется в контроллере? Оно компилируется в машинный код виртуального процессора, реализуемого ПЛК. И это позволяет безболезненно ставить в ПЛК любой процессор, сохраняя совместимость.
0
STL дизасемблировался в близкий (не идентичный) машинный код когда в качестве ЦП контроллера применялся 16-разрядный С166, лет 6-8 назад.
С165 прекратили ставить в центральные процессоры в 2003-ем году… отказались от батарейки в пользу ММС.
Functional Description
The architecture of the C165 combines advantages of both RISC and CISC processors
and of advanced peripheral subsystems in a very well-balanced way. In addition the
on-chip memory blocks allow the design of compact systems with maximum
performance.
A register bank can consist of up to 16 wordwide (R0 to R15)
вот на этом они эмулировали систему комманда 32-х разрядного виртуального варианта моторолловского 6502
http://s7detali.narod.ru/S7_315/S7_315AF0.html

У меня такое чувство, что вы не совсем в теме.
Чувства тебя всё время оманывают :)
http://winccflexrussian.narod.ru/step7help/step7help.html

из печалек… кончились длительные поездки в поездах и просто не стало времени на :(
0
>> Оно компилируется в машинный код виртуального процессора, реализуемого ПЛК.
Это я недостаточно ясно наверное высказался в комментариях. Simatic машина реального времени, никакой ВМ в нем нет. ВМ для поддерживаемых языков образует IDE Step 7.
0
Лолвут? VM в IDE нужна разве что для симулятора. В IDE мог бы быть компилятор в архитектуру процессора, на котором построен ПЛК, но насколько я знаю — это не тот случай, да и из такого бинарника было бы проблематично восстановить сорец на МЭК-языках, а насколько я знаю, из ПЛК достается вполне себе удобоваримый код.
Если же в ПЛК хранится код под виртуальный процессор — то и VM находится в ПЛК. А сделать ее реалтаймовой — вполне реальная задача, к тому же, насколько я помню завляемые для ПЛК спеки — они никак не впечатляют для того проца, который в нем стоит, что намекает на то, что VM там вообще интерпретирующая.
0
Реальное время...
с средним циклом прохода цикла программы в 10 миллисекунд :) 100 проходов в секунду = реальное время :)
может и хотел Сименс сделать силиконовый процессор… но кризис заставил эмулировать его систему команд на том, что было
http://www.infineon.com/dgdl/c165_ds_v20_2000_12.pdf?fileId=db3a304412b407950112b43a49a66fd7
0
Step 7 позволяет достаточно просто увидеть и оценить минимальное, типовое и максимальное время исполнения программы.
У моей программы, написанной на STL, минимальное — 1мс, типовое — 2мс, максимальное — 11мс. Время исполнения зависит от языка программы и ветвей кода, подключенных в данный конкретный момент.
0
У моей программы, написанной на STL, минимальное — 1мс, типовое — 2мс, максимальное — 11мс.
«реальное время» гуляет на порядок :)
За что не уважаю трепопедию — слишком много «учителей» не знающих даже основ учения, но упорно распространяющих вымыслы и домыслы как истину
читайте документацию… там могут быть описки или ошибки перевода… но это более достоверная информация по сравнению трепонетом.
В промышленном программировании ПЛК есть много особенностей, которые непонятны обычному компьютерному «эмбедеру»…
0
Я спокойный человек, обычно на обострение не иду, не по характеру.
О каком эмбедере вы рассуждаете? Я тридцать лет работаю на производстве с непрерывным циклом. И тут гуры начинают меня учить как надо работать… Мало того, что мне эти советы по барабану (не в теме), просто смешно…
0
Я тридцать лет работаю на производстве с непрерывным циклом...
вероятно у тебя большой альбом производственных фоток :)
цифра у меня появилась в 2002-м

Небарабанщикам:
Согласно МЭК Язык IL (Instruction List, Список Команд) представляет собой ассемблероподобный язык… и у Сименса был микропроцессор под этот язык… то было время эйфории окончательной победы RISC над CISC и казалось не проблемой создать простенький 32-х разрядный RISC с двумя аккумуляторами(более простой чем 64-х разрядный DEC Alpha AXP 21064) (кстати в S7-400-х стояли 64-х разрядные MIPS)
за 30 лет не смог прочитать первые страницы основного документа :(
0
вероятно у тебя большой альбом производственных фоток :)
Нет такого альбома. И камеры на телефоне нет. Если надо что то снять, прошу более молодых коллег со смартфонами.
0
да… жаль, что из-за одного админа-оболтуса накрылся официальный форум и официальный сайт… это ж надо было додуматься разместить сайт на виртуальной машине и внутри этой машины делать архивы… виртуалка погребла десятилетие накопленного сообществом опыта и знаний…
жумп на plcforum.uz.ua/
0
жумп на
Задумка хорошая, но ведь там почти ничего нет (своего). Цитировать не заслуга.
0
твоё отношение к чему то не имеет значения для меня, тем более к этому долгожителю.
Мне надо прочитать ещё 5000 страниц

с ассемблером для S7-300/400 всё ясно
S7-1500 уже полный полный эмулятор…
0
Повторюсь, STL — один из МЭК (IEC) стандарта IEC61131-3 языков программирования.
В стандарте уже все указано…
0
Ну это не мешает ему при этом быть одновременно ассемблером виртуального процессора реализующего ПЛК. В самом деле, если у нас есть прокрустово ложе стандарта МЭК, то нам проще сделать виртуальную машину ему соответствующую и не ломать мозг как бы написать компилятор этого (и всех остальных МЭК) языка под каждую новую архитектуру.
0
По моему виртуальной машиной и является Step 7. Он работает с языками, не предусмотренными стандартной поставкой, в него интегрируются все дополнения. При этом все эти дополнительные драйвера доступны для всех языков. Снять Upload с машины в удобочитаемом формате невозможно без наличия исходников в папке Source. Все действия происходят через Step 7.
При тупом Upload вы получите всю программу в STL. С ним надо уметь работать…
0
Виртуальная машина, как и следует из названия, является машиной, исполняющей код. IDE код не исполняет (за исключением отладки в симуляции), код исполняет ПЛК — он и является виртуальной машиной.
А транслятор LAD/SCL/etc в STL называется компилятором.
P.S. Прекрати отвечать куда попало. Твой ответ окажется дальше от комментария, на который ты отвечаешь, чем если ты ответишь непосредственно на этот комментарий.
0
>> Прекрати отвечать куда попало.
Не буду.
Если коротко, код исполняет контроллер. И исполняет машинный код. Этот код в него залит Step 7. Кроме исполняемого кода в нем ничего нет, почитайте Бергера.
Теоретизировать просто не о чем…
0
Если коротко, код исполняет контроллер. И исполняет машинный код.
Ну так и я о том же. Это ты говоришь, что VM-де в IDE.
0
Я говорю о том, что для размещения VM в контроллере не места и необходимых ресурсов на обслуживание. Аналогом VM является IDE Step 7. По иному не получается…
0
VM бывают разные. Некоторые спокойно влазят в контроллеры вроде атмеги8.
Аналогом VM является IDE Step 7
Ты вообще в курсе, что такое VM? Судя по тому, что несешь — нет.

P.S. По вестям с полей, 300-я и 400-я серии кормятся STL-байткодом, а 1500 — машинным кодом того процессора, что в них стоит. При этом в 400-й стоит микросхема, которая вполне может быть аппаратным STL-процессором, в 300-й обычный процессор и VM.
0
Виртуальная машина исполняет некоторый машинно-независимый код (например, байт-код, шитый код, p-код) или машинный код реального процессора.
Контроллер исполняет машинно-зависимый код. От какого контороллера код будет зависим выполняется в настройках проекта Step 7. И уже IDE решает для какого контроллера компилировать код.
У меня такое чувство, что вы со Step 7 не сталкивались. Иначе вопросы и предположения были бы другими…
0
У меня такое чувство, что вы со Step 7 не сталкивались. Иначе вопросы и предположения были бы другими…
Вживую — нет. Иначе я бы говорил увереннее о simatic-specific вещах (хотя в данном обсуждении я в основном обсуждаю вопросы общие, а не специфичные для конкретных ПЛК) и не ссылался на «вести с полей».
Виртуальная машина исполняет некоторый машинно-независимый код (например, байт-код, шитый код, p-код) или машинный код реального процессора.
Определение еще более дурацкое, чем в статье про разделение байткода и машинного. Впрочем, если заглянуть в источник — то это уже и не определение, определение в первом абзаце, и в нем нет ереси типа «VM выполняет машинно-независимый код». Более того, VM и есть то, что делает код машинно-независимым. Любой код, например 8086-й.
Но даже в процитированном кусочке есть ключевой пункт — «выполняет». IDE ничего не выполняет. Выполняет ПЛК. Поэтому либо VM в ПЛК, либо ее нет вообще, но в IDE она может быть только в составе симулятора, если таковой там есть.
0
VM нет в PLC, на каком языке это еще сказать?
0
Пруф?
0
Не мешает, но является ли он им? Точно сказать никто не может, на профильном сайте Siemens всплывал такой вопрос.
Почти дословный ответ — Siemens постоянно работает над адаптацией своих продуктов под требования пользователей. Понимай как хочешь…
0
Приложения Java обычно транслируются в специальный байт-код, поэтому они могут работать на любой компьютерной архитектуре, с помощью виртуальной Java-машины. Это я так думал. Это не так?
0
А что, байткод — не машинный код?
0
Если глянуть вики, то она разграничивает байткод и машинный код по признаку исполнения — на аппаратном обеспечении или на программном. Но я нахожу это разграничение весьма спорным:
1) В принципе, для любого байткода можно сделать аппаратный процессор. Учитывая, что они обычно достаточно похожи на МК аппаратных процессоров — неделька в квартусе и можно смело утверждать, что «данный байткод исполняется в железе, а значит является машинным».
2) Машинный код для аппаратного процессора не так уж редко исполняется программным. Пример я уже указывал — различные эмуляторы, позволяющие на одном процессоре запускать код для совершенно другого. Считать ли код для MIPS или x86 в таких ситуациях байткодом?
3) Энивей, аппаратные JVM-процы существуют, так что по этому критерию он машинный.
0
>> А что, байткод — не машинный код?
Вообще то нет. Байткод не привязан к конкретной архитектуре процессора, на конкретной архитектуре присутствует свой интерпретатор байткода, который и транслирует его в машинные команды.
0
Привязан, эта архитектура называется JVM.

На всякий случай напомню о существовании:
1) Процессоров, исполняющих JVM-код напрямую. Jazelle DBX, в частности.
2) Программ, исполняющих машинный код на процессоре чужой архитектуры (всевозможные эмуляторы, слой поддержки программ для PowerPC в макоси для x86).
3) Ну и собственно то, что все современные х86 процессоры являются виртуальной х86-машиной поверх RISC-ядра. Эльбрус, кстати, тоже имеет такую.
0
Для сравнения программные модели виртуального процессора Степ7 и реального процессора 6800

Найди принципиальные различия в виртуальном и реальном процессоре :)
Кстати как вы отлаживаете в бежтаговских симуляторах программы на виртуальных процессорах i8051, Атмегах, STM… на х86 процессоре.
0
Я, в отличие от anakost'а, ничего не имею против виртуального процессора. Я спрашиваю, существует ли соответствующий STL машинный код? Так, как машинный код 68000 соответсвует ассемблеру 68000, а машинный код JVM соответствует ассемблеру JVM.
0
Трудно ответить прямо и однозначно. Если сравнить одинаковый исходник и код, генерируемый Step 7 и TIA Portal, выходные файлы будут разные. Но первый генерирует код для S7-300/400, второй для S7-1200/1500. Не пробовал залить код, не предназначенный для конкретного контроллера.
0
Лет *цать назад может было бы проблемой создать такой виртуальный процессор с таким набором регистров и операций… хотя у того же 68000 уже тогда были 32-х разрядные регистры, а у 8087 80-ти разрядные с плавающей точкой и аппаратным синусом…
сейчас даже школьники на матрице могут запрограммировать подобный :)
Сначала появился ассемблер для Эльбруса, затем его прогнали на виртуальной модели, потом на матрицах и только потом отдали в производство.
0
Не проблема. Но сдается мне, что существующие ПЛК транслируют его в нечто иное, более для них удобное. Так что он компилируется, а не ассемблируется.
Но по семантике да — типичный язык ассемблера.
0
Как вы отлаживаете…
Как получится
0
Java Virtual Machine (сокращенно Java VM, JVM) — виртуальная машина Java — основная часть исполняющей системы Java, так называемой Java Runtime Environment (JRE). Виртуальная машина Java исполняет байт-код Java, предварительно созданный из исходного текста Java-программы компилятором Java (javac).
И где здесь привязан?
0
Попробуй выполнить JVM-код на другой машине. Скажем, на .net. Или на х86.
0
JVM предназначена для конкретной архитектуры. Для другой архитектуры предназначена своя версия JVM. Разве непонятно?
0
Я говорю не о JVM, а о JVM-коде, ака бацйткоде явы.
0
Приходится повторяться. Байткод не привязан к конкретной архитектуре процессора, на конкретной архитектуре присутствует свой интерпретатор байткода, который и транслирует его в машинные команды.
0
Он привязан к конкретной архитектуре — JVM. Это процессор, пусть и обычно реализованный программно. И на другой архитектуре, скажем на х86, он не запустится. Он запустится только на JVM.
0
Java Virtual Machine это не архитектура. Это реализация архитектуры под конкретные аппаратные и программные ресурсы предоставляемые конкретной платформой. Для Windows, Linux, Max есть свои версии JVM. И возможностями они отличаются, при похожем железе.
0
Это реализация архитектуры под конкретные аппаратные и программные ресурсы предоставляемые конкретной платформой.
Вот именно. Архитектуры. Возможно, у нее есть свое название, я не слишком глубоко знаю жабу. Впрочем, если глянуть на процы — то и реализация, и спецификация (архитектура) называются одним словом. Так что JVM — это архитектура, у которой есть разные реализации. Скажем, JRE. Или KJava. Или Jazelle DBX. Последняя, кстати, реализует JVM в железе.
И байткод жабы привязан именно к этой архитектуре. Архитектуре JVM.
0
Убедил, я не настолько хорошо знаю Джаву, чтобы дальше продолжать этот диалог. Если честно почти не знаю, привел как пример, неудачный. Программировать на ней не приходилось, в отличии от Step 7.
0
Вообще, на сегодня границы между различными вариантами трансляции настолько размыты, что сложно строго разграничить ассемблирование, компиляцию, интерпретацию, машинный код, промежуточный код, etc. А при нестрогом разграничении — раз похож язык на сферический ассемблер в вакууме — так и нехай зовется ассемблером (на самом деле языком ассемблера, но про этот нюанс вообще никто не вспоминает).
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.