Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Работа c GCC в AVR Studio
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Михаил_K
Добрый день.
Установил на машину AVR Studio и WinAVR, после чего появилась вроде неплохая альтернатива Image Craft. Но вот создавая проект в AVR Studio у меня получается использовать язык C, но не получается использовать С++. Как можно это побороть.
Marian
"WinAVR is a suite of executable, open source software development tools for the Atmel AVR series of RISC microprocessors hosted on the Windows platform. It includes the GNU GCC compiler for C and C++."
Если хочешь получить ответ, задавай вопрос конкретно.
kurtis
возможно, нужно попробовать переименовать файлы "*.c" в "*.cpp" ?
Qwertty
Студия не работает с плюсовым компилятором. Нужно написатьсвой Makefile с вызовами соответствующего компилятора и подключить в Студии как внешний. А зачем в маленьком контроллере, где любимое дело подсчитывать такты C++? Проекты для AVR не настолько большие, чтобы ощутить прелести ООП. Но это естественно ИМХО.
ReAl
Цитата(Qwertty @ Aug 26 2009, 23:42) *
А зачем в маленьком контроллере, где любимое дело подсчитывать такты C++? Проекты для AVR не настолько большие, чтобы ощутить прелести ООП. Но это естественно ИМХО.
Ну так и пользоваться только минимумом от С++. "С с классами" тоже неплохо. ИМХО :-)

Посмотрите, например, это
http://electronix.ru/forum/index.php?s=&am...st&p=487831

С-шный "#define-макрос" NONATOMIC_BLOCK - нечто очень хитрое, ползующееся непереносимыми на другие компиляторы расширениями GCC.
Без этих расширений не выйдет написать макрос так, чтобы изнутри привязанного к нему блока кода можно было выйти по break/goto/return.
Можно сказать "это далеко не всегда нужно", а можно привыкнуть и коазывается, что это часто удобно.

Ну так вот на С++ это же самое пишется гораздо более переносимо, остаётся зависимость от архитектуры, но привязка к расширениям GCC пропадает.

Или вот
http://electronix.ru/forum/index.php?s=&am...st&p=547510
делаем шаблон, при помощи которого любой POD-тип можно "атомизировать" - любой доступ к нему будет производиться при запрещённых прерываниях. Иначе любое обращение пришлось бы оборачивать в ATOMIC_BLOCK(ATOMIC_RESTORESTATE)

А тут
http://electronix.ru/forum/index.php?s=&am...st&p=535341
наоборот - обёртка для volatile-переменной, которая в обработчике прерывания кеширует volatile-переменную во временой, все модификации в ней и при любом выходе из прерывания сохраняет значение назад в volatile-переменную.

(эти два примера - atomiser и cache_volatile - надо бы скрестить в один, научить cache_volatile<> принимать atomic<>)

По объёму кода/тактам - везде примеры компиляции, вроде и не проигрывает тому, что для того же функционала надо будет писать на С.
И так по мелочи можно программировать пусть и без ОО, но возможностями С++ сделать работу комфортнее.
Михаил_K
Цитата(Qwertty @ Aug 27 2009, 00:42) *
Студия не работает с плюсовым компилятором. Нужно написатьсвой Makefile с вызовами соответствующего компилятора и подключить в Студии как внешний. А зачем в маленьком контроллере, где любимое дело подсчитывать такты C++? Проекты для AVR не настолько большие, чтобы ощутить прелести ООП. Но это естественно ИМХО.


Жаль конечно. Очень уж меня не радует перспектива вручную Makefile писать.
ReAl
Цитата(Михаил_K @ Aug 27 2009, 09:37) *
Жаль конечно. Очень уж меня не радует перспектива вручную Makefile писать.
В WinAVR, вроде бы ж, входит генератор makefile (я не отслеживаю, пишу вручную).
_Pasha
Цитата(Михаил_K @ Aug 27 2009, 09:37) *
Жаль конечно. Очень уж меня не радует перспектива вручную Makefile писать.

Возьмите вменяемый шаблон. И добавляйте по мере необходимости все, что надо.

Цитата(ReAl @ Aug 27 2009, 14:36) *
В WinAVR, вроде бы ж, входит генератор makefile (я не отслеживаю, пишу вручную).

Плохо только то, что он делает свою структуру каталогов, несколько усложняя процесс
Qwertty
Цитата(ReAl @ Aug 27 2009, 02:16) *
А тут
http://electronix.ru/forum/index.php?s=&am...st&p=535341
наоборот - обёртка для volatile-переменной, которая в обработчике прерывания кеширует volatile-переменную во временой, все модификации в ней и при любом выходе из прерывания сохраняет значение назад в volatile-переменную.

Я видимо чего то не понимаю в этой жизни. Делать обертку для volatile переменной, чтобы ее использовать в прерывании как обычную с помощью union или конструтора и деструктора объекта...
Вместо простого:
Код
volatile uint8_t Var;

ISR(vector_name)
{
uint8_t  *pVar = (uint8_t*)&Var;
...
*pVar++;
// в общем работаем как обычно  
// при выходе переменная будет гарантировано сохранена
}

Работа через указатель оставляет полную свободу оптимизатору вплоть до сокращения до нуля всего и вся smile.gif
Какие минусы по сравнению с Вашим вариантом?
ReAl
Цитата(Qwertty @ Aug 28 2009, 23:29) *
Я видимо чего то не понимаю в этой жизни. Делать обертку для volatile переменной, чтобы ее использовать в прерывании как обычную с помощью union или конструтора и деструктора объекта...
Извините, но чтобы показать, что С++ ничем не лучше, нужно привести опровержения для всех примеров, а не для одного.

Цитата(Qwertty @ Aug 28 2009, 23:29) *
Работа через указатель оставляет полную свободу оптимизатору вплоть до сокращения до нуля всего и вся smile.gif
Какие минусы по сравнению с Вашим вариантом?
Как в старом анекдоте про молодого специалиста в юридической консультации
Цитата
-- скажите, имею ли я прав...
-- имеете!
-- скажите, а имею ли я пра...
-- имеете!
-- скажите, а мог..
-- не можете!!!

Мало иметь права оставлять полную свободу, надо ещё чтобы это давало результат.
Даже оставляя за скобками то, что я не люблю не только снятие const приведением указателя, но и снятие volatile (это вопрос несколько "вкусовой") - повторяем пример в такой форме.
Код
#include <avr/io.h>
#include <avr/interrupt.h>

volatile uint8_t timer;

ISR(TIMER0_OVF_vect)
{
    uint8_t  *ptimer = (uint8_t*)&timer;

    if( --*ptimer == 0 ) {
        *ptimer = 127;
    }
    
    if( PINB & 0x02) return; // тут тоже запишется назад изменённое значение
    
    if( *ptimer & 0x01 ) PINB |= 0x01;

}
Получаем тело обработчика в пяти случаях из шести (WinAVR 20060421, 20071221, 20090313) * (-O2 -Os) такое, как будто снятие volatile просто проигнорировано:
Код
.global    __vector_16
    .type    __vector_16, @function
__vector_16:
    push __zero_reg__
    push __tmp_reg__
    in __tmp_reg__,__SREG__
    push __tmp_reg__
    clr __zero_reg__
    push r24

    lds r24,timer
    subi r24,lo8(-(-1))
    sts timer,r24
    tst r24
    brne .L2
    ldi r24,lo8(127)
    sts timer,r24
.L2:
    sbic 35-0x20,1
    rjmp .L1
    lds r24,timer
    sbrc r24,0
    sbi 35-0x20,0
.L1:
    pop r24
    pop __tmp_reg__
    out __SREG__,__tmp_reg__
    pop __tmp_reg__
    pop __zero_reg__
    reti
что на пять слов и несколько тактов длиннее, чем С++ - ный вариант.
И только в одном случае (WinAVR 20060421 -O2, но -O2 в большинстве случаев хуже, чем -Os) имеем вариант, совпадающий с С++ - ным и с таким:
Код
ISR(TIMER1_OVF_vect)
{
    uint8_t  t = timer;

    if( --t == 0 ) {
        t = 127;
    }
    
    if( PINB & 0x02) {
        timer = t;
        return;
    }
    
    if( t & 0x01 ) PINB |= 0x01;

    timer = t;
}
Собственно, С++ просто автоматизировал несложным и недлинным шаблоном такое поведение, которое тут выписано врукопашную.

Так как насчёт остальных примеров?

Вернёмся к атомайзеру.
Берём атомайзер по приведенному выше линку и пишем.
Код
atomic<uint16_t> timer;

void delay(uint16_t tim) {
    uint16_t start = timer;
    while( (uint16_t)(timer - start) < tim);
}
Получаем код
Код
    .text
.global    _Z5delayj
    .type    _Z5delayj, @function
_Z5delayj:
    movw r22,r24
    in r24,95-0x20
/* #APP */
    cli
/* #NOAPP */
    lds r20,timer
    lds r21,(timer)+1
    out 95-0x20,r24
.L2:
    in r18,95-0x20
/* #APP */
    cli
/* #NOAPP */
    lds r24,timer
    lds r25,(timer)+1
    out 95-0x20,r18
    sub r24,r20
    sbc r25,r21
    cp r24,r22
    cpc r25,r23
    brlo .L2
    ret

Пишем тот же функционал на С
Код
#include <stdint.h>
#include <util/atomic.h>

volatile uint16_t timer;

void delay(uint16_t tim) {
    uint16_t start, current;
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
        start = timer;
    }
    do {
        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
            current = timer;
        }
    } while( (uint16_t)(current - start) < tim);
}
И получаем 100% совпадающий код.
Код
    .text
.global    delay
    .type    delay, @function
delay:
    movw r22,r24
    in r24,95-0x20
/* #APP */
    cli
/* #NOAPP */
    lds r20,timer
    lds r21,(timer)+1
    out 95-0x20,r24
.L2:
    in r18,95-0x20
/* #APP */
    cli
/* #NOAPP */
    lds r24,timer
    lds r25,(timer)+1
    out 95-0x20,r18
    sub r24,r20
    sbc r25,r21
    cp r24,r22
    cpc r25,r23
    brlo .L2
    ret
За что боролись, отказываясь от С++ ?
Я видимо чего то не понимаю в этой жизни ™. Заводить дополнительную переменную, оборачивать код в макросы - чтобы получить тот же функционал, который на С++ пишется парой ясных строчек и при этом не выиграть ни грамма кода по сравненпию с С++...
Legotron
Цитата(Михаил_K @ Aug 27 2009, 10:37) *
Жаль конечно. Очень уж меня не радует перспектива вручную Makefile писать.

Самый простой способ в данном случае - взять Makefile, сгенерированный студией и подключить его как внешний (одну галочку поставить), а потом в нем потихонечку что-то менять, добавить зависимость для плюсовых файлов с плюсовым компилятором будет несложно.
Также посмотрите красивые примеры Makefile-ов, например для scmRTOS (gcc-avr.mak можно смело брать за основу)

P.S. И еще, будьте аккуратнее со смешанными проектами (одновременно С и С++), не забывайте про extern "C" {}
Sirko
Подскажите пожалуйста на русском языке, как использовать классы на AVRGCC.
Или отправьте на русскоязычный ресурс.
Google - злодей не помог.
Serjio
Можно для старта воспользоваться визардом в ATMANAVR.
haker_fox
Цитата(Sirko @ Sep 16 2009, 08:03) *
Подскажите пожалуйста на русском языке, как использовать классы на AVRGCC.

Вы можете использовать классы в AVR GCC точно также, как это принято стандартом. Вам следует почитать хорошее руководство по программированию на этом языке. Например, это http://doc.mpv.ru/c++/
Sirko
Цитата
Например, это http://doc.mpv.ru/c++/

Что такое С++ и ООП, представление имею.
Проблема объяснить компилятору, об моем желании компилить .cpp
AVR Studio cpp файлы даже не видит, неговоря уже об их сборке.
Посему наверное Make нужно ручками править, а как, понятия не имею.
Вот и прошу подсказать, где бы глянуть на родном языке.

ATMANAVR не знаю, но поищу, попробую.
Хотя куда ни глянь, народ и с AVR Studio както замечательно живет.
mdmitry
Цитата(Sirko @ Sep 16 2009, 12:39) *
Проблема объяснить компилятору, об моем желании компилить .cpp
AVR Studio cpp файлы даже не видит, неговоря уже об их сборке.
Посему наверное Make нужно ручками править, а как, понятия не имею.
Вот и прошу подсказать, где бы глянуть на родном языке.

Хотя куда ни глянь, народ и с AVR Studio както замечательно живет.

Посмотрите, пожалуйста, весь этот топик с самого начала. Есть ключевые фразы. В разделе GNU Opensource обсуждалась работа make. Есть перевод на русский язык документации по make.
Попробуйте Eclipse в качестве среды. Я в AVR Studio только симулятором пользовался, проекты собирались под Eclipse с помощью winavr.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.