yakuzaa 0 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба помнится для авр все было очень просто: пишешь перед переменной __flash и все... как это сделать на STM32 ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба Используйте модификатор const, остальное сделает линкер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба Используйте модификатор const, остальное сделает линкер. У меня в Кейле был "прецедент", когда простой const не помогал - константа всё равно копировалась в озу. Выручил static const. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба У меня в Кейле был "прецедент", когда простой const не помогал - константа всё равно копировалась в озу. Очень интересно было бы взглянуть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба Очень интересно было бы взглянуть. Вот кусок функции: 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба Вот кусок функции: Собственно, а чего Вы ожидали приписывая этот квалификатор к ЛОКАЛЬНОЙ переменной? Все совершенно нормально - приказали разместить в RAM, но запретили модифицировать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба Собственно, а чего Вы ожидали приписывая этот квалификатор к ЛОКАЛЬНОЙ переменной? Все совершенно нормально - приказали разместить в RAM, но запретили модифицировать. Я лишь показал, что одного квалификатора const недостаточно, чтобы все подряд константы стали размещаться только во флеш :) Однако не находите, какая это глупость - переменная инициализирована и является константой - так какого чёрта её засовывать в ОЗУ? Недоработка компилятора? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба Я лишь показал, что одного квалификатора const недостаточно, чтобы все подряд константы стали размещаться только во флеш :) Дык это у вас был не "прецедент", а недопонимание в различиях размещения в памяти переменных разных типов. В вашем примере вы создали а) немодицифицируемую б) локальную в) инициализированную г) переменную. А локальные переменные размещаются на стеке или в регистрах, бо время их жизни ограничено необходимостью наличия только внутри функции. Во втором примере тип static дал переменной "неограниченное" время жизни, позволив линкеру разметить ее "на постоянное место жительства" во Flash. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба Дык это у вас был не "прецедент", а недопонимание в различиях размещения в памяти переменных разных типов. В вашем примере вы создали а) немодицифицируемую б) локальную в) инициализированную г) переменную. Ну и почему эта константа должна быть расположена в ОЗУ? Есть рациональное объяснение? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба Я дописал пояснение. См. выше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба Я дописал пояснение. См. выше. Тут лишь слепое следование стандартному механизму. Но ведь сейчас компиляторы такие продвинутые, highly optimizing. Тогда для чего копировать константу в ОЗУ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба Ну и почему эта константа должна быть расположена в ОЗУ? Есть рациональное объяснение? Есть, конечно. 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. То есть стандарт в данном случае прямо предписывает создавать новую копию переменной. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба То есть стандарт в данном случае прямо предписывает создавать новую копию переменной. Ну, я и говорю - слепое следование стандарту. А не рациональное объяснение. Потому что смысла в данном случае - нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба Ну, я и говорю - слепое следование стандарту. А не рациональное объяснение. Слепое следование стандарту - это и есть рациональное объяснение. Не должен компилятор заниматься самодеятельностью ни при каких условиях. Потому что смысла в данном случае - нет. Почему же? Мало ли, может я хочу создать массив для ускорения вычислений, но ОЗУ жалко, а стека - нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 21 августа, 2010 Опубликовано 21 августа, 2010 · Жалоба Тут лишь слепое следование стандартному механизму. Но ведь сейчас компиляторы такие продвинутые, highly optimizing. Тогда для чего копировать константу в ОЗУ? Стандарты для того и придумывают, чтобы описать правила общие для всех. Компиляторы сейчас стараются делать как можно ближе к этому стандарту. Диктуется сие необходимостью устранения недопониманий между желанием человека-программиста и реализацией его желания в командах для конкретной железяки. Язык программирования это средство описания желаний программиста. ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться