во всяком случае в винде make от Borland (или как там теперь эта компания называется?) в упор не умеет работать с проектами avr-gcc - на каждую строчку ругается "неизвестная команда".
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
2) Зачем Вы говорите про какой-то make, если у Вас ошибка при запуске avr-gcc. Вбейте "руками" строку запуска gcc и убедитесь, что проблема осталась (т.е make тут вообще "никаким боком").
Добавьте в строку запуска gcc ключик вывода расширенной информации (-v) и сюда все что Вам в ответ "вывалилось"
Добавьте в строку запуска gcc ключик вывода расширенной информации (-v) и сюда все что Вам в ответ "вывалилось"
Добавил, вот:
Код:
~/Desktop2/fm7segm-master> make all avr-gcc -v -g -Wall -Werror -lm -Os -mcall-prologues -fshort-enums -ffunction-sections -fdata-sections -MMD -MP -MT build/volume.o -MF build/./volume.d -mmcu=atmega8 -DF_CPU=8000000 -D_PIN1 -D_TEA5767 -D_RDA580X -D_TUX032 -c -o build/volume.o volume.c Using built-in specs. Reading specs from /opt/cross/lib/gcc/avr/5.4.0/device-specs/specs-atmega8 COLLECT_GCC=/opt/cross/bin/avr-gcc Target: avr Configured with: ../gcc-5.4.0/configure -v --target=avr --disable-nls --mandir=/opt/cross/share/man --infodir=/opt/cross/share/info --program-prefix=avr- --prefix=/opt/cross --with-gnu-ld --with-gnu-as --enable-languages=c,c++ --disable-libssp --with-dwarf2 Thread model: single gcc version 5.4.0 (GCC) COLLECT_GCC_OPTIONS='-v' '-g' '-Wall' '-Werror' '-Os' '-mcall-prologues' '-fshort-enums' '-ffunction-sections' '-fdata-sections' '-MMD' '-MP' '-MT' 'build/volume.o' '-MF' 'build/./volume.d' '-D' 'F_CPU=8000000' '-D' '_PIN1' '-D' '_TEA5767' '-D' '_RDA580X' '-D' '_TUX032' '-c' '-o' 'build/volume.o' '-specs=device-specs/specs-atmega8' '-mmcu=avr4' /opt/cross/libexec/gcc/avr/5.4.0/cc1 -quiet -v -imultilib avr4 -MMD build/volume.d -MF build/./volume.d -MP -MT build/volume.o -D__AVR_ATmega8__ -D__AVR_DEVICE_NAME__=atmega8 -D F_CPU=8000000 -D _PIN1 -D _TEA5767 -D _RDA580X -D _TUX032 volume.c -mn-flash=1 -mno-skip-bug -quiet -dumpbase volume.c -mcall-prologues -mmcu=avr4 -auxbase-strip build/volume.o -g -Os -Wall -Werror -version -fshort-enums -ffunction-sections -fdata-sections -o /tmp/cc4A5zi6.s GNU C11 (GCC) version 5.4.0 (avr) compiled by GNU C version 4.8.3 20140627 [gcc-4_8-branch revision 212064], GMP version 5.1.3, MPFR version 3.1.2, MPC version 1.0.2 warning: GMP header version 5.1.3 differs from library version 5.1.2. warning: MPC header version 1.0.2 differs from library version 1.0. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ignoring nonexistent directory "/opt/cross/lib/gcc/avr/5.4.0/../../../../avr/sys-include" #include "..." search starts here: #include <...> search starts here: /opt/cross/lib/gcc/avr/5.4.0/include /opt/cross/lib/gcc/avr/5.4.0/include-fixed /opt/cross/lib/gcc/avr/5.4.0/../../../../avr/include End of search list. GNU C11 (GCC) version 5.4.0 (avr) compiled by GNU C version 4.8.3 20140627 [gcc-4_8-branch revision 212064], GMP version 5.1.3, MPFR version 3.1.2, MPC version 1.0.2 warning: GMP header version 5.1.3 differs from library version 5.1.2. warning: MPC header version 1.0.2 differs from library version 1.0. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 0968929aedc7da3ce3f041d621a0f017 COLLECT_GCC_OPTIONS='-v' '-g' '-Wall' '-Werror' '-Os' '-mcall-prologues' '-fshort-enums' '-ffunction-sections' '-fdata-sections' '-MMD' '-MP' '-MT' 'build/volume.o' '-MF' 'build/./volume.d' '-D' 'F_CPU=8000000' '-D' '_PIN1' '-D' '_TEA5767' '-D' '_RDA580X' '-D' '_TUX032' '-c' '-o' 'build/volume.o' '-specs=device-specs/specs-atmega8' '-mmcu=avr4' as -v -mmcu=avr4 -mno-skip-bug -o build/volume.o /tmp/cc4A5zi6.s GNU ассемблер, версия 2.28.0 (i586-suse-linux); используется BFD версии (GNU Binutils; devel:gcc / openSUSE_13.1) 2.28.0.20170308-270 as: неизвестный ключ «-mmcu=avr4» make: *** [build/volume.o] Ошибка 1
Есть пара варнингов, но вряд ли дело в них.
WiseLord писал(а):
Ругается на отсутствующий avr4. У меня в Gentoo это /usr/avr/lib/avr4/ (тут и для atmega8 объектный файл лежит). Но принадлежит это не пакету avr-gcc, а avr-libc. Убедитесь, что эта библиотека тоже установлена.
avr-libc установлен, без него Suse не давала ставить остальное - ругалась про неудовлетворенные зависимости и все такое. Стоит это дело в /opt/cross/avr/lib/avr4 Пробовал копировать в /usr/avr/lib/ - разницы никакой
as -v -mmcu=avr4 -mno-skip-bug -o build/volume.o /tmp/cc4A5zi6.s GNU ассемблер, версия 2.28.0 (i586-suse-linux); используется BFD версии (GNU Binutils; devel:gcc / openSUSE_13.1) 2.28.0.20170308-270 as: неизвестный ключ «-mmcu=avr4»
Вместо AVR ассемблера вызвался ассемблер для хоста (i586-suse-linux), который знать ничего не знает про avr. Скорей всего при конфигурировании при сборке Вашего gcc, что-то напутали (as вызывается без полного пути - а ассемблер хоста находится раньше).
Как временная мера - попробуйте, путь в котором лежат бинарники для avr указать самым первым в переменной PATH (чтобы avr-овский as находился раньше, чем as-хоста (обычно лежит /usr/bin)). По хорошему - надо собрать gcc чтобы вызывался свой-родной кросс-ассемблер (с полным путем).
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Мы не ищем легких путей Просто раньше компилировал только через гуи в WinAvr, и пока не разобрался в консольных командах avr-gcc.
viiv писал(а):
Как временная мера - попробуйте, путь в котором лежат бинарники для avr указать самым первым в переменной PATH (чтобы avr-овский as находился раньше, чем as-хоста (обычно лежит /usr/bin)). По хорошему - надо собрать gcc чтобы вызывался свой-родной кросс-ассемблер (с полным путем).
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Заголовок сообщения: Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Сб мар 25, 2017 05:54:54
Открыл глаза
Зарегистрирован: Ср мар 15, 2017 18:52:10 Сообщений: 43
Рейтинг сообщения:0
Нет, ничего не вышло Нашел багрепорты Suse с этой же проблемой: начиная с версий 4.19.x, компилятор упорно использует as, но на этот баг почему-то дружно забили и в репозитории продолжают выкладываться заведомо кривые пакеты (старая добрая традиция OpenSuse). Вроде несколько пользователей пересобирали rpm с правильными путями к avr-as, буду искать.
Upd. Решил проблему дешево и сердито На время компиляции зашел в /usr/bin и переименовал as в as_old, а avr-as в as - прошивка собралась! Это, конечно, не дело так каждый раз переименовывать, но хоть как-то добился нужного результата.
Заголовок сообщения: Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Сб мар 25, 2017 10:10:14
Открыл глаза
Зарегистрирован: Ср мар 15, 2017 18:52:10 Сообщений: 43
Рейтинг сообщения:0
Нет. Компилятор эту строку даже не заметил.
Помогло другое: в папке /usr/avr/bin/ лежат ссылки на правильные файлы, там файл as ссылается на нужный мне avr-as. В строку вызова avr-gcc дописал новый путь для поиска: -B /usr/avr/bin/ - и компиляция прошла!
В случае с Makefile'ом:
Код:
CC = avr-gcc -B /usr/avr/bin/
Как я понимаю, этот путь надо бы добавить где-то в настройках системы.
Добавлено after 1 hour 19 minutes 10 seconds: Ну вот и разобрался. Нашел такую штуку, что при создании в домашнем каталоге папки с именем bin этот путь автоматически добавляется в пути поиска программ, причем ставится он выше /usr/bin/ Так что просто создал эту папку, в ней создал симлинк as на файл /usr/bin/avr-as, и теперь все компилируется без лишней мороки
Заголовок сообщения: Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Сб мар 25, 2017 11:28:07
Открыл глаза
Зарегистрирован: Ср мар 15, 2017 18:52:10 Сообщений: 43
Рейтинг сообщения:0
Да, в путях. Просто надеялся найти в репах пакеты, где компилятор работал бы "из коробки", но все связанное с avr в Suse требует доработки напильником. Всем спасибо за подсказки
Помогите пожалуйста разобраться с ошибкой "multiple definition" в WinAvr. Дело в том что у меня в файле main.h есть глобальные переменные, которые используются в нескольких сишных файлах и поэтому я подключаю этот main.h в этих файлах. Вроде же это логично? И на этапе линковки происходит эта ошибка. Если main.h не подключить хотя бы в одном файле, где используются переменные с него, то естественно ругается компилятор что не определена переменная в таком то файле. Директива #ifndef MAIN_H #define MAIN_H //код #endif в файле main.h стоит, но это не помогает избежать множественного определения Видимо я еще слишком не опытный и что то делаю не так, буду благодарен за помощь. А пока покопаюсь в чужих исходниках, может докопаюсь до истины.
#ifndef MAIN_H #define MAIN_H extern int isTheWorldOnFire; #endif
---- main.c
Код:
int isTheWorldOnFire = 0;
int main(int /*argc*/, char** /*argv*/) {
forkTrumpAITask();
while (!isTheWorldOnFire) drinkYetAnotherBottleOfBeerHandler();
abort();
return 34782567453; /* es ist shon egal, kein Schwein kann diese Zeile erreichen */ }
---- tmp.c
Код:
void redButtonHandler() {
if (!isTheWorldOnFire) { for (int i = 0; i < 59; i++) startYetAnotherTomahawk(i); isTheWorldOnFire = 1; } }
как "полюбля́ют говоря́ть" на CRI "слово дня - extern". Сей модификатор намекает, что переменная isTheWorldOnFire "где-то там" определена. Без него переменная isTheWorldOnFire определена здесь и сейчас - т.е. в каждом отдельно компилируемом файле. Сводя подобные продукты компиляции в единую программку, линкер понятным делом ругается на множество isTheWorldOnFire. Поэтому определяем isTheWorldOnFire только в main.c (или кому как нравится) - а в остальных файлах на него ссылаемся помогая себе чудесным extern-ом. Amen ....
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
Siarzhuk, Спасибо большое буду пробовать, но что-то пока не получается. Если я правильно понял, достаточно написать в заголовочном файле "extern имя переменной", объявить эту переменную в одном си файле (кстати есть ли разница в каком?) и эта переменная будет видна во всех си файлах и при этом заголовочный файл не нужно включать в сишные файлы? Достаточно один раз его включить.
Может у меня Makefile не правильно настроен, если такое возможно, потому что нет разницы с extern и без него, ругается на не объявленные переменные в тех файлах где они используются.
void abc(unsigned long int a, unsigned char b) { //какой-то код
if(!power) { //что-то делаем power = 1; }
}
//ошибка menu.c:5: error: 'power' undeclared (first use in this function)
По изучал чужие исходники и еще больше запутался. В некоторых из них один и тот же h файл, который в проекте, включается во все сишные файлы и при этом компилируется без проблем, нет ошибки линковщика - multiple definition (множественное определение). Интересно как это? Почему у меня тогда ругается если так же делаю?
у меня в файле main.h есть глобальные переменные, которые используются в нескольких сишных файлах и поэтому я подключаю этот main.h в этих файлах. Вроде же это логично?
Нет. Поскольку каждый .c файл компилируется отдельно, то при таком подходе в каждом полученном .o файле будет копия этой переменной. А уже потом линкер при совмещении .o файлов в .elf выдаст ошибку "multiple definition". И трюк с #ifndef MAIN_H / #define MAIN_H / #endif тут не поможет.
Так что, как уже подсказали, нужно использовать модификатор extern. Возможно два равноценных варианта:
1) В одном .c файле объявить переменную как обычно, в других с extern. Неудобство в том, что в каждом из новых .c файлов, которым нужна эта переменная, придётся делать это объявление.
2) Обычно код оформляется в виде библиотек - парах файлов вроде module.c/module.h. Тогда в module.c переменная объявляется как обычно, а в module.h с extern, и тем самым она становится видимой во всех .c файлах, которые инклюдят этот хидер.
hosturik писал(а):
А пока покопаюсь в чужих исходниках, может докопаюсь до истины.
Живой пример из одного моего проекта. Переменная tuner для доступа к параметрам тюнера определена в tuner.c и объявлена в tuner.h с модификатором extern. Любой другой файл просто её использует.
Ещё один возможный подход - использование функций-геттеров (ну и сеттеров при необходимости). Т.е. в tuner.c было бы что-то вроде:
Код:
static Tuner_type tuner;
Tuner_type getTuner(void) { return tuner; }
А в tuner.h вместо extern быо бы просто интерфейс функции
Код:
Tuner_type getTuner(void);
В нужном месте кода вместо прямого выхова глобальной переменной tuner использовалась бы локальная
Код:
Tuner_type tuner = getTuner();
Ну а дальше - как обычно.
Такой подход в больших проектах более правильный, т.к. глобальные переменные - это не очень безопасно. Но в проектах на МК часто (не всегда) глобальные переменные дают небольшой выигрыш в размере кода.
[...] и эта переменная будет видна во всех си файлах и при этом заголовочный файл не нужно включать в сишные файлы?
Как это работает: 1. Препроцессор -> 2. Компилятор -> 3. Линкер Первый собирает из одного .c и всех .h на которые тот прямо либо косвенно (из включаемых .h) ссылается и комбинирует огромнейший [как правило] .с файл и отдаёт его на компиляцию. Это делается отдельно для каждого .с файла в проекте - поэтому подключать .h нужно в каждый .с где требуется знание об этой переменной. И лишь линкер собирает откомпилированные обьекты воедино - и тогда наступает Момент Истины - либо а) дубликаты переменных, либо б) одна переменная и ссылки на неё из других файлов, либо, что тоже не исключено, ц) одни только ссылки на несуществуюшую переменную.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
Господа, подскажите почему не работает код Задача: по внешнему прерыванию INT0 изменяем значение переменной reg. В зависимости от состояния reg включается разный режим работы светодиода. AVR Studio компилирует без ошибок, но ничего не работает в Proteus
//Глобальные переменные сюда: unsigned char reg=0; //Переменная reg - режим
//Обработка прерывания по спаду напряжения на INT0 ISR(INT0_vect) { reg++; //при нажатии на кнопку Увеличиваем значение переменной reg на 1 if (reg==4) reg=0; //Если досчитали до 4, то reg=0 }
void INTinit() { GIMSK=(1<<6); //Разрешаем прерывание INT0 MCUCR=(1<<0)|(1<<1); //Прерывыание по ниспадающему форонту (с 1 на 0); ISC01=1, ISC00=1 }
int main (void) { DDRB=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7); //Порт В на ВЫХод
Уж сколько раз твердили миру... volatile. Ну и антидребезга нет никакого. Для Proteus не важно, но в жизни при нажатии на кнопку прерываний до десятка будет за раз. В коде последний комментарий вообще не в тему. Итогом выполнения программы вижу постоянно находящийся в единичном состоянии PB0, веди ничто его в ноль в принципе не уводит.
Уж сколько раз твердили миру... volatile. Ну и антидребезга нет никакого. Для Proteus не важно, но в жизни при нажатии на кнопку прерываний до десятка будет за раз.
Спасибо!!! Все заработало! Как же все было не сложно...
В коде последний комментарий вообще не в тему. Итогом выполнения программы вижу постоянно находящийся в единичном состоянии PB0, веди ничто его в ноль в принципе не уводит.
Это, так скажем, заготовка была с целью организовать выполнение прерывания по INT0, что с Вашей помощью и получилось Теперь дальше дописывать режимы, добавлять антидребезг, так же понадобятся мне свои задержки с интервалами больше 15сек и тд... А Вам еще раз Спасибо!
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения