Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Выравнивание структуры на ARM и x86 одинаково?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
sigmaN
Объявлены вот такие структуры
Код
template<class T, uint8_t X_SZ>
struct Table2D_storage
{        
    static const uint8_t x_size = X_SZ;    ///< number of elements in row
    T data[X_SZ];
};

template<class T, uint8_t X_SZ, uint8_t Y_SZ>
struct Table3D_storage
{        
    void SetDescription(const char* newDescr) volatile
    {
        for (auto& i : description)
        {
            i = *newDescr;
            
            if( newDescr == 0)
                break;
            newDescr++;
        }        
        description[TABLE_DESCRIPTION_LEN - 1] = 0;        
    }
        
    static const uint8_t    x_size = X_SZ;    ///< number of elements in row
    static const uint8_t    y_size = Y_SZ;    ///< number of elements in column

    T data[Y_SZ][X_SZ];
    char description[TABLE_DESCRIPTION_LEN];    
};
enum
{
    2D_X_SIZE = 16,

    3D_X_SIZE = 16,
    3D_Y_SIZE = 2,
};

typedef Table2D_storage<uint16_t, 2D_X_SIZE > 2D_t;
typedef Table3D_storage<Q7_8::RawValue_t, 3D_X_SIZE, 3D_Y_SIZE> 3D_t;

typedef struct
{
    2D_t RPMQuant;
    3D_t IgnWork;
}LookupTablesStorage_t;


LookupTablesStorage_t будет состоять из разных наборов шаблонов Table2D_storage<> и Table3D_storage<>
Их тип T может меняться от int8_t до int32_t. Размеры X_SZ и Y_SZ, соответственно, тоже могут быть разные...

Так вот было бы ОЧЕНЬ удобно в на ПК иметь тот-же заголовочный файл с объявлением LookupTablesStorage_t, заполнить ее нужными данными и потом просто сделать memcpy() на девайс(ну через интерфейс связи с ПК просто побайтово перекинуть данные).

Объявлять структуры пакованными не очень бы хотелось по причине невозможности использования указателей на члены и снижения быстродействия. В общем то с этим можно мириться конечно...
Делать более сложный протокол передачи с присвоением значений каждому члену структуры отдельно без веской причины тоже лень, да и лишний код в прошивке как-бы...

Есть подозрение, что т.к. обе архитектуры 32битные - требования к выравниванию должны совпадать.

Гуглил гуглил, но так и не нагуглил будет ли выравнивание одинаковым на x86 и ARM Cortex M3?
Прошивка девайса собирается ARM GCC, на ПК будет наверно MinGW, который тоже считай GCC.

Что скажите? Стоит ли так делать или обязательно паковать/присваивать почленно?
AHTOXA
В принципе, если потом не надо будет добавлять архитектуры, то можно и не упаковывать.
Хотя возможны сюрпризыsm.gif (Погуглите про ключик -mno-ms-bitfields для mingw, например.)
sigmaN
Даа, майкрософт и тут отличился!
Интересно что делать если нужна и бинарная совместимость с микрософтовским кодом и упаковка структур для коммуникации через интерфейс какой-нибудь? Вот это там извращения по ходу будут...
CrimsonPig
Цитата(sigmaN @ May 29 2015, 10:57) *
Даа, майкрософт и тут отличился!
Интересно что делать если нужна и бинарная совместимость с микрософтовским кодом и упаковка структур для коммуникации через интерфейс какой-нибудь? Вот это там извращения по ходу будут...


Писать сериализацию\десериализацию, чего тут сложного.
Ну, можно еще попытаться убедить мировое сообщество принять ваши стандарты для кроссплатформенных приложений, как пример, разработчики стандартов ethernet-фреймов.. Они не жалуются ни на упаковку структур, ни на самолично разложенные грабли с #pragma pack sm.gif
AHTOXA
Цитата(sigmaN @ May 29 2015, 14:57) *
Даа, майкрософт и тут отличился!

Дело не в том, что микрософт отличился. Дело в том, что никто не гарантирует, что в следующей версии вашего компилятора упаковка структур останется такой же. Появится новый ключик - и кирдык вашей совместимости. Поэтому тут надо всё внимательно взвесить, и уже потом принять решение. Если структур немного - лучше один разок поднапрячься, и написать сериализацию/десериализацию. Тем более, что в c++ её можно прямо в структуру встроить. И будет что-то типа:
Код
DataPacket data;
adc.GetData(data);
data.Serialize(buf, sizeof(buf));
uart.Send(buf);
zltigo
QUOTE (sigmaN @ May 28 2015, 20:33) *
Есть подозрение, что т.к. обе архитектуры 32битные - требования к выравниванию должны совпадать.

Для любой архитектуры просто следует САМОМУ задать ОДИНАКОВЫЕ правила паковки/выравнивания НЕ задумываясь что там по умолчанию какой-то компилятор творит. Единственно, что если отличия в big/little-endian то тут уже без вариантов тупо копировать не пройдет.
CrimsonPig
Цитата(zltigo @ May 29 2015, 13:55) *
Для любой архитектуры просто следует САМОМУ задать ОДИНАКОВЫЕ правила паковки/выравнивания НЕ задумываясь что там по умолчанию какой-то компилятор творит. Единственно, что если отличия в big/little-endian то тут уже без вариантов тупо копировать не пройдет.


Есть такая штука, как ABI
http://en.wikipedia.org/wiki/Application_binary_interface
zltigo
QUOTE (CrimsonPig @ May 29 2015, 16:01) *
Есть такая штука, как ABI
http://en.wikipedia.org/wiki/Application_binary_interface

Много чего есть для сокрытия сущности явлений sm.gif. "Продвинутые" пофигисты вооюще витают, например, в JVM -там с байткодом все хорошо sm.gif
CrimsonPig
Цитата(zltigo @ May 29 2015, 14:32) *
Много чего есть для сокрытия сущности явлений sm.gif. "Продвинутые" пофигисты вооюще витают, например, в JVM -там с байткодом все хорошо sm.gif


Да-да.. самый высокоуровневый язык программирования это Power Point
sigmaN
Ооо, zltigo вернулся! Здравствуйте! Вы меня наверно не помните, но я знаю, что когда-то вы давали мне самые ценные и правильные(на мой взгляд) советы. За это вам огромная благодарность.

В общем, как я понял, профессионалы против самого тупого варианта сериализации под названием memcpy() и всё-таки рекомендуют структуру даже не паковать, а просто почленно копировать в некий байт-буфер и на приёме потом раскладывать это всё дело обратно. Правильно я понимаю? А там и big/little endian можно учесть в этой процедуре...
zltigo
QUOTE (sigmaN @ May 29 2015, 20:23) *
Ооо, zltigo вернулся! Здравствуйте!

И Вам здравствовать!
QUOTE
В общем, как я понял, профессионалы против самого тупого варианта сериализации под названием memcpy()

Отчего-же? Лично я не склонен придерживаться каких-либо стереотипов. Все зависит от задачи. Излишества ради следования неким принципам не становятся более полезными. Если-же какой-то исходник заточен под, например, big-endian и ЛИЧНО Вам, как автору, пока ни как не видна необходимость его портирования на little платформу, то достаточно просто добавить кусочек проверки на big/little, дабы если вдруг кто-то захочет бездумно перенести, получил предупреждение и занялся нужными ЕМУ доработками.
Сергей Борщ
Я использую один и тот же заголовочный файл с описанием неупакованных структур на всех архитектурах. Сталкивался с двумя проблемами: -mno-ms-bitfields и выравнивание (для AVR проблемы выравнивания нет, поэтому там структура получается упакованной сама по себе) - в этом случае просто добавляю в структуры в нужные места пустые байты для создания на AVR нужного выравнивания. И стараюсь данные в структурах располагать так, чтобы структура получалась без пустых мест, тогда достаточно только дописать в конец структуры несколько байтов для выравнивания размера всей структуры. Можно использовать атрибут aligned(x), но мне он тут не нравится эстетически. Передаю данные между устройствами побайтным чтением памяти. Использую только gcc, вопрос совместимости с другими компиляторами меня не беспокоит.
zltigo
QUOTE (Сергей Борщ @ May 29 2015, 23:24) *
Можно использовать атрибут aligned(x), но мне он тут не нравится эстетически.

Очень зря, поскольку именно он снимает необходимость рассоввывать врукопашную "пустые байты". А в чем его неэстетичность в сравнеии с прописыванием в структуре фиктивных членов? Использование разных компиляторов еще хоть как-то может нарушать чувство прекрасного синтаксическим разнообразием, но когда "только gcc, вопрос совместимости с другими компиляторами меня не беспокоит", то вообще какие проблемы?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.