Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: WinAVR криво собирает код...
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Spider
Писал себе и писал прошивку и вдруг в один прекрасный момент она начала собираться "криво" и откатить назад не получается. Всё пропало. Помогите, что я натворил то?
А именно кривость проявляется в следующем. если после сборки открыть и посмотреть листинг вокруг строки sei(); перед циклом майна. То там какие-то хаотические куски кода, на которых проц то делает переполнение то ребутится. В общем ведёт себя неадекватно, а в main.c этого кода нет. Точнее есть но не в этом месте.
SysRq
Да вроде бы в этом куске кода GCC как обычно распихивает константы по регистрам перед запуском сурового алгоритма rolleyes.gif

PS: Makefile надо бы исправить: счастье что make сам догадывается что нет main.cpp, а есть main.c, и что оно C, и вовсе не C++ smile.gif
Spider
А можете дать результат сборки вашей? lss и hex...
SysRq
Цитата(Alexey Belyaev @ Apr 5 2009, 00:15) *
А можете дать результат сборки вашей? lss и hex...
Spider
Но всё же какой-то косяк...
К примеру вот такой 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>

От куда это он пытается вызвать функцию? Что за бред?
_Pasha
Цитата(Alexey Belyaev @ Apr 6 2009, 07:06) *
От куда это он пытается вызвать функцию? Что за бред?

Вероятно, это косяк objdump
Spider
Цитата(_Pasha @ Apr 6 2009, 12:44) *
Вероятно, это косяк objdump

тогда это ещё косяк Proteus и ARVStudio ибо они в отладке на этот же адрес хотят перейти, да и на железе не работает.
_Pasha
Цитата(Alexey Belyaev @ Apr 6 2009, 08:56) *
тогда это ещё косяк Proteus и ARVStudio ибо они в отладке на этот же адрес хотят перейти, да и на железе не работает.


Дык поделитесь тайной: версия компилятора и содержимое makefile
В lss от SysRq такого косяка ведь нет sad.gif
Сергей Борщ
Цитата(Alexey Belyaev @ Apr 6 2009, 07:06) *
От куда это он пытается вызвать функцию? Что за бред?
Это не бред. Не забывайте, что PC имеет ограниченную разрядность. Для меги8 это 13 бит. И при прыжке назад присходит отбрасывание старших разрядов. Итого, для меги8 это будет прыжок на адрес 6F2 - 4080 = 0xfffff702 & 0x1FFFF = 0x1702. Прием очень полезный, ибо команда rjmp не позволяет дотянуться до этого адреса прыжком вперед.
Spider
Цитата(_Pasha @ Apr 6 2009, 13:10) *
Дык поделитесь тайной: версия компилятора и содержимое makefile
В lss от SysRq такого косяка ведь нет sad.gif

Код
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)
_Pasha
Скачал. Собрал. Посмотрел. Описанного глюка не было. Полный отчет о make + lss в аттаче.Нажмите для просмотра прикрепленного файла

Цитата(Сергей Борщ @ Apr 6 2009, 11:04) *
Прием очень полезный, ибо команда rjmp не позволяет дотянуться до этого адреса прыжком вперед.

Неполезный это прием, т.к. обычно считается, что джамп в область вне пространства памяти приведет к непредсказуемым результатам. И лишь благодаря тому, что камень вменяемый...
ReAl
Цитата(_Pasha @ Apr 6 2009, 18:21) *
Неполезный это прием, т.к. обычно считается, что джамп в область вне пространства памяти приведет к непредсказуемым результатам. И лишь благодаря тому, что камень вменяемый...

1) Вроде как именно для 8-килобайтных AVR-ок такое поведение задокумениторвано, у 90s8515 и прочих просто нет команды jump (ну, по описанию smile.gif ) и такое применение rjmp/rcall для 8-килобайтных - единственный способ достать до всего адресного пространства
2) -mno-wrap
Сергей Борщ
Цитата(_Pasha @ Apr 6 2009, 18:21) *
Неполезный это прием, т.к. обычно считается, что джамп в область вне пространства памяти приведет к непредсказуемым результатам.
Это не вне пространства. Пространство памяти программ не безгранично, оно ограничено разрядностью счетчика команд и замкнуто в кольцо все той же разрядностью. Вас ведь не смущает, что таймер, досчитав до 0xFFFF переходит на 0? И SUBI Rx, lo8(-(const)) == Rx + const вас тоже не смущает.

Абсолютно аналогичный прием используется в ARM для доступа к контроллеру прерываний (лежит в конце памяти) из области векторов (лежит в начале памяти). Таким же образом высчитываются простейшие задержки на таймерах. Никакого криминала, чистая математика.
Spider
Спасибо за разъяснения. Будем продолжать учиться.
ARV
Было бы просто замечательно, если бы кто-то из глубоко вникших в AVR-GCC, посоветовал, как отключить (избежать, обойти) эту фичу с переходами "вне пространства адресов". в условиях недостатка средств отладка в протеусе - единственно возможный вариант, а он, зараза, не понимает, что ограничение разрядности аппаратно встроено в AVR, и не дает вести отладку... AVR Studio такую ситуацию отрабатывает верно, но вести в ней отладку проектов, завязанных на внешние сигналы, практически нереально sad.gif
_Pasha
Я б выбрал для симуляции другой камень типа м168, чтоб разрешить jmp

Цитата(Сергей Борщ @ Apr 6 2009, 18:46) *
Никакого криминала, чистая математика.

Пользовался rjmp, представляя себе простую модель перехода +/- 2кслов с 13-разр РС. И никаких проблем, пока не увидел, что пишет objdump smile.gif
Сергей Борщ
Цитата(ARV @ Apr 7 2009, 08:25) *
Было бы просто замечательно, если бы кто-то из глубоко вникших в AVR-GCC, посоветовал, как отключить (избежать, обойти) эту фичу с переходами "вне пространства адресов".
Цитата(ReAl @ Apr 6 2009, 18:46) *
2) -mno-wrap
ARV
Уважаемый Сергей Борщ!
Я прочитал в документации про опцию -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
ReAl
Цитата(ARV @ Apr 7 2009, 18:55) *
Я прочитал в документации про опцию -mno-wrap - это, как я надеялся, и есть решение проблемы. НО! я так и не смог ею воспользоваться! не смотря на то, что вызов avr-gcc.exe --target-help подтверждает поддержку этой опции, компиляция всегда завершается ошибкой:
Вообще-то это ключ ассемблера, в мануалах он описан в binutils/as

-mmcu= пробрасывается из gcc всем вызываемым проходам, видать и этот тоже, хотя он нужен только ассемблеру, так что надо явно указать -Wa,-mno-wrap

Возможно, без этого ключа ассемблер форимрует такую запись в объектнике, что линкер после вычисления разности текущего адреса и адреса перехода игнорирует не влазящие в поле смещения в команде биты, если они все единички, т.е. если "сворачивание" проходит. А с этим ключом такого не делает и линкер ругается на превышение диапазона.
Я не разбирался, так как для меня эта тема не актуальна.
ARV
Цитата(ReAl @ Apr 7 2009, 20:58) *
Вообще-то это ключ ассемблера, в мануалах он описан в binutils/as

-mmcu= пробрасывается из gcc всем вызываемым проходам, видать и этот тоже, хотя он нужен только ассемблеру, так что надо явно указать -Wa,-mno-wrap

Возможно, без этого ключа ассемблер форимрует такую запись в объектнике, что линкер после вычисления разности текущего адреса и адреса перехода игнорирует не влазящие в поле смещения в команде биты, если они все единички, т.е. если "сворачивание" проходит. А с этим ключом такого не делает и линкер ругается на превышение диапазона.
Я не разбирался, так как для меня эта тема не актуальна.
если его передать ассемблеру явно -Wa,-mno-wrap - вообще никаких изменений не наблюдается - код получается 100% прежним. судя по всему, no-wrap понимается как использование "медленных" инструкций "дальних" переходов JMP/CALL, которые в меге8 не присутствуют... но ведь цепочка коротких RJMP вкупе с одним RCALL ничем не хуже! я надеюсь, что это действительно так... хотя вот здесь, похоже, над такой идеей посмеиваются... (извините за мой промптовый английский)
ReAl
Цитата(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 - разрешить ему делать сворачивание по заданному модулю.
_Pasha
Цитата(ReAl @ Apr 7 2009, 22:35) *
*) при том, что мне эта тема малоинтересна :-) в попытках что-то понять обнаружил у линкера интересный ключ:


В аврстудии при настройке avrasm есть аналогичный параметр, но менее гибкий (только на 4к), насколько это позволено в инструкции rjmp/rcall
SysRq
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 штук ОК и на инициализации МК полный превед...) wassat.gif
ARV
протеус у меня точно такой же.
я активно применяю возможности форматированного ввода-вывода, а это однозначно прибавляет до 2-3К кода, поэтому порой буквально один новый оператор в программе приводит к тому, что вход в main оказывается "далеко" от кода инициализации (секции .init*), avr-gcc генерирует "хитрые" переходы, которые протеус отвергает. я понимаю, что виноват протеус, но, блин, надо же как-то выкрутиться... теоретически можно как-то поколдовать скриптами линкера, изменив порядок следования модулей, но ведь это решение не универсальное...

off: протеус - как наркотик: один вред, а подсаживает с первой пробы, всерьез и надолго sad.gif
_Pasha
Цитата(SysRq @ Apr 8 2009, 01:20) *
Т.е. "rjmp .-2696" его нисколько не смутил,

О чем Вы поете? Оно ж пишет rjmp в байтах, а не в словах! А нам, чтобы добиться глюка, надо получить адрес > 4096 байт. В противном случае вообще ни один rjmp не работал бы.
ARV
с -mno-wrap вообще странность какая-то... вот сейчас выбрал target Atmega32, в которой имеются и RJMP и JMP. по умолчанию всюду используются трехсловные JMP. куда опцию -mno-wrap не лепил - и в командную строку avr-gcc, и непосредственно ассемблеру передавал через -Wa - ноль эффекта! результаты 100% одинаковые всегда.
-relax успешно заменяет JMP на RJMP, оставляя при этом одно слово пустым, т.е. скорость исполнения возрастает...

кстати, глюка-то в GCC и нет - выше было рассказано, как оно работает... это протеусу не нравится, когда с адреса, скажем, 0x100 происходит RJMP .-2000... протеус уверен, что в результате попадем в точку где-то дааааалеко за имеющимися 8 или 32К... т.е. не учитывает аппаратное маскирование старших битов PC...
ReAl
Цитата(ARV @ Apr 8 2009, 08:14) *
-relax успешно заменяет JMP на RJMP, оставляя при этом одно слово пустым, т.е. скорость исполнения возрастает...
Это в векторах, там по другому нельзя. А в остальном коде можно команды сдвинуть и размер прошивки уменьшается.
manul78
... Народ !!! У меня еще прикольнее...

Понадобилось мне написать код для маленького и простого 2313... 2 кб...

Я обычно как делаю : в процессе отладки когда памяти становится "мало-мало" беру *.lss файл и
оптимизирую код уже сам - в ручную...

Последняя версия, то биш 20090313 сжал мне в 900 байт...

20080610 более старый в 950 байт...

а самый старый 20070525 сжал и "дал" самый с моей точки зрения хороший и грамотный код в 760 байт.
Работоспособный ! Отлично оптимизированный. и *.lss файл ровный без "глюков"... а самый последний
20090313 наворочал и код кривой, и коментарии не в попад...
Мне вот интересно стало, это что ? Типа как с "виндой" что-ли много памяти - Атмеги64 и 128-е и дальше
разжижают мозги создателям компиляторов ?
zltigo
Цитата(manul78 @ Apr 8 2009, 21:43) *
Атмеги64 и 128-е и дальше разжижают мозги создателям компиляторов ?

Ну не компиляторов а в основном одного компилятора, да и его создателей особо и не найдешь - абстрактному среднему писателю GCC лишь-бы непрерывно монстреющий Linux собирался и более ничего особо не надо sad.gif.
Petka
Цитата(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, а может уже и меньше. а возможностей гораздо больше.
Rst7
Цитата
абстрактному среднему писателю GCC лишь-бы непрерывно монстреющий Linux собирался и более ничего особо не надо


Плюс дофига. Меня тут уже тыкали носом в "жрите что дают" sad.gif

Желание пользовать гнуся от этого совсем не прибавилось. Разочарования - добавилось.
manul78
Блин, у меня теперь еще интересней проблема !

На работе, где стоит старый 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 гектар... сносить проблемматично. Че делать ? smile3046.gif
ARV
по поводу увеличения размера кода "свежими" версиями - я тут создавал темку, где мне доступно объяснили, что есть масса ключей оптимизации, которые позволяют и свежей версией получить минимальный размер кода. в моем случае я довольно легко добился лучшего результата, чем при сборке старой версией. возможно, немножко обидно, что раньше маленький код получался сам, а теперь надо какие-то опции включать-выключать и т.п. - однако, никто не сравнивал "старый" и "новый" код по быстродействию, например? может, размер - не самое главное? тем более когда речь не о килобайтах, а о байтах разницы.

раньше, например, когда писалось PORTB |= _BV(PB1); компилятор всегда генерировал код с обращением к ячейке памяти по соответствующему адресу, т.е. делал минимум 3 команды: LDS, ORI и STS. это было очень хорошо (с одной стороны), так как легко позволяло обращаться к порту по указателю, но по скорости SBI все-же гораздо лучше. и вот в последней версии заметил, что теперь генерируется именно SBI! причем при обращении через указатель получается "старый" вариант - ведь лучше же стало, а?! smile.gif хотя странности присутствуют все равно в коде smile.gif
_Pasha
Цитата(ARV @ Apr 9 2009, 08:57) *
и вот в последней версии заметил, что теперь генерируется именно SBI!

Первый WinAVR, с которым я начал серьезно работать - 20071221 уже без проблем делал sbi/cbi/sbic
Вы какой именно "старый" имеете ввиду - GCC 3 ?
ReAl
Цитата(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 уже был снесён на всех компах.
Сергей Борщ
Цитата(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, а идущие в комплекте забудьте как страшный сон.
ARV
"старый" - это какой-то старый smile.gif я всегда инсталлирую новые версии в одну и ту же папку WinAVR - так что память о версии старых стерта вместе с версиями smile.gif но ведь это и не принципиально. стало лучше - это главное. хотя финты с тасовкой регистров порой изумляют smile.gif
ARV
и все-таки, почему никто из гуру не ответит на вопрос: как заставить работать опцию -mno-wrap? она не опознается как "родная", если передавать ее просто в командной строке avr-gcc и не производит никакого эффекта, если передать ее ассемблеру! а очень нужно избавиться от rjmp в проекте на atmega32.
manul78
Цитата(Сергей Борщ @ Apr 9 2009, 11:41) *
Поиск в гугле по сообщению об ошибке очень помогает в таких случаях.

В комплекте WinAVR идет какая-то очень древняя версия утилит из msys, которую очень любит Eric Weddington. И вместе с этим набором из версии в версию WinAVR кочуют и все болячки той версии msys. На мои призывы к автору обновить эти утилиты был дан ответ - "у них нет нормального инсталятора, мне лень".



Сходите на сайт mingw32/msys и скачайте там самые свежие версии всех этих утилит. После чего используйте их со всеми версиями WinAVR, а идущие в комплекте забудьте как страшный сон.


Уважаемый Сергей ! Я даже не знаю как Вас благодарить... laughing.gif

Самое интересное, что на "стационарном" компе и на "буке" были совершенно разные "занозы" !!!
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 И все ! Земля опять завертелась !!!

Жму руку как ПРОФЕССИОНАЛУ, заходящему сюда не "флудить" а помогать словом и делом !!!
Nick_Shl
А я столкнулся с таким глюком: есть бутлоадер с эмуляцией 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);
Пробовал каждый раз на разных файлах, поэтому "вроде"...
aesok
Цитата(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;
}


Это баг не в комптляторе, это баг в коде.

Анатолий.
Nick_Shl
Цитата(aesok @ Apr 9 2009, 21:32) *
Вот ЭТО написано человеком который поленился прочитать документацию:
Код не мой. Return взят из какого-то файла скачанного из ветки в этом форуме. Но этот код к вышеописанной проблеме отношения не имеет.
aesok
Цитата(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.

Анатолий.
Nick_Shl
Цитата(aesok @ Apr 9 2009, 22:38) *
Если readBits вызывается как функция
Она вообще не вызывается если не давать команды CMD_READ_FUSE_ISP или CMD_READ_LOCK_ISP. Чтение локов и фузов действительно не работает, но оно меня толком и не интересует.
SysRq
Цитата(_Pasha @ Apr 8 2009, 08:34) *
О чем Вы поете? Оно ж пишет rjmp в байтах, а не в словах!
Логично, логично. Лажа с моей стороны имеет место быть sad.gif

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'а вообще никак) - делать патч (маскировать лишние биты).
_Pasha
Цитата(Nick_Shl @ Apr 9 2009, 21:45) *
А я столкнулся с таким глюком:.....

Заинтересовался... Единственное, что делает новый код - он на три команды короче.
Nick_Shl
Цитата(_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 команды.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.