Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как не звать __aeabi_idiv и иже сними?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
kosyak©
Есть код
Код
...
    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?
demiurg_spb
Код
    static const int D = 100;
    static const int K = 11;
  
    volatile int d = D;
    volatile int k = K;
    volatile int q = D / K;
scifi
Цитата(kosyak© @ Dec 9 2010, 14:59) *
Как заставить его не использовать __aeabi_idiv?

А зачем, если не секрет?
Ну и, как уже отметил demiurg_spb, компилятор не стал оптимизировать этот код из-за того, что применено ключевое слово volatile. Всё правильно компилятор сделал.
kosyak©
Так и думал что в волатиле начнут носом тыкать sm.gif
Ну тогда по порядку - волатиле написал сознательно, чтоб компилятор не проявлял чудеса оптимизМА и не посчитал мне это выражение на этапе компиляции sm.gif
Интересует конкретно вопрос как его заставить не использовать __aeabi_idiv а скомпилировать деление прям в функцию.
Вот, например (пример из пальца выососан сразу предупреждаю), - есть функция, она выполняется из рамки (RAM) и затирает скажем внутреннюю флэш.. в функции считается страница ( / ) и смещение ( % ) - и тут компилятор решил выпендриться и использовать для деления __aeabi_idiv, вместо того чтобы честно скомпилировать нужный код, __aeabi_idiv ессно лежит в стираемой флэше..вот такая вот загогулина...
Да, я конечно, понимаю что можно вю библиотеку используемых компилятором функций запихнуть в рамку и проблемы вроде как бы не станет - но интересует именно как заставить его их не использовать...
IgorKossak
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 ессно лежит в стираемой флэше..вот такая вот загогулина...

Если размер Вашей страницы не является константой и не кратен степени двойки, то ничего удивительного в поведении компилятора нет.
kosyak©
Архитектура действительно ARM7TDMI-S. Я тоже считаю что ничего удивительного нет, но осталась ли возможность принудительно инлайнить подобные функции?
IgorKossak
А всё же. Каков размер страницы и почему он не константный?
Ведь всё могло свестись к сдвиговым операциям.
kosyak©
Ну тогда дополню картину:
Стоит датафлэш AT45DBxxx (именно xxx), перепрошивка осуществляется через эту флэш - т.е. сперва полный бинарь записывается в нее, а потом, если все хорошо, камень перепрошивается. Вот тут и возник прикол с __aeabi_idiv. Я прекрасно понимаю что можно написать загручик который будет полностью работает в рамке и проблема снимется.... Предвосхищая вопросы - питание у устройства аккумуляторное.

Да и вообще - сейчас это уже больше академический интерес sm.gif.
MALLOY2
Академический вопрос, что в загрузчике делает __aeabi_idiv ? На верняка можно обойтись без деления, ну если конечно не используется паковка, шифрование, хитрые CRC (обычные работают без деления).
kosyak©
Страничная организация DataFlash. Из линейного адреса нужно посчитать - номер страницы, смещение в странице...
Делается все примерно так


page = la / page_size;
offs = la % page_size;

Предложите другой метод? Метод вычисления page и offs, а не метод нахождения частного и остатка.
MALLOY2
Мда..... так и знал sm.gif

Все делается через маску и сдвиг
Код
#define ADDR_TO_SECTOR_NUMBER(x) ((x) >> 9) //for page == 512 bytes

#define ADDR_TO_PAGE_OFFSET(x) ((x) & 0x1FFu) //for page == 512 bytes





kosyak©
Цитата(kosyak© @ Dec 10 2010, 11:23) *
...
Стоит датафлэш AT45DBxxx (именно xxx)
...


Тем что "(именно xxx)" я хотел подчеркнуть, что на этапе компиляции я не знаю какую флэш поставят. Соответственно не знаю размер страницы... Мало того, сейчас стали приходить dataflash, у которых размер страницы - степень двойки... раньше у атмела в этих флэшах страница была с аппендиксом и ее размер не был равен степени двойки sm.gif.
MALLOY2
И какие с этим проблемы ?

Глава 14. Manufacturer and Device ID Read

Изучайте мат часть

Цитата
степень двойки... раньше у атмела в этих флэшах страница была с аппендиксом и ее размер не был равен степени двой


По моему вы вобще мануал не читали или не умеете sad.gif
kosyak©
Уф!
Вообщем так - на плату может быть поставлена любая микросхема из серии AT45DBXXXD, программа должна определять по выше упомянутому Вами "Manufacturer and Device ID Read" тип микросхемы и, соответственно, размер страницы. Еще раз повторю - не все микросхемы серии AT45DBXXXD имеют размер страницы кратный степени двойки, соотвественно нельзя использовать "маску и сдвиг" для преобразования линейного адреса в страничный....
MALLOY2
13. "Power of 2" Binary Page Size Option
"Power of 2" binary page size Configuration Register is a user-programmable nonvolatile regis-
ter that allows the page size of the main memory to be configured for binary page size
(512 bytes) or DataFlash standard page size (528 bytes). The "power of 2" page size is a one-
time programmable configuration register and once the device is configured for "power
of 2" page size, it cannot be reconfigured again. The devices are initially shipped with the
page size set to 528 bytes. The user has the option of ordering binary page size (512
bytes) devices from the factory. For details, please refer to Section 26. "Ordering Information" on
page 48.
For the binary "power of 2" page size to become effective, the following steps must be followed:
1. Program the one-time programmable configuration resister using opcode sequence
3DH, 2AH, 80H and A6H (please see Section 13.1).
2. Power cycle the device (i.e. power down and power up again).
3. The page for the binary page size can now be programmed.
If the above steps are not followed to set the page size prior to page programming, incorrect
data during a read operation may be encountered.
kosyak©
Ладно - цитирую мануал:

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?


Эх...не успел... предложили сконфигурировать в степень двойки sad.gif((
MALLOY2
Создаем проблемы и героически их решаем sm.gif
Вы знаете когда размер страницы равен 528 байт, то страница всен равно хранит 512 байт информации и остаток используется для контрольной суммы и/или востановления информации. Если вы хотите использовать 528 для линейной адресации, подход явно через...
kosyak©
Ну...еще раз скажу - вопрос не про конкретное применение операции деления!

Цитата(MALLOY2 @ Dec 10 2010, 13:15) *
...
когда размер страницы равен 528 байт, то страница всен равно хранит 512 байт информации и остаток используется для контрольной суммы и/или востановления информации
...


О_о кем используется остаток? Как "все равно" хранит 512 байт? Это сейчас о чем?
scifi
Согласен, что случай, когда код прошивки флэш должен быть в ОЗУ, весьма актуален. Насколько я знаю, у компилятора нет настроек, позволяющих гарантировать, что кусок кода, скопированный в ОЗУ, не будет вызывать функции из флэш. Можно, конечно, подрихтовать код "ручками", но нет гарантии, что при переходе на новую версию компилятора или при смене его настроек не придётся рихтовать код снова. Чтобы это гарантировать, нужно оформить код в ОЗУ как самостоятельный проект, полностью размещённый в ОЗУ. Для связи с основной прошивкой можно придумать простенький ABI: таблица указателей на функции. Забыл добавить: или писать код в ОЗУ на ассемблере.
_Bill
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;
...
Или нет?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.