Вопрос

Я пытаюсь запрограммировать ARM с помощью Eclipse + CDT + yagarto (gnu toolchain) + OpenOCD.В нескольких примерах проектов (например, с сайта yagarto) Я нашел скрипты компоновщика (*.ld), где указано много информации о ссылках (наряду с определениями разделов).На самом деле я раньше не сталкивался с этими файлами (IAR в них не нуждается), и я нахожу их несколько трудными для понимания с первого взгляда.Итак, мой вопрос в том, могу ли я использовать один такой файл сценария для моего целевого процессора (STR710FZ2T6) со всеми моими проектами, или я должен ознакомиться с написанием этих сценариев и написать их для каждого проекта.Если я могу использовать один файл для всех проектов для конкретного целевого процессора, не могли бы вы посоветовать, где я могу найти такой универсальный файл?

Это было полезно?

Решение

Я предполагаю, что у каждого третьего человека есть свой сценарий или решение.Есть ряд проблем, которые необходимо решить, разные компоновщики собираются решать их по-разному.Я думаю, что GNU сделала это слишком сложным, если не считать черной магии.

Для встраиваемой системы у вас часто будет флэш-память, eeprom или какая-либо другая форма постоянной памяти для загрузки.Как и у других процессоров, у ARM есть векторная таблица, которая по существу сообщает ему, где находится код сброса, прерывание и т.д.Таким образом, эта таблица должна находиться в определенном месте, и вы должны сказать компоновщику поместить ее в это конкретное место (сначала).

Один из сценариев, который мне нравится использовать, это:

MEMORY
{
    bob (RX) : ORIGIN = 0x0000000, LENGTH = 32K
    joe (WAIL) : ORIGIN = 0x2000000, LENGTH = 256K
}

SECTIONS
{
    JANE : { startup.o } >bob
}

Обычно я использую ram и rom в качестве имен вместо bob и joe, но здесь демонстрирую, что не имеет значения, какие это имена, это просто ярлыки.

Еще одна вариация на тему:

MEMORY
{
    rom(RX)   : ORIGIN = 0x00000000, LENGTH = 0x8000
    ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 0x2000
}

SECTIONS
{
    .text : { *(.text*) } > rom
}

Первый позволяет вам размещать файлы в командной строке компоновщика в любом порядке, но у вас должна быть векторная таблица в файле startup.o.Последнее позволяет вам использовать любые имена файлов, но первый файл в скрипте компоновщика должен иметь векторную таблицу.

arm-thumb-elf-gcc -Wall $(COPS) vectors.o putget.o blinker2.c -T memmap -o blinker2.elf

Или напрямую с ld

arm-thumb-elf-ld vectors.o putget.o blinker2.o -T memmap -o blinker2.elf

RX сообщает компоновщику поместить данные для чтения и выполнения в этот раздел памяти, а ВОПЛЬ - это, по сути, все остальное.Например, если у вас только одна оперативная память, вы можете поместить все флаги RXWAIL в строку, указывающую, где находится оперативная память.В зависимости от вашего загрузчика в этом случае вы можете положиться на файл elf, указывающий загрузчику, с чего начать ответвление, или вы можете просто сделать точку входа началом двоичного файла, и загрузчик может быть проще.Arms (не cortex-m3) имеют инструкцию ветвления в качестве первого вектора для вектора сброса, поэтому вы можете просто притвориться, что в любом случае создаете векторную таблицу для решения ram, и это просто сработает.

С этим решением связан ряд проблем, которые меня, оказывается, не беспокоят.Я инициализирую переменные в своем коде, а не во время объявления.

Это

int rx;

int main ( void )
{
  rx = 7;

вместо того, чтобы

int rx=7;

int main ( void )
{

Я также никогда не предполагаю, что переменная равна нулю при запуске кода, я всегда инициализирую ее чем-то перед запуском.Ваш код запуска и скрипт компоновщика в команде могут работать вместе, чтобы упростить автоматизацию сброса кода bss и копирования ненулевых данных инициализации из ПЗУ в ОЗУ при загрузке.(что int rx=7;вышеизложенное требует некоторого кода, который копирует значение 7 откуда-то из ПЗУ и записывает его в ячейку памяти в ОЗУ, выделенную для переменной rx, чтобы при запуске main() 7 было там.

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

.globl _start
_start:
    b reset
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang

hang : b hang

reset:
    ldr sp,=0x10004000
    bl main
    b hang

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

Мой итог таков: ДА, вы можете работать только с одним скриптом компоновщика для всей вашей работы с ARM.Но вы должны адаптировать свою работу к этому сценарию.Скорее всего, вы не найдете ни одного скрипта, который работал бы со всеми примерами кода.Чем сложнее сценарий, тем сложнее его будет позаимствовать.Да, мои сценарии, приведенные выше, вероятно, могут быть выполнены в командной строке ld, но еще раньше (gcc 2.95) Я не смог заставить это работать, поэтому разработал приведенный выше минимальный скрипт и с тех пор использую его до сих пор.По какой-то причине пришлось внести изменения во второй скрипт, но с 4.x.x, конечно, 4.4.x я могу использовать любой из них.

Другие советы

Не существует универсального сценария компоновщика. Эти сценарии очень важны, так как они определяют, где в памяти (RAM или ROM) будут размещаться различные разделы данных и программ. В компиляторах IAR есть что-то эквивалентное (файлы xcl, если я правильно помню). Вы, очевидно, до сих пор использовали только стандартные.

Есть хороший документ о STR7xx, который называется «Использование инструментов с открытым исходным кодом для STR7xx Cross». Развитие & Quot ;. Вы можете найти ссылку на домашней странице Yagarto. Я рекомендую вам взглянуть на него и попытаться понять, как работают файлы компоновщика. Есть также некоторые другие файлы конфигурации, которые вам необходимо иметь некоторое понимание.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top