|
STM32: как разместить константу только во флеш?, IAR EWARM |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 20)
|
Aug 21 2010, 21:07
|

Любитель
    
Группа: Свой
Сообщений: 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" Константы располагаются вместе с кодом. Как видно, сначала они считываются из флеш в стёк, и уже затем передаются оттуда указателем. Совершенно лишние действия и растрата стёка. А если константа будет весить килобайт? Компилер и в этом случае полностью копирует её на стёк!  . Но совсем другой вид, когда добавляем 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.
|
|
|
|
|
Aug 21 2010, 22:15
|
Гуру
     
Группа: Свой
Сообщений: 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. То есть стандарт в данном случае прямо предписывает создавать новую копию переменной.
|
|
|
|
|
Aug 21 2010, 22:43
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Aug 22 2010, 02:22)  Ну, я и говорю - слепое следование стандарту. А не рациональное объяснение. Слепое следование стандарту - это и есть рациональное объяснение. Не должен компилятор заниматься самодеятельностью ни при каких условиях. Цитата(sonycman @ Aug 22 2010, 02:22)  Потому что смысла в данном случае - нет. Почему же? Мало ли, может я хочу создать массив для ускорения вычислений, но ОЗУ жалко, а стека - нет.
|
|
|
|
|
Aug 21 2010, 22:50
|

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

|
Цитата(aaarrr @ Aug 22 2010, 02:43)  Слепое следование стандарту - это и есть рациональное объяснение. Которое в данном случае приводит к иррациональным действиям - пустой трате процессорного времени и памяти. Не в этом ли смысл оптимизации? Цитата(aaarrr @ Aug 22 2010, 02:43)  Почему же? Мало ли, может я хочу создать массив для ускорения вычислений, но ОЗУ жалко, а стека - нет. Тут не понял - стёка нет, но массив то копируется именно на него? ЗЫ: а, дошло  В этом случае, действительно, может быть прок от такого массива. Но я бы тогда просто убрал const.
|
|
|
|
|
Aug 21 2010, 22:53
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Aug 22 2010, 02:50)  Которое в данном случае приводит к иррациональным действиям - пустой трате процессорного времени и памяти. Не в этом ли смысл оптимизации? Так ведь вы сами попросили сделать именно так, а не иначе. Цитата(sonycman @ Aug 22 2010, 02:50)  Тут не понял - стёка нет, но массив то копируется именно на него? Имелось в виду, что стека не жалко.
|
|
|
|
|
Aug 21 2010, 23:08
|

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

|
Цитата(aaarrr @ Aug 22 2010, 03:04)  Да, каюсь, мне как-то и в голову не пришло, что речь может идти и о локальной переменной. Ну, и мне тогда в голову не могло прийти, что будет такая ахинея благодаря стандарту. Надеюсь, автор топика, также, как и я, почерпнёт отсюда пригоршню полезной информации
|
|
|
|
|
Aug 22 2010, 10:33
|

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

|
Это ладно, когда переменные по 1-2 кбайт. Вот у меня OGG/VORBIS плагин для диктофона на vs1053 весит 24 кило!!! Проблему я решил, так: сначала перевел плагин в бинарник, залил на SD карту полученный файл, и считывал с помощью FatFs-ки загружая его в вс-ку по 4 байта, очень удобненько кстати. Теперь запихал этот плагин во внешнюю флешку M25P64. Плагины, которые я нашел на сайте VLSI, очень даже немаленькие, особенно те, что для кодирования ворбиса. Такчто размещать 24 лишних кило в прошивке микроконтроллера - для моего случая не вариант.
Сообщение отредактировал Ivan Kuznetzov - Aug 22 2010, 10:35
--------------------
Разработчик
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|