PDA

Просмотр полной версии : Как записать по адресу указателя?



Загнетов
03.09.2012, 17:39
1) синтаксис ST lkz "прочитать по адресу указателя " понятен:
destination := pointer^;

а как записать в ячейку по этому же адресу?
pointer^ := source; ??????????????


2) удастся ли одним оператором записать по адресу всё содержимое структуры (порядка 400 байт ради сетевого обмена).
Может capzap или Валенок тоже что-то подскажут, они высказывали интересные мысли в смежной теме
http://www.owen.ru/forum/showthread.php?t=10252&page=2

capzap
03.09.2012, 17:58
400 байт можно попробовать через цикл, в теле которого будет присвоение и переход на следующий байт. Главное чтоб цикл ПЛК не "вывалился" в стоп.
И не стесняйтесь заходить на сайт oscat.de, Германия это не только порно, но и бесплатная помощь по КДС в виде библиотек. Там много функций построены на указателях
Это классический вариант, а можно и создать указатель на 400-байтную структуру из модбас слейва и также присвоить значение структуры

Загнетов
03.09.2012, 18:01
400 байт можно попробовать через цикл, в теле которого будет присвоение и переход на следующий байт. Главное чтоб цикл ПЛК не "вывалился" в стоп.
И не стесняйтесь заходить на сайт oscat.de, Германия это не только порно, но и бесплатная помощь по КДС в виде библиотек. Там много функций построены на указателях


я хотел спросить и про синтаксис команды записи по указателю (вопрос №1)
как написать pointer^ := source; ?

capzap
03.09.2012, 18:05
давно бы уже написали тестилку да проверили, а так что можно сказать, вроде все верно, только надо бы знать какие типы у переменных pointer и source, в конкретно в Вашем случае, тогда и можно дать утвердительный ответ

Загнетов
03.09.2012, 18:26
давно бы уже написали тестилку да проверили, а так что можно сказать, вроде все верно, только надо бы знать какие типы у переменных pointer и source, в конкретно в Вашем случае, тогда и можно дать утвердительный ответ

вроде пишет по указателю.
а почему нужно использовать библиотеку, или ST не умеет отрабатывать присваивание составного типа (всей сттруктуры)?


и еще - при ошибке в работе с указателями - можно повредить оперативную память контроллера, или она не доступна таким способом?

capzap
03.09.2012, 20:01
а почему нужно использовать библиотеку

не использовать, а ознакомиться с примерами, как должен писаться код для ПЛК

Yegor
03.09.2012, 20:33
Есть стандартная библиотека SysLibMem, содержащая функции для выделения, освобождения, копирования и заполнения памяти.
а как записать в ячейку по этому же адресу?
pointer^ := source; ??????????????Да, таков синтаксис разыменования указателя. Если тип указателя соответствует типу source, то прямо так и присваивайте. Если тип не соответствует, но вы уверены, что размер подходящий, то пользуйтесь функциями библиотеки SysLibMem.

capzap
03.09.2012, 20:47
не увлекайтесь SysLibMem, при частом её использовании, ПЛК "лажает" в совершенно не ожиданных местах, хорошо если это проявиться во время отладки, а если на производстве...

Загнетов
03.09.2012, 20:59
не использовать, а ознакомиться с примерами, как должен писаться код для ПЛК я бы ознакомился http://oscat.de/ , но на немецком языке понять не могу, а на других европейских они не пишут.


Есть стандартная библиотека SysLibMem, содержащая функции для выделения, освобождения, копирования и заполнения памяти.Да, таков синтаксис разыменования указателя. Если тип указателя соответствует типу source, то прямо так и присваивайте. Если тип не соответствует, но вы уверены, что размер подходящий, то пользуйтесь функциями библиотеки SysLibMem.

Да, проверил, так работает, кода тип source 16 битный. Попробовал записать по указателям на биты, но не получается и причина непонятна.
Вернее значения записываются в иное место , далее в программе из этого места успешно считывается.

Сравнил адреса указателей на 16 битную переменную и на ее отдельные биты - совсем разные значения, 202b3750 и 40, 41 (файл "исполнение").

capzap
03.09.2012, 21:02
http://oscat.de/downloadmanager/viewdownload/3-oscatbasic/90-oscat-basic-docu-english.html вот на англицком, а исходники на ST так они в любой стране одинаковы, на них языковые барьеры не действуют

Загнетов
03.09.2012, 21:10
http://oscat.de/downloadmanager/viewdownload/3-oscatbasic/90-oscat-basic-docu-english.html вот на англицком, а исходники на ST так они в любой стране одинаковы, на них языковые барьеры не действуют

Спасибо, Тобиас оказался программно-плодовитым, список функций занимает 16 листов. Буду потихоньку читать.
А что скажете, почему не удается записать биты и указатели на ячейки приходят короткие (40,41)?

capzap
03.09.2012, 21:17
BITADR тоже для не стоит применять. В КДС откройте справка - содержание, в поиске наберите BITADR. Само описание функции и прочтите про ошибку №4031
С помощью неё ни чего присваивать не получиться, да и само смещение надо дополнительно разбирать

ЗЫ оскат это сообщество программистов пишущих открытый исходный код, так что одного человека нечего благодарить :)

Загнетов
03.09.2012, 21:34
BITADR тоже для не стоит применять. В КДС откройте справка - содержание, в поиске наберите BITADR. Само описание функции и прочтите про ошибку №4031
С помощью неё ни чего присваивать не получиться, да и само смещение надо дополнительно разбирать

ЗЫ оскат это сообщество программистов пишущих открытый исходный код, так что одного человека нечего благодарить :)

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

capzap
03.09.2012, 21:37
спасибо.
если переписывать в память обмена модбас не единый массив, а например две независимые структуры, предполагаю , что между структурами может быть "щель" из адресного пространства, используемого для других целей.
компилятор и редактор связей не обязаны размещать отдельные переменные вплотную.
да и собственно структуру не обязан размещать единым блоком?

ну так ведь и в области слейва можно несколько каналов поименовать, чтоб сделать два указателя соответствующие каждой структуре

Загнетов
04.09.2012, 00:34
ну так ведь и в области слейва можно несколько каналов поименовать, чтоб сделать два указателя соответствующие каждой структуре
Это удобно в каждом канале начинать заполнение с начала области сетевого обмена. Такая конфигурация ? (скриншот)
И мастер будет воспринимать их как 2 разных slave устройства на одной линии?
А внутри структуры отсутствие щелей между компонентами (исключая выравнивание, если оно там есть) гарантировано?

capzap
04.09.2012, 07:11
Это удобно в каждом канале начинать заполнение с начала области сетевого обмена. Такая конфигурация ? (скриншот)
И мастер будет воспринимать их как 2 разных slave устройства на одной линии?
А внутри структуры отсутствие щелей между компонентами (исключая выравнивание, если оно там есть) гарантировано?

я говорил про каналы, а не слейвы. Внутри структуры нет щелей, методы выравнивания в ней не действуют, ставте пустышки

Загнетов
04.09.2012, 08:55
я говорил про каналы, а не слейвы. Внутри структуры нет щелей, методы выравнивания в ней не действуют, ставте пустышки

как канал именуется в конфигурации ресурсов?

Валенок
04.09.2012, 20:55
Егор про тип указателя правильно сказал :
v : тип
pv : pointer to тип

v:=pv^;
pv^:=v;
И syslibmem не нужен, и скорость таже (в отдельных случаях даже быстрее)


Внутри структуры нет щелей
К сожалению - есть. И struct ровняется под кварту в отличие от ФБ. И sizeof офлайн/онлайн - из-за этого могут отличаться. Но лично я тоже предпочитаю явное указание пустышек.


не увлекайтесь SysLibMem, при частом её использовании, ПЛК "лажает"
Ну тут бы я поспорил :) Лажает только при косяках пользователя. Но незачем ее неподелу трогать. И, по чесноку, у syslibmem есть (или была :confused: ) махонькая ошибка при юзании кучи. И еще бывают траблы c P : pointer to dword/real не выровненым под кварту.


при ошибке в работе с указателями
Причем лучше сразу попасть в недоступную память - чтоб сразу перезагрузка и разобраться. CheckPointer на стадии отладки может помочь.

Кстати по Bitaddr можно добраться до бита - там типа сегментов в ПК. Но нужен сегмент. А битадр - это смещение этого бита в сегменте. А вот с сегментами разбираться нет желания. Причем в каждом ПОУ разные сегменты судя по всему, у i/o конфигурации тоже.

capzap
04.09.2012, 21:20
Кстати по Bitaddr можно добраться до бита - там типа сегментов в ПК. Но нужен сегмент. А битадр - это смещение этого бита в сегменте. А вот с сегментами разбираться нет желания. Причем в каждом ПОУ разные сегменты судя по всему, у i/o конфигурации тоже.

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

по поводу SysLibMem, я вроде на веб-сервере попался, когда клеил строчки, при частом использовании результат был не тот, что записывал, экспериментировать долго не стал, перешел на CONCAT и поблема исчезла

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

Валенок
04.09.2012, 21:37
Склейка строчек специфична. Может где случайно SIZEOF вставили вместо LEN[+1]. Или нолик забыли поставить или наоборот лишний в строку в центре воткнули. Или забыли что просто string - это 81 байт.

STRUCT T
W : WORD;
RR : REAL;
END_STRUCT

Проверьте в онлайне

p : pointer to real;
v : T;

p := adr( T.W ) + sizeof(t.w); (*казалось бы правильно чтоб добраться до T.RR*)

capzap
04.09.2012, 22:19
Склейка строчек специфична. Может где случайно SIZEOF вставили вместо LEN[+1]. Или нолик забыли поставить или наоборот лишний в строку в центре воткнули. Или забыли что просто string - это 81 байт.

STRUCT T
W : WORD;
RR : REAL;
END_STRUCT

Проверьте в онлайне

p : pointer to real;
v : T;

p := adr( T.W ) + sizeof(t.w); (*казалось бы правильно чтоб добраться до T.RR*)

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

а по поводу структур, действительно есть дыры, пора начинать делать ошибки чтоб освежить тонкости работы плк :)

Валенок
04.09.2012, 22:38
STRING(255) слегка увеличивает размеры строки
Если в смысле что больше чем 80. То это да. Но ведь и string(2000) - тоже ничего, но работать можно только через syslibstr/mеm или самому через указатель.

PS
А в верхнем примере добавьте
if p^ <> 0 then ; end_if
:) :)

Загнетов
05.09.2012, 05:51
я говорил про каналы, а не слейвы. Внутри структуры нет щелей, методы выравнивания в ней не действуют, ставте пустышки


что такое канал?

capzap
05.09.2012, 07:09
что такое канал?

а повторяю, когда начнем читать документацию?
Если более подробно: http://www.kipshop.ru/CoDeSys/steps/owen_plc-configuration.pdf
И совсем уже банально, раздел "Используемые термины"
:) ктото утверждал, что читает

Загнетов
05.09.2012, 07:48
а повторяю, когда начнем читать документацию?
Если более подробно: http://www.kipshop.ru/CoDeSys/steps/owen_plc-configuration.pdf
И совсем уже банально, раздел "Используемые термины"
:) ктото утверждал, что читает

читаю, но замотался, почти переполнилась коробочка :)

Загнетов
05.09.2012, 08:18
а повторяю, когда начнем читать документацию?
Если более подробно: http://www.kipshop.ru/CoDeSys/steps/owen_plc-configuration.pdf
И совсем уже банально, раздел "Используемые термины"
:) ктото утверждал, что читает


кстати, рекомендуемый Вами файл
owen_plc-configuration.pdf на 100 страницах 1,55 МБ (1 634 303 байт)
а
plc_configuration_owen.pdf на 119 страницах 3,80 МБ (3 986 153 байт)

какая версия актуальная?

1exan
12.01.2024, 04:34
...
К сожалению - есть. И struct ровняется под кварту в отличие от ФБ. И sizeof офлайн/онлайн - из-за этого могут отличаться. ...

Десять лет... и это единственное упоминание про минимальный размер структуры и про его различие для онлайн/офлайн - полдня проковырялся с этим размером