PDA

Просмотр полной версии : Обращение через указатель. Перезагрузка



mkhm
29.04.2015, 09:32
PROGRAM PLC_PRG
VAR
i:UINT;
ptw,ptwi:POINTER TO WORD;

In_1 : ARRAY [1..255] OF BYTE; (* Входной массив номер 1*)
Out_1: ARRAY [1..255] OF BYTE; (* Выходной массив номер 1*)


END_VAR


ptw:=ADR(Out_1[8]);
ptw^:=2015;


Перезагрузка на последнем шаге.
ПЛК 110-30. 2.15.3.

Раньше сталкивался с таким : если правильно помню, обходил смещением объявлений
переменных для того, чтобы не было необходимости в выравнивании границ.
(Если делать массив с четным кол-м, например, 250- перезагрузок нет.)

Сейчас в одном проекте не смог обойти привычным способом:
В чем причина перезагрузок. Как не допускать?

lazy
29.04.2015, 09:51
может быть POINTER TO BYTE? или ARRAY [1..XXX] OF WORD?

или

FUNCTION SetWord : DWORD

VAR_INPUT
i_dwAddress: POINTER TO BYTE;
i_wVal: WORD;
END_VAR

(* res *)
i_dwAddress^ := WORD_TO_BYTE( i_wVal / 256 );
i_dwAddress := i_dwAddress + 1;
i_dwAddress^ := WORD_TO_BYTE( i_wVal );

SetWord := i_dwAddress + 1;

capzap
29.04.2015, 10:07
PROGRAM PLC_PRG
VAR
i:UINT;
ptw,ptwi:POINTER TO WORD;

In_1 : ARRAY [1..255] OF BYTE; (* Входной массив номер 1*)
Out_1: ARRAY [1..255] OF BYTE; (* Выходной массив номер 1*)


END_VAR


ptw:=ADR(Out_1[8]);
ptw^:=2015;


Перезагрузка на последнем шаге.
ПЛК 110-30. 2.15.3.

Раньше сталкивался с таким : если правильно помню, обходил смещением объявлений
переменных для того, чтобы не было необходимости в выравнивании границ.
(Если делать массив с четным кол-м, например, 250- перезагрузок нет.)

Сейчас в одном проекте не смог обойти привычным способом:
В чем причина перезагрузок. Как не допускать?

на самом деле бред какой то, массив байтовый а указатель на word, что Вы этим хотели добится?

Дмитрий Артюховский
29.04.2015, 10:12
"на самом деле бред какой то, массив байтовый а указатель на word, что Вы этим хотели добится?"

все типы данных в компьютерах передают через байтовые потоки ))) обычно ! битовые, также выравнивают по байтам !

mkhm
29.04.2015, 10:23
Спасибо,этот вариант понятен.

Исходный с несовпадением типа массива и указателя использовать нельзя?
(В нескольких проектах работает без проблем)

capzap
29.04.2015, 10:36
"на самом деле бред какой то, массив байтовый а указатель на word, что Вы этим хотели добится?"

все типы данных в компьютерах передают через байтовые потоки ))) обычно ! битовые, также выравнивают по байтам !

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

mkhm
29.04.2015, 10:45
"на самом деле бред какой то, массив байтовый а указатель на word, что Вы этим хотели добится?"

все типы данных в компьютерах передают через байтовые потоки ))) обычно ! битовые, также выравнивают по байтам !

Бред "все типы ... передают через байтовые потоки )))"
Заполнение любого массива потоками "слов", соответствующих разрядности процессора - стандартная вещь, хотя возможны и байтовые потоки.
Например, в 16 разрядном процессоре переписывать массив 16 битными словами (lodsw stosw).

mkhm
29.04.2015, 12:05
сейчас речь не о передаче данных, а о присвоении данных внутри программы, смотрите внимательно, массив начинается с индекса 1, значит два байта присвоенного ворда через указатель на восьмой индекс создают полный хаос и никакое выравнивание тут ни причем. Первым делам надо объявления привести в порядок, тогда и вся остальная цепочка вплоть до передачи по сети возможно пройдет нормально без ошибок

Спасибо, понятно.( Для избежания проблем типы привести в соответствие.)

Но для полноты картины: такие же объявления и код в других проектах работают без проблем.
Например, и указанный пример заработал без перезагрузок в таком виде:17963

capzap
29.04.2015, 12:19
Спасибо, понятно.( Для избежания проблем типы привести в соответствие.)

Но для полноты картины: такие же объявления и код в других проектах работают без проблем.
Например, и указанный пример заработал без перезагрузок в таком виде:17963

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

Валенок
29.04.2015, 13:29
никакое выравнивание тут ни причем
Тут именно выравнивание. Разлет с типами - как раз и не имеет значения

Пусть топик вставит
var ek : bool;

ptw:=ADR(Out_1[8]);
ek := (ptw mod 2) = 1; //вот тута и увидит
ptw^:=2015;

capzap
29.04.2015, 13:34
Тут именно выравнивание. Разлет с типами - как раз и не имеет значения

Пусть топик вставит
var ek : bool;

ptw:=ADR(Out_1[8]);
ek := (ptw mod 2) = 1; //вот тута и увидит
ptw^:=2015;

массив начинается с индекса 1, считаем пары байт чтоб получить ворд: {1,2},{3,4},{5,6},{7,8},{9,10}
указатель ADR(Out_1[8]) разложит ворд на первый байт в третью пару, а второй байт в четвертую пару, теперя понятно что я имел ввиду, выравнивание тут не причем, здесь не правильное программирование

mkhm
29.04.2015, 13:43
Тут именно выравнивание. Разлет с типами - как раз и не имеет значения

Пусть топик вставит
var ek : bool;

ptw:=ADR(Out_1[8]);
ek := (ptw mod 2) = 1; //вот тута и увидит
ptw^:=2015;

Спасибо, все верно.

Валенок
29.04.2015, 13:45
такие же объявления и код в других проектах работают без проблем.
Например, и указанный пример заработал без перезагрузок в таком виде..
Не такие же объявы. Разница в малом - как размещены данные.

Валенок
29.04.2015, 14:03
выравнивание тут не причем, здесь не правильное программирование
))
Индекс не имеет значения. Если [1..255] : byte; размещен с четного адреса - то {13,14}, {27,28} - нормуль при обращении к слову, а {2,3} {12,13} - кирдык. Если же сам массив размещен с нечетного адреса - то все наоборот.

mkhm
29.04.2015, 14:23
))
Индекс не имеет значения. Если [1..255] : byte; размещен с четного адреса - то {13,14}, {27,28} - нормуль при обращении к слову, а {2,3} {12,13} - кирдык. Если же сам массив размещен с нечетного адреса - то все наоборот.

У топика КДС расположил массив-2 с четного адреса. А индекс с 1 -> значит четный индекс - с нечетного адреса с вытекающими..
Топик может решить местный трабл просто сделав [0..255]. Но это всего-лишь примочка.

Чисто для инфрмации.
Байтовый массив имеет право размещатся с любого адреса.
В глобал/function/program размещение булей/байтов/байтобульных массивов/стрингов трудно прогнозировать, поэтому оное может быть и с нечетных адресов, но при этом:
1.Чётко и ясно, в порядке объявления, размещаются любые поля фб и структур (с учетом неявных полей)
2.Гарантировано с квартного адреса размещаются их экземпляры
вот из этого и надо исходить.

И еще раз, спасибо.

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

Филоненко Владислав
29.04.2015, 19:03
Спасибо,этот вариант понятен.

Исходный с несовпадением типа массива и указателя использовать нельзя?
(В нескольких проектах работает без проблем)

Процессор ARM очень жёстко различает операции обращения к байтам, словам и двойным словам. И ADR[8] имеет нечётный адрес, по которому можно обращаться только и исключительно побайтно. Иначе в процессоре генерится исключение и процессор, видя ошибку в адресе уходит в перезагрузку.

Yegor
30.04.2015, 06:12
Третий топик на эту тему менее чем за месяц: раз (http://www.owen.ru/forum/showthread.php?t=21099&p=168453#post168453), два (http://www.owen.ru/forum/showthread.php?t=21078&p=168217#post168217). Объявляю карантин.

mkhm
30.04.2015, 08:20
Третий топик на эту тему менее чем за месяц: раз (http://www.owen.ru/forum/showthread.php?t=21099&p=168453#post168453), два (http://www.owen.ru/forum/showthread.php?t=21078&p=168217#post168217). Объявляю карантин.
Поискал перед тем как постить, но неудачно. Спасибо, по ссылке хорошее решение с SysLibMem и SysMemCopy