Страница 24 из 111
Добавлено: Вс фев 14, 2010 22:20:28
ARV
пока писал - опередили

и предложили "решение в лоб" - третий способ

в сущности, мой первый вариант мало отличается от этого...
Добавлено: Вс фев 14, 2010 23:01:15
DimAlt
Вариант с битовыми полями интересный, спасибо.
Скомпилировал все варианты, "решение в лоб" оказалось самое короткое

Добавлено: Сб фев 20, 2010 16:02:13
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;
Добавлено: Сб фев 20, 2010 17:24:02
smac
krolaka писал(а):обясните почему себя так ведет sprintf вот привожу пример програмы
В первую очередь рекоммендую явно задать размер массива yf -
пять символов, ибо sprintf ввыводит в память строку с завершающим символом '\0'.
А вообще что-то не пойму логики, зачем какие-то операции над year_10 и year_1 и зачем вообще эти переменные? Не проще так:
Код: Выделить всё
char yf[5]
uint16 year;
year=2010;
sprintf(yf, "%.4i", year)
В качестве полезного совета предлагаю сначала отладить sprintf на строке из чисел, а потом переходить к преобразованиям.
Добавлено: Сб фев 20, 2010 23:41:03
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...
Помогите плизз!! =)
Добавлено: Вс фев 21, 2010 00:01:38
smac
xVekx писал(а):Как врубить поддержку c++ в проектах ??...
попробуйте переименовать main.c в main.cpp
Добавлено: Вс фев 21, 2010 00:12:44
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...
класс прошёл, но дин массив нет =(( .
Добавлено: Вс фев 21, 2010 02:28:26
avreal
"Вы будете смеяться", но нужно дать файлу расширение .cpp
Можно, конечно, дать ключ
но логичнее просто дать расширение, соответствующее языку.
Пример использования С++ для avr-gcc можно посмотреть
тут
Правда, там new не используется.
Ещё полезное место - тема о С++ в avr-gcc на
avrfreaks
Добавлено: Вс фев 21, 2010 03:15:29
xVekx
хех флаг
надо было добавить =)), но ошибка все равно есть
Код: Выделить всё
S:\AVRWIN001\default/../main.c:18: undefined reference to `operator new[](unsigned int)'
вот мой Makefile
Использую связку AVR studio + WinAVR-20100110.
Добавлено: Вс фев 21, 2010 10:11:08
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.
Добавлено: Вс фев 21, 2010 15:32:36
xVekx
Спасибо за ответы!!.
Мда если в winavr (8бит) нету операторов new и delete, то что ожидать в дальнейшем, короче убогий ваш winavr=((, Продолжу писать в IAR там хоть нету такова =)).
Добавлено: Пн фев 22, 2010 09:17:48
ArtDen
А есть какие-нибудь рекомендации по уменьшению размера сгенерированного кода? Компилирую с оптимизацией по размеру (-Os), extern перед функциями я расставил, -fno-inline в опции компиляции добавил, но всё равно код еле-еле в 2к умещается. Если надо будет добавить дополнительную функциональность, то это будет затруднительно.
Добавлено: Пн фев 22, 2010 13:14:25
ARV
рекомендаций много
extern далеко не всегда помогает уменьшить объем кода, скорее наоборот, а вот
static может сильно помочь (если вы, конечно, понимаете, что это и как оно работает). вы запрещаете инлайнить функции - но зачем? поверьте, компилятор лучше вас разберется, когда это выгодно делать, а когда нет: запрещая инлайнить небольшую функцию вы заставляете компилятор каждый раз при ее вызове спасать в стеке несколько регистров, инициализировать ее локальные переменные и т.д. - а если она проинлайнится, то все это скорее всего будет лишним, и еще вопрос, станет ли код больше...
если вы программируете не очень аккуратно и у вас имеются функции, которые просто "для запаса" содержатся в тексте - они будут включены в код, хотя по сути лишние. так вот, убрать их можно опцией компилятора -ffunction-sections и опцией линкера -Wl,-gc-sections - для "мусорного кода" очень большой эффект!
вчера из проекта с кодом в 2038 байт сумел сделать 1930 байт путем замены некоторых статических глобальных переменных на
регистровые.
WinAVR не может похвастаться сверхоптимальным кодом для работы с битовыми полями, особенно когда эти поля знаковые или многобитные. но если структура с битовыми полями умещается в регистре или паре регистров, то сделав ее регистровой переменной вы получите заметный выигрыш. часто можно отказаться от однобитовых полей, заменив их отдельными байтовыми переменными или полями в структуре - если ОЗУ хватает, то скорее всего получите выигрыш в размере кода.
используйте для функции
main() атрибут
OS_main. помните о том, что если вы описываете статическую или глобальную переменную и сразу инициализируете ее ненулевым значением, то это самое значение приплюсуется к коду. подумайте, действительно необходимо это делать или можно обойтись нулевым значением по умолчанию.
посмотрите, реально ли необходимо иметь в функциях более одного параметра? действительно ли необходимы типы
int и
long? можно ли обойтись
uint8_t или нет? не используйте
float и
double - для проектов на tiny ничего хорошего не выйдет скорее всего из этой попытки...
есть и еще тонкости, которые все я не помню, хотя дома записано многое

Добавлено: Пн фев 22, 2010 18:17:42
ArtDen
ARV писал(а):рекомендаций много
extern далеко не всегда помогает уменьшить объем кода, скорее наоборот, а вот
static может сильно помочь (если вы, конечно, понимаете, что это и как оно работает).
Извиняюсь. Конечно же static. ОписАлся.
ARV писал(а):вы запрещаете инлайнить функции - но зачем? поверьте, компилятор лучше вас разберется, когда это выгодно делать, а когда нет: запрещая инлайнить небольшую функцию вы заставляете компилятор каждый раз при ее вызове спасать в стеке несколько регистров, инициализировать ее локальные переменные и т.д. - а если она проинлайнится, то все это скорее всего будет лишним, и еще вопрос, станет ли код больше...
Да просто код короче в этом случае получился.
За рекомендацию о глобальных переменных в регистрах спасибо. Буду пробовать

Что с новыми версиями WinAVR?
Добавлено: Вт фев 23, 2010 21:11:23
Alex_Jet
Здравствуйте, уважаемые!
Возникла небольшая проблемка с новыми версиями WinAVR.
Сидел на старой WinAVR-20060125, поскольку не требовалось пока ничего большего. Программатор ponyser. При разработке устройства перешел с Attiny26 на 461, avrdude старой версии ее не знает. Поэтому поставил свежий WinAVR-20100110...... без проблем откомпилировал, зашил программу и...ничего не работает...
Перепробовал разные версии WinAVR, перебрав с 20100110 по 20071221 - все то же! В итоге снова установил старую версию 20060125 и в avrdude.conf описал attiny461.
Что же такое может быть в новых версиях? 2 часика порылся в инете - ничего не нашел

Re: Что с новыми версиями WinAVR?
Добавлено: Чт фев 25, 2010 17:03:13
Telek
Alex_Jet писал(а):
Что же такое может быть в новых версиях? 2 часика порылся в инете - ничего не нашел

Оптимизация скорее всего. Нужно код смотреть. Сравни ассемблерный код по результату компиляции.
Добавлено: Пт фев 26, 2010 21:12:13
Alex_Jet
Попробую сравнить....прийдется еще раз новый WinAVR ставить.
Не знаю что получу, поскольку ассемблер вообще не знаю(
Но для меня все это было открытием. Поскольку код простой, а тут такая ерунда. Надо частями попробовать откомпилировать программу...может найду "косячный" блок.
Добавлено: Сб фев 27, 2010 07:36:11
ARV
в новых версиях был такой грех: несколько раз менялись форматы функций для работы с EEPROM, причем менялись кардинально: аргументы функция переставлялись местами. в итоге вполне может оказаться, что исходник уже абсолютно не так собирается. последние три или четыре версии WinAVR уже одинаково все делают, но по сравнению с более древними факт может иметь место. возможно, есть и другие моменты, о которых я не знаю - сам-то я пользуюсь более-менее свежими версиями 2009 и 2010 годов.
Re: Что с новыми версиями WinAVR?
Добавлено: Сб фев 27, 2010 17:36:57
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
и новвые версии этим правом пользуются, если им кажется, что экономия использованных регистров того стоит.
Не обязательно проблема в этом, но стоит обратить внимание.
Добавлено: Вс фев 28, 2010 18:53:41
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" сопоставлять содержимое индексу?