|
|
  |
EWARM 5.10 |
|
|
|
Mar 18 2008, 16:39
|

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

|
Цитата(Vitaliy_ARM @ Mar 18 2008, 12:10)  Может можно это отключить, и сделать так, чтобы sizeof() возвращал количество байт? Бессмысленность какая-то НУ ЗАЧЕМ ИМЕТЬ некое абстрактное число, которое, Вы называете "КОЛИЧЕСТВО БАЙТ", если оно НЕ СООТВЕТСТВУЕТ реальному состоянию дел? sizeof() возвращает именно количество байт занимаемое структурой. Для чего понадобилось-бы число байт которое-бы занимала-бы структура если-бы была-бы упакована я ума не приложу - откройте тайну! Заодно еще один вопрос - а причем тут тема EWARM 5.10 ?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 18 2008, 18:24
|
Знающий
   
Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246

|
Цитата(zltigo @ Mar 18 2008, 19:39)  Бессмысленность какая-то НУ ЗАЧЕМ ИМЕТЬ некое абстрактное число, которое, Вы называете "КОЛИЧЕСТВО БАЙТ", если оно НЕ СООТВЕТСТВУЕТ реальному состоянию дел? sizeof() возвращает именно количество байт занимаемое структурой. Для чего понадобилось-бы число байт которое-бы занимала-бы структура если-бы была-бы упакована я ума не приложу - откройте тайну! Заодно еще один вопрос - а причем тут тема EWARM 5.10 ? С программе больше 70 различных структур данных, которые в итоге, в зависимости от состояния программы, отправляются одной и той же функцией по RS232. Причем данные в структурах периодически меняются, но всегда выровнены по DWORD, за исключением байтовых концовок. Причем содержимое(размер) структур колеблется при написании программы. Есть функция, которая умеет тупо передавать массив байт. При отправке указатель на структуру приводится к BYTE*, и еще указывается длина (все как обычно). Вот и хотел избавить себя от рутинной работы измерения размера структуры каждый раз при ее изменении и прописывания ее размера через константу в #define. Но как выяснилось, такое сделать не получается в принципе
--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
|
|
|
|
|
Mar 18 2008, 18:42
|

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

|
Цитата(Vitaliy_ARM @ Mar 18 2008, 21:24)  ...отправляются одной и той же функцией по RS232. Есть функция, которая умеет тупо передавать массив байт. При отправке указатель на структуру приводится к BYTE*, и еще указывается длина (все как обычно). Ну и чем, этой функции передачи, простите, поможет знание того, что в структре есть XX байтов, которые нужно выковырять и переслать? Все равно БЕЗ ЗНАНИЯ СТРУКТУРЫ только по XX функция передачи не сможет из извлечь. А если она знает структуру, то на кой ей сдалось какое-то число байтов живописно в этой структуре расположенных. Посему вопрос остался открытым - зачем? В таких случаях несмотря на поигрыш в быстродействии идут на паковку структур. Получается просто и беспроблемно принимать-передавать. В конце концов все не так и срашно c паковкой - Вы ведь работаете со строками, например? Цитата Но как выяснилось, такое сделать не получается в принципе Пока не выяснилось, как Вы себе представляете выковыривание значащих байтов из неупакованной структуры НЕ располагая знаниями о самой структуре.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 18 2008, 19:02
|
Знающий
   
Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246

|
Цитата(zltigo @ Mar 18 2008, 21:42)  Пока не выяснилось, как Вы себе представляете выковыривание значащих байтов из неупакованной структуры НЕ располагая знаниями о самой структуре. Я не хочу ковырять байты, для этого пустоты ликвидировал, уже писал, что все структуры выровнены, например так: struct MyStr { BYTE P1; BYTE P2; WORD Z1; DWORD Z2; DWORD Z3; BYTE K1; } Вот эта структура выровнена, потому что в ней все данные находятся в нужных местах и дыр в ней нет. Длина ее 13 байт, а область памяти, которую выделит компановщик, будет 16 байт. Передавать надо по GPRS, поэтому плодить лишьний трафик не выгодно. Собственно мне не хотелось еще плодить дополнительные директивы для определения длины каждой структуры. Которые потом надо еще не забыть поменять.
Сообщение отредактировал Vitaliy_ARM - Mar 18 2008, 19:05
--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
|
|
|
|
|
Mar 19 2008, 07:05
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
Код struct MyStr { BYTE P1; BYTE P2; WORD Z1; DWORD Z2; DWORD Z3; BYTE K1; ДЫРКА 1; ДЫРКА 2; ДЫРКА 3; }  Выход конечно есть , обьявляете массив из 13 байт, а далее через приведение типов. Но в будущем если понадобится изменить структру или она выростит или еще что то, проблемы гарантированы. Код char buff[13]; ((struct MyStr*)buff)->P1 = 0xFF;
|
|
|
|
|
Mar 19 2008, 08:12
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
Цитата Что объяснить? Что компилятор имеет право выделять каждой из переменных неупакованной структуры, например, по 32 бита? 1. Мы ведь в ветке IAR, значит речь идет о нем, следовательно читаем как он пакует структуры. 2. Я еще не видел в жизни компилятора который для структуры из 4 байт выделил бы 16 байт памяти 3. Выравнивание структуры подрузумевает размещение переменных согластно их типу по нужному для этого типа адресу + учитывается архитектура ядра (не все ядра умеют работать с байтами, но это уже отдельный случай), а не просто создание размера струкруры кратной кокогото размера. Вывод НЕ ИМЕЕТ такого права, если конечно потдерживает стандарт.
|
|
|
|
|
Mar 19 2008, 10:11
|

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

|
Цитата(MALLOY2 @ Mar 19 2008, 11:12)  Вывод НЕ ИМЕЕТ такого права, если конечно потдерживает стандарт. Тогда пречитайте свой-же п.3, (только до того места, когда началась явная отсебятина) - "Выравнивание структуры подрузумевает размещение переменных согластно их типу по нужному для этого типа адресу + учитывается архитектура ядра". В который (последний, ибо утомило  ) раз спрашиваю, зачем отдавая паковку на опкуп компилятору пытатся после этого перехитрить и компилятор, и себя, и сетовать на разработчиков языка, если предусмотрено УПРАВЛЕНИЕ паковкой структур???
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 19 2008, 12:30
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
Цитата который (последний, ибо утомило ) раз спрашиваю, зачем отдавая паковку на опкуп компилятору пытатся после этого перехитрить и компилятор, и себя, и сетовать на разработчиков языка, если предусмотрено УПРАВЛЕНИЕ паковкой структур??? Производительность !. Код с упакованными структурами меделеннее и более емкий. так как компилятор начинает с структурой по байтово работать. Расмотрим такой вариант. Есть некий интерфейс скажем UART. Он умеет отсылать массив данных. Прототип Код u32_t uart_send (void *data, u32_t len);
u32_t uart_rcv (void *data, u32_t len); Чисто гипотетически выдумаем протокол. Структура протокола u8_t prot_type; u8_t paket_len; u16_t cmd; u32_t parametrs; u16_t crc; u8_t data[x]; //где x это поле данных которое имеет переменную длинну указанную в paket_len; Сточки зрения структур "С" его надо упаковывать. Но у него все поля выравнены, и с точки зрения программы на ASM никакого выравнивания не надо так как все поля находятся с учетом алигна на своих адресах. Имеем следующую функцию Код void Device_Send_Cmd(Cmd, Parametrs, char *data, u8_t len) { char send_buff[SEND_BUFF_SIZE]; char *data_ptr; u32_t i; ((struct MyStr*)send_buff)->prot_type = MY_PROTOCOL; ((struct MyStr*)send_buff)->paket_len = len ((struct MyStr*)send_buff)->cmd = Cmd; ((struct MyStr*)send_buff)->parametrs= Parametrs; ((struct MyStr*)send_buff)->crc = crc_update(...); data_ptr = &send_buff[11]; //это не достакок размер структуры нужно посчитать самому и подставить нужное смещение для данных; for (i=0;i<len; len++) *data_ptr++ = *data++; uart_send(send_buff, len+11); //тут тоже кривовато, но можно все вынести в дефайн } Вот на таком примере можете посмотреть на листинг функции с упакованной структорой и нет. И раскажите в чем выиграш упаковки, в переносимости ? удобстве ? за все это можно заплать ценой более мощного контроллера или кричать что на С код большой и начинать функцию писать на асме, что приведет к полной потере переносимости. Иногда удорожание девайса на 10 центов недопустимо. Исключением составляют 8 битные процессоры на них код будет одинаковый что с упакованной структурой что нет. Цитата пытатся после этого перехитрить и компилятор, и себя, и сетовать на разработчиков языка Ну это уже проблемы сугобо личные... P.S. отредактировал под автора
|
|
|
|
|
Mar 19 2008, 12:59
|
Знающий
   
Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246

|
Цитата(MALLOY2 @ Mar 19 2008, 10:05)  Выход конечно есть , обьявляете массив из 13 байт, а далее через приведение типов. Но в будущем если понадобится изменить структру или она выростит или еще что то, проблемы гарантированы. Собственно примерно так и работал. В итоге получается что при использовании структур нарушается переносимость кода с платформы на платформу. Например один и тот же код под AVR будет компилироваться без проблем, Под ARM уже могут быть дыры, если элементы структуры не выровнены. Получается для более менее хорошей переносимости необходимо ориентироваться на старший процессор.
--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
|
|
|
|
|
Mar 19 2008, 13:17
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
Цитата(Vitaliy_ARM @ Mar 19 2008, 16:59)  Собственно примерно так и работал. В итоге получается что при использовании структур нарушается переносимость кода с платформы на платформу. Например один и тот же код под AVR будет компилироваться без проблем, Под ARM уже могут быть дыры, если элементы структуры не выровнены. Получается для более менее хорошей переносимости необходимо ориентироваться на старший процессор. Что бы получить кросс платформенность при обмене с внешним миром, без кучи кучи настроек не обойдетесь, так как ядрабывают разные, бывает с разным представление чисел в памяти (LITE ENDIAN & BIG ENDIAN), есть у которых минимальная еденица (char) 16 бит - TMS320VC5502 и т.д. завта появятся 64 битные и т.д. Вот более переносимый код, я думаю он все же оптималнее чем упакованные структуры, но не факт, прогсто для примера Код #define STRUCT_FILED_SIZE(filed) sizeof(((struct MyStr*)0)->field) void Device_Send_Cmd(Cmd, Parametrs, char *data, u8_t len) { char send_buff[SEND_BUFF_SIZE]; char *data_ptr; u32_t i; head_len = 0; ((struct MyStr*)send_buff)->prot_type = MY_PROTOCOL; head_len += STRUCT_FILED_SIZE(prot_type); ((struct MyStr*)send_buff)->paket_len = len head_len += STRUCT_FILED_SIZE(paket_len); ((struct MyStr*)send_buff)->cmd = Cmd; head_len += STRUCT_FILED_SIZE(cmd); ((struct MyStr*)send_buff)->parametrs= Parametrs; head_len += STRUCT_FILED_SIZE(parametrs); ((struct MyStr*)send_buff)->crc = crc_update(...); head_len += STRUCT_FILED_SIZE(crc); data_ptr = &send_buff[head_len]; for (i=0;i<len; len++) *data_ptr++ = *data++; uart_send(send_buff, len+head_len); }
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|