pyroman 2 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба У меня, правда, в EWAVR компилятор выбрасывает обращение к volatile переменной, размещённой в ОЗУ, на high-оптимизации. Вот этот прикол я тоже не понял... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KSN 0 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба Доброго дня. Использую такой подход: // configData размещается во flash памяти. #pragma section "FLASH" #pragma location = "FLASH" __root const SettingStruct configData = { /*начальные значения элементов структуры SettingStruct*/}; // Объявляю указатель на структуру. Указатель размещается в RAM. SettingStruct *toConfig; void main() { // Инициализация указателя. toConfig = (SettingStruct*)&configData; .... } Доступ к значению во flash: toConfig->... Изменение значений: через процедуру перезаписи страницы flash памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба 6 minutes ago, KSN said: Использую такой подход: А я вот выше показал, что у меня такой подход с включенной оптимизацией balanced или speed не приводит к результату. Даже если указатель на структуру объявлен со словом volatile. Данные из флеши читаются, да. Но не используются. Что не противоречит стандарту. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба Ну тогда пусть линкер считает, что это RW область, а адреса подпихните из нужной области Flash. Объявите структуру const volatile, и тогда эта банда компилятор с линкером будут бессильны против Вашей воли. Для этого лучше будет объявить отдельный регион памяти (не знаю насчет IAR), и разместить в root-секции этот массив, чтобы rw_copy() не распространялся на эту область. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба 1 minute ago, Arlleex said: Ну тогда пусть линкер считает, что это RW область, а адреса подпихните из нужной области Flash. Всё же выходит, что поставленная проблема в топике - нетривиальная?)))) Интересно бы ещё услышать, что уважаемый @jcxz скажет))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба 31 минуту назад, haker_fox сказал: Всё же выходит, что поставленная проблема в топике - нетривиальная?)))) Видите ли в чем штука, тут нужно знать/иметь опыт специфики взаимодействия компилятора и линкера конкретно у IAR. Тут далеко не каждый в курсе каких-то особенностей Потому что в силу наворотов для улучшения оптимизации (а ведь смотрите как он наоптимизировал функции, в другом случае это был бы огромный плюс!), будут появляться "дыры", "заплатки", для устранения такой оптимизации. Однозначно, к Си это не имеет отношения, поэтому где-то в дебрях документации IAR, собранная по кусочкам информация даст картину, которая будет согласована с реальностью, которую Вы наблюдаете)) P.S. А еще можно попробовать поместить эту структуру в отдельную единицу трансляции (сишник), объявить в нужных местах (extern) и отключить LTO, если была включена. Не забыть только про extern const volatile struct ... {} = {}, а то в плюсах для глобального объекта const имеет внутреннюю связь(( 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KSN 0 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба У меня в icf файле область памяти для размещение констант вынесена из общего объема, который может использовать IAR как ему вздумается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pyroman 2 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба DECLARING OBJECTS VOLATILE AND CONST If you declare a volatile object const, it will be write-protected but it will still be stored in RAM memory as the C standard specifies. To store the object in read-only memory instead, but still make it possible to access it as a const volatile object, declare it with the __ro_placement attribute. See __ro_placement, page 371. To store the object in read-only memory instead, but still make it possible to access it as a const volatile object, define the variable like this: const volatile int x @ "FLASH"; The compiler will generate the read/write section FLASH. That section should be placed in ROM and is used for manually initializing the variables when the application starts up. Thereafter, the initializers can be reflashed with other values at any time. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vit496 0 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба 3 hours ago, haker_fox said: Всё же выходит, что поставленная проблема в топике - нетривиальная?)))) да как-то не было проблем. Делаю так *.icf: define region sect_region = mem:[from 0x08070000 to 0x08077FFF]; place in sect_region { section sect }; *.c: #define fix_rom _Pragma("location=\"sect\"") fix_rom const uint8_t arr[] = { .... }; читать uint32_t x = *(volatile uint32_t*) 0x08070000; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба 2 часа назад, pyroman сказал: If you declare a volatile object const, it will be write-protected but it will still be stored in RAM memory as the C standard specifies. Какую же только ерунду не выдумают, однако. Немцы уже и про стандарт нафантазировали, но хорошо, что хотя бы задокументировали у себя. 9 минут назад, vit496 сказал: fix_rom const uint8_t arr[] = { .... }; читать uint32_t x = *(volatile uint32_t*) 0x08070000; Во-первых, у ТС там лежит структура, к которой обращаться всяко приятнее, чем к непонятно что значащим элементам неких uint32_t. Во-вторых, повторюсь, это потенциально кривой способ, т.к. при банальной смене распределения памяти все уедет и по новой сиди адреса правь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 231 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба 4 часа назад, haker_fox сказал: Всё же выходит, что поставленная проблема в топике - нетривиальная?)))) Да вроде - ничего там сложного. 4 часа назад, haker_fox сказал: Интересно бы ещё услышать, что уважаемый @jcxz скажет))) Сорри - весь топик не читал, нет времени, но по проблеме из первого поста, первое что бросается в глаза - я не вижу у Вас в скрипте компоновщика задания способа инициализации для секции ".calInfo". Я бы сделал примерно так: __packed struct GeneralCal { u16 z0; u16 z1; u16 z2; u16 z3; bool calibrated; }; __packed struct CalInfo { GeneralCal general; u16 tbl[4096]; }; __root CalInfo volatile const calInfo @ ".calInfo" = {3502, 3318, 369, 184, false}; .icf: define region FLASHC_regionB = mem:[from 0x08140000 to 0x0817FFFF]; //PMU/FLASH (cached) ... do not initialize {section .calInfo}; ... place in FLASHC_regionB {section .calInfo}; результат (.map): "P2": place in [from 0x08140000 to 0x0817ffff] { section .calInfo }; ... Section Kind Address Size Object ------- ---- ------- ---- ------ "P2": 0x200c P2-1 0x08140000 0x200c <Init block> .calInfo inited 0x08140000 0x200c main.o [1] - 0x0814200c 0x200c ... calInfo 0x08140000 0x200c Data Lc main.o [1] .lst: Спойлер In section .calInfo, align 4, root 00000000 0x0DAE 0x0CF6 DC16 3502, 3318, 369, 184 0x0171 0x00B8 00000008 0x00 DC8 0 00000009 0x0000 0x0000 DC16 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 00000035 0x0000 0x0000 DC16 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 00000061 0x0000 0x0000 DC16 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 ... Как видно - всё ок. И никаких ошибок или варнингов при компиляции. PS: IAR v7.80.4 for ARM. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 231 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба PPS: код: if (calInfo.general.calibrated) Pset(PIN_LED1); else Pclr(PIN_LED1); его .lst: if (calInfo.general.calibrated) Pset(PIN_LED1); 0x.... LDR.N R2,??DataTable16_30 0x.... LDR.N R0,??DataTable16_4 ;; 0x48028000 0x7A12 LDRB R2,[R2, #+8] 0xF200 0x5004 ADDW R0,R0,#+1284 0xF44F 0x7100 MOV R1,#+512 0x2A00 CMP R2,#+0 0xBF14 ITE NE 0x8001 STRHNE R1,[R0, #+0] 0x8041 STRHEQ R1,[R0, #+2] else Pclr(PIN_LED1); ... In section .text, align 4, keep-with-next ??DataTable16_30: 0x........ DC32 calInfo Как видно - и читается и используется в коде calInfo.general.calibrated правильно. Скомпилено это с максимальной оптимизацией (balanced). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба 1 hour ago, vit496 said: читать uint32_t x = *(volatile uint32_t*) 0x08070000 А где красота кода? Оперировать в сишнике адресами - дурной тон, ИМХО. Для этого линкер есть. 1 hour ago, Arlleex said: т.к. при банальной смене распределения памяти все уедет и по новой сиди адреса правь. Угу) 45 minutes ago, jcxz said: я не вижу у Вас в скрипте компоновщика задания способа инициализации для секции ".calInfo". Ух, спасибо! Я чувствовал, что у Вас будет индивидуальный рецепт, как всегда💗 Завтра буду пробовать на работе) 29 minutes ago, jcxz said: Как видно - и читается и используется в коде calInfo.general.calibrated правильно. Это внушает надежду!🤝🙏 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jack_avenger 4 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба Обычно в подобных случаях меня выручал вариант вида: return *((bool*)(&calInfo.general.calibrated)); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 231 24 августа, 2023 Опубликовано 24 августа, 2023 · Жалоба 12 минут назад, jack_avenger сказал: Обычно в подобных случаях меня выручал вариант вида: return *((bool*)(&calInfo.general.calibrated)); Это неверный вариант. Не выручит. Если конечно не держать оптимизацию всё время выключенной. Но мы же не колхозники - мы так не делаем, правда? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться