Перейти к содержанию
    

проблемы с выравниванием ARM7

Есть такой код для процессора ARM7

char     data[256];

void foo(void)
{
   int parametr = 0xAA55BBCC; 
   char*   ptr = data;

   //если сделать так
  *((int*)(ptr+1)) = paramtr;
  // то прцессор вылетет в DataAbort

  // можно сделать конечно так
  memcpy(ptr+1, &parametr, sizeof(parametr));

}

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Или "правильно" писать программы c "правильными" структурами данных. Или не сбивать с толку компилятор и дать ему инфрмацию об объекте с которым он работает. Либо действительно пользоваться memcpy(), котрая разберется с проблемой в online.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Или "правильно" писать программы c "правильными" структурами данных. Или не сбивать с толку компилятор и дать ему инфрмацию об объекте с которым он работает. Либо действительно пользоваться memcpy(), котрая разберется с проблемой в online.

 

С "правильной" структурой данных не получается. Т.к. тип передаваемых данных в data[] в разных местах программы может быть разным. data[] это массив для передачи донных из процессора по запросу внешнего устройства. А внешнее устройство в одном случае может запросить данные типа time_t, а в другом данные типа char.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это не "проблема", это - факт "наличия присутствия" выравнивания. Общая техника в этих случаях - обращаться к переменным по адресам, кратным их (переменных) формату. А если не получается - перегонять байты (напрямую или memcpy()) и формировать типы ручками.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С "правильной" структурой данных не получается. Т.к. тип передаваемых данных в data[] в разных местах программы может быть разным.

Значит и структуры данных должны быть описаны для разных случаев и объединены в union. Что по любому полезно, ибо общение в стиле второй бит слева в 33 байте справа в массиве data по любому путь у никуда.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

перегонять байты (напрямую или memcpy()) и формировать типы ручками.
Зачем же? Существует такое понятие, как упаковка структур:

#include  <stdint.h>
uint8_t Buffer[256];


typedef struct 
__attribute__((packed))
{
   uint8_t   Data1;
   uint32_t  Data2;
} answer_t;

void foo(void)
{

    int parametr = 0xAA55BBCC; 
    answer_t * pAnswer = (answer_t *)Buffer;

    pAnswer->Data2 = paramtr;
    pAnswer->Data1 = 0x12;

}

Пример для GCC, для других компиляторов с высокой долей вероятности будет #pragma pack(1)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Либо действительно пользоваться memcpy(), котрая разберется с проблемой в online.

 

Очень редко у меня возникали случаи когда внутри memcpy появлялся аборт. Так что memcpy не панацея.

Либо не пудрить мозг компилятору, либо писать свою функцию memcpy, которая 100% не допустит аборта.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем же? Существует такое понятие, как упаковка структур:

 

Спасибо !!! Так работает.

Выглядит читабельно, но копирование происходит побайтно ( смотрел листинг в IAR).

Но от этого никуда не денешься в данной ситуации.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пример для GCC, для других компиляторов с высокой долей вероятности будет #pragma pack(1)

GCC 4.x тоже уже поддерживает "#pragma pack" - не так давно был сам приятно удивлен

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

но копирование происходит побайтно ( смотрел листинг в IAR).
А как вы хотели, если только побайтно можно обратиться к любому адресу? Не, ну если заранее знать, что 4-байтовое число расположено со сдвигом на 1 байт, то можно скопировать первый байт, потом полуслово и потом последний байт, но такое - только ручками.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очень редко у меня возникали случаи когда внутри memcpy появлялся аборт. Так что memcpy не панацея.

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

 

 

но такое - только ручками.

Такое, и даже большее (при копировании больших массивов) делает хоть сколько нибудь приличное библиотечное memcpy().

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Такое, и даже большее (при копировании больших массивов) делает хоть сколько нибудь приличное библиотечное memcpy().
Потратив время на разбор - к какому из заготовленных сценариев отнести конкретный случай. Что для случая 4-байтовой или 2-байтовой переменной даст проигрыш во времени по сравнению с побайтовым копированием по месту. На больших структурах, да, эффект будет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Жаль, что не сохранил дизасм для неверующих. Замена memcpy на цикл с побайтным присваиванием непонятно куда из непонятно откуда чудесным образом всё починило.

 

P.S. Моя первая реакция на такое чудо была такая же как у Вас на мой пост в теме.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...