Страница 32 из 75
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Пт мар 24, 2017 07:14:22
ARV
WiseLord писал(а):А make должен любой абсолютно подходить.
ага. должен. но не подходит.

во всяком случае в винде make от Borland (или как там теперь эта компания называется?) в упор не умеет работать с проектами avr-gcc - на каждую строчку ругается "неизвестная команда".
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Пт мар 24, 2017 11:41:18
viiv
Andrew88 писал(а):При попытке хоть что-то скомпилить, получаю ошибку:
1) Под этой фразой я понимаю попытку скомпилировать самый простой исходник, типа
Спойлер
А Вы понимаете: собрать проект, который в архиве занимает около 200K (понятно, что там не только исходники,но "копать" проект не сильно хочется).
Andrew88 писал(а):
Код: Выделить всё
avr-gcc -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
as: неизвестный ключ «-mmcu=avr4»
2) Зачем Вы говорите про какой-то make, если у Вас ошибка при запуске avr-gcc. Вбейте "руками" строку запуска gcc и убедитесь, что проблема осталась (т.е make тут вообще "никаким боком").
Добавьте в строку запуска gcc ключик вывода расширенной информации (
-v) и сюда все что Вам в ответ "вывалилось"
Код: Выделить всё
$ 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
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Пт мар 24, 2017 15:12:53
Andrew88
viiv писал(а):
1) Под этой фразой я понимаю попытку скомпилировать самый простой исходник, типа
Да. Создал в Code Blocks проект-"рыбу" под AVR, в выхлопе та же ошибка
Код: Выделить всё
-------------- Build: Release in avr (compiler: GNU GCC Compiler for AVR)---------------
avr-gcc -Wall -mmcu=atmega8 -DF_CPU=8000000UL -Os -I/usr/include -c fuse.c -o obj/Release/fuse.o
as: неизвестный ключ «-mmcu=avr4»
Process terminated with status 1 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))
viiv писал(а):Добавьте в строку запуска 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/ - разницы никакой

Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Пт мар 24, 2017 17:54:41
viiv
Andrew88 писал(а):
Добавил, вот:
Ну Вы и упорный

Зачем make? Чтобы думать, что он там наставил в переменных окружения? Трудно в командную строку скопировать
Код: Выделить всё
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
Ну да ладно.
Вот, похоже Ваша проблема:
Код: Выделить всё
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 чтобы вызывался свой-родной кросс-ассемблер (с полным путем).
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Пт мар 24, 2017 18:07:51
Andrew88
viiv писал(а):
Ну Вы и упорный

Зачем make? Чтобы думать, что он там наставил в переменных окружения? Трудно в командную строку скопировать
Код: Выделить всё
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
Мы не ищем легких путей
Просто раньше компилировал только через гуи в WinAvr, и пока не разобрался в консольных командах avr-gcc.
viiv писал(а):
Как временная мера - попробуйте, путь в котором лежат бинарники для avr указать самым первым в переменной PATH (чтобы avr-овский as находился раньше, чем as-хоста (обычно лежит /usr/bin)). По хорошему - надо собрать gcc чтобы вызывался свой-родной кросс-ассемблер (с полным путем).
Ок, сейчас проверю, получится ли.
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Пт мар 24, 2017 18:13:08
WiseLord
Возможно, в случае Makefile поможет AS=avr-as. Но не уверен.
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Сб мар 25, 2017 05:54:54
Andrew88
Нет, ничего не вышло
Нашел багрепорты Suse с этой же проблемой: начиная с версий 4.19.x, компилятор упорно использует as, но на этот баг почему-то дружно забили и в репозитории продолжают выкладываться заведомо кривые пакеты (старая добрая традиция OpenSuse).
Вроде несколько пользователей пересобирали rpm с правильными путями к avr-as, буду искать.
Upd.
Решил проблему дешево и сердито

На время компиляции зашел в /usr/bin и переименовал as в as_old, а avr-as в as - прошивка собралась!

Это, конечно, не дело так каждый раз переименовывать, но хоть как-то добился нужного результата.
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Сб мар 25, 2017 08:24:04
WiseLord
А попытка прописать переменную окружения AS=avr-as тоже не помогла?
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Сб мар 25, 2017 10:10:14
Andrew88
Нет. Компилятор эту строку даже не заметил.
Помогло другое: в папке /usr/avr/bin/ лежат ссылки на правильные файлы, там файл
as ссылается на нужный мне
avr-as. В строку вызова avr-gcc дописал новый путь для поиска: -B /usr/avr/bin/ - и компиляция прошла!
В случае с Makefile'ом:
Как я понимаю, этот путь надо бы добавить где-то в настройках системы.
Добавлено after 1 hour 19 minutes 10 seconds:
Ну вот и разобрался. Нашел такую штуку, что при создании в домашнем каталоге папки с именем bin этот путь автоматически добавляется в пути поиска программ, причем ставится он выше /usr/bin/
Так что просто создал эту папку, в ней создал симлинк
as на файл /usr/bin/avr-as, и теперь все компилируется без лишней мороки

Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Сб мар 25, 2017 10:12:45
ARV
говорил же, что проблема в путях...
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Сб мар 25, 2017 11:28:07
Andrew88
Да, в путях. Просто надеялся найти в репах пакеты, где компилятор работал бы "из коробки", но все связанное с avr в Suse требует доработки напильником.
Всем спасибо за подсказки

Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Сб апр 08, 2017 22:25:44
hosturik
Помогите пожалуйста разобраться с ошибкой "multiple definition" в WinAvr. Дело в том что у меня в файле main.h есть глобальные переменные, которые используются в нескольких сишных файлах и поэтому я подключаю этот main.h в этих файлах. Вроде же это логично? И на этапе линковки происходит эта ошибка.
Если main.h не подключить хотя бы в одном файле, где используются переменные с него, то естественно ругается компилятор что не определена переменная в таком то файле.
Директива
#ifndef MAIN_H
#define MAIN_H
//код
#endif
в файле main.h стоит, но это не помогает избежать множественного определения
Видимо я еще слишком не опытный и что то делаю не так, буду благодарен за помощь.
А пока покопаюсь в чужих исходниках, может докопаюсь до истины.
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Сб апр 08, 2017 22:47:44
Siarzhuk
hosturik писал(а):
---- 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 ....
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Вс апр 09, 2017 00:56:37
hosturik
Siarzhuk, Спасибо большое буду пробовать, но что-то пока не получается.
Если я правильно понял, достаточно написать в заголовочном файле "extern имя переменной", объявить эту переменную в одном си файле (кстати есть ли разница в каком?) и эта переменная будет видна во всех си файлах и при этом заголовочный файл не нужно включать в сишные файлы? Достаточно один раз его включить.
Может у меня Makefile не правильно настроен, если такое возможно, потому что нет разницы с extern и без него, ругается на не объявленные переменные в тех файлах где они используются.
вот так у меня не сработает
Спойлер
Код: Выделить всё
///////////////////
main.h
///////////////////
#ifndef MAIN_H
#define MAIN_H
//глобальные переменные
extern volatile unsigned char power;
#endif
Код: Выделить всё
///////////////////
main.c
///////////////////
#include "main.h"
volatile unsigned char power = 0;
int main( void )
{
while(1)
{
abc(аргумент 1, аргумент 2);
power // какое то действие
}
}
Код: Выделить всё
//////////////////
menu.h
///////////////////
#ifndef MAIN_H
#define MAIN_H
прототип функции
void abc(unsigned long int a, unsigned char b);
#endif
Код: Выделить всё
//////////////////////
menu.c
//////////////////////
#include "menu.h"
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 (множественное определение). Интересно как это? Почему у меня тогда ругается если так же делаю?
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Вс апр 09, 2017 04:09:33
WiseLord
hosturik писал(а):у меня в файле 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 использовалась бы локальная
Ну а дальше - как обычно.
Такой подход в больших проектах более правильный, т.к. глобальные переменные - это не очень безопасно. Но в проектах на МК часто (не всегда) глобальные переменные дают небольшой выигрыш в размере кода.
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Вс апр 09, 2017 08:28:50
Siarzhuk
hosturik писал(а):[...] и эта переменная будет видна во всех си файлах и при этом заголовочный файл не нужно включать в сишные файлы?
Как это работает: 1. Препроцессор -> 2. Компилятор -> 3. Линкер Первый собирает из одного .c и всех .h на которые тот прямо либо косвенно (из включаемых .h) ссылается и комбинирует огромнейший [как правило] .с файл и отдаёт его на компиляцию. Это делается отдельно для каждого .с файла в проекте - поэтому подключать .h нужно в каждый .с где требуется знание об этой переменной. И лишь линкер собирает откомпилированные обьекты воедино - и тогда наступает Момент Истины - либо а) дубликаты переменных, либо б) одна переменная и ссылки на неё из других файлов, либо, что тоже не исключено, ц) одни только ссылки на несуществуюшую переменную.
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Вс апр 09, 2017 10:33:09
hosturik
Всем большое спасибо. Все получилось.
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Чт июн 29, 2017 14:39:04
REQW84
Господа, подскажите почему не работает код
Задача: по внешнему прерыванию INT0 изменяем значение переменной reg. В зависимости от состояния reg включается разный режим работы светодиода.
AVR Studio компилирует без ошибок, но ничего не работает в Proteus
Вот код:
Код: Выделить всё
#include <avr/io.h> //Подключаем библиотеку AVR
#include <avr/iotn2313.h> //Подключаем библиотеку ATtiny2313
#include <avr/interrupt.h> //Подключаем библиотеку прерываний
//Глобальные переменные сюда:
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); //Порт В на ВЫХод
PORTD=(1<<2); //Порт PD2 Подтягивающий резистор ВКлючен
INTinit(); // вызываем функцию инициализации прерываний
sei(); //Глобальное разрешение прерываний
while (1)
{
if (reg==1) PORTB=(1<<0); //Если reg досчитал до 1, то на ножке PD2 выставляем высокий уровень
};
}
Что я делаю не так?!
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Чт июн 29, 2017 14:45:43
WiseLord
Уж сколько раз твердили миру... volatile.
Ну и антидребезга нет никакого. Для Proteus не важно, но в жизни при нажатии на кнопку прерываний до десятка будет за раз.
В коде последний комментарий вообще не в тему.
Итогом выполнения программы вижу постоянно находящийся в единичном состоянии PB0, веди ничто его в ноль в принципе не уводит.
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Чт июн 29, 2017 15:09:33
REQW84
[uquote="WiseLord",url="/forum/viewtopic.php?p=3135281#p3135281"]Уж сколько раз твердили миру... volatile.
Ну и антидребезга нет никакого. Для Proteus не важно, но в жизни при нажатии на кнопку прерываний до десятка будет за раз.[/uquote]
Спасибо!!! Все заработало!
Как же все было не сложно...
Антидребезг обязательно добавлю!
Добавлено after 2 minutes 58 seconds:
[uquote="WiseLord",url="/forum/viewtopic.php?p=3135281#p3135281"]В коде последний комментарий вообще не в тему.
Итогом выполнения программы вижу постоянно находящийся в единичном состоянии PB0, веди ничто его в ноль в принципе не уводит.[/uquote]
Это, так скажем, заготовка была с целью организовать выполнение прерывания по INT0, что с Вашей помощью и получилось
Теперь дальше дописывать режимы, добавлять антидребезг, так же понадобятся мне свои задержки с интервалами больше 15сек и тд...
А Вам еще раз Спасибо!