Нежелательное распределение в ОЗУ, если const не используется, несмотря на размещение по абсолютному адресу Flash - PullRequest
5 голосов
/ 26 апреля 2019

Я использую GCC. Я создаю РАЗДЕЛ во Flash с помощью файла компоновки .ld, Я поместил туда некоторые данные (704 байта) с директивой __attribute__((section... Данные отображаются во флэш-памяти, но такое же пространство выделяется в ОЗУ, если я не использую ключевое слово const при объявлении данных.

Если я использую const ОЗУ не используется - но я заметил увеличение использования флэш-памяти, поскольку она была выделена там дважды!

Файл компоновщика:

FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 14K
USER_DATA_FLASH (rx)      : ORIGIN = 0x8003800, LENGTH = 2K
}

SECTIONS
{ /* placing my named section at given address: */
  .my_block 0x8003800 :
 {
  KEEP(*(.UserDataSector)) 
 } > USER_DATA_FLASH
}

Объявление массива имеет инициализаторы:

mytab_type  __attribute__((section (".UserDataSector "))) progr16[16]=
{ 
    { {LIST1,LIST2....

В этом случае я не использовал const. Предполагая, что progr16 был вынужден быть во флэш-памяти, и на самом деле он выглядит там, если я проверяю браузер памяти во время отладки. Но, похоже, он тоже занимает ОЗУ

FLASH    RAM
text     data    bss   dec     
9268     772     1948  11988    

Если я добавлю ключевое слово const:

FLASH    RAM
text     data    bss    dec 
9972     68      1948   11988

Хорошо, 704 байта данных в ОЗУ сохраняются, но почему такое же количество байтов увеличивает использование Flash, если эти значения уже находятся во Flash (из-за инициализаторов)?

1 Ответ

0 голосов
/ 27 апреля 2019

У меня не было возможности на самом деле настроить и построить автономный проект, как я планирую, чтобы полностью протестировать это, но работает ли добавление NOLOAD, как указано ниже, работает?

SECTIONS
{ 
    .my_block (NOLOAD) :
    {
        KEEP(*(.UserDataSector));
    } >USER_DATA_FLASH
}

Вот некоторые заметки, которые я сделал в руководстве пользователя v2.32 ld PDF для «NOLOAD»: enter image description here

Кажется, это то, что вам может понадобиться.

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

т:

static my_type my_array_name[] __attribute__((section(".UserDataSector"))) =
{
    // member 1,
    // member 2,
    // member 3,
    // etc
};

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

Также еще несколько заметок:

  1. Обратите внимание, что вам нужно немного очистить форматирование, отступы и т. Д., Чтобы облегчить чтение кода в вашем вопросе.
  2. Я не думаю, что KEEP здесь необходимо, но это тоже ничего не ранит.
  3. Вы должны изучить и прочитать официальное руководство по GNU Linker Script (LD). Он доступен онлайн в формате html, здесь: https://sourceware.org/binutils/docs/ld/. последняя версия v2.32.

    1. Тем не менее, я думаю, что гораздо легче учиться в PDF, так что вы можете ввести его, выделить его, выделить его, сразу выполнить поиск по нему и т. Д. Постройте руководство пользователя LD pdf, затем используйте Foxit Читатель (кроссплатформенный и бесплатный) для изучения и разметки руководства.
    2. Как создать PDF-руководство пользователя Linker Script (LD):
    3. Скачать исходный код: https://www.gnu.org/software/binutils/
      1. Пример: получить последнюю версию binutils (в настоящее время binutils-2.32.tar.xz ) здесь: https://ftp.gnu.org/gnu/binutils/
    4. Извлеките его (например, щелкните правой кнопкой мыши и перейдите к «Извлечь здесь» в Linux Ubuntu).
    5. перейдите в папку: cd binutils-2.32
    6. Затем настройте и сделайте:

      ./configure
      make
      make pdf
      
    7. Готово! Вот PDF-файлы сейчас (найдено с find | grep '\.pdf'):

      binutils-2.32/libiberty/libiberty.pdf
      binutils-2.32/bfd/doc/bfd.pdf
      binutils-2.32/ld/ld.pdf    <----- THE MAIN ONE I WANT!
      binutils-2.32/gprof/gprof.pdf
      binutils-2.32/gas/doc/as.pdf
      binutils-2.32/binutils/doc/binutils.pdf
      
    8. Сохраните и используйте ld.pdf , который теперь является PDF-версией руководства по binutils HTML 2.32, на которое я ссылался выше.

  4. Возможно, вам придется прочитать файл запуска, чтобы увидеть, делает ли он что-то странное.

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

Другие вопросы о скрипте компоновщика, примечание

  1. Доступ к "значению" переменной сценария компоновщика неопределенное поведение в C?
  2. Как получить значение переменной, определенной в сценарии компоновщика ld, из C
...