реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Keil. Не работает код, typedef struct
jcxz
сообщение May 12 2014, 07:01
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Golikov A. @ May 12 2014, 10:40) *
Что-то я совсем потерялся....

Что в процах с 32 битным выравниванием данных прямые бездумные обращения к памяти чреваты - это точно. В таких процах создание массивов элементов размера не кратного 32 битам и бездумное обращение с ними как с памятью - тоже чревато.

А вот объяснения и примера я чет хорошего придумать не могу%(.... вы все врем меня стандартами языка придавливаетеsad.gif....

Вы почему-то путаете невыровненный доступ CPU и работу си-компиляторов со структурами.
Это две не относящиеся друг к другу вещи.
Во всех примерах, что я привел нигде нет невыровненного доступа. Даже в случаях с пакованными структурами. sm.gif
В случае с пакованной структурой, вы указываете (величиной паковки в pack()) инструкциями какой максимальной длины
следует обращаться к элементам структуры.
Таким образом, чтение элемента T::a
#pragma pack(push, 1)
struct T { u32 a; };
#pragma pack(pop)
на ARM7/9 будет осуществляться 4-мя байтовыми LDRB с последующей склейкой байт в u32.
Для:
#pragma pack(push, 2)
struct T { u32 a; };
#pragma pack(pop)
на ARM7/9 сгенерит две LDRH с последующей склейкой в u32.

Для Cortex-M3 компилятор имеет право сгенерить в обоих случаях одну невыровненную LDR (если, как указал уважаемый Сергей Борщ,
соответствующий бит разрешает невыровненный доступ) (не помню уж - есть-ли такая настройка в опциях компилёра, чтобы указать ему состояние этого бита).
А может он просто - поступает так же, как для ARM7/9. Не помню.

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

PS: Я кстати стараюсь не пользоваться пакованными структурами. А там, где это нужно (например - для описания форматов кадров протоколов обмена),
предпочитаю в качестве членов структур, размер которых превышает выравнивание структуры, использовать свои типы данных, реализованные классами с
соответствующими методами доступа к ним.
В таком случае не возникает проблем с указателями на пакованные структуры в компиляторе.
И что ещё более важно - такие описания структур легко переносятся между разными компиляторами, так как не привязаны к прагмам, которые в разных компиляторах = разные.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 12 2014, 07:56
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Вы почему-то путаете не выровненный доступ CPU и работу си-компиляторов со структурами

Очевидно вы правы, я смешал 2 независимые вещи...

Что-то мне казалось что в зависимости от типа проца (от величины его выравнивания), среда задает такой же параметр паковки структур по умолчанию. Вероятно это скорее исключение чем правило, но мне сейчас кажется что я пару раз на такое нарывался...

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

Вот и теперь я понял откуда растут проблемы которые я пытался описать:
Когда с обоих концов стоит проц и язык С, проблемы реально мной надуманы. А вот когда у вас посылки делает проц с языком С, а приемник у вас ПЛИС с автоматом разбора входящего сообщения, вот тут проблемы не пакованных структур и вопросы понимания что как лежит в памяти встают в полный рост!




Также вот такой пример мне вспомнился

Код
struct __packed str
{
   char A;
   char B;
}

если есть функция передачи 1 поля структуры, по UART, например, то попытки разбора аля
Код
memcpy((void *)&my_str.B, data, 1);

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

Go to the top of the page
 
+Quote Post
jcxz
сообщение May 12 2014, 08:17
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Golikov A. @ May 12 2014, 13:56) *
Что-то мне казалось что в зависимости от типа проца (от величины его выравнивания), среда задает такой же параметр паковки структур по умолчанию. Вероятно это скорее исключение чем правило, но мне сейчас кажется что я пару раз на такое нарывался...

От CPU зависит только максимальное выравнивание. Т.е. - struct T { u32 a; }; для 32-битных CPU будет выровнена на 32, а для 16-битных CPU - на 16.
В соответствии с основной разрядностью CPU.

Цитата(Golikov A. @ May 12 2014, 13:56) *
Код
struct __packed str
{
   char A;
   char B;
}

если есть функция передачи 1 поля структуры, по UART, например, то попытки разбора аля
Код
memcpy((void *)&my_str.B, data, 1);

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

А в чём тут проблема? В поле my_str.B будет скопирован 1 char из data. С любым выравниванием.
Ну кроме процов, где char - не байт, а другой размер. Но там тоже всё ок, только будет скопирован не байт, а char wink.gif
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 12 2014, 09:28
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Код
struct __packed str
{
   char A;
   char B;
}


если экземпляр этой структуры my_str лежит, допустим, по адресу 0, и у нас проц типа кортекса М0, с 32 битным выравниванием памяти.

какой адрес будет иметь my_str.B? числовое значение? что передастся в memcpy? чем закончится вызов? и где окажутся в итоге данные?




Go to the top of the page
 
+Quote Post
jcxz
сообщение May 12 2014, 11:14
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Да какое тут 32-битное выравнивание???
Кроме 32-битных инструкций (LDR/STR), у ARM-ов есть и 8-и (LDRB/STRB) и 16-битные (LDRH/STRH) инструкции доступа к памяти.
И выравнивание зависит от разрядности инструкции.
Для байтовых переменных будет конечно-же использованы LDRB/STRB (или LDRSB/STRSB).
и ваш пример будет выполнен корректно.

Иначе - следуя вашей логике, когда вы объявляете переменную размером байт, у вас всегда бы выделялось 32 бита памяти под неё.
Но это-же бред.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 12 2014, 11:18
Сообщение #21


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Golikov A. @ May 12 2014, 12:28) *
что передастся в memcpy? чем закончится вызов? и где окажутся в итоге данные?
Для ответа на этот вопрос достаточно прочитать (нагуглить) описание memcpy(). Она работает с любыми адресами и любым выравниванием. Снаружи это выглядит, как будто она копирует побайтно (и при таком копировании проблем возникнуть не может). Внутри же она может вызывать различные ветки своего алгоритма в зависимости от фактических аргументов (т.е. может скопировать 3 байта до невыровненного адреса побайтно а потом перейти на копирование 4-байтных выровненных слов, потом аналогично побайтно скопировать оставшиеся 3..1 байт, может делать так независимо для источника и приемника), а может подставить одну-две-три команды в точку вызова, если все параметры известны на момент компиляции - это уже забота компилятора и его оптимизатора. В общем с memcpy работать будет всегда.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 12 2014, 11:42
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Ладно, сдаюсь... все всегда будет работать хорошо, уговорили....

Go to the top of the page
 
+Quote Post
Belikov_lp
сообщение May 18 2014, 03:42
Сообщение #23


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 16-03-14
Пользователь №: 80 948



Алгоритмы не пробовал добавлять?
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 09:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.01424 секунд с 7
ELECTRONIX ©2004-2016