Jump to content
    

IAR 9.30.1, как запретить оптимизировать чтение из FLASH?

У меня, правда, в EWAVR компилятор выбрасывает обращение к volatile переменной, размещённой в ОЗУ, на high-оптимизации. Вот этот прикол я тоже не понял...

Share this post


Link to post
Share on other sites

Доброго дня. Использую такой подход:

// configData размещается во flash памяти.

#pragma section "FLASH"

#pragma location = "FLASH"

__root const SettingStruct configData = { /*начальные значения элементов структуры SettingStruct*/};

// Объявляю указатель на структуру. Указатель размещается в RAM.

SettingStruct *toConfig;

void main()

{

// Инициализация указателя.

toConfig = (SettingStruct*)&configData;

....

}

Доступ к значению во flash: toConfig->...

Изменение значений: через процедуру перезаписи страницы flash памяти.

Share this post


Link to post
Share on other sites

6 minutes ago, KSN said:

Использую такой подход:

А я вот выше показал, что у меня такой подход с включенной оптимизацией balanced или speed не приводит к результату. Даже если указатель на структуру объявлен со словом volatile. Данные из флеши читаются, да. Но не используются. Что не противоречит стандарту.

Share this post


Link to post
Share on other sites

Ну тогда пусть линкер считает, что это RW область, а адреса подпихните из нужной области Flash.

Объявите структуру const volatile, и тогда эта банда компилятор с линкером будут бессильны против Вашей воли.

Для этого лучше будет объявить отдельный регион памяти (не знаю насчет IAR), и разместить в root-секции этот массив, чтобы rw_copy() не распространялся на эту область.

Share this post


Link to post
Share on other sites

1 minute ago, Arlleex said:

Ну тогда пусть линкер считает, что это RW область, а адреса подпихните из нужной области Flash.

Всё же выходит, что поставленная проблема в топике - нетривиальная?))))

 

Интересно бы ещё услышать, что уважаемый @jcxz скажет)))

Share this post


Link to post
Share on other sites

31 минуту назад, haker_fox сказал:

Всё же выходит, что поставленная проблема в топике - нетривиальная?))))

Видите ли в чем штука, тут нужно знать/иметь опыт специфики взаимодействия компилятора и линкера конкретно у IAR. Тут далеко не каждый в курсе каких-то особенностей:smile:

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

Однозначно, к Си это не имеет отношения, поэтому где-то в дебрях документации IAR, собранная по кусочкам информация даст картину, которая будет согласована с реальностью, которую Вы наблюдаете))

P.S. А еще можно попробовать поместить эту структуру в отдельную единицу трансляции (сишник), объявить в нужных местах (extern) и отключить LTO, если была включена.

Не забыть только про extern const volatile struct ... {} = {}, а то в плюсах для глобального объекта const имеет внутреннюю связь((

Share this post


Link to post
Share on other sites

У меня в icf файле область памяти для размещение констант вынесена из общего объема, который может использовать IAR как ему вздумается.

image.thumb.png.d5f2b1128690a34da826eb44105fbc11.png

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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;

Share this post


Link to post
Share on other sites

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.
Во-вторых, повторюсь, это потенциально кривой способ, т.к. при банальной смене распределения памяти все уедет и по новой сиди адреса правь.

Share this post


Link to post
Share on other sites

4 часа назад, haker_fox сказал:

Всё же выходит, что поставленная проблема в топике - нетривиальная?))))

Да вроде - ничего там сложного.  :wink2:

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.

Share this post


Link to post
Share on other sites

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).

Share this post


Link to post
Share on other sites

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 правильно.

Это внушает надежду!🤝🙏

Share this post


Link to post
Share on other sites

12 минут назад, jack_avenger сказал:

Обычно в подобных случаях меня выручал вариант вида: 

return *((bool*)(&calInfo.general.calibrated));

Это неверный вариант. Не выручит.

Если конечно не держать оптимизацию всё время выключенной. Но мы же не колхозники - мы так не делаем, правда?  :sarcastic:

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...