Можно ли изменить разделы по умолчанию для всего файла со встроенным GNU Arm?

Можно ли со встроенным набором инструментов GNU Arm изменить разделы символов по умолчанию для всего файла?

Ранее я работал с Rowley Crossworks, у которого есть параметр, который вы можете установить для любого исходного файла или папки, чтобы изменить различные разделы по умолчанию, например раздел по умолчанию для обнуленных переменных: введите здесь описание изображения (из Руководство по Crossworks)

Это очень полезно, чтобы убедиться, что большое приложение помещается во флэш-память и микроконтроллеры с ограниченными ресурсами ОЗУ. Однако я не могу найти способ сделать это с помощью обычного набора инструментов GNU Arm.

Я знаю, что могу использовать __attribute__((section(".sectionname"))), но это требует модификации кода, что проблематично при компиляции одного и того же кода для разных целей, некоторые из которых могут иметь не более одного раздела.

Идеальным решением был бы параметр командной строки GCC, чтобы поместить, например, обнуленные данные в пользовательский раздел для конкретной единицы компиляции. Затем я мог применить это к определенным файлам, папкам или проектам из CMake, не внося никаких изменений в фактический исходный код. Существует ли что-то подобное?


person hlnd    schedule 31.08.2020    source источник
comment
Значит, вы не хотите делать это в скрипте компоновщика? вызвать весь файл и изменить, где он идет? Должен быть в командной строке gcc?   -  person old_timer    schedule 08.09.2020
comment
легко использовать инструменты gnu, чтобы удерживать размер приложения в пределах ресурсов микроконтроллера. Какую настоящую проблему вы пытаетесь решить здесь?   -  person old_timer    schedule 08.09.2020
comment
@old_timer В идеале я хотел бы использовать аргументы командной строки, но решение сценария компоновщика также приветствуется. Изучая комментарий Лундина ниже, я увидел, что, возможно, это можно сделать из скрипта компоновщика, но не сразу смог заставить его работать, как ожидалось, и еще не смог снова вникнуть в детали.   -  person hlnd    schedule 10.09.2020


Ответы (3)


Это возможно с __attribute__, но недостаточно просто ввести раздел для переменной. Такой раздел должен присутствовать в скрипте компоновщика, что означает, что вам нужно вручную изменить этот раздел (часто называемый .ld/.lcf или что-то подобное, в зависимости от цели). Различные диалекты, похоже, существуют в зависимости от цели, подробности см. в руководстве по компоновщику GCC.

Crossworks делает эту часть за вас - насколько я помню, они позволяют вам изменять более простой в использовании формат XML, чтобы вам не приходилось напрямую вмешиваться в скрипт компоновщика. Вы можете просмотреть выходные файлы Crossworks, и вы найдете файл с расширением .ld или эквивалентным. Вероятно, именно так должен выглядеть ваш файл компоновщика для gcc для данной целевой платформы.

person Lundin    schedule 31.08.2020
comment
Извините, возможно, я неясно выразился, но я знаю о __attribute__ и о том, как он работает вместе со сценарием компоновщика. Проблема в том, что исходный код, с которым я работаю, создан для нескольких целей, поэтому установка атрибута в исходном коде исправляет одну цель, но ломает другую. Вероятно, это можно обойти с помощью какого-то макроса, но вместо этого я надеялся, что будет какой-то параметр командной строки GCC, чтобы я мог решить это исключительно из CMake. Я попытался немного расширить вопрос. - person hlnd; 31.08.2020
comment
@hlnd Хорошо. Эти вещи просто не переносимы. Некоторые компиляторы используют для этого нестандартный оператор @, другие — специальный #pragma и так далее. Где-нибудь вам понадобится куча #ifdef. - person Lundin; 01.09.2020
comment
На самом деле я не слишком озабочен переносимостью между компиляторами. Преимущество решения с параметрами командной строки в первую очередь заключается в поддержке разных процессоров из одной и той же кодовой базы, например. один с несколькими разными блоками ОЗУ по разным адресам, а другой только с одним большим непрерывным блоком. Возможно, я мог бы сделать это, добавив поддельные разделы в сценарий компоновщика второго процессора, но это немного странно, и я бы предпочел избегать этого, если это вообще возможно. - person hlnd; 01.09.2020
comment
@hlnd Некоторые сценарии компоновщика поддерживают добавление одного и того же раздела в несколько областей памяти (я не помню, делает ли это gcc и как). Пока у вас есть несколько переменных и т. д., компоновщик добавит их в область памяти, где есть место, а затем перейдет к следующей, когда предыдущая будет заполнена. Довольно часто встречается при работе с младшими микроконтроллерами с фрагментированными картами памяти (банковскими). - person Lundin; 01.09.2020
comment
Это звучит очень интересно. У вас есть ссылки на то, как это работает и какой синтаксис требуется? Моя первоначальная наивная попытка, просто поставив *(.bss*) и в .bss, и в .ethram, похоже, не дала никакого эффекта. - person hlnd; 02.09.2020
comment
@hlnd Я новичок в скриптах компоновщика gcc, поэтому мне придется поискать его. Но другие цепочки инструментов поддерживают это, поэтому я не понимаю, почему gcc этого не сделает. - person Lundin; 02.09.2020

Не могли бы вы изменить рецепт компиляции, чтобы создать файл .s, применить awk / sed / etc..., чтобы настроить разделы по своему вкусу, а затем собрать результат. Это своего рода старый способ сделать это, но он достаточно портативный и надежный.

person mevets    schedule 04.09.2020

Мне не удалось найти параметр командной строки или аналогичный для этой функции, но comment от Lundin заставил меня более подробно изучить скрипты компоновщика, и в итоге я получил следующее:

.bss :
{
    . = ALIGN(4);
    __bss_start__ = .;
    *main.cpp.obj*(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
} >RAM

.ethram (NOLOAD):
{
    __ethram_start__ = .;
    *(.ethram)
    *(.bss*)
    __ethram_end__ = .;
} >ETHRAM

Выше я прямо заявляю, что в выходной раздел .bss должен быть включен только раздел main.cpp .bss, и что он должен быть помещен в обычную оперативную память. К тому времени, имея неограниченный .bss в ETHRAM, компоновщик помещает туда секции .bss других файлов, и этого было достаточно для моего использования.

Также можно явно исключить файлы из раздела вывода, например, как здесь, но моему приложению это не нужно:

.bss :
{
    . = ALIGN(4);
    __bss_start__ = .;
    EXCLUDE_FILE(*main.cpp.obj*)*(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
} >RAM
person hlnd    schedule 13.10.2020