Darth Vader 0 15 мая, 2020 Опубликовано 15 мая, 2020 · Жалоба Задача - разместить объект (контрольная сумма 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 файле? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 15 мая, 2020 Опубликовано 15 мая, 2020 · Жалоба 27 minutes ago, Darth Vader said: Получается другая ерунда - секция размещается слишком далеко - по адресу 0х00001090 (см. Size для LR_IROM1). Загадочные данные - это упакованное содержимое RW-секций. Последний вариант sct правильный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 16 мая, 2020 Опубликовано 16 мая, 2020 · Жалоба 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. Как такое сделать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 16 мая, 2020 Опубликовано 16 мая, 2020 · Жалоба 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) } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 17 мая, 2020 Опубликовано 17 мая, 2020 · Жалоба 18 часов назад, aaarrr сказал: а если так: Тогда регион ER_IROM2 с секцией CODE_CRC32 размещаются в адресном пространстве сразу после RW_IRAM2, а это область ОЗУ, а не флеш. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 17 мая, 2020 Опубликовано 17 мая, 2020 · Жалоба Просмотрел многочисленные scat'ы, которые когда-то сочинял - принудительное размещение секций использовал только по фиксированным адресам, а CRC располагал в начале прошивки (подозреваю, не случайно). По логике, правильным должен быть ваш второй вариант, наблюдаемое поведение похоже на глюк линкера. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 17 июля, 2020 Опубликовано 17 июля, 2020 · Жалоба Коллеги, приветствую! Подскажите пожалуйста, если у меня в регионе размещено 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 региона отдельных создавать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 17 июля, 2020 Опубликовано 17 июля, 2020 · Жалоба 3 minutes ago, Arlleex said: Что теперь, 2 региона отдельных создавать? В данном конкретном случае достаточно будет дописать +First к .intvec Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 17 июля, 2020 Опубликовано 17 июля, 2020 · Жалоба 6 минут назад, aaarrr сказал: В данном конкретном случае достаточно будет дописать +First к .intvec Сейчас даже сам себя носом ткну, где об этом написано. Спасибо =) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 1 декабря, 2021 Опубликовано 1 декабря, 2021 · Жалоба И снова здравствуйте. Решил для своего проекта на 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 1 декабря, 2021 Опубликовано 1 декабря, 2021 · Жалоба 8 minutes ago, Arlleex said: Может есть какой-нибудь атрибут, чтобы не было этих сообщений? --diag_suppress 6312 Только смысл? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 1 декабря, 2021 Опубликовано 1 декабря, 2021 · Жалоба Только что, aaarrr сказал: Только смысл? В глазах рябить будет при пересборках, можно чего-то и упустить потом в дальнейшем. У себя считаю хорошим тоном сборку проекта без errors/warnings. Спасибо, в принципе, подавление предупреждения меня устраивает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kentAVR 0 28 августа, 2022 Опубликовано 28 августа, 2022 · Жалоба Вот статья про скетер файл https://habr.com/ru/post/685028/ Всех приглашаю к обсуждению. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 35 28 августа, 2022 Опубликовано 28 августа, 2022 · Жалоба 7 hours ago, kentAVR said: Вот статья про скетер файл https://habr.com/ru/post/685028/ Всех приглашаю к обсуждению. Ещё есть свойства файла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maksimdag0 0 18 февраля Опубликовано 18 февраля · Жалоба Доброго времени суток! У меня есть вопрос, той же тематики, но немного другой. Никак не могу разобраться что где как, вижу здесь много знатоков по этой теме. Подскажите, вопрос связанный со 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/ Всех приглашаю к обсуждению. Кстати на не тоже натыкался, но до меня так и не доперло Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться