|
Как не звать __aeabi_idiv и иже сними? |
|
|
|
Dec 9 2010, 11:59
|

Частый гость
 
Группа: Свой
Сообщений: 179
Регистрация: 1-10-07
Из: НЧ
Пользователь №: 30 966

|
Есть код Код ... volatile int d = 100; volatile int k = 11; volatile int q = d / k; ... Компилятор (EWARM6101) при любом из уровней оптимизации компилирует это как Код volatile int d = 100; MOV R1,#+100 STR R1,[SP, #+4] volatile int k = 11; MOV R1,#+11 STR R1,[SP, #+0] 65 volatile int q = d / k; ^ LDR R0,[SP, #+4] LDR R1,[SP, #+0] BL __aeabi_idiv STR R0,[SP, #+8] Как заставить его не использовать __aeabi_idiv?
|
|
|
|
|
Dec 9 2010, 20:11
|

Частый гость
 
Группа: Свой
Сообщений: 179
Регистрация: 1-10-07
Из: НЧ
Пользователь №: 30 966

|
Так и думал что в волатиле начнут носом тыкать  Ну тогда по порядку - волатиле написал сознательно, чтоб компилятор не проявлял чудеса оптимизМА и не посчитал мне это выражение на этапе компиляции  Интересует конкретно вопрос как его заставить не использовать __aeabi_idiv а скомпилировать деление прям в функцию. Вот, например (пример из пальца выососан сразу предупреждаю), - есть функция, она выполняется из рамки (RAM) и затирает скажем внутреннюю флэш.. в функции считается страница ( / ) и смещение ( % ) - и тут компилятор решил выпендриться и использовать для деления __aeabi_idiv, вместо того чтобы честно скомпилировать нужный код, __aeabi_idiv ессно лежит в стираемой флэше..вот такая вот загогулина... Да, я конечно, понимаю что можно вю библиотеку используемых компилятором функций запихнуть в рамку и проблемы вроде как бы не станет - но интересует именно как заставить его их не использовать...
|
|
|
|
|
Dec 10 2010, 08:06
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
QUOTE (kosyak© @ Dec 9 2010, 22:11)  Интересует конкретно вопрос как его заставить не использовать __aeabi_idiv а скомпилировать деление прям в функцию. Вы не указали архитектуру. Если это ARM7TDMI-S, то функция __aeabi_idiv вместе с __aeabi_idivmod занимает 332 байта (Code Sourcery Lite). При таком размере компилятор её не проинлайнит. QUOTE (kosyak© @ Dec 9 2010, 22:11)  Вот, например (пример из пальца выососан сразу предупреждаю), - есть функция, она выполняется из рамки (RAM) и затирает скажем внутреннюю флэш.. в функции считается страница ( / ) и смещение ( % ) - и тут компилятор решил выпендриться и использовать для деления __aeabi_idiv, вместо того чтобы честно скомпилировать нужный код, __aeabi_idiv ессно лежит в стираемой флэше..вот такая вот загогулина... Если размер Вашей страницы не является константой и не кратен степени двойки, то ничего удивительного в поведении компилятора нет.
|
|
|
|
|
Dec 10 2010, 08:23
|

Частый гость
 
Группа: Свой
Сообщений: 179
Регистрация: 1-10-07
Из: НЧ
Пользователь №: 30 966

|
Ну тогда дополню картину: Стоит датафлэш AT45DBxxx (именно xxx), перепрошивка осуществляется через эту флэш - т.е. сперва полный бинарь записывается в нее, а потом, если все хорошо, камень перепрошивается. Вот тут и возник прикол с __aeabi_idiv. Я прекрасно понимаю что можно написать загручик который будет полностью работает в рамке и проблема снимется.... Предвосхищая вопросы - питание у устройства аккумуляторное. Да и вообще - сейчас это уже больше академический интерес  .
|
|
|
|
|
Dec 10 2010, 09:39
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
Мда..... так и знал  Все делается через маску и сдвиг Код #define ADDR_TO_SECTOR_NUMBER(x) ((x) >> 9) //for page == 512 bytes
#define ADDR_TO_PAGE_OFFSET(x) ((x) & 0x1FFu) //for page == 512 bytes
|
|
|
|
|
Dec 10 2010, 09:45
|

Частый гость
 
Группа: Свой
Сообщений: 179
Регистрация: 1-10-07
Из: НЧ
Пользователь №: 30 966

|
Цитата(kosyak© @ Dec 10 2010, 11:23)  ... Стоит датафлэш AT45DBxxx (именно xxx) ... Тем что "(именно xxx)" я хотел подчеркнуть, что на этапе компиляции я не знаю какую флэш поставят. Соответственно не знаю размер страницы... Мало того, сейчас стали приходить dataflash, у которых размер страницы - степень двойки... раньше у атмела в этих флэшах страница была с аппендиксом и ее размер не был равен степени двойки  .
|
|
|
|
|
Dec 10 2010, 09:53
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
И какие с этим проблемы ? Глава 14. Manufacturer and Device ID Read Изучайте мат часть Цитата степень двойки... раньше у атмела в этих флэшах страница была с аппендиксом и ее размер не был равен степени двой По моему вы вобще мануал не читали или не умеете
|
|
|
|
|
Dec 10 2010, 10:04
|

Частый гость
 
Группа: Свой
Сообщений: 179
Регистрация: 1-10-07
Из: НЧ
Пользователь №: 30 966

|
Ладно - цитирую мануал: User Configurable Page Size – 256-Bytes per Page – 264-Bytes per Page – Page Size Can Be Factory Pre-configured for 256-Bytes Не предлагайте мне сконфигурировать микросхему чтоб размер страницы стал кратен степени 2! как это сделать я знаю сам! Прочитайте еще раз название темы... и забудте Вы про конкретное применение этого кода! Еще раз, специально для Вас ув. MALLOY2, Как заставить компилятор IAR EWARM6101 инлайнить функции вида __aeabi_idiv? Эх...не успел... предложили сконфигурировать в степень двойки  ((
|
|
|
|
|
Dec 10 2010, 10:20
|

Частый гость
 
Группа: Свой
Сообщений: 179
Регистрация: 1-10-07
Из: НЧ
Пользователь №: 30 966

|
Ну...еще раз скажу - вопрос не про конкретное применение операции деления! Цитата(MALLOY2 @ Dec 10 2010, 13:15)  ... когда размер страницы равен 528 байт, то страница всен равно хранит 512 байт информации и остаток используется для контрольной суммы и/или востановления информации ... О_о кем используется остаток? Как "все равно" хранит 512 байт? Это сейчас о чем?
|
|
|
|
|
Dec 10 2010, 10:42
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Согласен, что случай, когда код прошивки флэш должен быть в ОЗУ, весьма актуален. Насколько я знаю, у компилятора нет настроек, позволяющих гарантировать, что кусок кода, скопированный в ОЗУ, не будет вызывать функции из флэш. Можно, конечно, подрихтовать код "ручками", но нет гарантии, что при переходе на новую версию компилятора или при смене его настроек не придётся рихтовать код снова. Чтобы это гарантировать, нужно оформить код в ОЗУ как самостоятельный проект, полностью размещённый в ОЗУ. Для связи с основной прошивкой можно придумать простенький ABI: таблица указателей на функции. Забыл добавить: или писать код в ОЗУ на ассемблере.
|
|
|
|
|
Dec 11 2010, 21:08
|
Местный
  
Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219

|
QUOTE (kosyak© @ Dec 9 2010, 15:59)  Есть код ... Как заставить его не использовать __aeabi_idiv? Ну, например, можно сделать так CODE #define D 100 #define K 11 #define Q D/K ... volatile int d = D; volatile int k = K; volatile int q = Q; ... Или нет?
Сообщение отредактировал IgorKossak - Dec 11 2010, 22:15
Причина редактирования: Лишнее цитирование
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|