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

 
 
> Расположение массивов, Хомут понятен, а вот побудительные мотивы компилятора - нет
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
Ответов
Andy Mozzhevilov
сообщение Oct 28 2009, 06:44
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 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
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 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
Сообщение #4


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

Группа: Свой
Сообщений: 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



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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 13:40
Рейтинг@Mail.ru


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