реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> STM32: как разместить константу только во флеш?, IAR EWARM
Ivan Kuznetzov
сообщение Aug 21 2010, 11:42
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 307
Регистрация: 6-02-08
Из: Россия, Екатеринбург
Пользователь №: 34 798



помнится для авр все было очень просто: пишешь перед переменной __flash и все...
как это сделать на STM32 ?


--------------------
Разработчик
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 21 2010, 12:30
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Используйте модификатор const, остальное сделает линкер.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Aug 21 2010, 12:40
Сообщение #3


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(aaarrr @ Aug 21 2010, 16:30) *
Используйте модификатор const, остальное сделает линкер.

У меня в Кейле был "прецедент", когда простой const не помогал - константа всё равно копировалась в озу.
Выручил static const.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 21 2010, 17:08
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(sonycman @ Aug 21 2010, 16:40) *
У меня в Кейле был "прецедент", когда простой const не помогал - константа всё равно копировалась в озу.

Очень интересно было бы взглянуть.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Aug 21 2010, 21:07
Сообщение #5


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(aaarrr @ Aug 21 2010, 21:08) *
Очень интересно было бы взглянуть.

Вот кусок функции:
Код
void    TagReader::LoadTags(TAG_FILESLOT * sl)
{
    const char tag_v1[] = {'T', 'A', 'G'};
    const char tag_v2[] = {'I', 'D', '3'};
    const char title[] = {'T', 'I', 'T', '2'};
    const char artist[] = {'T', 'P', 'E', '1'};
    ...
    if (!memcmp(buf, tag_v2, sizeof(tag_v2)) ...

генерится такой код:
Код
;;;282    void    TagReader::LoadTags(TAG_FILESLOT * sl)
000000  e92d4ff3          PUSH     {r0,r1,r4-r11,lr}
;;;283    {
000004  4604              MOV      r4,r0
;;;285        
;;;286        const char tag_v1[] = {'T', 'A', 'G'};
000006  a0d1              ADR      r0,|L11.844|
000008  f5ad7d37          SUB      sp,sp,#0x2dc        ;283
00000c  6800              LDR      r0,[r0,#0]
;;;287        const char tag_v2[] = {'I', 'D', '3'};
00000e  90b0              STR      r0,[sp,#0x2c0]
000010  a0cf              ADR      r0,|L11.848|
;;;288        const char title[] = {'T', 'I', 'T', '2'};
;;;289        const char artist[] = {'T', 'P', 'E', '1'};
000012  2140              MOVS     r1,#0x40
000014  6800              LDR      r0,[r0,#0]          ;287
000016  90b1              STR      r0,[sp,#0x2c4]      ;288
000018  a0ce              ADR      r0,|L11.852|
00001a  6800              LDR      r0,[r0,#0]          ;288
00001c  90b2              STR      r0,[sp,#0x2c8]      ;289
00001e  a0ce              ADR      r0,|L11.856|
000020  6800              LDR      r0,[r0,#0]          ;289
000022  90b3              STR      r0,[sp,#0x2cc]      ;290
        ...
;;;330        if (!memcmp(buf, tag_v2, sizeof(tag_v2))
000098  2203              MOVS     r2,#3
00009a  a9b1              ADD      r1,sp,#0x2c4
00009c  68e0              LDR      r0,[r4,#0xc]
00009e  f7fffffe          BL       memcmp
        ...
000346  e8bd8ff0          POP      {r4-r11,pc}
;;;558    
                          ENDP

00034a  0000              DCW      0x0000
                  |L11.844|
00034c  54414700          DCB      "TAG",0
                  |L11.848|
000350  49443300          DCB      "ID3",0
                  |L11.852|
000354  54495432          DCB      "TIT2"
                  |L11.856|
000358  54504531          DCB      "TPE1"

Константы располагаются вместе с кодом.
Как видно, сначала они считываются из флеш в стёк, и уже затем передаются оттуда указателем.
Совершенно лишние действия и растрата стёка.
А если константа будет весить килобайт? Компилер и в этом случае полностью копирует её на стёк! sad.gif.

Но совсем другой вид, когда добавляем static:
Код
;;;282    void    TagReader::LoadTags(TAG_FILESLOT * sl)
000000  e92d4ff3          PUSH     {r0,r1,r4-r11,lr}
;;;283    {
000004  4604              MOV      r4,r0
;;;285        
;;;286        static const char tag_v1[] = {'T', 'A', 'G'};
;;;287        static const char tag_v2[] = {'I', 'D', '3'};
;;;288        static const char title[] = {'T', 'I', 'T', '2'};
;;;289        static const char artist[] = {'T', 'P', 'E', '1'};
000006  2000              MOVS     r0,#0
000008  f5ad7d33          SUB      sp,sp,#0x2cc        ;283
        ...
;;;330        if (!memcmp(buf, tag_v2, sizeof(tag_v2))
000080  2203              MOVS     r2,#3
000082  49bf              LDR      r1,|L11.896|
000084  68e0              LDR      r0,[r4,#0xc]
000086  f7fffffe          BL       memcmp
        ...
000330  f50d7d35          ADD      sp,sp,#0x2d4
000334  e8bd8ff0          POP      {r4-r11,pc}
;;;558    
                          ENDP
                  |L11.896|
                          DCD      ||.constdata||+0x3

                          AREA ||.constdata||, DATA, READONLY, ALIGN=0

                  tag_v1
000000  544147            DCB      0x54,0x41,0x47
                  tag_v2
000003  49                DCB      0x49
000004  4433              DCB      0x44,0x33
                  title
000006  5449              DCB      0x54,0x49
000008  5432              DCB      0x54,0x32
                  artist
00000a  5450              DCB      0x54,0x50
00000c  4531              DCB      0x45,0x31

Вот теперь константы хранятся в своей секции и выбираются прямым указателем без копирования на стёк.

Компилятор RealView 4.1 из uVision 4.10, оптимизация О2.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 21 2010, 21:28
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (sonycman @ Aug 21 2010, 23:07) *
Вот кусок функции:

Собственно, а чего Вы ожидали приписывая этот квалификатор к ЛОКАЛЬНОЙ переменной? Все совершенно нормально - приказали разместить в RAM, но запретили модифицировать.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sonycman
сообщение Aug 21 2010, 21:52
Сообщение #7


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(zltigo @ Aug 22 2010, 01:28) *
Собственно, а чего Вы ожидали приписывая этот квалификатор к ЛОКАЛЬНОЙ переменной? Все совершенно нормально - приказали разместить в RAM, но запретили модифицировать.

Я лишь показал, что одного квалификатора const недостаточно, чтобы все подряд константы стали размещаться только во флеш smile.gif

Однако не находите, какая это глупость - переменная инициализирована и является константой - так какого чёрта её засовывать в ОЗУ?
Недоработка компилятора?
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 21 2010, 22:03
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(sonycman @ Aug 22 2010, 03:52) *
Я лишь показал, что одного квалификатора const недостаточно, чтобы все подряд константы стали размещаться только во флеш smile.gif

Дык это у вас был не "прецедент", а недопонимание в различиях размещения в памяти переменных разных типов. В вашем примере вы создали а) немодицифицируемую б) локальную в) инициализированную г) переменную. А локальные переменные размещаются на стеке или в регистрах, бо время их жизни ограничено необходимостью наличия только внутри функции. Во втором примере тип static дал переменной "неограниченное" время жизни, позволив линкеру разметить ее "на постоянное место жительства" во Flash.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Aug 21 2010, 22:05
Сообщение #9


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(rezident @ Aug 22 2010, 02:03) *
Дык это у вас был не "прецедент", а недопонимание в различиях размещения в памяти переменных разных типов. В вашем примере вы создали а) немодицифицируемую б) локальную в) инициализированную г) переменную.

Ну и почему эта константа должна быть расположена в ОЗУ? Есть рациональное объяснение?
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 21 2010, 22:11
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Я дописал пояснение. См. выше.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Aug 21 2010, 22:15
Сообщение #11


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(rezident @ Aug 22 2010, 02:11) *
Я дописал пояснение. См. выше.

Тут лишь слепое следование стандартному механизму.

Но ведь сейчас компиляторы такие продвинутые, highly optimizing. Тогда для чего копировать константу в ОЗУ?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 21 2010, 22:15
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(sonycman @ Aug 22 2010, 02:05) *
Ну и почему эта константа должна быть расположена в ОЗУ? Есть рациональное объяснение?

Есть, конечно.
Цитата
6.2.4 Storage durations of objects
...
4 An object whose identifier is declared with no linkage and without the storage-class
specifier static has automatic storage duration.
5 For such an object that does not have a variable length array type, its lifetime extends
from entry into the block with which it is associated until execution of that block ends in
any way. (Entering an enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. The initial value of the object is indeterminate. If an
initialization is specified for the object, it is performed each time the declaration is
reached in the execution of the block; otherwise, the value becomes indeterminate each
time the declaration is reached.

То есть стандарт в данном случае прямо предписывает создавать новую копию переменной.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Aug 21 2010, 22:22
Сообщение #13


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(aaarrr @ Aug 22 2010, 02:15) *
То есть стандарт в данном случае прямо предписывает создавать новую копию переменной.

Ну, я и говорю - слепое следование стандарту.
А не рациональное объяснение. Потому что смысла в данном случае - нет.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 21 2010, 22:43
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(sonycman @ Aug 22 2010, 02:22) *
Ну, я и говорю - слепое следование стандарту.
А не рациональное объяснение.

Слепое следование стандарту - это и есть рациональное объяснение. Не должен компилятор заниматься самодеятельностью ни при каких условиях.

Цитата(sonycman @ Aug 22 2010, 02:22) *
Потому что смысла в данном случае - нет.

Почему же? Мало ли, может я хочу создать массив для ускорения вычислений, но ОЗУ жалко, а стека - нет.
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 21 2010, 22:48
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(sonycman @ Aug 22 2010, 04:15) *
Тут лишь слепое следование стандартному механизму.

Но ведь сейчас компиляторы такие продвинутые, highly optimizing. Тогда для чего копировать константу в ОЗУ?

Стандарты для того и придумывают, чтобы описать правила общие для всех. Компиляторы сейчас стараются делать как можно ближе к этому стандарту. Диктуется сие необходимостью устранения недопониманий между желанием человека-программиста и реализацией его желания в командах для конкретной железяки. Язык программирования это средство описания желаний программиста. wink.gif
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 03:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.0148 секунд с 7
ELECTRONIX ©2004-2016