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

 
 
> Расположение массивов, Хомут понятен, а вот побудительные мотивы компилятора - нет
SasaVitebsk
сообщение Oct 27 2009, 23:00
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Столкнулся с проблемой. Сразу отмечу, что понимаю её корни и вижу несколько способов решения, но мне непонятно почему компилятор так поступает. Кто объяснит.

Смысл следующий. Я размещаю несколько массивов типа
Код
const    uint8_t        __rom        Roll0[]    =
{
  0xDA, 0x54, 0x00, 0x00, 0x01, 0x60, 0xea, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x23, 0x31, 0x5E,    //
  0xF7, 0x5E, 0x3A, 0x5E, 0xEC, 0x2E, 0x5E, 0xF1, 0x00, 0xDA, 0x54, 0x00, 0x00, 0x01, 0x60, 0xEA,    //
  0x08, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x23, 0x31, 0x5E, 0xC4, 0x2E, 0x5E, 0xCC, 0x2E, 0x5E, 0xC3,    //
  0x00, 0xDA, 0x45, 0x5F, 0xEA    //
};

const    uint8_t        __rom        Roll1[]    =
{
  0xDA, 0x54, 0x00, 0x00, 0x01, 0x70, 0x17, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x23, 0x43, 0x01,    //
  0x23, 0x31, 0x5E, 0xF7, 0x5E, 0x3A, 0x5E, 0xEC, 0x2E, 0x23, 0x43, 0x03, 0x5E, 0xF1, 0x00, 0xDA,    //
  0x54, 0x00, 0x00, 0x01, 0x60, 0xEA, 0x08, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x23, 0x31, 0x23, 0x43,    //
  0x01, 0x5E, 0xC4, 0x2E, 0x5E, 0xCC, 0x2E, 0x5E, 0xC3, 0x00, 0xDA, 0x45, 0x5F, 0xEA    //
};


и так далее ...
Потом объявляю массив ...
Код
const    uint8_t    __rom *    const __rom AdrRoll[] =
{
  (const    uint8_t    __rom *)&Roll0, (const    uint8_t    __rom *)&Roll1, (const    uint8_t    __rom *)&Roll2,
  (const    uint8_t    __rom *)&Roll3, (const    uint8_t    __rom *)&Roll4, (const    uint8_t    __rom *)&Roll5,
  (const    uint8_t    __rom *)&Roll6, (const    uint8_t    __rom *)&Roll7
};


Поскольку массивы идут попорядку, то я ожидал, что компилятор их и разместит попорядку во флэши. Причём в результирующем HEXе для AVR так и происходит. А для ARM7 компилятор разбрасывает массивы как хочет.

Почему это происходит?

Я бы хотел, чтобы они шли подряд. Как вариант вижу объединить их в структуру. Но непонятен мотив компилятора. Он что так место пытается экономить? Типа дырки забивает - так вроде не видно...

Кто подскажет?

PS: Проблема несколько сложнее чем показалось с первого взгляда. Размеры массивов разные и объединить их в структуру не очень удобно. Придётся явно объявлять их длину. А мне это делать очень неудобно. Они будут меняться от реализации к реализации. Высчитывать - нет желания. Хотелось бы простое и крассивое решение. Как компилятор заставить распологать массивы по порядку?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 12)
_Pasha
сообщение Oct 28 2009, 05:38
Сообщение #2


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Есть предположение, что виноваты оптимально размещенные stubs
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Oct 28 2009, 06:06
Сообщение #3


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



А что если вынести в отдельную единицу компиляции, и выключить отпимизацию?
Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Oct 28 2009, 06:44
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206



Цитата(SasaVitebsk @ Oct 28 2009, 02:00) *
Столкнулся с проблемой. Сразу отмечу, что понимаю её корни и вижу несколько способов решения, но мне непонятно почему компилятор так поступает. Кто объяснит.

Потому что стандарт С не обязывает компилятор к размещению переменных в порядке их объявления.



Цитата(HARMHARM @ Oct 28 2009, 09:06) *
А что если вынести в отдельную единицу компиляции, и выключить отпимизацию?

Помочь может, но это будет частный случай. В общем случае гарантии нет.


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 28 2009, 10:04
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Andy Mozzhevilov @ Oct 28 2009, 09:44) *
Потому что стандарт С не обязывает компилятор к размещению переменных в порядке их объявления.

Это понятно - претензий нет. А зачем он это делает? Дырки оптимизирует, которые при выравнивании остаются?
Может тогда достаточно сделать выравнивание на границу байта в начале массивов и вернуть к исходному в конце?

Ладно. Зайдём с другого конца. Может кто-нибудь предложит решение красивое.
Задача такова.
Имеется несколько массивов. Они находятся во флэш, но в то же время я их меняю иногда. Не хотелось бы чтобы изменение массивов в тексте программы требовало вмешательство ещё куда-нибудь. Массивы разной длины. В программе мне надо знать начало этого массива и его конец. Я брал указатель на начало массива 1, а в качестве конца использовал указатель на начало массива 2. Дырка, заполненная 0 или ff, к примеру, меня не беспокоит.

Как красиво и правильно это реализовать? Так чтобы я поменял, к примеру, массив в готовой проге, и она осталась полностью работоспособной.
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Oct 28 2009, 10:11
Сообщение #6


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Например, так (С++):
Код
TTrackerCanMsgParser* const TTrackerCanMsgParserJ1939::messages[] =
{
    &SPEED,    
    ...
    &NHFUELLEVELltr
};

const unsigned int CAN_J1939_TAG_COUNT = sizeof( TTrackerCanMsgParserJ1939::messages ) / sizeof ( TTrackerCanMsgParser* );

При этом CAN_J1939_TAG_COUNT - это константа во flash.
Если она нужна только в этой единице компиляции, то можно сделать static, и она будет прямо подставлена. Или используйте extern из других файлов.
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Oct 28 2009, 10:31
Сообщение #7


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



по моему структура самое правильное решение тут
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Oct 28 2009, 10:48
Сообщение #8


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Глянул - массивы ведь не выровненные на 32 бита. А дырки какого размера?
Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Oct 28 2009, 11:06
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206



Почему бы просто дополнительно не хранить длину массива? Жалко 2 байта во флеш?
Ну можно поизвращаться:
Код
#define SLON1_INIT 1, 2, 3, 4
#define SLON2_INIT 5, 6, 7, 8, 9, 10
#define SLON3_INIT 11, 12

extern const uint8_t *pSlon1;
extern const uint8_t *pSlon2;
extern const uint8_t *pSlon3;
extern const uint8_t *pSlonEnd;

static const uint8_t Slon1_Init[] = { SLON1_INIT };
static const uint8_t Slon2_Init[] = { SLON2_INIT };
static const uint8_t Slon3_Init[] = { SLON3_INIT };

const uint8_t Slon[] = { SLON1_INIT, SLON2_INIT, SLON3_INIT };

const uint8_t *pSlon1   = Slon;
const uint8_t *pSlon2   = pSlon1 + sizeof(Slon1_Init);
const uint8_t *pSlon3   = pSlon2 + sizeof(Slon2_Init);
const uint8_t *pSlonEnd = pSlon3 + sizeof(Slon3_Init);


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post
KRS
сообщение Oct 28 2009, 11:25
Сообщение #10


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(SasaVitebsk @ Oct 28 2009, 13:04) *
Как красиво и правильно это реализовать? Так чтобы я поменял, к примеру, массив в готовой проге, и она осталась полностью работоспособной.

Вы же все равно прогу перекомпилируете?
Тогда почему нельзя использовать sizeof?
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 28 2009, 11:36
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Andy Mozzhevilov @ Oct 28 2009, 14:06) *
Почему бы просто дополнительно не хранить длину массива? Жалко 2 байта во флеш?

Наверное так и сделаю. Прогу придётся править.
Цитата
Ну можно поизвращаться:

rolleyes.gif
Любопытно. Так вроде как дважды память будет выделена. Или static не даст? В смысле, если эти массивы не будут в данном файле использованы?
Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Oct 28 2009, 11:56
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206



Цитата(SasaVitebsk @ Oct 28 2009, 14:36) *
Любопытно. Так вроде как дважды память будет выделена. Или static не даст? В смысле, если эти массивы не будут в данном файле использованы?

В общем случае это от компилятора зависит. Iar это оптимизирует, большинство других современных тоже скорее всего.
Возникает только warning , который можно в принципе прибить через #pragma
Но, имхо это извращения какие-то.
Я бы создал структуру, состоящую из указатетеля на массив и длины.
А потом бы создал и проинициализировал массив таких структур. Ну или просто, как рекомендовали выше, sizeof() для определения длины.


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Oct 28 2009, 18:39
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Мне кажется, проблема надумана.
Желание не указывать длину массива и при этом сохранить работоспособность программы при смене массива как-то не вяжется.
Объявить длины массивов, уложить в структуру. Массив указателей тогда не нужен.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 16:34
Рейтинг@Mail.ru


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