Перейти к содержанию
    

Линкер-скрипт .sct - размещение секции

Задача - разместить объект (контрольная сумма CRC32 прошивки) сразу после самой прошивки во флеш-памяти

Объявляю сам объект с атрибутом размещения в секции

// Значение CRC-32 бинарного файла всего приложения
volatile const uint32_t AppImgCRC32 __attribute__((section("CODE_CRC32"))) = 0xFFFFFFFF;

Пишем линкер-скрипт:

LR_IROM1 0x00000000 0x00010000  {    ; load region size_region
  ER_IROM1 +0  0x0001FFFC {  					; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RO_IROM2 +0  0x04 {  					; load address = execution address
   .ANY (CODE_CRC32)
  }

  RW_IRAM1 0x20000000 0x00008000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x20100000 0x00004000  {
   .ANY (+RW +ZI)
  }
}

Что получаем на выходе:

Load Region LR_IROM1 (Base: 0x00000000, Size: 0x00010090, Max: 0x00010000, ABSOLUTE, COMPRESSED[0x0000f05c])
  Execution Region ER_IROM1 (Base: 0x00000000, Size: 0x0000ed78, Max: 0x0000fffc, ABSOLUTE)

Далее идет Execution Region RO_IROM2 с секцией CODE_CRC32 размещается по адресу 0x0000ed78 - все логично и соответствует адресу размещения и размеру предыдущего ER_IROM1. Как и задумывалось.

Но! Прошиваю МК и смотрю во флешь: далее моего значения AppImgCRC32 с адреса 0х0000ED7C вплоть до адреса 0х0000F05C (см. LR_IROM1 COMPRESSED) идут какие-то данные, которых нет в .map файле. Нет ни одного объекта с адресом из диапазона от 0x0000ed7C до  0х0000F05C.

Что это за данные и как расположить мою секцию после них?

Пробовал делать так:

LR_IROM1 0x00000000 0x00010000  {    ; load region size_region
  ER_IROM1 +0  0x0001FFFC {  					; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }

  RW_IRAM1 0x20000000 0x00008000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x20100000 0x00004000  {
   .ANY (+RW +ZI)
  }
}

LR_IROM2 +0 0x00000004  {
 RO_CRC32 +0 {
  .ANY (CODE_CRC32)
  }
}

Получается другая ерунда - секция размещается слишком далеко - по адресу 0х00001090 (см. Size для LR_IROM1).

Полагаю, что мне надо получить адрес размещения моей секции равный Base+COMPRESSED (см. LR_IROM1). Но как это сделать?

И почему эти непонятные таинственные данные никак не фигурирут в .map файле?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

27 minutes ago, Darth Vader said:

Получается другая ерунда - секция размещается слишком далеко - по адресу 0х00001090 (см. Size для LR_IROM1).

Загадочные данные - это упакованное содержимое RW-секций. Последний вариант sct правильный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 часов назад, aaarrr сказал:

Последний вариант sct правильный.

Тогда возникает вопрос по этим данным:

Load Region LR_IROM1 (Base: 0x00000000, Size: 0x00010090, Max: 0x00010000, ABSOLUTE, COMPRESSED[0x0000f05c])

Сколько же в итоге занимают ЗНАЧИМЫЕ данные? Size байт или COMPRESSED?

Если Size, тогда они не помещаются в выделенный мной диапазон - Max. Линкер должен был выдать ошибку - не могу разместить данные в выделенной области.

Если же COMPRESSED - то помещаются. Но тогда выходит, что диапазон адресов  между Base+Comressed и Base+Size ничем не занят. Никакими значимыми данными. Именно это я и наблюдаю во флеше - там нет данных, только исходное состояние флеш-памяти 0xFF. Т.е. значимая для работы прошивки часть данных занимает в памяти именно COMPRESSED байт в адресном пространстве от Base до Base+COMPRESSED.

Вот я и хочу разместить свою секцию сразу за ними, т.е. по адресу Base+COMPRESSED. Как такое сделать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Darth Vader said:

Именно это я и наблюдаю во флеше - там нет данных, только исходное состояние флеш-памяти 0xFF.

Странно, а если так:

LR_IROM1 0x00000000 0x00010000  {    ; load region size_region
  ER_IROM1 +0  0x0001FFFC {  					; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }

  RW_IRAM1 0x20000000 0x00008000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x20100000 0x00004000  {
   .ANY (+RW +ZI)
  }

  ER_IROM2 +0 0x00000004  {
   .ANY (CODE_CRC32)
  }
}

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18 часов назад, aaarrr сказал:

а если так:

Тогда регион ER_IROM2 с секцией CODE_CRC32 размещаются в адресном пространстве сразу после RW_IRAM2, а это область ОЗУ, а не флеш.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Просмотрел многочисленные scat'ы, которые когда-то сочинял - принудительное размещение секций использовал только по фиксированным адресам,

а CRC располагал в начале прошивки (подозреваю, не случайно). По логике, правильным должен быть ваш второй вариант, наблюдаемое поведение

похоже на глюк линкера.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Коллеги, приветствую!

Подскажите пожалуйста, если у меня в регионе размещено 2 секции, их реальный порядок размещения может отличаться от описанного в файле скрипта?

Вот мой скрипт

LR_IROM1 0x08000000 0x00010000
{
  ER_IROM1 0x08000000 0x00010000
  {
    *.o (RESET, +First)
    *(InRoot$$Sections)
    .ANY (+RO)
    .ANY (+XO)
  }
  
  NVRAM 0x20000000 UNINIT 0x000000B8
  {
    *.o (.intvec)
    *.o (.dfuflg)
  }
  
  RW_IRAM1 0x200000B8 0x00001F48
  {
    .ANY (+RW +ZI)
  }
}

 

У меня должен быть кусок в ОЗУ начиная с адреса 0x20000000 для таблицы векторов (44 слова), и 2 слова для флага обновления ПО.

Расположил секции в естественном порядке - сначала .intvec, затем .dfuflg.

В коде объявил

static volatile struct
{
  u8 str[8];
}DFU __attribute__((section(".dfuflg"), zero_init));

static volatile u32 VTblApp[44] __attribute__((section(".intvec"), zero_init));

 

Но в map-файле вижу

.dfuflg 0x20000000 Section   8  hw.o(.dfuflg)
DFU     0x20000000 Data      8  hw.o(.dfuflg)
.intvec 0x20000008 Section 176  hw.o(.intvec)
VTblApp 0x20000008 Data    176  hw.o(.intvec)

что есть немного не то, что я хотел. Что теперь, 2 региона отдельных создавать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, Arlleex said:

Что теперь, 2 региона отдельных создавать?

В данном конкретном случае достаточно будет дописать +First к .intvec

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, aaarrr сказал:

В данном конкретном случае достаточно будет дописать +First к .intvec

Сейчас даже сам себя носом ткну, где об этом написано. Спасибо =)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И снова здравствуйте.

Решил для своего проекта на STM32F4 сразу написать скрипт компоновщика, а не пользоваться Keil-овским

Скрытый текст

LR 0x08000000 1048576
{
  FLASH 0x08000000 1048576
  {
    *.o (RESET, +First)
    *(InRoot$$Sections)
    .ANY (+RO)
    .ANY (+XO)
  }
  
  CCSRAM 0x10000000 65536
  {
  }
  
  SRAM1 0x20000000 114688
  {
    .ANY (+RW +ZI)
  }
  
  SRAM2 0x2001C000 16384
  {
    .ANY (+RW +ZI)
  }
  
  BACKUPSRAM 0x40024000 4096
  {
  }
}


Пока что я не использую CCM и Backup SRAM, но для удобства описал их регионы (чтобы потом не возвращаться к этому вопросу).

Линковщик при сборке проекта выдает предупреждения о пустых регионах

Цитата

.\linkerscript.sct(13): warning: L6312W: Empty Execution region description for region CCSRAM
.\linkerscript.sct(27): warning: L6312W: Empty Execution region description for region BACKUPSRAM


Может есть какой-нибудь атрибут, чтобы не было этих сообщений? Пробовал EMPTY, но размер ZI-секции увеличивается на размер этих регионов. Т.е. родной __main(), скорее всего, будет писать туда нули. Хотя в описании на EMPTY пишут, что эти области не инициализируются нулем.

P.S. Ну да, не инициализируются. Просто теперь немного напрягает, когда пустой проект имеет

Цитата

Program Size: Code=376 RO-data=408 RW-data=0 ZI-data=71776  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 minutes ago, Arlleex said:

Может есть какой-нибудь атрибут, чтобы не было этих сообщений?

--diag_suppress 6312

 

Только смысл?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что, aaarrr сказал:

Только смысл?

В глазах рябить будет при пересборках, можно чего-то и упустить потом в дальнейшем. У себя считаю хорошим тоном сборку проекта без errors/warnings.

Спасибо, в принципе, подавление предупреждения меня устраивает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 hours ago, kentAVR said:

Вот статья про скетер файл https://habr.com/ru/post/685028/

Всех приглашаю к обсуждению.

Ещё есть свойства файла.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Доброго времени суток!

У меня есть вопрос, той же тематики, но немного другой. Никак не могу разобраться что где как, вижу здесь много знатоков по этой теме.  Подскажите, вопрос связанный со Scatter-файлом, а именно как разместить какой либо код(функцию или переменную, например) по определенному адресу в Keil . Не хватает знаний. Сразу скажу, ответ на вопрос искал на просторах интернета долго, пишу сюда так как недоперло до конца.
Есть Scatter-файл со следующим содержанием:


LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00020000 { ; RW data
.ANY (+RW +ZI)
}
}

прогуглив, я узнал, что: LR_IROM1 – это регион(область) загрузки, ER_IROM1 – это регион(область) выполнения. Я понял так, что область загрузки это область памяти куда будет загружен нами указанный код , в данном примере код будет загружен в область, которая начинается с адреса 0x08000000 размером 0x00080000.

1) Ну что же такое регион(область) выполнения(ER_IROM1 0x08000000 0x00080000 )?

Второй вопрос:
2) Если я дал правильное определение что такое "LR_IROM1", то почему в теле LR_IROM1 прописано RW_IRAM1 0x20000000 0x00020000, ведь эти адреса( 0x20000000 0x00020000) никак не входят в область 0x08000000 0x00080000 ?

 

В 28.08.2022 в 03:34, kentAVR сказал:

Вот статья про скетер файл https://habr.com/ru/post/685028/

Всех приглашаю к обсуждению.

Кстати на не тоже натыкался, но до меня так и не доперло

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...