Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: WinAVR, проблемы с оптимизацией -O0
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
MrKot
Решил во время отладки включить оптимизацию -O0, но тут компилятор выдал ошибку
constant value required. Покопался и нашел причину ошибки:
драйвер clksys_driver (из апноута), конкретно функция CCPWrite, а еще конкретнее:
Код
asm volatile(
        "movw r30,  %0"    "\n\t"
        "ldi  r16,  %2"    "\n\t"
        "out   %3, r16"    "\n\t"
        "st     Z,  %1"
        :
        : "r" (tmpAddr), "r" (value), "M" (CCP_IOREG_gc), "m" (CCP)
        : "r16", "r30", "r31"
        );

разбил блок на строки оказалась проблема в:

out %3, r16

В асме не силен, по этому прошу помощи знающих людей - в чем может быть проблема? Может быть есть другое решение работы с CCP? (хотя врядли тут без асма обойдешься...)

PS С любой оптимизацией кроме -O0 работает
Сергей Борщ
-O0 - это не оптимизация, это ее полное отключение. В вашем случае адрес регистра CCP описан как математическое выражение, которое компилятор может вычислить при включенной оптимизации, но вынужден оставить выражением и считать на этапе выполнения, поскольку оптимизацию даже выражений вида 1+1 вы запретили.
Цитата(MrKot @ Dec 1 2009, 09:07) *
PS С любой оптимизацией кроме -O0 работает
Вот и не отключайте ее. Без оптимизации код разбухает и становится медленнее в разы и не имеет ничего общего с тем кодом, который будет у вас работать в боевом устройстве. Просто запомните, что -O0 включать не нужно никогда. Для AVR используйте -Os или -О2. Обычно лучшие результаты дает -Os.
demiurg_spb
Почитайте это:
http://www.nongnu.org/avr-libc/user-manual/inline_asm.html
В асмовых макросах/функциях нехорошо использовать регистры MCU непосредственно.
А для чего Вам нужна эта асмовая вставка? На Си что никак (или тайминги нужно соблюдать)?
MrKot
Спасибо, помогло!

2demiurg_spb: работа с CCP является критической по времени выполнения, и тут без асма никак.
zltigo
Цитата(MrKot @ Dec 2 2009, 09:12) *
и тут без асма никак.

И как это Ваше заявление вяжется с тем, что "в асме не силен"? Просто где-то слышали, что это "круто" и т.д. и т.п. sad.gif
В 'С' сильны (хотя -O0 уже о многом говорит)? Пишите на нем, смотрите на результат в листинге при максимальной оптимизации того, чего надо и решайте, насколько "круче" можете написать на ASM после 'С'. Да, в исходнике надо пробовать подтолкнуть компилятор в нужном направлении и при этом порулить более тонкими опциями оптимизации, нежели готовые наборы.
MrKot
А к чему вообще последний пост? Товарищ zltigo сумничал? И к чему это в ветке форума "В помощь начинающему"? Если Вы такой умный - покажите это, дав точный и емкий ответ, например как сделал это Сергей Борщ.
demiurg_spb
Он просто дал Вам тему для размышления. И показывать/доказывать тут Вам никто не должен.
Просто для вопрошающего очень важно понять направление куда стоит двигаться, а куда нет.
Что zltigo и удаётся методично делать весьма долгое время.
DpInRock
В xmega на модификацию защищенных регистров отводится ровно 4 цикла.

Код
void CCPWrite( volatile unsigned char * address, unsigned char value )
{
// Move destination address pointer to Z pointer registers.
    asm("movw r30, r16");
#ifdef RAMPZ
    asm("ldi  R16, 0 \n"
            "out  0x3B, R16"
        );
#endif
    asm("ldi  r16,  0xD8 \n"
        "out  0x34, r16  \n"
#if (__MEMORY_MODEL__ == 1)
        "st     Z,  r17  \n");
#elif (__MEMORY_MODEL__ == 2)
        "st     Z,  r18  \n");
#else /* (__MEMORY_MODEL__ == 3) || (__MEMORY_MODEL__ == 5) */
        "st     Z,  r19  \n");
#endif /* __MEMORY_MODEL__ */

}

У меня вот такая хрень работает. Без всяких процентов.
Сергей Борщ
Цитата(DpInRock @ Dec 3 2009, 15:54) *
хрень работает. Без всяких процентов.
Пока компилятор не попытается в процессе оптимизации разместить что-то полезное в R16-R19 перед вызовом этой функции и после вызова забрать обратно. О "магическом" числе 0xD8 вообще промолчу.
DpInRock
Ну, именно так рекомендует Атмел поступать. Вместе с IAR.
Сергей Борщ
Цитата(DpInRock @ Dec 3 2009, 18:27) *
Вместе с IAR.
О! Вот оно что. Сразу бы и говорили. У ИАРа никаких процентов и нету. Поэтому встретив асм-вставку его оптимизатор поднимает лапки. А чтобы это обойти, они вынуждены вводить интринсик-функции даже на такое элементарное действие, как __no_operation(). Так и получается - сначала асм, выключающий оптимизатор, в следующей версии - интринсики. В теме совсем другой компилятор указан.
mdmitry
Цитата(Сергей Борщ @ Dec 3 2009, 17:37) *
Пока компилятор не попытается в процессе оптимизации разместить что-то полезное в R16-R19 перед вызовом этой функции и после вызова забрать обратно. О "магическом" числе 0xD8 вообще промолчу.

В добавление к сообщению Сергей Борща. WinAVR в зависимости от версии использует разные регистры для своих целей, эта информация есть в описании avr-libc.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.