Как разместить переменные в компиляторе IAR в определенном порядке?

Я пытаюсь поместить некоторые переменные в определенную ROM-линию.

В файле конфигурации компоновщика:

define symbol __ICFEDIT_region_APP_ROM_start__  = 0x08070000 ;
define symbol __ICFEDIT_region_APP_ROM_end__    = 0x0807FFFF;

define region APP_ROM_region   = mem:[from __ICFEDIT_region_APP_ROM_start__   to __ICFEDIT_region_APP_ROM_end__];

place in APP_ROM_region { readonly section test_data};

В исходном файле:

#pragma default_variable_attributes = @ "test_data"

const U8 testVar8 = 0;
const U8 testArray512[512];
const uint32_t testVar32 = 0x1234ABCD;
const U8 testArray500[500];

#pragma default_variable_attributes =

Сгенерированный файл .map:

test_data           const    0x08070000   0x200  source_file.o [1]
test_data           const    0x08070200   0x1f4  source_file.o [1]
test_data           const    0x080703f4     0x4  source_file.o [1]
test_data           const    0x080703f8     0x1  source_file.o [1]
testArray512            0x08070000   0x200  Data  Gb  source_file.o [1]
testArray500            0x08070200   0x1f4  Data  Gb  source_file.o [1]
testVar32               0x080703f4     0x4  Data  Gb  source_file.o [1]
testVar8                0x080703f8     0x1  Data  Gb  source_file.o [1]

У всех работает - переменные находятся в правильном разделе.

Но компоновщик навел порядок из-за размера переменных.

Есть ли способ сказать компоновщику не изменять порядок переменных, чтобы они отображались в файле карты в том же порядке, в котором они объявлены в исходном файле?

Цель:

testArray8              0x08070000     0x1  Data  Gb  source_file.o [1]
testArray512            0x08070001   0x200  Data  Gb  source_file.o [1]
testVar32               0x08070201     0x4  Data  Gb  source_file.o [1]
testVar500              0x08070205   0x1f4  Data  Gb  source_file.o [1]

person Nick    schedule 09.04.2020    source источник
comment
Не проще ли просто использовать struct?   -  person KamilCuk    schedule 09.04.2020
comment
@KamilCuk, к сожалению, совсем нет. Этот файл будет сгенерирован вне проекта, поэтому его внешний вид фиксирован. Он состоит из строк: имя типа начальное_значение. И в случае использования struct начальные_значения должны быть установлены отдельно от объявления.   -  person Nick    schedule 09.04.2020
comment
Компиляторы C и компоновщики могут сортировать по своему усмотрению. Вы можете узнать, как работают ваши, и попытаться навязать определенный порядок. Однако стандарт C определяет последовательность только для structs. -- Компоновщик достаточно умен, чтобы сначала поместить самый большой объект, чтобы найти хорошее решение. Он может иметь или не иметь возможность изменить это поведение. Вы прочитали все его руководство? И вы спросили IAR, кто предоставил инструмент?   -  person the busybee    schedule 09.04.2020
comment
@thebusybee, спасибо за ответ! Да, я просмотрел полное официальное руководство IAR в формате pdf и не нашел подходящего решения. Я также попытаюсь получить ответ от службы поддержки IAR, но было бы идеально, если бы я мог найти быстрое решение или совет здесь :)   -  person Nick    schedule 09.04.2020
comment
Ну я особо и не ответил, только намекнул. ;-) Но, если мануалы не раскрывают какой-то вариант, боюсь, что его нет. Возможно, вы захотите вернуться к ассемблеру, чтобы получить то, что хотите.   -  person the busybee    schedule 09.04.2020


Ответы (1)


Есть ли способ сказать компоновщику не изменять порядок переменных, чтобы они отображались в файле карты в том же порядке, в котором они объявлены в исходном файле?

Мне не известен параметр, который заставляет компоновщик соблюдать порядок переменных в исходном файле.
Но есть способ достичь цели с помощью директивы block в файле конфигурации компоновщика.

Руководство по разработке IAR C/C++ указывает для директивы place in:

Директива place in размещает разделы и блоки в определенном регионе. Секции и блоки будут размещены в регионе в произвольном порядке. Чтобы указать конкретный порядок, используйте директиву block.

Таким образом, в исходном файле каждая из переменных должна находиться в отдельной секции:

const U8       testVar8          @ test_data_1 = 0;
const U8       testArray512[512] @ test_data_2;
const uint32_t testVar32         @ test_data_3 = 0x1234ABCD;
const U8       testArray500[500] @ test_data_4;

В файле конфигурации компоновщика мы добавляем определение block с разделами test_data_* в желаемом порядке и помещаем его в начало целевого региона:

define symbol __ICFEDIT_region_APP_ROM_start__  = 0x08070000 ;
define symbol __ICFEDIT_region_APP_ROM_end__    = 0x0807FFFF;

define region APP_ROM_region   = mem:[from __ICFEDIT_region_APP_ROM_start__   to __ICFEDIT_region_APP_ROM_end__];

define block TEST_DATA with fixed order { 
  readonly section test_data_1,
  readonly section test_data_2,
  readonly section test_data_3,
  readonly section test_data_4
};

place at start of APP_ROM_region { block TEST_DATA };

person Blue    schedule 16.04.2020