|
|
  |
WinAVR, проблемы с оптимизацией -O0, xmega, winavr, проблема с драйвером clksys_driver |
|
|
|
Dec 1 2009, 07:07
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 23-07-08
Пользователь №: 39 158

|
Решил во время отладки включить оптимизацию -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 работает
|
|
|
|
|
Dec 1 2009, 08:11
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
-O0 - это не оптимизация, это ее полное отключение. В вашем случае адрес регистра CCP описан как математическое выражение, которое компилятор может вычислить при включенной оптимизации, но вынужден оставить выражением и считать на этапе выполнения, поскольку оптимизацию даже выражений вида 1+1 вы запретили. Цитата(MrKot @ Dec 1 2009, 09:07)  PS С любой оптимизацией кроме -O0 работает Вот и не отключайте ее. Без оптимизации код разбухает и становится медленнее в разы и не имеет ничего общего с тем кодом, который будет у вас работать в боевом устройстве. Просто запомните, что -O0 включать не нужно никогда. Для AVR используйте -Os или -О2. Обычно лучшие результаты дает -Os.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 2 2009, 06:12
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 23-07-08
Пользователь №: 39 158

|
Спасибо, помогло!
2demiurg_spb: работа с CCP является критической по времени выполнения, и тут без асма никак.
|
|
|
|
|
Dec 2 2009, 12:56
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(MrKot @ Dec 2 2009, 09:12)  и тут без асма никак. И как это Ваше заявление вяжется с тем, что "в асме не силен"? Просто где-то слышали, что это "круто" и т.д. и т.п.  В 'С' сильны (хотя -O0 уже о многом говорит)? Пишите на нем, смотрите на результат в листинге при максимальной оптимизации того, чего надо и решайте, насколько "круче" можете написать на ASM после 'С'. Да, в исходнике надо пробовать подтолкнуть компилятор в нужном направлении и при этом порулить более тонкими опциями оптимизации, нежели готовые наборы.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 3 2009, 11:30
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 23-07-08
Пользователь №: 39 158

|
А к чему вообще последний пост? Товарищ zltigo сумничал? И к чему это в ветке форума "В помощь начинающему"? Если Вы такой умный - покажите это, дав точный и емкий ответ, например как сделал это Сергей Борщ.
|
|
|
|
|
Dec 3 2009, 13:54
|

Гуру
     
Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515

|
В 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__ */
} У меня вот такая хрень работает. Без всяких процентов.
--------------------
On the road again (Canned Heat)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|