|
|
  |
WinAVR криво собирает код... |
|
|
|
Apr 6 2009, 04:06
|

В поисках истины
  
Группа: Свой
Сообщений: 431
Регистрация: 7-01-06
Из: Россия
Пользователь №: 12 923

|
Но всё же какой-то косяк... К примеру вот такой lss получается: Код bufferInit((cBuffer*)&uartTxBuffer, (unsigned char *)uartTxData, sizeof(uartTxData)); 6e6: 8c ec ldi r24, 0xCC; 204 6e8: 93 e0 ldi r25, 0x03; 3 6ea: 68 e6 ldi r22, 0x68; 104 6ec: 71 e0 ldi r23, 0x01; 1 6ee: 4f e7 ldi r20, 0x7F; 127 6f0: 08 d8 rcall .-4080 ; 0xfffff702 <__eeprom_end+0xff7ef702> От куда это он пытается вызвать функцию? Что за бред?
|
|
|
|
|
Apr 6 2009, 08:42
|

В поисках истины
  
Группа: Свой
Сообщений: 431
Регистрация: 7-01-06
Из: Россия
Пользователь №: 12 923

|
Цитата(_Pasha @ Apr 6 2009, 13:10)  Дык поделитесь тайной: версия компилятора и содержимое makefile В lss от SysRq такого косяка ведь нет  Код Using built-in specs. Target: avr Configured with: ../gcc-4.3.2/configure --enable-win32-registry=WinAVR-20081205 --with-gmp=/usr/local --with-mpfr=/usr/local --prefix=/c/WinAVR --target=avr --enable-languages=c,c++,objc --with-dwarf2 --enable-doc --disable-shared --disable-libada --disable-libssp --disable-nls --with-pkgversion='WinAVR 20081205' --with-bugurl='URL:http://sourceforge.net/tracker/?atid=520074&group_id=68108&func=browse' Thread model: single gcc version 4.3.2 (WinAVR 20081205)
|
|
|
|
|
Apr 6 2009, 15:46
|

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

|
Цитата(_Pasha @ Apr 6 2009, 18:21)  Неполезный это прием, т.к. обычно считается, что джамп в область вне пространства памяти приведет к непредсказуемым результатам. Это не вне пространства. Пространство памяти программ не безгранично, оно ограничено разрядностью счетчика команд и замкнуто в кольцо все той же разрядностью. Вас ведь не смущает, что таймер, досчитав до 0xFFFF переходит на 0? И SUBI Rx, lo8(-(const)) == Rx + const вас тоже не смущает. Абсолютно аналогичный прием используется в ARM для доступа к контроллеру прерываний (лежит в конце памяти) из области векторов (лежит в начале памяти). Таким же образом высчитываются простейшие задержки на таймерах. Никакого криминала, чистая математика.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 7 2009, 05:25
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Было бы просто замечательно, если бы кто-то из глубоко вникших в AVR-GCC, посоветовал, как отключить (избежать, обойти) эту фичу с переходами "вне пространства адресов". в условиях недостатка средств отладка в протеусе - единственно возможный вариант, а он, зараза, не понимает, что ограничение разрядности аппаратно встроено в AVR, и не дает вести отладку... AVR Studio такую ситуацию отрабатывает верно, но вести в ней отладку проектов, завязанных на внешние сигналы, практически нереально
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Apr 7 2009, 15:55
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Уважаемый Сергей Борщ! Я прочитал в документации про опцию -mno-wrap - это, как я надеялся, и есть решение проблемы. НО! я так и не смог ею воспользоваться! не смотря на то, что вызов avr-gcc.exe --target-help подтверждает поддержку этой опции, компиляция всегда завершается ошибкой: Цитата make all Building file: ../bground.c Invoking: AVR Compiler avr-gcc -Wall -g3 -Os -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields -mno-wrap -mmcu=atmega8 -DF_CPU=8000000UL -MMD -MP -MF"bground.d" -MT"bground.d" -c -o"bground.o" "../bground.c" cc1.exe: error: unrecognized command line option "-mno-wrap" make: *** [bground.o] Error 1 не будете ли вы так любезны пояснить, в чем мое заблуждение? P.S. работаю с WinAVR 20091303
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Apr 7 2009, 16:58
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(ARV @ Apr 7 2009, 18:55)  Я прочитал в документации про опцию -mno-wrap - это, как я надеялся, и есть решение проблемы. НО! я так и не смог ею воспользоваться! не смотря на то, что вызов avr-gcc.exe --target-help подтверждает поддержку этой опции, компиляция всегда завершается ошибкой: Вообще-то это ключ ассемблера, в мануалах он описан в binutils/as -mmcu= пробрасывается из gcc всем вызываемым проходам, видать и этот тоже, хотя он нужен только ассемблеру, так что надо явно указать -Wa,-mno-wrap Возможно, без этого ключа ассемблер форимрует такую запись в объектнике, что линкер после вычисления разности текущего адреса и адреса перехода игнорирует не влазящие в поле смещения в команде биты, если они все единички, т.е. если "сворачивание" проходит. А с этим ключом такого не делает и линкер ругается на превышение диапазона. Я не разбирался, так как для меня эта тема не актуальна.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Apr 7 2009, 17:48
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(ReAl @ Apr 7 2009, 20:58)  Вообще-то это ключ ассемблера, в мануалах он описан в binutils/as
-mmcu= пробрасывается из gcc всем вызываемым проходам, видать и этот тоже, хотя он нужен только ассемблеру, так что надо явно указать -Wa,-mno-wrap
Возможно, без этого ключа ассемблер форимрует такую запись в объектнике, что линкер после вычисления разности текущего адреса и адреса перехода игнорирует не влазящие в поле смещения в команде биты, если они все единички, т.е. если "сворачивание" проходит. А с этим ключом такого не делает и линкер ругается на превышение диапазона. Я не разбирался, так как для меня эта тема не актуальна. если его передать ассемблеру явно -Wa,-mno-wrap - вообще никаких изменений не наблюдается - код получается 100% прежним. судя по всему, no-wrap понимается как использование "медленных" инструкций "дальних" переходов JMP/ CALL, которые в меге8 не присутствуют... но ведь цепочка коротких RJMP вкупе с одним RCALL ничем не хуже! я надеюсь, что это действительно так... хотя вот здесь, похоже, над такой идеей посмеиваются... (извините за мой промптовый английский)
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Apr 7 2009, 19:35
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(ARV @ Apr 7 2009, 20:48)  если его передать ассемблеру явно -Wa,-mno-wrap - вообще никаких изменений не наблюдается - код получается 100% прежним Да, действительно, объектники совпадают побитово. Цитата(ARV @ Apr 7 2009, 20:48)  судя по всему, no-wrap понимается как использование "медленных" инструкций "дальних" переходов JMP/CALL, которые в меге8 не присутствуют... но ведь цепочка коротких RJMP вкупе с одним RCALL ничем не хуже! я надеюсь, что это действительно так... Это всё-таки ключ ассемблера, с одной стороны, а он в генерации кода "от себя" не замечен. С другой - для объектов из разных модулей вообще неизвестно кто кроме линкера (но у него этого *) ключа нет) и как должен промежуточные переходы вставлять. *) при том, что мне эта тема малоинтересна :-) в попытках что-то понять обнаружил у линкера интересный ключ: Цитата --pmem-wrap-around=<val> Make the linker relaxation machine assume that a program counter wrap-around occures at address <val>. Supported values are 8k, 16k, 32k and 64k. Т.е. когда он при --relax заменяет jump -> rjmp, call -> rcall - разрешить ему делать сворачивание по заданному модулю.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Apr 7 2009, 22:20
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
ARV, а Proteus версии у вас какой? Пробегавший мимо 7.4 SP3 Build 6792 нормально съел *.hex с: Код PORTD ^= 1; ae4: 82 b3 in r24, 0x12; 18 ae6: 89 27 eor r24, r25 ae8: 82 bb out 0x12, r24; 18 aea: bc ca rjmp .-2696 ; 0x64 <main+0x6> Т.е. "rjmp .-2696" его нисколько не смутил, простенькая программа работала. Однако, если я увеличивал размер кода nop'ами (вставлял nop до rjmp), то в какой-то момент он переставал запускать симуляцию, и при этом ошибку не выдавал в чем дело (в логе 10 штук ОК и на инициализации МК полный превед...)
Сообщение отредактировал SysRq - Apr 7 2009, 22:21
|
|
|
|
|
Apr 8 2009, 04:23
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
протеус у меня точно такой же. я активно применяю возможности форматированного ввода-вывода, а это однозначно прибавляет до 2-3К кода, поэтому порой буквально один новый оператор в программе приводит к тому, что вход в main оказывается "далеко" от кода инициализации (секции .init*), avr-gcc генерирует "хитрые" переходы, которые протеус отвергает. я понимаю, что виноват протеус, но, блин, надо же как-то выкрутиться... теоретически можно как-то поколдовать скриптами линкера, изменив порядок следования модулей, но ведь это решение не универсальное... off: протеус - как наркотик: один вред, а подсаживает с первой пробы, всерьез и надолго
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Apr 8 2009, 05:14
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
с -mno-wrap вообще странность какая-то... вот сейчас выбрал target Atmega32, в которой имеются и RJMP и JMP. по умолчанию всюду используются трехсловные JMP. куда опцию -mno-wrap не лепил - и в командную строку avr-gcc, и непосредственно ассемблеру передавал через -Wa - ноль эффекта! результаты 100% одинаковые всегда. -relax успешно заменяет JMP на RJMP, оставляя при этом одно слово пустым, т.е. скорость исполнения возрастает...
кстати, глюка-то в GCC и нет - выше было рассказано, как оно работает... это протеусу не нравится, когда с адреса, скажем, 0x100 происходит RJMP .-2000... протеус уверен, что в результате попадем в точку где-то дааааалеко за имеющимися 8 или 32К... т.е. не учитывает аппаратное маскирование старших битов PC...
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Apr 8 2009, 19:23
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(manul78 @ Apr 8 2009, 22:43)  ... Народ !!! У меня еще прикольнее...
Понадобилось мне написать код для маленького и простого 2313... 2 кб... Я обычно как делаю : в процессе отладки когда памяти становится "мало-мало" беру *.lss файл и оптимизирую код уже сам - в ручную...
Последняя версия, то биш 20090313 сжал мне в 900 байт...
20080610 более старый в 950 байт...
а самый старый 20070525 сжал и "дал" самый с моей точки зрения хороший и грамотный код в ... 1) winavr он же GCC, перешёл с версии 3.xxx на версию 4.xxx 2) GCC имеет свой цикл разработки. существуют 2 основных ветки: а) текущий релиз. в нём архитектуру не меняют, только правят баги и делают небольшие косметические правки. понятно, что со временем эта версия вылизывается практически до идеала. однако т.к. заложенные подходы в компилятор являются немного устаревшими принципиально новые вещи в этой ветке не реализуются. б) ветка разработки, в неё добавляют самые последние технологии компиляторостроения, закладывается достаточно большой запас прочности и потенциал для развития, учитываются современные технологии процессоров и.т.п. Однако т.к. эта ветка самая "свежая", когда она становится "текущим релизом" в ней есть места, которые на практике надо дорабатывать. С временем она раскрывает весь свой потенциал, пока разрабатывают уже новые подходы и т.д. 3) приоритеты в новых компиляторах немного меняются. например в современных контроллерах много флеша, поэтому размер кода обычно не так критичен как скорость выполнения, более линейных код. 4) мега8 стоит практически столько-же как и т2313, а может уже и меньше. а возможностей гораздо больше.
|
|
|
|
|
Apr 8 2009, 22:06
|

Местный
  
Группа: Участник
Сообщений: 403
Регистрация: 14-05-07
Из: Россия, г.Пенза
Пользователь №: 27 719

|
Блин, у меня теперь еще интересней проблема ! На работе, где стоит старый 20070525 все работает как часы... А вот дома, притом и на "стационарном" компе и на "буке" 20090313... Решил новый "наганть" и поставить старый, дык он собака где-то прописался и старый (е) у меня их около 5 сортов разных лет - не хотят работать. Весь реестр вычистил, НУ ВСЕ высистил, что можно - балда ! Вещает : > "make.exe" all AllocationBase 0x0, BaseAddress 0x71590000, RegionSize 0x3C0000, State 0x10000 C:\WinAVR-20070525\utils\bin\sh.exe: *** Couldn't reserve space for cygwin's heap, Win32 error 487 AllocationBase 0x0, BaseAddress 0x71590000, RegionSize 0x3C0000, State 0x10000 C:\WinAVR-20070525\utils\bin\sh.exe: *** Couldn't reserve space for cygwin's heap, Win32 error 487 -------- begin -------- avr-gcc (GCC) 4.1.2 (WinAVR 20070525) Copyright © 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. AllocationBase 0x0, BaseAddress 0x71590000, RegionSize 0x3C0000, State 0x10000 C:\WinAVR-20070525\utils\bin\sh.exe: *** Couldn't reserve space for cygwin's heap, Win32 error 487 make.exe: *** [sizebefore] Error 1 > Process Exit Code: 2 > Time Taken: 00:01 Блин ! Да что-же это такое !!! И на буке таже песня ! Новый ставишь - все работает. Любого из старичков - пишет (см. верх) . Раньше не было такого никогда. Может знает кто - где он помимо реестра следы остав- ляет ? Пытался искать в SYSTEM32 и прочих "отсеках" - куда там, у меня винда стоит 3-тий год, распухла до 12 гектар... сносить проблемматично. Че делать ?
Сообщение отредактировал manul78 - Apr 8 2009, 22:10
--------------------
" Многие вещи нам непонятны не потому, что наши понятия слабы; но потому, что сии вещи не входят в круг наших понятий." (с) К.Прутков.
|
|
|
|
|
Apr 9 2009, 05:57
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
по поводу увеличения размера кода "свежими" версиями - я тут создавал темку, где мне доступно объяснили, что есть масса ключей оптимизации, которые позволяют и свежей версией получить минимальный размер кода. в моем случае я довольно легко добился лучшего результата, чем при сборке старой версией. возможно, немножко обидно, что раньше маленький код получался сам, а теперь надо какие-то опции включать-выключать и т.п. - однако, никто не сравнивал "старый" и "новый" код по быстродействию, например? может, размер - не самое главное? тем более когда речь не о килобайтах, а о байтах разницы. раньше, например, когда писалось PORTB |= _BV(PB1); компилятор всегда генерировал код с обращением к ячейке памяти по соответствующему адресу, т.е. делал минимум 3 команды: LDS, ORI и STS. это было очень хорошо (с одной стороны), так как легко позволяло обращаться к порту по указателю, но по скорости SBI все-же гораздо лучше. и вот в последней версии заметил, что теперь генерируется именно SBI! причем при обращении через указатель получается "старый" вариант - ведь лучше же стало, а?!  хотя странности присутствуют все равно в коде
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Apr 9 2009, 07:29
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(ARV @ Apr 9 2009, 08:57)  раньше, например, когда писалось PORTB |= _BV(PB1); компилятор всегда генерировал код с обращением к ячейке памяти по соответствующему адресу, т.е. делал минимум 3 команды: LDS, ORI и STS. это было очень хорошо (с одной стороны), так как легко позволяло обращаться к порту по указателю, но по скорости SBI все-же гораздо лучше. и вот в последней версии заметил, что теперь генерируется именно SBI! Код #include <avr/io.h>
void foo() { PORTB |= 0x01; } WinAVR-20060421 (gcc 3.4.6) -Os -S -mmcu=atmega8 Код foo: sbi 56-0x20,0 ret Более древних на работе нет, но что-от мне вспоминается, что это только с gcc 2.95 такое было, а с перехода на 3.х я уже вместо макросов inb, outb, sbi да cbi стал писать обычное =, |= да &=~ Точнее, с момента полного перехода, кода 2.95 уже был снесён на всех компах.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Apr 9 2009, 07:41
|

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

|
Цитата(manul78 @ Apr 9 2009, 01:06)  C:\WinAVR-20070525\utils\bin\sh.exe: *** Couldn't reserve space for cygwin's heap, Win32 error 487 Поиск в гугле по сообщению об ошибке очень помогает в таких случаях. В комплекте WinAVR идет какая-то очень древняя версия утилит из msys, которую очень любит Eric Weddington. И вместе с этим набором из версии в версию WinAVR кочуют и все болячки той версии msys. На мои призывы к автору обновить эти утилиты был дан ответ - "у них нет нормального инсталятора, мне лень". Сходите на сайт mingw32/msys и скачайте там самые свежие версии всех этих утилит. После чего используйте их со всеми версиями WinAVR, а идущие в комплекте забудьте как страшный сон.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 9 2009, 16:56
|

Местный
  
Группа: Участник
Сообщений: 403
Регистрация: 14-05-07
Из: Россия, г.Пенза
Пользователь №: 27 719

|
Цитата(Сергей Борщ @ Apr 9 2009, 11:41)  Поиск в гугле по сообщению об ошибке очень помогает в таких случаях. В комплекте WinAVR идет какая-то очень древняя версия утилит из msys, которую очень любит Eric Weddington. И вместе с этим набором из версии в версию WinAVR кочуют и все болячки той версии msys. На мои призывы к автору обновить эти утилиты был дан ответ - "у них нет нормального инсталятора, мне лень". Сходите на сайт mingw32/msys и скачайте там самые свежие версии всех этих утилит. После чего используйте их со всеми версиями WinAVR, а идущие в комплекте забудьте как страшный сон. Уважаемый Сергей ! Я даже не знаю как Вас благодарить... Самое интересное, что на "стационарном" компе и на "буке" были совершенно разные "занозы" !!! 1) Ноутбук я победил сам. Почти пол дня ковырялся ! Причиной "глюка" был Антивирус Касперского. почти всю ночь и пол дня я читал описание на WinAVR и понял суть проблемы, файл sh.exe из utils\bin работает с операционной системой, единственное, что могло этому обмену помешать, это "проактивн- ая защита Касперского". До его установки все было гуд. Я внес sh.exe в доверенную зону - и все за- работало !!! 2) С "стационарным" компом такие выкрутасы не прошли. Я затужил. Работа горит а главный мой комп что-то вроде "осьминога" напичкан всеми примочками для отладки "в железе". Он важнее чем "бук" Зашел по вашей ссылке, почитал и уже собирался вникать в Линукс и прочие дела, кстати про "палки в колеса со стороны антивирусов, там тоже есть". Хотел было уже качать 500 метровый GNU pack... Но заглянул на крошечную ссылку, http://www.madwizard.org/electronics/articles/winavrvista Я сначала пролетел, у меня то XP ! Там нашлось лекарство, и очень простое ! Качаем 300 сот килограммовый msys-rebased.zip и перезаписываем его в utils\bin , там это по мое- му единственная DLL-ка ms-1.0 dll И все ! Земля опять завертелась !!! Жму руку как ПРОФЕССИОНАЛУ, заходящему сюда не "флудить" а помогать словом и делом !!!
--------------------
" Многие вещи нам непонятны не потому, что наши понятия слабы; но потому, что сии вещи не входят в круг наших понятий." (с) К.Прутков.
|
|
|
|
|
Apr 9 2009, 18:45
|
Участник

Группа: Участник
Сообщений: 55
Регистрация: 17-04-08
Пользователь №: 36 850

|
А я столкнулся с таким глюком: есть бутлоадер с эмуляцией STK500. Пишу через него - пишется нормально. Читаю - бывают ошибки, по адресу 0x4000 ошибок нет. Читаю ISP программатором - тех ошибок что показывал бутлоадер нет, по адресу 0x4000 лежит слово FFFF. Вроде помогла такая штука: Было: Код n_bytes = ((*(rx_pntr + 1) * 256) + *(rx_pntr + 2)); // number of databytes to read from flash Стало: Код *(((unsigned char *)&n_bytes) + 1) = *(rx_pntr + 1); *(((unsigned char *)&n_bytes) + 0) = *(rx_pntr + 2); Пробовал каждый раз на разных файлах, поэтому "вроде"...
|
|
|
|
|
Apr 9 2009, 19:32
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Nick_Shl @ Apr 9 2009, 22:45)  А я столкнулся с таким глюком: Вот ЭТО написано человеком который поленился прочитать документацию: Код unsigned char readBits(unsigned int address) { asm volatile( "mov r31,r25 \n\t" "mov r30,r24 \n\t" "lds r24,%0 \n\t" "ori r24,0x09 \n\t" "sts %0,r24 \n\t" "lpm \n\t" "mov r24,r0 \n\t" : "=m" (SPMCSR) ); return address&0xFF; } Это баг не в комптляторе, это баг в коде. Анатолий.
Сообщение отредактировал aesok - Apr 9 2009, 19:54
|
|
|
|
|
Apr 9 2009, 20:06
|
Участник

Группа: Участник
Сообщений: 55
Регистрация: 17-04-08
Пользователь №: 36 850

|
Цитата(aesok @ Apr 9 2009, 21:32)  Вот ЭТО написано человеком который поленился прочитать документацию: Код не мой. Return взят из какого-то файла скачанного из ветки в этом форуме. Но этот код к вышеописанной проблеме отношения не имеет.
|
|
|
|
|
Apr 9 2009, 20:38
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(aesok @ Apr 9 2009, 23:32)  Вот ЭТО написано человеком который поленился прочитать документацию: Код unsigned char readBits(unsigned int address) { asm volatile( "mov r31,r25 \n\t" "mov r30,r24 \n\t" "lds r24,%0 \n\t" "ori r24,0x09 \n\t" "sts %0,r24 \n\t" "lpm \n\t" "mov r24,r0 \n\t" : "=m" (SPMCSR) ); return address&0xFF; } Это баг не в комптляторе, это баг в коде. Если readBits вызывается как функция то проблем не возникнет, так как регистры r24, r25, r30 и r31 являются CALL_USED регистрами и в коде вызывающей функции предполагаться что они не содержат те значения, что были в них перед вызовом readBit. Когда же код этой функции инлайнится то могут возникнуть проблемы, так как регистры r24, r25, r30 и r31 искажаются в ассемблерной вставке, но компилятор об этом не предупрежден. Может генерироваться код записывающий информацию в эти регистры до ассемблерной вставки и использующий эту информацию после, не смотря на то что она искажена. Регистры r24, r25, r30 и r31 должны быть добавлены в clobber list. Анатолий.
|
|
|
|
|
Apr 9 2009, 21:17
|
Участник

Группа: Участник
Сообщений: 55
Регистрация: 17-04-08
Пользователь №: 36 850

|
Цитата(aesok @ Apr 9 2009, 22:38)  Если readBits вызывается как функция Она вообще не вызывается если не давать команды CMD_READ_FUSE_ISP или CMD_READ_LOCK_ISP. Чтение локов и фузов действительно не работает, но оно меня толком и не интересует.
|
|
|
|
|
Apr 9 2009, 22:48
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата(_Pasha @ Apr 8 2009, 08:34)  О чем Вы поете? Оно ж пишет rjmp в байтах, а не в словах! Логично, логично. Лажа с моей стороны имеет место быть  Proteus, кажется (может я не нашел?), и правда битность PC не учитывает: CODE .text:1003E3F4 OPCODE_rcall_CALL proc near .text:1003E3F4 arg_0 = word ptr 4 .text:1003E3F4 .text:1003E3F4 push edi .text:1003E3F5 mov edi, ecx .text:1003E3F7 mov eax, [edi] .text:1003E3F9 mov ecx, edi .text:1003E3FB add dword ptr [edi+3080h], 1 .text:1003E402 call dword ptr [eax+34h] .text:1003E405 movzx eax, [esp+4+arg_0] .text:1003E40A mov edx, eax .text:1003E40C and edx, 0FFFh .text:1003E412 test eax, 800h .text:1003E417 jz short loc_1003E41F .text:1003E419 add edx, 0FFFFF000h .text:1003E41F .text:1003E41F loc_1003E41F: .text:1003E41F add [edi+3080h], edx .text:1003E425 pop edi .text:1003E426 retn 4
.text:1003E42A OPCODE_rjmp_CALL proc near .text:1003E42A arg_0 = word ptr 4 .text:1003E42A .text:1003E42A movzx edx, word ptr [esp+4] .text:1003E42F mov eax, edx .text:1003E431 and eax, 0FFFh .text:1003E436 test edx, 800h .text:1003E43C jz short loc_1003E443 .text:1003E43E add eax, 0FFFFF000h .text:1003E443 .text:1003E443 loc_1003E443: .text:1003E443 mov edx, [ecx+3080h] .text:1003E449 lea eax, [eax+edx+1] .text:1003E44D mov [ecx+3080h], eax .text:1003E453 retn 4 Как временное решение (ежели без Proteus'а вообще никак) - делать патч (маскировать лишние биты).
|
|
|
|
|
Apr 10 2009, 04:23
|
Участник

Группа: Участник
Сообщений: 55
Регистрация: 17-04-08
Пользователь №: 36 850

|
Цитата(_Pasha @ Apr 10 2009, 02:03)  Заинтересовался... Единственное, что делает новый код - он на три команды короче. Там есть несколько таких мест. Одно из них обработчик команды CMD_LOAD_ADDRESS. Было: Код address_flash = ((*(rx_pntr+3)*256)+*(rx_pntr+4))*2; Стало: Код address_flash = 0; *(((unsigned char *)&address_flash) + 1) = *(rx_pntr + 3); *(((unsigned char *)&address_flash) + 0) = *(rx_pntr + 4); address_flash *= 2; Возможно проблема в нем. В этом коде отличий побольше. Новый даже длиннее на 3 команды.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|