WinAvr в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

пока писал - опередили :) и предложили "решение в лоб" - третий способ :))) в сущности, мой первый вариант мало отличается от этого...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
DimAlt
Вымогатель припоя
Сообщения: 576
Зарегистрирован: Пт май 19, 2006 05:39:11
Контактная информация:

Сообщение DimAlt »

Вариант с битовыми полями интересный, спасибо.
Скомпилировал все варианты, "решение в лоб" оказалось самое короткое :))
Аватара пользователя
krolaka
Нашел транзистор. Понюхал.
Сообщения: 169
Зарегистрирован: Пн мар 02, 2009 12:23:37
Контактная информация:

Сообщение krolaka »

обясните почему себя так ведет sprintf вот привожу пример програмы

char yf[];

.....

char year,year_10, year_1

.....

year_10=(bq32000_addr[6]&0b11110000)>>4;
year_1=bq32000_addr[6]&0b00001111;

sprintf(yf,"%2i%2i",year_10,year_1);
lcd_puts(yf);

выводит мне 5853 вместо 2010 да и вобще любое схожое число там пишет не пойму почему :(
в переменуюю специально записал bq32000_addr[6]=0b00101010;
Изображение
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

krolaka писал(а):обясните почему себя так ведет sprintf вот привожу пример програмы

В первую очередь рекоммендую явно задать размер массива yf - пять символов, ибо sprintf ввыводит в память строку с завершающим символом '\0'.
А вообще что-то не пойму логики, зачем какие-то операции над year_10 и year_1 и зачем вообще эти переменные? Не проще так:

Код: Выделить всё

char yf[5]
uint16 year;
year=2010;
sprintf(yf, "%.4i", year)

В качестве полезного совета предлагаю сначала отладить sprintf на строке из чисел, а потом переходить к преобразованиям.
xVekx
Встал на лапы
Сообщения: 125
Зарегистрирован: Вс мар 01, 2009 20:41:19

Сообщение xVekx »

Как врубить поддержку c++ в проектах ??
Хотел перейти с IAR на WINAVR а тут такой касяк =((

Код: Выделить всё

#include <avr>
#include <avr>
#include <avr>

class Test
{
public:Test();
};
Test::Test(){}

int main()
{char *a=new char [2];}



Код: Выделить всё

avr-gcc  -mmcu=atmega2560 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c  ../main.c
../main.c:5: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Test'
../main.c:9: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token
../main.c: In function 'main':
../main.c:12: error: 'new' undeclared (first use in this function)
../main.c:12: error: (Each undeclared identifier is reported only once
../main.c:12: error: for each function it appears in.)
../main.c:12: error: expected ',' or ';' before 'char'
../main.c:12: warning: unused variable 'a'
make: *** [main.o] Error 1
Build failed with 6 errors and 1 warnings...

Помогите плизз!! =)
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

xVekx писал(а):Как врубить поддержку c++ в проектах ??...

попробуйте переименовать main.c в main.cpp
xVekx
Встал на лапы
Сообщения: 125
Зарегистрирован: Вс мар 01, 2009 20:41:19

Сообщение xVekx »

пробовал

Код: Выделить всё

cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
../main.cpp: In function 'int main()':
../main.cpp:9: warning: unused variable 'a'
avr-g++ -mmcu=atmega2560 -Wl,-Map=AVRWIN001.map main.o     -o AVRWIN001.elf
main.o: In function `main':
S:\AVRWIN001\default/../main.cpp:9: undefined reference to `operator new[](unsigned int)'
make: *** [AVRWIN001.elf] Error 1
Build failed with 1 errors and 2 warnings...

класс прошёл, но дин массив нет =(( .
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Сообщение avreal »

"Вы будете смеяться", но нужно дать файлу расширение .cpp
Можно, конечно, дать ключ

Код: Выделить всё

avr-gcc -x c++ -c main.c
но логичнее просто дать расширение, соответствующее языку.

Пример использования С++ для avr-gcc можно посмотреть тут
Правда, там new не используется.

Ещё полезное место - тема о С++ в avr-gcc на avrfreaks
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
xVekx
Встал на лапы
Сообщения: 125
Зарегистрирован: Вс мар 01, 2009 20:41:19

Сообщение xVekx »

хех флаг

надо было добавить =)), но ошибка все равно есть

Код: Выделить всё

S:\AVRWIN001\default/../main.c:18: undefined reference to `operator new[](unsigned int)'

вот мой Makefile
Использую связку AVR studio + WinAVR-20100110.
Вложения
Makefile.zip
Makefile
(1004 байт) 303 скачивания
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Сообщение avreal »

xVekx писал(а):хех флаг

надо было добавить =))
Я всё же рекомендую использовать не этот флаг, а правльное расширение - если файл будет main.cpp, то єтот флаг не нужен. В проекте по разным соображениям может возникнуть желане применить и С-шные файлы (свои или чужие) и по расширению "драйвер" avr-gcc разберётся и применит нужный компилятор, а ключ смешивает всё в одну кучу.

xVekx писал(а):но ошибка все равно есть

Код: Выделить всё

S:\AVRWIN001\default/../main.c:18: undefined reference to `operator new[](unsigned int)'
операторов new и delete нет в библиотеке, их проблематично сделать полностью соответствующими стандарту (кто и куда будет выбрасывать исключение по нехватке памяти std::bad_alloc ? исключения для AVR пока вообще не предусмотрены и я себе плохо представляю их необходимоть) и они отданы на откуп пользователю.
В простейшем варианте new/delete предлгается сделать через malloc/free.
Посмотрите ту тему на avrfreaks.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
xVekx
Встал на лапы
Сообщения: 125
Зарегистрирован: Вс мар 01, 2009 20:41:19

Сообщение xVekx »

Спасибо за ответы!!.
Мда если в winavr (8бит) нету операторов new и delete, то что ожидать в дальнейшем, короче убогий ваш winavr=((, Продолжу писать в IAR там хоть нету такова =)).
Аватара пользователя
ArtDen
Мучитель микросхем
Сообщения: 462
Зарегистрирован: Пн фев 22, 2010 09:12:34
Контактная информация:

Сообщение ArtDen »

А есть какие-нибудь рекомендации по уменьшению размера сгенерированного кода? Компилирую с оптимизацией по размеру (-Os), extern перед функциями я расставил, -fno-inline в опции компиляции добавил, но всё равно код еле-еле в 2к умещается. Если надо будет добавить дополнительную функциональность, то это будет затруднительно.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

рекомендаций много :)

extern далеко не всегда помогает уменьшить объем кода, скорее наоборот, а вот static может сильно помочь (если вы, конечно, понимаете, что это и как оно работает). вы запрещаете инлайнить функции - но зачем? поверьте, компилятор лучше вас разберется, когда это выгодно делать, а когда нет: запрещая инлайнить небольшую функцию вы заставляете компилятор каждый раз при ее вызове спасать в стеке несколько регистров, инициализировать ее локальные переменные и т.д. - а если она проинлайнится, то все это скорее всего будет лишним, и еще вопрос, станет ли код больше...

если вы программируете не очень аккуратно и у вас имеются функции, которые просто "для запаса" содержатся в тексте - они будут включены в код, хотя по сути лишние. так вот, убрать их можно опцией компилятора -ffunction-sections и опцией линкера -Wl,-gc-sections - для "мусорного кода" очень большой эффект!

вчера из проекта с кодом в 2038 байт сумел сделать 1930 байт путем замены некоторых статических глобальных переменных на регистровые.

WinAVR не может похвастаться сверхоптимальным кодом для работы с битовыми полями, особенно когда эти поля знаковые или многобитные. но если структура с битовыми полями умещается в регистре или паре регистров, то сделав ее регистровой переменной вы получите заметный выигрыш. часто можно отказаться от однобитовых полей, заменив их отдельными байтовыми переменными или полями в структуре - если ОЗУ хватает, то скорее всего получите выигрыш в размере кода.

используйте для функции main() атрибут OS_main. помните о том, что если вы описываете статическую или глобальную переменную и сразу инициализируете ее ненулевым значением, то это самое значение приплюсуется к коду. подумайте, действительно необходимо это делать или можно обойтись нулевым значением по умолчанию.

посмотрите, реально ли необходимо иметь в функциях более одного параметра? действительно ли необходимы типы int и long? можно ли обойтись uint8_t или нет? не используйте float и double - для проектов на tiny ничего хорошего не выйдет скорее всего из этой попытки...

есть и еще тонкости, которые все я не помню, хотя дома записано многое :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ArtDen
Мучитель микросхем
Сообщения: 462
Зарегистрирован: Пн фев 22, 2010 09:12:34
Контактная информация:

Сообщение ArtDen »

ARV писал(а):рекомендаций много :)

extern далеко не всегда помогает уменьшить объем кода, скорее наоборот, а вот static может сильно помочь (если вы, конечно, понимаете, что это и как оно работает).
Извиняюсь. Конечно же static. ОписАлся.

ARV писал(а):вы запрещаете инлайнить функции - но зачем? поверьте, компилятор лучше вас разберется, когда это выгодно делать, а когда нет: запрещая инлайнить небольшую функцию вы заставляете компилятор каждый раз при ее вызове спасать в стеке несколько регистров, инициализировать ее локальные переменные и т.д. - а если она проинлайнится, то все это скорее всего будет лишним, и еще вопрос, станет ли код больше...
Да просто код короче в этом случае получился.

За рекомендацию о глобальных переменных в регистрах спасибо. Буду пробовать :)
Alex_Jet
Родился
Сообщения: 2
Зарегистрирован: Вт фев 23, 2010 20:52:12
Контактная информация:

Что с новыми версиями WinAVR?

Сообщение Alex_Jet »

Здравствуйте, уважаемые!

Возникла небольшая проблемка с новыми версиями WinAVR.
Сидел на старой WinAVR-20060125, поскольку не требовалось пока ничего большего. Программатор ponyser. При разработке устройства перешел с Attiny26 на 461, avrdude старой версии ее не знает. Поэтому поставил свежий WinAVR-20100110...... без проблем откомпилировал, зашил программу и...ничего не работает...
Перепробовал разные версии WinAVR, перебрав с 20100110 по 20071221 - все то же! В итоге снова установил старую версию 20060125 и в avrdude.conf описал attiny461.
Что же такое может быть в новых версиях? 2 часика порылся в инете - ничего не нашел :(
Telek
Встал на лапы
Сообщения: 115
Зарегистрирован: Пт май 23, 2008 23:59:37
Откуда: Москва

Re: Что с новыми версиями WinAVR?

Сообщение Telek »

Alex_Jet писал(а):Что же такое может быть в новых версиях? 2 часика порылся в инете - ничего не нашел :(
Оптимизация скорее всего. Нужно код смотреть. Сравни ассемблерный код по результату компиляции.
Alex_Jet
Родился
Сообщения: 2
Зарегистрирован: Вт фев 23, 2010 20:52:12
Контактная информация:

Сообщение Alex_Jet »

Попробую сравнить....прийдется еще раз новый WinAVR ставить.
Не знаю что получу, поскольку ассемблер вообще не знаю(
Но для меня все это было открытием. Поскольку код простой, а тут такая ерунда. Надо частями попробовать откомпилировать программу...может найду "косячный" блок.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

в новых версиях был такой грех: несколько раз менялись форматы функций для работы с EEPROM, причем менялись кардинально: аргументы функция переставлялись местами. в итоге вполне может оказаться, что исходник уже абсолютно не так собирается. последние три или четыре версии WinAVR уже одинаково все делают, но по сравнению с более древними факт может иметь место. возможно, есть и другие моменты, о которых я не знаю - сам-то я пользуюсь более-менее свежими версиями 2009 и 2010 годов.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Re: Что с новыми версиями WinAVR?

Сообщение avreal »

Alex_Jet писал(а):Возникла небольшая проблемка с новыми версиями WinAVR.
Сидел на старой WinAVR-20060125, поскольку не требовалось пока ничего большего.
Большего или не большего, но из старых (gcc 3.x.x) всё же 20060424 поприличнее.

Alex_Jet писал(а):Поэтому поставил свежий WinAVR-20100110...... без проблем откомпилировал, зашил программу и...ничего не работает...
Перепробовал разные версии WinAVR, перебрав с 20100110 по 20071221 - все то же!
А вот эти (gcc 4.x.x) несколько "агрессивнее" (но, тем не менее, в полном соответствии со стандартом С) оптимизируют код в том, что управляется ключевым словом volatile. В смысле чаще находят что выбросить, так как без volatile оно выглядит ненужным или переставить местами код.
Для справки (в даном конкретном случае лучше ипользовать макросы из util/atomic.h - и писать меньше, и оибки такой из-за барьеров "memory" не будет, но на этом примере хорошо видно):

Код: Выделить всё

uint16_t vvar; /* надо бы volatile, но старые версии это прощали */
uint16_t foo()
{
    uint16_t temp;
    uint8_t sreg_copy = SREG;
    cli();
    temp = vvar;
    SREG = sreg_copy;
}

компилятор имеет право сделать где-то так

Код: Выделить всё

    in r24, SREG
    cli
    out SREG, r24
    lds r24, vvar
    lds r25, vvar+1
    ret
и новвые версии этим правом пользуются, если им кажется, что экономия использованных регистров того стоит.

Не обязательно проблема в этом, но стоит обратить внимание.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Alex_NEMO
Открыл глаза
Сообщения: 66
Зарегистрирован: Чт фев 14, 2008 16:12:52

Сообщение Alex_NEMO »

Мужики, подскажите ПЛС по WinAVR(GCC). есть некий массив:

Код: Выделить всё

volatile unsigned char vol_tda[] = {0x1C,0x1E,0x20,0x22,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
                                    0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F };

Вопрос: как мне обратиться к любому элменту массива по индексу а не по содержимому? Через "CASE" сопоставлять содержимое индексу?
Ответить

Вернуться в «AVR»