ViKo 1 13 января, 2022 Опубликовано 13 января, 2022 · Жалоба Имею тип - структуру, создаю без инициализации. Хочу при рестарте программы (сброс не по питанию) проверить её содержимое. Далее или работать с ней, или грузить из EEPROM, или задать по умолчанию. Как запретить инициализировать структуру нулями? Что мне нужно в scatter файле задать? Как в программе на нужного типа секцию сослаться? Я вижу в map файле, что и без атрибутов структура попадает в .bss секцию. От чего зависит? Разве глобальные переменные не должны быть забиты нулями? Заодно, как посмотреть, где разместились все переменные? Может, ключи какие-то есть? Вот такие штуки пишу. RW_IRAM1 0x20000000 UNINIT 0x100 { ; 256 RW no init // Interface.o (holding) Interface.o (.bss) } // Holding_t Holding __attribute__((section("holding"))); // Holding_t Holding __attribute__((section(".bss"))); Holding_t Holding; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 13 января, 2022 Опубликовано 13 января, 2022 · Жалоба RW_IRAM1 0x20000000 UNINIT 0x100 { Interface.o (.bss.structUninit) } __attribute__((section(".bss.structUnint"))) Holding_t Holding; 1 час назад, ViKo сказал: Я вижу в map файле, что и без атрибутов структура попадает в .bss секцию. От чего зависит? .bss - это секция, куда попадают данные без явной инициализации. Глобальные переменные без инициализации согласно Си-стандарту инициализируются нулем. Соответственно, они будут помещены в .bss (потому что без инициализации), но неявно будут занулены. Значит, .bss - секция с занулением данных. Внутри .bss можно создать "подсекцию" (.bss.structUninit, например) - и, указав в скрипте линкера UNINIT, заставить не инициализировать переменные этой секции. 1 час назад, ViKo сказал: Заодно, как посмотреть, где разместились все переменные? Может, ключи какие-то есть? В map-файле. И еще: версия компилятора какая? 5 или 6? Там есть различия в синтаксисах. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 13 января, 2022 Опубликовано 13 января, 2022 · Жалоба Компилятор 6.16, а то. В map и смотрю. Добавить нужной информации, видимо, не получится. Вот пример, что есть в map. Exec Addr Load Addr Size Type Attr Idx E Section Name Object 0x20000000 - 0x00000060 Zero RW 159 .bss c_p.l(libspace.o) 0x20000060 - 0x00000008 Zero RW 57 .bss.AdcData adc.o Судя по пропуску в Load Addr, AdcData не инициализируется. Но нулями забиваются? Ясно. Утром пробовал (.bss.holding), не получалось чего-то. Сейчас сработало. Exec Addr Load Addr Size Type Attr Idx E Section Name Object 0x20000000 - 0x00000040 Zero RW 156 .bss.holding interface.o И никак не разобрать, забивается нулями или нет? И секцию эту по каким адресам логичнее разместить? Вопрос еще один. Как EEPROM описать? Сам Keil в свойствах МК никак эту память не показывает. По крайней мере у меня. Я не использую из Run-Time Environment практически ничего. Так годится? RW_IEEPROM 0x08080000 0x07FF { ; 2K EEPROM Interface.o (backup) } Что там в скобках приписать: (+RW) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 13 января, 2022 Опубликовано 13 января, 2022 · Жалоба Или для EEPROM мне нужно новый LR задать в скаттер-файле? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 13 января, 2022 Опубликовано 13 января, 2022 · Жалоба 31 минуту назад, ViKo сказал: Exec Addr Load Addr Size Type Attr Idx E Section Name Object 0x20000000 - 0x00000060 Zero RW 159 .bss c_p.l(libspace.o) 0x20000060 - 0x00000008 Zero RW 57 .bss.AdcData adc.o Судя по пропуску в Load Addr, AdcData не инициализируется. Но нулями забиваются? Ясно. Не совсем корректно "не инициализируется". Инициализируется, просто не явно. Да, нулями. Load Addr пустой, потому как не имеет смысла хранить 0. Цитата Exec Addr Load Addr Size Type Attr Idx E Section Name Object 0x20000000 - 0x00000040 Zero RW 156 .bss.holding interface.o И никак не разобрать, забивается нулями или нет? Да, не разобрать. Из этого описания видно лишь, что помещена в .bss.holding, но теперь, чтобы понять точно - нужно лезть в скрипт линкера. Цитата И секцию эту по каким адресам логичнее разместить? Вам виднее, ваш проект же Цитата Вопрос еще один. Как EEPROM описать? Какую EEPROM? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 13 января, 2022 Опубликовано 13 января, 2022 · Жалоба 1 минуту назад, Arlleex сказал: Вам виднее, ваш проект же Какую EEPROM? Я в начало ОЗУ забросил. Логичнее разместить после инициализируемых переменных, чтобы все разом обнулить. Но в конце же стек. EEPROM - встроенная в STM32L051K8. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 13 января, 2022 Опубликовано 13 января, 2022 · Жалоба 20 минут назад, ViKo сказал: Я в начало ОЗУ забросил. Логичнее разместить после инициализируемых переменных, чтобы все разом обнулить... Далеко не факт, что разные ZI-секции "разом" обнулятся - на усмотрении средств сборки Цитата Но в конце же стек. Тоже можно перетащить в начало - да хоть куда. В начало даже лучше - настраиваем MPU на отлов доступа ниже начала ОЗУ и аппаратный overflow-контроль на руках. Насчет EEPROM - можете описать как еще один execution region в том же load region, где описаны другие, и в нем определить .eeprom-секцию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 14 января, 2022 Опубликовано 14 января, 2022 · Жалоба я делал так (для Keil 4) // pragma запрещает начальную инициализацию #pragma arm section zidata = "non_initialized" unsigned char SensorRecordsArray[4096]; #pragma arm section zidata Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 14 января, 2022 Опубликовано 14 января, 2022 · Жалоба #pragma clang section In Arm Compiler 5, the section types you can use this pragma with are rodata, rwdata, zidata, and code. In Arm Compiler 6, the equivalent section types are rodata, data, bss, and text respectively. Но так не делаются неинициализируемые нулями переменные. Может, в Keil 4 делались, не могу знать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 14 января, 2022 Опубликовано 14 января, 2022 (изменено) · Жалоба Все правильно, я немного ступил. Массив размещался в области FLASH, а прагма позволяла использовать его как обычный массив для чтения, при этом начальная инициализация массива не проводилась. Но на сайте KEIL подход как у вас, через секцию. https://www.keil.com/support/man/docs/armcc/armcc_chr1359124243221.htm Изменено 14 января, 2022 пользователем Edit2007 Доп.информация Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 14 января, 2022 Опубликовано 14 января, 2022 · Жалоба А вот, чтобы EEPROM описать, и подключить алгоритм программирования в Keil. И он автоматом запрограммирует свою EEPROM? Надо только в SystemInit инициализировать EEPROM. Правильно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 17 января, 2022 Опубликовано 17 января, 2022 · Жалоба Если вы из KEIL хотите запрограммировать EEPROM то смотреть надо в сторону создания *.flm файлов (это по сути алгоритм загрузки файла в МК). Но могут быть проблемы с верификацией записи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 18 января, 2022 Опубликовано 18 января, 2022 · Жалоба 17.01.2022 в 12:06, Edit2007 сказал: Если вы из KEIL хотите запрограммировать EEPROM то смотреть надо в сторону создания *.flm файлов (это по сути алгоритм загрузки файла в МК). Но могут быть проблемы с верификацией записи. Уже не хочу. Но, я думаю, всё бы сохранилось в *.hex файле. По адресу EEPROM лежали бы нужные данные. А алгоритм программирования EEPROM я задал в настройках Keil. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться