Как-то я всегда обходил стороной работу с указателями при работе с ПЛК. Казались мне они дико страшными со времен студенчества, когда старые дедушки рассказывали тебе за С/С++. Но времена идут, так что давайте углубимся в этот прекрасный мир небезопасной работы с памятью.
Указатель по версии Codesys
Указатели хранят адреса переменных, программ, функциональных блоков, методов и функций во время выполнения прикладной программы. Указатель указывает на один из упомянутых объектов или на переменную с любым типом данных.
Синтаксис достаточно простой:
<identifier>: POINTER TO <data type | function block | program | method | function>;
Но чтобы поместить туда адрес нам надо будет его взять с помощью команды ADR()
Вот и пришла пора посмотреть как это будет работать
Берем указатель
Первым делом создадим файл с глобальными переменными. И запишем туда парочку.
Дальше я создам функциональный блок, дабы посмотреть адреса наших переменных.
Не забудьте добавить данный ФБ в программу и запускаем в эмуляции.
Отлично адреса вроде как есть. Теперь мы можем немного разыменовать указатели, чтобы посмотреть что там есть за значения.
Добавляем просто три переменные. И смотрим что там есть... Разумеется ничего. Мы же их не инициализировали. Так что предлагаю что-то туда записать.
Прогружаем наше творение и созерцаем.
Перекидываем адреса ячеек
Теперь есть предложение немного перемешать адреса ячеек, чтобы полностью запутаться.
Мы передадим наш адрес обычной переменной типа DWORD. Зачем? Ну потому что можем. Потом передадим эту переменную в указатель, потом разыменуем указатель и зададим значение и посмотрим, что же у нас останется в переменных.
Вот мы и передали значение, совершая переход по адресам.
Ну раз мы такие молодцы, что можем ходить по адресам из ячейки в ячейку давайте попробуем кое что...
Мы инициализируем три переменных типа INT, зная адрес лишь одной ячейки.
Перерабатываем наш файл с глобальными переменными. И вот тут уже последовательность важна.
Все целочисленные переменные находятся первыми в списке.(А вот тут я не знаю правильно ли думаю. Давайте смотреть)
Что нам надо взять адрес, присвоить значение, потом к адресу прибавить новый адрес и опять присвоить значение. И вот тут у меня начались проблемы с адресацией. Оказывается адресация глобальных переменных сохраняется. Не знаю насколько это будет верным утверждением относительно реального ПЛК, но на эмуляторе первоначальный фокус не прокатил(да у нас тут не все с первого раза работает). Пришлось создать новый файл с глобальными переменными и там по порядку написать три целочисленные переменные.
И вот тут все заработало.
Как мы и планировали. Значения записались туда куда мы и хотели.
Записываем в Input
А дальше у нас увлекательное шоу. Мне не особо нравятся переменные типа IN_OUT. Так вот, попробуем записать в переменную в блоке Input. Возможно ли такое?
Стираем все что было до этого и оставляем одну переменную с плавающей точкой в инпутах.
В ФБ такое работает...
Но вспомнил, что ФБ имеет очень интересную вещь, как экземпляр, а значит все данные дублируются. Попробуем с обычной функцией.
А вот с обычно функцией результат, вроде как работает. Теперь передадим за место переменной указатель на нее.
Как видно теория работает.
ВЫВОДЫ
На простых примерах мы поняли, что указатели работают, помогают нам преодолеть кое какие ограничения системы. Открывают чудесный мир работы с памятью, но в то же время - это очень опасно.
Если есть вопросы или пожелания, то пишите в комментарии.
Всем спасибо)