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

 
 
> Приём/передача незапакованной структуры для C2000, Программерская смекалка :)
sigmaN
сообщение Oct 26 2009, 12:59
Сообщение #1


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Код
typedef uint32_t ba05_blockKey[BA05_BLOCKKEYSIZE];

//заголовок у обоих типов пакетов общий, поэтому опишем его один раз
struct ba05_net_pktHeader
{
    uint16_t    packetType    : 3;    //ID-пакет, BlockPacket или HeaderPacket
    uint16_t    connStageID    : 3;    //public_keys_interchange, random_sample_interchange, hash_interchange
    uint16_t    needACK        : 1;    //сообщает приёмнику, что в ответ на этот пакет нужно обязательно отправить ACK пакет
    uint16_t    ACK            : 1;    //Признак пакета подтверждения. Если ACK==1 - все остальные поля не используются(кроме crc8,естественно)    
    uint16_t    crc8         : 8;
};
//описание поля data для пакета IDPacket
struct ba05_net_IDPacket_data
{
    ba05_ID                public_ID;    
    ba05_ID                corp_ID;    
};
//поле data для Block-пакета описано в объявлении ba05_net_packet ниже
typedef struct
{
    struct ba05_net_pktHeader             header;
    union
    {
        struct ba05_net_IDPacket_data     asIDPacket;
        ba05_blockKey                asBlockPacket;
    }data;
}ba05_net_packet;

Прагмы, заставляющей компилятор запаковать структуру - нет.
Тип ba05_blockKey может изменяться в зависимости от настроек алгоритма. Т.е. вместо uint32_t там может появиться uint16_t или uint64_t, соответственно, выравнивание будет разным.
На данный момент, не сложно догадаться, после header идёт пустышка(1слово), длее идёт data.
Если бы структура передавалась всегда полностью - проблем бы не было. Но в зависимости от ситуации, передаётся либо только header, либо header + asIDPacket, либо целиком(header + asBlockPacket).
Функции отправки/приёма анализируют header.packetType и по нему определяют сколько байт нужно отправить/принять(а также обработать при пересчёте CRC).
И всё было-бы хорошо, если бы не тот факт, что из-за пустышек, применяемых для выравнивания, сумма sizeof всех полей получается меньше sizeof всей структуры.
Как я уже говорил, настройки могут меняться и нужно это дело как-то обработать универсальным способом.
На данный момент я сделал так:
Код
*/
*    Ниже, я постарался обработать эту ситуацию с помощью препроцессора и арифметики с указателями.
*    Суть в том, что вместо sizeof я применял разность адресов .data и .header
*    оператор взятия адреса(&) позволит нам уловить момент вставки компилятором пустышки
*    пример: <header size=1byte,address=0><пустышка size=1byte,address=1><data size=2,address=2>
*    если просто взять sizeof(header) + sizeof(data) байт и отправить - то мы отправим header полностью
*    пустышку полностью, а поле data будет передано не полностью(на sizeof(пустышка) байт меньше)
*    Но если я вместо sizeof(header) использую (&data -  &header) то пустышка будет учтена.
*/
enum {  HeaderPacketSize = sizeof(((ba05_net_packet *)0)->header) }; //header сам по себе никуда не выравнивается
//а дальше пришлось мудрить
#define BlockPacketSize ( ((int)&((ba05_net_packet *)0)->data.asBlockPacket - (int)&((ba05_net_packet *)0)->header) + sizeof(((ba05_net_packet *)0)->data.asBlockPacket) )
#define IDPacketSize ( ((int)&((ba05_net_packet *)0)->data.asIDPacket - (int)&((ba05_net_packet *)0)->header) + sizeof(((ba05_net_packet *)0)->data.asIDPacket) )

//теперь нам нужно правильно определить размер в байтах
#ifdef SIZEOF_IS_IN_WORDS
    enum {  HeaderPacketSize_bytes = HeaderPacketSize * 2    };
    #define BlockPacketSize_bytes ( BlockPacketSize * 2 )
    #define    IDPacketSize_bytes ( IDPacketSize * 2 )
#elif defined(SIZEOF_IS_IN_BYTES)
    enum {  HeaderPacketSize_bytes = HeaderPacketSize        };
    #define BlockPacketSize_bytes ( BlockPacketSize )
    #define    IDPacketSize_bytes ( IDPacketSize )
#endif

Работает. Но как-то мудрёно получается....
Прокомментируйте решение, пожалуйста. Что можно поменять? Как сделать проще/лучше?

P.S. SIZEOF_IS_IN_WORDS/SIZEOF_IS_IN_BYTES тут присутствуют для обеспечения портируемости. Дело в том, что мой компилятор возвращает sizeof в словах(по 2 байта). Побайтового доступа к памяти нет.
Однако, при работе с сетью нам нужны байты. На других архитектурах, где sizeof() ведет себя прилично - этой проблемы не будет. Поэтому я обрабатываю эту ситуацию отдельно.
А функции отправки/приёма просто могут использовать *_bytes и не беспокоиться не о чём smile.gif


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 11)
zltigo
сообщение Oct 26 2009, 13:30
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(sigmaN @ Oct 26 2009, 15:59) *
Прагмы, заставляющей компилятор запаковать структуру - нет.

Поскольку данное утверждение практически не вероятно, то дальше читать не стал sad.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 26 2009, 13:49
Сообщение #3


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



аа. Т.е. как это? Это стандартная фича?
а у меня в описании компилятора виднеется
Цитата
6.9 Pragma Directives
Pragma directives tell the compiler how to treat a certain function, object, or section of code.
The C28x C/C++ compiler supports the following pragmas:
· CODE_ALIGN
· CODE_SECTION
· DATA_ALIGN
· DATA_SECTION
· FAST_FUNC_CALL
· FUNC_EXT_CALLED
· INTERRUPT
· MUST_INTERATE
· UNROLL
Поэтому я как-бы и растерялся маленько smile.gif


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 26 2009, 13:52
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(sigmaN @ Oct 26 2009, 16:49) *
аа. Т.е. как это? Это стандартная фича?

Это фича без которой на не восьмибитовых контроллерах не жизнь. Что за компилятор для C28x ? Этот TMS320 вообще теоретически способен работать с невыровненными данными?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 26 2009, 14:04
Сообщение #5


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
Что за компилятор для C28x ?
CCS code gen tools 5.2.2 проц TMS320F28335
Цитата
Этот TMS320 вообще теоретически способен работать с невыровненными данными?
похоже, что нет. Где-то помню чётко было прописано, что LSW должен располагаться по чётному адресу, а MSW по нечётному(или наоборот...нет, кажется правильно) Тогда понятно, почему паковать структуру не дают.

sad.gif sad.gif sad.gif

added:
Цитата
All 32-bit reads and writes to memory are aligned at the memory interface to
an even address boundary with the least significant word of the 32-bit data
aligned to the even address.


Для пробы добавил #pragma pack(1) - даёт warning неизвестная прагма sad.gif


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 26 2009, 14:15
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(sigmaN @ Oct 26 2009, 17:04) *
Тогда понятно, почему паковать структуру не дают.

Ну тогда я в заголовок добавлю TMS320


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 26 2009, 14:34
Сообщение #7


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
Ну тогда я в заголовок добавлю TMS320

Тогда, наверное, правильнее будет C2000. Потому как на TMS320 начинается достаточно много процессоров. В том числе и таких, на которых этой проблемы нет.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 26 2009, 17:51
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Я извиняюсь, а · DATA_ALIGN это случайно не аналог pragma pack?
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 26 2009, 18:06
Сообщение #9


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



думаю, что не совсем
Цитата
The DATA_ALIGN pragma aligns the symbol to an alignment boundary.
The alignment boundary is the maximum of the symbol's default alignment value or the value of the constant in bytes.
The constant must be a power of 2.
The syntax of the pragma in C is:
#pragma DATA_ALIGN ( symbol , constant );


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 26 2009, 18:14
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(sigmaN @ Oct 26 2009, 23:06) *
думаю, что не совсем
Ну дык все верно. В CCS для TMS320C2000 char же 16-и битный. laughing.gif
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 26 2009, 18:58
Сообщение #11


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Но есть интринсик __byte() который позволяет быстро "пройтись" по байтам структуры без всяких сдвигов и масок. Если бы она была char к char'у(хоть и по 16бит) без пропусков.

А DATA_ALIGN разместит только начало структуры с выравниванием, указанным в DATA_ALIGN. На члены структуры это повлияет, но не всегда гарантировано, то не будет пропусков. Т.е. не на 100% так, как это сделала бы #pragma pack()
По-моему придётся сделать что-то вроде struct_to_packet(), которая по одному будет считывать поля структуры и ложить их в пакет(буфер) байт за байтом без пробелов.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Nov 9 2009, 16:03
Сообщение #12


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



А может кто-то подскажет оригинальную идею?
Ведь не один же этот проц такой. Люди же как-то эту проблему решают....

Я конечно выкрутился, но что-то берут меня сомнения насчёт красоты решения smile.gif


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 12:36
Рейтинг@Mail.ru


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