Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: WinAVR-20100110
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
Страницы: 1, 2, 3
_Pasha
Собсно сабж.
Попробовал пока ничего плохого не могу сказать. За выходные разберемся
Слито вместе avr & avr32. Прикольно. 275 метров

AVR-gcc 4.3.3
AVR32-gcc 4.3.2
Make 3.81 - наконец-то ! Или он уже давно там... не помню, ну да ладно.
kurtis
Цитата(_Pasha @ Jan 16 2010, 02:18) *
Слито вместе avr & avr32. Прикольно. 275 метров

На официальном сайте на sourceforge версия занимает 29.9 MB
Petka
Цитата(_Pasha @ Jan 16 2010, 03:18) *
...
AVR-gcc 4.3.3
AVR32-gcc 4.3.2
...

А ваши отзывы?
Напишите хотя-бы как изменился размер собранных бинарников? (было/стало).
SysRq
Цитата
AVR32 GNU toolchain

Splint 3.1.2 Splint is a tool for statically checking C programs for security vulnerabilities and programming mistakes. Splint does many of the traditional lint checks. More powerful checks are made possible by additional information given in source code annotations.

New Device Support

Component Version Upgrades


Цитата(kurtis @ Jan 16 2010, 13:30) *
На официальном сайте на sourceforge версия занимает 29.9 MB
Размер указанный _Pasha - это установленный столько занимает (278 МБ (291 557 454 байт)).

Цитата(Petka @ Jan 16 2010, 13:31) *
Напишите хотя-бы как изменился размер собранных бинарников? (было/стало).
Device: atmega128
20081205: 87924 bytes (67.1% Full);
Новый, 20100110: 87710 bytes (66.9% Full).
zltigo
Цитата(SysRq @ Jan 16 2010, 14:26) *
20081205: 87924 bytes (67.1% Full);
Новый, 20100110: 87710 bytes (66.9% Full).

А оптимизация-то какая при этом?
SysRq
Цитата(zltigo @ Jan 16 2010, 14:28) *
А оптимизация-то какая при этом?
Os.
ARV
я тоже скачал официальный релиз и, как обычно (за последние 4 релиза), обратил внимание, что размер генерируемого бинарника (при полностью одинаковых исходных параметрах) увеличился... не на много, но все-таки возрос. я проверял на тестовом проекте - получил +10 байт (но и сам проект едва 2 килобайта перешагнул).

выходит, с каждым релизом все меньше и меньше шансов использовать всякие "недомерки" attiny13, attiny2xxx и т.п.... жалко...
SysRq
Цитата(ARV @ Jan 16 2010, 17:32) *
...размер генерируемого бинарника (при полностью одинаковых исходных параметрах) увеличился...
А вы генерируемый код не сравнивали, за счет чего конкретно увеличение?

Я рабочие проекты попересобирал (только Си, ++ нету), и в итоге везде уменьшение размера кода: стабильно от 2 байт и больше (2 байта - разница в стартапе). Везде оптимизация по размеру, и
Код
CFLAGS += -ffunction-sections

LDFLAGS += -Wl,--gc-sections
LDFLAGS += -Wl,--relax

Выше я писал 214 байт высвободилось. Сейчас еще один пересобрал - 270 байт освободилось!
Код
D:\Projects_UPD\SA_application>avr-size _main.elf
   text    data     bss     dec     hex filename
   5294       4    1136    6434    1922 _main.elf

D:\Projects_UPD\SA_application>avr-size main.elf
   text    data     bss     dec     hex filename
   5024       4    1136    6164    1814 main.elf

Сравниваю генерируемый код, ибо интересно откуда... cranky.gif

--

Просмотрел по-быстрому. Чудес нету sad.gif
Функция с __attribute__((const)) static inline перестала инлайниться - функция из 12 команд, без пролога\эпилога; вероятно, с форсированием инлайна не прав я -- надо проверить в железе;
Еще одна просто static тоже перестала инлайниться - тут уже решение компилятора в обоих случаях, и мне пофиг;
Кое-где jmp заменен на rjmp, и небольшие оптимизации по использованию регистров (Z -> X), как следствие, возможно, изменений с функциями...
demiurg_spb
Цитата(_Pasha @ Jan 16 2010, 03:18) *
Собсно сабж.

http://www.avrfreaks.net/index.php?name=PN...p;postorder=asc
ARV
а как вы поступаете: ставите сразу несколько копий WinAVR? как можно с удобством тестировать разные сборки компилятора на одинаковых проектах? как быть с прописыванием путей? неудобно же... или я в танке?
Сергей Борщ
Цитата(ARV @ Jan 16 2010, 22:30) *
а как вы поступаете: ставите сразу несколько копий WinAVR? как можно с удобством тестировать разные сборки компилятора на одинаковых проектах? как быть с прописыванием путей?
позаимствовано у ReAl: в makefile прописываем:
Код
#TOOLSET = C:/WinAVR/20090313
TOOLSET = C:/WinAVR/20100110
TARGET = avr-
CC = $(TARGET)gcc
OBJCOPY = $(TARGET)objcopy
OBJDUMP = $(TARGET)objdump
SIZE = $(TARGET)size

# if TOOLSET variable set,
# add TOOLSET bin directory first in PATH    
ifneq ($(strip $(TOOLSET)),)
ifeq (,$(findstring;,$(PATH)))
  PATH := $(subst :,,/$(TOOLSET)/bin):$(PATH)
else
  PATH := $(subst /,\,$(TOOLSET)/bin);$(PATH)
endif
export PATH
endif
Дальше раскомментируем нужную строчку TOOLSET= и все собирается нужной версией.


Цитата(_Pasha @ Jan 16 2010, 02:18) *
Make 3.81 - наконец-то ! Или он уже давно там... не помню, ну да ладно.
Уже давно. Но с древней глючной msys-1.0.dll. На днях автор закрыл мою очередную (датированную 2008-10-02) просьбу в баг-трекере заменить эту dll на более свежую с резолюцией won't fix. Уже давно сделал себе рабочий комплект утилит непосредственно с их родины - проекта msys и утилиты из WinAVRa идут в сад сразу.

По качеству кода - по сравнению с 20090319 на двух проектах код на одном вырос, на втором существенно сократился. Размеры проектов - 1836->1854 (загрузчик) и 6042->5816 (приложение, мега8, С++, виртуальные функции). Работоспособность не проверял. Опции оптимизации для последнего (подбирались по минимальному коду для 20090313):
Код
CFLAGS += -ffunction-sections
CFLAGS += -fdata-sections
CFLAGS += -mcall-prologues

#CFLAGS += -fno-ivopts
CFLAGS += -fno-tree-scev-cprop
CFLAGS += -fno-split-wide-types
CFLAGS += -fno-inline-small-functions

CFLAGS += --param inline-call-cost=0
#CFLAGS += -fno-reorder-blocks
#CFLAGS += -fno-reorder-blocks-and-partition
#CFLAGS += -fno-reorder-functions
#CFLAGS += -fno-toplevel-reorder
CFLAGS += -fno-move-loop-invariants
#CFLAGS += -fno-unroll-loops
#CFLAGS += -fno-unroll-all-loops
#CFLAGS += --param max-unroll-times=0
Левое предупреждение "only initialized variables can be placed into program memory area" на плюсовых исходниках осталось. Баги 40112, 40013 остались.
Судя по рассылке - много правили в avr-libc. Имеет смысл переходить.

P.S. Заметил, что некорректно распаковал новую версию и сравнивал 20090313 с ней же. Исправил. Написаному выше теперь - верить.
_Pasha
Цитата(ARV @ Jan 17 2010, 00:30) *
а как вы поступаете: ставите сразу несколько копий WinAVR? как можно с удобством тестировать разные сборки компилятора на одинаковых проектах? как быть с прописыванием путей? неудобно же... или я в танке?

Я на флешке держу все используемые ГЦЦ - от MinGW до SDCC +несколько версий winAVR и yagarto. Выбор через makefile. Откатиться на предыдущую версию - одним # в начале строки выбора. Однако, 2009 стабильненький был. Ни разу не огорчил.

Цитата(Сергей Борщ @ Jan 17 2010, 02:36) *
Уже давно сделал себе рабочий комплект утилит непосредственно с их родины - проекта msys и утилиты из WinAVRa идут в сад сразу.

То же самое. Неприятно только, что winavr кидает свои binutils в пути, потом приходится вычищать.

Так. Пробую. Проект с параметрами из-под плагина студии
Код
avr-gcc.exe  -mmcu=atmega16 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -fu
nsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -mcall-prologues
-finline-limit=2 -MD -MP -MT


WinAVR-2009
Код
AVR Memory Usage
----------------
Device: atmega16

Program:    6300 bytes (38.5% Full)
(.text + .data + .bootloader)

Data:         75 bytes (7.3% Full)
(.data + .bss + .noinit)

EEPROM:       57 bytes (11.1% Full)
(.eeprom


WinAVR-2010
Код
AVR Memory Usage
----------------
Device: atmega16

Program:    6238 bytes (38.1% Full)
(.text + .data + .bootloader)

Data:         75 bytes (7.3% Full)
(.data + .bss + .noinit)

EEPROM:       57 bytes (11.1% Full)
(.eeprom)


Вывод пока один - avr-libc немного подрихтовали-таки. Насчет работоспособности проекта - тоже пока не проверял.
ReAl
Цитата(ARV @ Jan 16 2010, 22:30) *
а как вы поступаете: ставите сразу несколько копий WinAVR? как можно с удобством тестировать разные сборки компилятора на одинаковых проектах? как быть с прописыванием путей?
Однин из моих подходов озвучен выше.
Правда, эта "поделка" подходит не всем, так как мои makefile есть не у всех, не входят в стандатную поставку WinAVR, а стандартный и доступный каждому Mfile такого не генерирует.

Второй способ действует не попроектно, а валом на все, зато PATH не модифицируется на лету и всякие AVRstudio работают. И удобно для каких-то проверок прямо в командной строке набрать avr-gcc -Os -S foo.c.
Используется возможность файловой системы NTFS создавать линки на каталоги (на файлы тоже может, но это другая история, позволяющая на несколкьо мегабайт сократить размер каталога WinAVR-XXXX путём замены копий файлов из WinAVR-XXXXXX\bin на линки к телам файлов из WinAVR-XXXXXX\avr\bin Впрочем, сейчас это не актуально)

Ставим как и раньше толпу WinAVR-XXXX в соответствующие каталоги, но в PATH происываем C:\WinAVR\bin - как для установки одной версии в этот каталог. Но самого каталога нет.
Теперь лезем сюда http://technet.microsoft.com/en-us/sysinte...s/bb896768.aspx и берём программу junction либо ставим FAR.
Для работы с конкретной версией, например, WinAVR-20060421, говорим
Цитата
junction C:\WinAVR C:\WinAVR-20060421
кстати, WinAVR-20060421 может стоять вообще в f:\avr\gcc\WinAVR-20060421, тогда говорим
Цитата
junction C:\WinAVR f:\avr\gcc\WinAVR-20060421

Либо в FAR становимся на каталог f:\avr\gcc\WinAVR-20060421, наимаем Alt-F6 и в строке ввода набираем C:\WinAVR (либо нажимем Ctrl-Down и выбираем из списка).
Дополнительного места на диске C: это практически не займёт.
Кажется, что-то такое есть и в TotalCommnder через плугин.
FAR напротив такого каталога показывает не <Folder> а <Link>, по F8 стирает только линк.
Windows explorer в W2000/XP никак не выделяет, более того, при попытке вытереть линк он трёт его и все файлы каталога, на который указывал линк! Левая рука вин не знает, что сделала правая.

Теперь все программы, которые будут лезть в С:\WinAVR\ - будут попадать в указываемый линком каталог. Если в makefile ничего не указано, рассчитано на размещение компилятора по PATH, то при смене цели линка все проектіначнут копилироваться другой версией.
Сергей Борщ
Цитата(_Pasha @ Jan 17 2010, 07:55) *
Неприятно только, что winavr кидает свои binutils в пути, потом приходится вычищать.
А я распаковываю инсталятор при помощи 7Zip и вытягиваю только нужные папки. И быстрее, и реестр не засоряется, и легко сносится удалением папки. Такой вот portable вариант.
Petka
Цитата(Сергей Борщ @ Jan 17 2010, 12:19) *
А я распаковываю инсталятор при помощи 7Zip и вытягиваю только нужные папки. И быстрее, и реестр не засоряется, и легко сносится удалением папки. Такой вот portable вариант.

Поступаю аналогично. Только использую батник, который создаёт консоль, с прописанными нужными путями. Из этой консоли можно запускать хоть make хоть eclipse. Давно собирался выложить на суд общественности своё решение по объединению всех GNU/OpenSource утилит и программ для embedded.
ReAl
Цитата(Petka @ Jan 17 2010, 12:00) *
Давно собирался выложить на суд общественности своё решение по объединению всех GNU/OpenSource утилит и программ для embedded.
Давно ждём :-)
demiurg_spb
Цитата(Petka @ Jan 17 2010, 13:00) *
Давно собирался выложить на суд общественности своё решение по объединению всех GNU/OpenSource утилит и программ для embedded.
Так что же сдерживает?smile.gif
ReAl
Цитата(demiurg_spb @ Jan 17 2010, 23:28) *
Так что же сдерживает?smile.gif
Дык эта... Времени нет найти время.
Genadi Zawidowski
Было...
Цитата
AVR Memory Usage
----------------
Device: atmega32

Program: 24930 bytes (76.1% Full)
(.text + .data + .bootloader)

Data: 1053 bytes (51.4% Full)
(.data + .bss + .noinit)


стало...

Цитата
AVR Memory Usage
----------------
Device: atmega32

Program: 23838 bytes (72.7% Full)
(.text + .data + .bootloader)

Data: 1053 bytes (51.4% Full)
(.data + .bss + .noinit)
demiurg_spb
Цитата(Сергей Борщ @ Jan 17 2010, 01:36) *
На днях автор закрыл мою очередную (датированную 2008-10-02) просьбу в баг-трекере заменить эту dll на более свежую с резолюцией won't fix.
Я тоже ждал около года пока вкрячат в pgmspace.h мой патч с интерфейсом для типа float (pgm_read_float).
Цитата
Уже давно сделал себе рабочий комплект утилит непосредственно с их родины - проекта msys и утилиты из WinAVRa идут в сад сразу
Может поделитесь опытом?
Цитата(Сергей Борщ @ Jan 17 2010, 12:19) *
А я распаковываю инсталлятор при помощи 7Zip и вытягиваю только нужные папки. И быстрее, и реестр не засоряется, и легко сносится удалением папки. Такой вот portable вариант.
Попробовал таким способом (или почти таким). Распаковал 7Zip новый дистрибутив и разместил его в директории c:\WinAVR
(там была раньше установлена предыдущая версия, которую я предварительно переименовал в c:\WinAVR_prev).
Что получил:
1. Не находит avr-gcc.exe (посмотрел в c:\WinAVR\bin там только avr-gcc-4.3.3.exe, ну я шифт+Ф5 и создал avr-gcc.exe из него - полегчало).
2. Файлы float.h, stddef.h и прочие переехали в с:\WinAVR\lib\gcc\avr32\4.3.2\include
3. Ну и:
Код
c:/winavr/lib/gcc/../../avr/include/avr/pgmspace.h:848: error: expected declaration specifiers or '...' before 'size_t'
c:/winavr/lib/gcc/../../avr/include/avr/pgmspace.h:849: error: expected declaration specifiers or '...' before 'size_t'
c:/winavr/lib/gcc/../../avr/include/avr/pgmspace.h:850: error: expected declaration specifiers or '...' before 'size_t'
...
c:/winavr/lib/gcc/../../avr/include/avr/pgmspace.h:861: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'strcspn_P'
c:/winavr/lib/gcc/../../avr/include/avr/pgmspace.h:862: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'strlcat_P'
...
Как с этим жить дальше?:-) Что я сделал не так?
PS в Path есть это: C:\WinAVR\bin;C:\WinAVR\utils\bin;
Сергей Борщ
По msys - взять с http://sourceforge.net/projects/mingw/files/ из MSYS proposed архив msysCORE последней версии, распаковать куда-нибудь, путь к его папке bin прописать в PATH, распаковать туда же MSYS coreutils и необходимые пакеты (MSYS bash, MSYS make, и т.д.).
Цитата(demiurg_spb @ Jan 18 2010, 12:13) *
1. Не находит avr-gcc.exe (посмотрел в c:\WinAVR\bin там только avr-gcc-4.3.3.exe, ну я шифт+Ф5 и создал avr-gcc.exe из него - полегчало).
2. Файлы float.h, stddef.h и прочие переехали в с:\WinAVR\lib\gcc\avr32\4.3.2\include
1 пункт - аналогично. 2 пункт - скопировал содержимое lib\gcc\avr\4.3.2\include из 20090313. Не решился брать из avr32 - все же слишком разные ядра, мало ли размер данных там где-то не будет совпадать. Это решило и проблему п.3
demiurg_spb
Цитата(Сергей Борщ @ Jan 18 2010, 14:54) *
По msys - взять с http://sourceforge.net/projects/mingw/files/ из MSYS proposed архив msysCORE последней версии, распаковать куда-нибудь, путь к его папке bin прописать в PATH, распаковать туда же MSYS coreutils и необходимые пакеты (MSYS bash, MSYS make, и т.д.).
Спасибо! Попробую.
Дальнейшие изыскания привели к следующему:
1. Пришлось shift+f5
из с:\WinAVR\avr\bin (objcopy.exe, objdump.exe и nm.exe)
в с:\WinAVR\bin (avr-objcopy.exe, avr-objdump.exe и avr-nm.exe) соответственно.
2. файл crtm1281 скопировал из c:\WinAVR\avr\lib\avr5\ в c:\WinAVR\avr\lib\avr51\
(сравнивая с предыдущим релизом WinAVR тут в avr\lib\avr51 не хватает массы файлов).
Проект скомпилился 63294 -> 62838 (стало меньше на 456 байт).
Сергей Борщ
Проинсталлил "честно".
Оно копирует кучу файлов. Искать и делать то же самое вручную считаю нецелесообразным. Поэтому инсталл в C:\WinAVR, нужные папки копирую в место постоянной прописки, получившуюся структуру каталогов архивирую для переноса на другие компы, после чего uninstall оригинала.
_Diman_
bb-offtopic.gif Я так приспособился разные версии проверять. Запускаю pn через батфайл с путями
Код
echo OFF
PATH;
set PATH=C:\WinAVR-20090313\bin;C:\WinAVR-20090313\utils\bin;
"E:\portable-pn20101010\pn.exe"
echo WinAVR-20090313


http://sourceforge.net/projects/winavr/files/ Я здесь не нашел WinAVR-20100110
_Pasha
Цитата(_Diman_ @ Jan 19 2010, 13:37) *
http://sourceforge.net/projects/winavr/files/ Я здесь не нашел WinAVR-20100110

Оригинально. Пока на эту тему-тишина. Даже на avrfreaks.
Зайцев Иван
А кто нибуть использовал уже avr32-gcc?
Если да то каие впечатления по сравнеию с родным Atmel-овским?
klen
Цитата(Зайцев Иван @ Jan 19 2010, 14:17) *
А кто нибуть использовал уже avr32-gcc?
Если да то каие впечатления по сравнеию с родным Atmel-овским?

а что такое родной атмеловский? оно разве когданить существовало?
или Вы про сборку атмеля имеете ввиду?
Зайцев Иван
Цитата(klen @ Jan 20 2010, 01:44) *
а что такое родной атмеловский? оно разве когданить существовало?
или Вы про сборку атмеля имеете ввиду?

Да я имел в виду toolchain собрвный Atmel-ом
Cyber_RAT
http://sourceforge.net/projects/winavr/files/
опять появился WinAVR-20100110
SysRq
Цитата(Cyber_RAT @ Jan 21 2010, 00:29) *
опять появился WinAVR-20100110
По отношению к выложенному ранее:
  • добавлено много *.h и несколько *.a для avr32;
  • убраны debug symbols из всех *.a;
  • в *.exe разница в паре байт в PE-заголовках.
_Pasha
Цитата(SysRq @ Jan 21 2010, 02:23) *
убраны debug symbols из всех *.a;

По этому поводу E.W. на avrfreaks писал типа "а что мешает самостоятельно их пострипать?" smile.gif
Сергей Борщ
Цитата(Сергей Борщ @ Jan 17 2010, 00:36) *
Размеры проектов - 1836->1854 (загрузчик) и 6042->5816 (приложение, мега8, С++, виртуальные функции). Работоспособность не проверял.
Проверил. Код работает. Сравнил листинги (правда для другого проекта). Основное отличие - обращение к eeprom. В 20090313 процедура чтения|записи блока принимала в качестве параметра указатель на функцию чтения|записи байта и косвенно вызывала эту функцию. Теперь функция чтения/записи байта встроена в чтение/запись блока, благодаря чему экономится место как на загрузке указателя так и на перетасовке регистров при косвенном вызове. В 20100110 вся процедура чтения/записи блока (со встроенным обращением) меньше, чем обертка вызова функции чтения/записи байта в 20090313. Кроме этого в 20090313 независимо от -msave-prologue запись/чтение блока вызывала процедуры сохранения/восстановления регистров, которые в 20100110 не понадобились. Результат - уменьшение кода на 148 байт. В остальном код на этом конкретном проекте идентичный до байта. Вывод - теперь можно смело использовать eeprom_read_block(). В 20090313 эффективнее получалось вручную читать побайтно в цикле.


Остался недостаток оптимизации при работе с байтовыми аргументами функций: При вызове функции, объявленной с аргументом типа "байт" в регистры заносится 2 байта (старший = 0), внутри функции копия аргумента тоже хранится как двухбайтовая переменная, хотя используется только младший байт:
Код
void hd44780::write_data(uint8_t byte)
162:    ff 92           push    r15
164:    0f 93           push    r16
166:    1f 93           push    r17                             <-----------------------------------
168:    8c 01           movw    r16, r24                       <-----------------------------------
16a:    f6 2e           mov    r15, r22
{
    write_tetrade(byte & 0xF0);
16c:    60 7f           andi    r22, 0xF0; 240
16e:    ec df           rcall    .-40    ; 0x148 <_ZN7hd4478013write_tetradeEh>
    write_tetrade(byte << 4);
170:    f2 94           swap    r15
172:    80 ef           ldi    r24, 0xF0; 240
174:    f8 22           and    r15, r24
176:    c8 01           movw    r24, r16                            <-----------------------------------
178:    6f 2d           mov    r22, r15
17a:    e6 df           rcall    .-52    ; 0x148 <_ZN7hd4478013write_tetradeEh>
17c:    8d e3           ldi    r24, 0x3D; 61
17e:    8a 95           dec    r24
180:    f1 f7           brne    .-4     ; 0x17e <_ZN7hd4478010write_dataEh+0x1c>
    _delay_us(50);
    ON(LCD_RS);
182:    c1 9a           sbi    0x18, 1; 24
}
184:    1f 91           pop    r17                        <-----------------------------------
186:    0f 91           pop    r16
188:    ff 90           pop    r15
18a:    08 95           ret
Vova75
Ошибку  в прологе/эпилоге при использовании ISR(xxx_vect, ISR_NOBLOCK) так и не исправили sad.gif
Проект для меги1280 на С++ в 14КБ собрался на 150 байт меньше, это хорошо.
ReAl
Однако...

То-то я чуйкой какой-то ("шестое чувство в пятой точке") играюсь разными версиями, а рабочие компиляции в 20071221 делаю :-)
Genadi Zawidowski
Цитата
Code:
#include <avr/io.h>
volatile uint8_t v;

int main(void) {
while (1) {
v;
v;
v;
#if BUG
uint8_t* p = (uint8_t*) &v; PORTC = *p;
#endif
}
}

avr-gcc 3.4.6 (WinAVR-20060421):
Code:

.text
.global main
.type main, @function
main:

ldi r28,lo8(__stack - 0)
ldi r29,hi8(__stack - 0)
out __SP_H__,r29
out __SP_L__,r28

lds r25,v
.L2:
lds r24,v
lds r24,v
lds r24,v
out 40-0x20,r25
rjmp .L2
(yes, first lds is placed out of loop)

avr-gcc 4.1.2 (WinAVR-20070525) - the same except no stack pointer initialisation
avr-gcc 4.2.2 (WinAVR=20071221) - the same except no stack pointer initialisation
avr-gcc 4.3.2 (WinAVR-20081205) and later - as WinAVR-20100110


А чего тут криминального? Чтений из volatile ровно столько, сколько надо. А от чтения по указателю на простой (не volatile) тип - ничего, кроме знаачения не гарантируется. А откуда оно его взяло - целиком на усмотрение оптимизатора. Вообще, всё что не volatile, может быть "закешированно" при входе в функцию и записано перед выходом из неё или вызовом чего-либо.
ReAl
Цитата(Genadi Zawidowski @ Feb 8 2010, 08:04) *
А чего тут криминального?
Тут всё нормально. Вы посмотрите что из этого делают версии WinAVR-2008, 2009 и та 2010, которая в теме и обсуждается. Там из v при -DBUG=1 делется одно чтение.
Вот это "as WinAVR-20100110"
Код
.global    main
    .type    main, @function
main:
.L2:
    lds r24,v
    out 53-32,r24
    rjmp .L2
У Klen-сборок 4.4.0 и 4.5.0 и у WinAVR по 20071221 включительно (т.е. по 4.2.x включительно) всё нормально.
Т.е. - похоже, что ошибка в 4.3.x

Цитата(Genadi Zawidowski @ Feb 8 2010, 08:04) *
Вообще, всё что не volatile, может быть "закешированно" при входе в функцию и записано перед выходом из неё или вызовом чего-либо.
И, если не зависит друг от друга, то переставлено местами (в том числе и с обращениями к volatile), и вообще выброшено.
А то я этого не знаю :-)
_Pasha
Цитата(ReAl @ Feb 5 2010, 01:24) *
Однако...

Однако, дубль два.
Имеем:
Код
double res;
//..............
return (int16_t) (lround(res) - 273);

Скомпилировано с опцией -mint8

Получаем:
Код
+000007BC:   01C8        MOVW    R24,R16          
+000007BD:   01B7        MOVW    R22,R14          
+000007BE:   D12D        RCALL   PC+0x012E   // lround(res) R23:R22:r25:r24 = 0x01870000
+000007BF:   019C        MOVW    R18,R24       // осторожно, грабли!  
+000007C0:   5121        SUBI    R18,0x11   // - 273      
+000007C1:   4031        SBCI    R19,0x01        
+000007C2:   01C9        MOVW    R24,R18

Вместо того чтобы правильный результат в старшей половине, отдает ноль.
Без опции -mint8 - все нормально.
Просьба советы никогда не применять указанную опцию не давать! smile.gif
А вначале был оч.рад, когда используя stdint.h получал утоптанные выражения целого типа. Недолго музыка играла.
_Pasha
Цитата(_Pasha @ Feb 8 2010, 16:59) *
Однако, дубль два.

sad.gif Боян оказываеццо, с 2004 года так и не удосужились подрихтовать.

Еще прикол. Кто нибудь знает, как избавиться от неправильного назначения регистровых пар? Например, имеем указатель на структуру, и поля в ней интенсивно используются. Сабж так любит регистры XH:XL, что поручает именно Х эту непосильную работу. В итоге, послав все к чертям, я прибил эти регистры
Код
register volatile uint8_t xL asm("r26");
register volatile uint8_t xH asm("r27");

Компилер немедленно взялся за ум и функция изрядно похудела, т.к. пошли в ход инструкции LDD/STD
cranky.gif Неужели эту фигню никогда не причешут?
А у KGP как с этим дела? (Нету времени попробовать...)
_Pasha
1111493779.gif Ау, я что, в палате №6? Не спим!
Нашел серьезную багу.
Предположим, имеется глобальная переменная или extern
Код
uint8_t period;

Попытка сделать задаром арифметическую операцию по модулю 100, например так
Код
period += 33;
if(period > 100) period -= 100;

Приводит к созданию неожиданного кода, наподобие
Код
  lds r24,period
  subi r24,0xdf // period += 33
  cpi  r24,0x64
  brlo label
  subi r24,0x43 // !!! а должно быть 0x64
label:

Оптимизация -Os
Это катастрофа. У оптимизатора появилась ложная зависимость, и он посчитал что надо вычесть не 100, а 100-33 = 67
Сколько таких случаев надо отсматривать в листинге - ХЗ smile3046.gif
Мне повезло, что вносилась доработка в уже готовое софто.

Проблема имеет workaround, як кажуть кляті англійці
Для того, чтобы код выполнялся правильно, надо period объявить volatile
Такие дела.
Видимо, придется возвращаться в WinAVR-20071221 cranky.gif
misyachniy
Друг спросил как разместить данные во флеш поопределенному адресу.

Сделал как по ссылке.

http://8515.avrfreaks.net/index.php?name=P...ic&p=589365

WinAVR-20100110.

Судя по листингу программа обращается к данным как задано

Код
  
const uint8_t part_number __attribute__ ((section (".part_number")))='A';

i = pgm_read_byte(&part_number);    
     2ee:    e0 ef           ldi    r30, 0xF0; 240    
     2f0:    ff e3           ldi    r31, 0x3F; 63    
     2f2:    e4 91           lpm    r30, Z+


Но ни в HEX ни в bin файле нету данных.

Обычное объявление переменных в памяти программ работает.
Совместить два аттрибута у меня не получилось.
Сергей Борщ
Цитата(misyachniy @ Feb 17 2010, 17:39) *
Но ни в HEX ни в bin файле нету данных.
попробйте обозвать секцию .text.partnumber или .progmem.partnumber
Я указываю секцию в скрипте линкера, --section-start не пользовался.
SysRq
Цитата(_Pasha @ Feb 17 2010, 09:59) *
Нашел серьезную багу.
Воссоздать не получается.

Используется два регистра, оттуда и такой подход с константами:
Код
    lds r25,period
    mov r24,r25
    subi r24,lo8(-(33))
    sts period,r24    
    cpi r24,lo8(101)
    brlo .L3
    subi r25,lo8(-(-67))
    sts period,r25
.L3
Дайте проект, в котором у вас такая ошибка возникает, ибо пока не понятно (доприбивались вы регистры, хехе laughing.gif).

--

Цитата(misyachniy @ Feb 17 2010, 18:39) *
Сделал как по ссылке.
Тоже сделал. Данные все на месте. Разница в оптимизации? Показывайте Makefile.
ReAl
Цитата(_Pasha @ Feb 17 2010, 08:59) *
Попытка сделать задаром арифметическую операцию по модулю 100, например так
...
Оптимизация -Os
Это катастрофа. У оптимизатора появилась ложная зависимость, и он посчитал что надо вычесть не 100, а 100-33 = 67
Мне не удалось полeчить такую бяку. Код странноватый (оптимизатор явно перемудрил) но корректный.
Более того - он не отличается от кода 20071221
Код
#include <avr/io.h>
      
extern uint8_t period;

void foo()
{
    period += 33;
    if(period > 100) period -= 100;
}


uint8_t moo(uint8_t i)
{
    i += 33;
    if(i > 100) i -= 100;
    return i;
}

-Os
Код
    .text
.global    foo
    .type    foo, @function
foo:
    lds r25,period
    mov r24,r25
    subi r24,lo8(-(33))
    sts period,r24
    cpi r24,lo8(101)
    brlo .L3
    subi r25,lo8(-(-67))       ; 67 вычитается из _исходного_ значения (+33-100) <=> (-67)
    sts period,r25
.L3:
    ret

.global    moo
    .type    moo, @function
moo:
    subi r24,lo8(-(33))
    cpi r24,lo8(101)
    brlo .L5
    subi r24,lo8(-(-100))
.L5:
    ret
ZiB
аналогично, не удалось воссоздать ошибку.
проверил на готовом проекте код уменьшился, сравнил - лучше оптимизация в условиях.
правда у меня во всех проектах оптимизция равна 2.
misyachniy
Цитата(Сергей Борщ @ Feb 17 2010, 19:50) *
попробйте обозвать секцию .text.partnumber или .progmem.partnumber
Я указываю секцию в скрипте линкера, --section-start не пользовался.


Переобъявил, секция попала сразу за таблицей векторов.
Как в скрипте линкера без --section-start настраивать я не умею.

Код
код
const uint8_t part_number __attribute__ ((section (".progmem.part_number")))='A';
const  unsigned long serial_number __attribute__ ((section (".progmem.serial_number"))) = 0x12345678;

маке
LDFLAGS += -Wl,--section-start=.progmem.part_number=$(PART_NUMBER_ADDRESS)
LDFLAGS += -Wl,--section-start=.progmem.serial_number=$(SERIAL_NUMBER_ADDRESS)

HEX
:100050000C9458 0041 78563412 456E7465722063D2

LST
00000054 <part_number>:
      54:    41                                                  A

  i = pgm_read_byte(&part_number);
     2f4:    e4 e5           ldi    r30, 0x54; 84
     2f6:    f0 e0           ldi    r31, 0x00; 0
     2f8:    e4 91           lpm    r30, Z+
Сергей Борщ
Цитата(misyachniy @ Feb 18 2010, 11:49) *
Переобъявил, секция попала сразу за таблицей векторов.
"Ну тогда не знаю laughing.gif "
Цитата(misyachniy @ Feb 18 2010, 11:49) *
Как в скрипте линкера без --section-start настраивать я не умею.
Идете в WinAVR/avr/lib/ldscripts, берете там скрипт для своего семейства, копируете в проект, правите, добавляете к ключам линкера LDFLAGS += -Wl,-T,<имя скрипта> и получаете полный контроль над адресным пространством. Вот пример для загрузчика m88 (регион и секция serial_no):
CODE
/* ATmega88 bootloader linker script */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:4)
MEMORY
{
application (rx) : ORIGIN = 0, LENGTH = 7K
bootloader (rx) : ORIGIN = 7K, LENGTH = 1K - 4
serial_no (rx) : ORIGIN = 8K-4, LENGTH = 4
ram (rw!x) : ORIGIN = 0x800100, LENGTH = 1K
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 512
}
SECTIONS
{
/* Internal text space or external memory. */
.app :
{
__app_start = . ;
/* reserve space */
. = 7K;
__app_end = . ;
} > application
__app_len = . - __app_start;
.text :
{
KEEP(*(.vectors))
/* For data that needs to reside in the lower 64k of progmem. */
*(.progmem.gcc*)
*(.progmem*)
. = ALIGN(2);
__trampolines_start = . ;
/* The jump trampolines for the 16-bit limited relocs will reside here. */
*(.trampolines)
*(.trampolines*)
__trampolines_end = . ;
/* For future tablejump instruction arrays for 3 byte pc devices.
We don't relax jump/call instructions within these sections. */
*(.jumptables)
*(.jumptables*)
/* For code that needs to reside in the lower 128k progmem. */
*(.lowtext)
*(.lowtext*)
__ctors_start = . ;
KEEP(SORT(*)(.ctors))
__ctors_end = . ;
__dtors_start = . ;
KEEP(SORT(*)(.dtors))
__dtors_end = . ;
/* From this point on, we don't bother about wether the insns are
below or above the 16 bits boundary. */
KEEP (*(.init0)) /* Start here after reset. */
KEEP (*(.init1))
KEEP (*(.init2)) /* Clear __zero_reg__, set up stack pointer. */
KEEP (*(.init3))
KEEP (*(.init4)) /* Initialize data and BSS. */
KEEP (*(.init5))
KEEP (*(.init6)) /* C++ constructors. */
KEEP (*(.init7))
KEEP (*(.init8))
KEEP (*(.init9)) /* Call main(). */
*(.text)
. = ALIGN(2);
*(.text.*)
. = ALIGN(2);
KEEP (*(.fini9)) /* _exit() starts here. */
KEEP (*(.fini8))
KEEP (*(.fini7))
KEEP (*(.fini6)) /* C++ destructors. */
KEEP (*(.fini5))
KEEP (*(.fini4))
KEEP (*(.fini3))
KEEP (*(.fini2))
KEEP (*(.fini1))
KEEP (*(.fini0)) /* Infinite loop after program termination. */
_etext = . ;
} > bootloader

.data :
{
PROVIDE (__data_start = .) ;
*(.gnu.linkonce.d*)
*(.rodata)
*(.rodata*)
*(.data)
*(.data*)
. = ALIGN(2);
_edata = . ;
PROVIDE (__data_end = .) ;
} > ram AT > bootloader

.bss :
{
PROVIDE (__bss_start = .) ;
*(.bss)
*(.bss*)
*(COMMON)
PROVIDE (__bss_end = .) ;
} > ram
__data_load_start = LOADADDR(.data);
__data_load_end = __data_load_start + SIZEOF(.data);

.serial_no :
{
KEEP(*(.serial_no))
} > serial_no

/* Global data not cleared after reset. */
.noinit :
{
PROVIDE (__noinit_start = .) ;
*(.noinit*)
PROVIDE (__noinit_end = .) ;
_end = . ;
PROVIDE (__heap_start = .) ;
} > ram

.eeprom :
{
*(.eeprom*)
__eeprom_end = . ;
} > eeprom

/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }

/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}
И еще - мне показалось удобнее хранить не константу серийного номера, а функцию, возвращающую серийный номер. А уже в код самой функции на этапе программирования подставлять коды LDI с серийным номером (avreal умеет). Это позволяет разместить такой серийник в защищенном от чтения по LPM загрузчике и тратить на чтение один ( R )CALL вместо сохранения Z, его загрузки, LPM, восстановления Z:
Код
__attribute__((section(".serial_no"), noinline))
uint8_t serial_no()
{
    return 0;
}


177                       .section    .serial_no,"ax",@progbits
178                   .global    serial_no
180                   serial_no:
181                   .LFB15:
182                   .LSM26:
183                   /* prologue: function */
184                   /* frame size = 0 */
185                   .LSM27:
186 0000 80E0              ldi r24,lo8(0)
187                   /* epilogue start */
188 0002 0895              ret
demiurg_spb
Забавный прикол:
Код
uint16_t x;
....
if ((x&1)==0) {...} // случай 1
if (!(x&1))      {...} // случай 2
Получаем листинг:
Код
// случай 1:
   1fd3c:    20 fd           sbrc    r18, 0
   1fd3e:    03 c0           rjmp    .+6      ; 0x1fd46 <main+0x4e4>

// случай 2
   1fd40:    c9 01           movw    r24, r18
   1fd42:    81 70           andi    r24, 0x01; 1
   1fd44:    90 70           andi    r25, 0x00; 0
   1fd46:    89 2b           or    r24, r25
   1fd48:    19 f4           brne    .+6      ; 0x1fd50 <main+0x4ee>
_Pasha
Цитата(ReAl @ Feb 17 2010, 22:53) *
Мне не удалось полeчить такую бяку. Код странноватый (оптимизатор явно перемудрил) но корректный.

Так. Вернувшись к вопросу, вынужден признать, что воссоздать ошибку снова мне не удалось. Это означает, что я поспешил с выводами. Приношу свои искренние извинения. Теперь осталось найти истинную причину, почему для получения рабочей программы требовалось volatile... 07.gif
_Pasha
Цитата(Сергей Борщ @ Feb 18 2010, 15:32) *
Вот пример для загрузчика m88

Кстати - столкнулся с проблемой написания загрузчика на мегу48. Условия уродливые - надо расшаривать протокол связи. В связи с этим разбил программу на две части :
Код
vectors
fixed_boot
progmem
init0
итд итп

В секцию fixed_boot помещаю весь протокол, контр.сумму и стартап.
После этого остутствует необходимость в таблице системных вызовов, обращаться в мини-биосу можно обычными вызовами функций, т.к. эта часть намертво пришпилена после таблицы векторовНажмите для просмотра прикрепленного файла
Кто что думает о таком варианте?
UPD: makefile был с ошибкой. Исправлено
Сергей Борщ
Цитата(_Pasha @ Mar 16 2010, 20:05) *
т.к. эта часть намертво пришпилена после таблицы векторов
До первой найденой ошибки или добавления еще одной функции в протокол.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.