реклама на сайте
подробности

 
 
> Работа c GCC в AVR Studio, Как использовать c++
Михаил_K
сообщение Aug 26 2009, 10:49
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 552
Регистрация: 29-02-08
Пользователь №: 35 481



Добрый день.
Установил на машину AVR Studio и WinAVR, после чего появилась вроде неплохая альтернатива Image Craft. Но вот создавая проект в AVR Studio у меня получается использовать язык C, но не получается использовать С++. Как можно это побороть.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Qwertty
сообщение Aug 26 2009, 20:42
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Студия не работает с плюсовым компилятором. Нужно написатьсвой Makefile с вызовами соответствующего компилятора и подключить в Студии как внешний. А зачем в маленьком контроллере, где любимое дело подсчитывать такты C++? Проекты для AVR не настолько большие, чтобы ощутить прелести ООП. Но это естественно ИМХО.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Aug 26 2009, 22:16
Сообщение #3


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(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<>)

По объёму кода/тактам - везде примеры компиляции, вроде и не проигрывает тому, что для того же функционала надо будет писать на С.
И так по мелочи можно программировать пусть и без ОО, но возможностями С++ сделать работу комфортнее.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Qwertty
сообщение Aug 28 2009, 20:29
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Цитата(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
Какие минусы по сравнению с Вашим вариантом?
Go to the top of the page
 
+Quote Post
ReAl
сообщение Aug 28 2009, 22:10
Сообщение #5


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(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
За что боролись, отказываясь от С++ ?
Я видимо чего то не понимаю в этой жизни ™. Заводить дополнительную переменную, оборачивать код в макросы - чтобы получить тот же функционал, который на С++ пишется парой ясных строчек и при этом не выиграть ни грамма кода по сравненпию с С++...


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Михаил_K   Работа c GCC в AVR Studio   Aug 26 2009, 10:49
- - Marian   "WinAVR is a suite of executable, open source...   Aug 26 2009, 16:07
- - kurtis   возможно, нужно попробовать переименовать файлы ...   Aug 26 2009, 19:18
|- - Михаил_K   Цитата(Qwertty @ Aug 27 2009, 00:42) Студ...   Aug 27 2009, 06:37
|- - ReAl   Цитата(Михаил_K @ Aug 27 2009, 09:37) Жал...   Aug 27 2009, 11:36
- - _Pasha   Цитата(Михаил_K @ Aug 27 2009, 09:37) Жал...   Aug 27 2009, 14:31
- - Legotron   Цитата(Михаил_K @ Aug 27 2009, 10:37) Жал...   Sep 9 2009, 06:26
- - Sirko   Подскажите пожалуйста на русском языке, как исполь...   Sep 15 2009, 23:03
|- - haker_fox   Цитата(Sirko @ Sep 16 2009, 08:03) Подска...   Sep 16 2009, 06:30
- - Serjio   Можно для старта воспользоваться визардом в ATMANA...   Sep 16 2009, 06:04
- - Sirko   ЦитатаНапример, это http://doc.mpv.ru/c++/ Что так...   Sep 16 2009, 08:39
- - mdmitry   Цитата(Sirko @ Sep 16 2009, 12:39) Пробле...   Sep 16 2009, 10:22


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th July 2025 - 03:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.0139 секунд с 7
ELECTRONIX ©2004-2016