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

 
 
13 страниц V  « < 8 9 10 11 12 > »   
Reply to this topicStart new topic
> Как писать на С++ при создание приложений под ARM, Примеры
neiver
сообщение Mar 2 2012, 18:24
Сообщение #136


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Цитата(brag @ Mar 2 2012, 15:43) *
Да вот я какраз хотел запретить. Спасибо за подсказку
Запретить бы вообще копирование по дефолту

Легко.
Код
class NotCopyable
{
private:
    NotCopyable(const NotCopyable&);//конструктор копирования
    NotCopyable & operator=(const NotCopyable&);//оператор присваивания
};
...
class Foo :NotCopyable
{
public:
...
};

В классе NotCopyable конструктор копирования и оператор присваивания закрыты и не имеют реализации. Все классы, копирования которых мы хотим запретить, просто наследуем от NotCopyable.
Go to the top of the page
 
+Quote Post
brag
сообщение Mar 2 2012, 19:53
Сообщение #137


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



neiver, типа такого и сделал, чтоб меньше буковок было.. Вот бы не забывать от него наследоватся, вернее взять за правило от него наследоватся всегда. (копи-абельные классы - в виде исключений, в основном просто структуры данных)
я имел в виду в компилере отключить эти '=' и default copy constructor
но тогда штука типа int a=21 работать не быдет, так что прийдется все же помнить про такой базовый класс
Go to the top of the page
 
+Quote Post
brag
сообщение May 28 2012, 19:24
Сообщение #138


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Из соседней ветки возник вопрос по умным указателям
Допустим есть такая штука(типа наш указатель):
CODE
template<class T> class smart_ptr{
public:
// create constructor (first reference)
smart_ptr(T* ptr)
: pData(ptr), pctr(&ctr), ctr(1) {
printf("new\n");
}
// copy constructor (following references)
smart_ptr(const smart_ptr<T> &sp)
: pData(sp.pData), pctr(sp.pctr) {
++*pctr;
printf("ref %d\n",*pctr);
}

~smart_ptr(){
--*pctr;
printf("ref %d\n",*pctr);
if(*pctr<1)delete pData;
}

T& operator*(){ return *pData; }
T* operator->(){ return pData; }
T& operator[](int i){ return pData[i]; }

private:
T *pData;
int *pctr;
int ctr;

smart_ptr& operator=(const smart_ptr&); // disabled temporary
};


И примерно так используем:
CODE
void f1(smart_ptr<char> p){
printf("f1 %s\n",&p[0]);
}

main(){
smart_ptr<char> p(new char[256]);

sprintf(&p[0],"blabla");

f1(p);
}


результат:

new
ref 2
f1 blabla
ref 1
ref 0


Все конечно ок, но для экономии памяти и повеышения производительности хотелось бы иметь f1(smart_ptr<char> &p);
Работает некорректно:
Код
new
f1 blabla
ref 0

Как в таком случаи его заставить правильно работать?

апд. в принципе оно вроде корректно, тк пока указатель не будет скопирован - можно считать, что больше ссылок на него не появилось.
Но хотелось бы сделать этот код более красивым и уменьшить размер smart_ptr до 8 байт...

апд2.
а не, код глючний, ибо если удалить самый первый обьект, то *pctr станет нерабочим. надо делать другой...

Как-то так вроде красиво
CODE
class ref_ctr{
public:
ref_ctr(): ctr(1) {}
int aquire(){ return ++ctr; }
int release(){ return --ctr; }
int count()const{ return ctr; }
private:
int ctr;
};

template<class T> class smart_ptr{
public:
// create constructor (first reference)
smart_ptr(T* ptr): pData(ptr) {
printf("new\n");
}
// copy constructor (following references)
smart_ptr(const smart_ptr<T> &sp): pData(sp.pData){
pData->aquire();
printf("ref %d\n",pData->count());
}

~smart_ptr(){
if(pData->release()<1){
delete pData;
printf("delete\n");
}else printf("ref %d\n",pData->count());
}

T& operator*(){ return *pData; }
T* operator->(){ return pData; }
T& operator[](int i){ return pData[i]; }

private:
T *pData;

smart_ptr& operator=(const smart_ptr&); // disable temporary
};


CODE
class chr: public ref_ctr{
public:
char c[256];
};

void f1(smart_ptr<chr> &p){
static smart_ptr<chr> pp=p;
printf("f1 %s\n",p->c);
}

void main(){
smart_ptr<chr> p(new chr);
sprintf(p->c,"blabla");
f1(p);
printf("exit\n");
}


new
ref 2
f1 blabla
exit
ref 1
delete


Сообщение отредактировал IgorKossak - May 29 2012, 06:57
Причина редактирования: [codebox] для длинного кода
Go to the top of the page
 
+Quote Post
neiver
сообщение May 29 2012, 10:34
Сообщение #139


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Вообще-то такой указатель должен канонично называться shared_ptr. smart_ptr - это уж больно общее название объектов, изображающих из себя указатели.
Еще надо не забыть ref_ctr сделать потоко-безопасным. Сейчас если такой указатель поделить между потоками, то... Наследовать данные от счетчика ссылок? Ну не знаю. Уж лучше в этот счетчик добавить указатель на данные.
Я когда делал подобную вещь, организовал shared_ptr-ы в связанный список. shared_ptr содержит указатель на данные и указатель на следующий shared_ptr в списке. Список можно сделать односвязный, двусвязный - как больше нравится. Скопировали указатель - добавили в список, при уничтожении - убрали из списка, удалили последний указатель - удалили данные. Если аккуратно реализовать, то будет потокобезопасно, поскольку нет разделяемых между потоками объектов.
Go to the top of the page
 
+Quote Post
brag
сообщение Jun 7 2012, 09:40
Сообщение #140


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Имена, то такое, это пример sm.gif
Потокобезопастность всегда прикручиваю позже, когда она нужна, наследуясь от потоконебезопасного класса и вешаю необходимую приблуду, а они могут быть разные (от запрета переключения контекста до хитрых lock-free структур)
Довольно редко для таких указателей оно надо.

Счетчик в указатель добавлять геморно, поскольку возникнет проблемма дублирования счетчика (хз с каким счетчиком потом работать).
Списки - хорошо, но потокобезопасный список - вещ не тривиальная, если lock-free, то довольно сложно реализуемая либо вообще не реализуемая. А в реализации ref_ctr легко сделать потокобезопасным на ARMv7m без всяких локов:
Код
void ref_ctr::aquire(){
    int c;
    do{
        c=__ldrex(&ctr)+1;
    }while(__strex(c,&ctr));
}

bool ref_ctr::release(){
    int c;
    do{
        c=__ldrex(&ctr)-1;
    }while(__strex(c,&ctr));
    
    return c<=0;
}
Go to the top of the page
 
+Quote Post
brag
сообщение Jun 16 2012, 16:02
Сообщение #141


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Возникла тут задача с аналогичным смыслом, который был изложен господином dxp в посте http://electronix.ru/forum/index.php?s=&am...st&p=942993 про сообщения.

Код, предложенный dxp потокоопасный и от части делает на рантайме то, что мог бы сделать компилятор на компилтайме..
Предлагаю такой вот упрощенный вариант
Код
class basewrapper{
public:
    virtual int id()=0;
};

template<class T> class wrapper :public basewrapper{
public:
    explicit wrapper(T *msg) :basewrapper(),pbody(msg) {}
    static int getClassId(){ return reinterpret_cast<int>(getClassId); }
    
    virtual int id(){ return getClassId(); }
    
    T* body()const{ return pbody; }
    
private:
    T *pbody;
};


Использовать как-то так:
Код
void ztest(){
    msg1 m1;
    msg2 m2;
    wrapper<msg1> wmsg1(&m1);
    wrapper<msg2> wmsg2(&m2);
    
    dbgprintf("%d %d\n",wmsg1.id(),wmsg2.id());
}


Конечно, поведение компилятора в функции getClassId() не совсем детерминировано(хотя хз), но тесты на gcc-4.7.1 и rvct-4.1 [Build 894] со всевозможными опциями оптимизации дали положительный результат.
Go to the top of the page
 
+Quote Post
brag
сообщение Jun 16 2012, 17:09
Сообщение #142


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Ну и еще один вариант, гарантирующий однозначность в принципе но увеличивающий размер кода, но без ущерба производительности. Использовать предефайнд-константу __PRETTY_FUNCTION__, бпльшинство компиляторов это поддерживают.
Код
template<class T> class wrapper :public basewrapper{
public:
    explicit wrapper(T *msg) :basewrapper(),pbody(msg) {}
    static int getClassId(){ return reinterpret_cast<int>(__PRETTY_FUNCTION__); }
    
    virtual int id(){ return getClassId(); }
    
    T* body()const{ return pbody; }
    
private:
    T *pbody;
};


UPD.
Подумал я тут на счет первого варианта... Чтобы линкер вдруг не умудрулся слить функции getClassId() шаблонов разных типов в одну, нужно ему как-то об'яснить, что выходной файл - динамическая библиотека, тогда каждая getClassId() однозначно будет иметь свое имя, и ессно свой адрес. Хотя есть еще алиасы, хз в общем sm.gif) Будем надятся, что линкер не на столько умный, чтобы сливать функции с разными именами и одинаковым телом в одну wink.gif
При самой агрессивной оптимизации ничего криминального не произошло:
CODE
arm-none-eabi-g++ -mcpu=cortex-m3 -mthumb -O3 -Wall -Wextra -flto -ffreestanding -fno-rtti -fno-exceptions -g -c ztest.cpp
arm-none-eabi-g++ -mcpu=cortex-m3 -mthumb -O3 -Wall -Wextra -flto -ffreestanding -nostdlib -g\
-Wl,-emain -Wl,--gc-sections -o z.elf ztest.o
arm-none-eabi-objdump -d z.elf

Disassembly of section .text:

00008000 <main>:
8000: f248 003c movw r0, #32828; 0x803c
8004: f248 0125 movw r1, #32805; 0x8025 <-----| Уникальные
8008: f248 0231 movw r2, #32817; 0x8031 <-----|
800c: b508 push {r3, lr}
800e: f2c0 0000 movt r0, #0
8012: f2c0 0100 movt r1, #0
8016: f2c0 0200 movt r2, #0
801a: f241 2334 movw r3, #4660; 0x1234
801e: 4798 blx r3; printf
8020: 2000 movs r0, #0
8022: bd08 pop {r3, pc}

00008024 <_ZN7wrapperI4msg1E10getClassIdEv.local.3.4006>:
8024: f248 0025 movw r0, #32805; 0x8025
8028: f2c0 0000 movt r0, #0
802c: 4770 bx lr
802e: bf00 nop

00008030 <_ZN7wrapperI4msg2E10getClassIdEv.local.2.4020>:
8030: f248 0031 movw r0, #32817; 0x8031
8034: f2c0 0000 movt r0, #0
8038: 4770 bx lr
803a: bf00 nop
Go to the top of the page
 
+Quote Post
brag
сообщение Jun 17 2012, 00:35
Сообщение #143


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



До коллекции еще один вариант, без виртуальных функций - чуть выше производительность при проверке типа и исполняемый код меньше.
Код
class IClassId{
public:
    explicit IClassId(unsigned id) :classid(id) {};
    unsigned id()const{ return classid; }
private:
    unsigned classid;
};

template<class T> class ClassIdBase: public IClassId{
public:
    explicit ClassIdBase(T*) :IClassId(getClassId()) {}
    static int getClassId(){ return reinterpret_cast<unsigned>(getClassId); }
    static T* getObjptr(IClassId *p){
        if(p->id()==getClassId())return static_cast<T*>(p);
        else return 0;
    }
};


Использовать как-то так
Код
class c1: public ClassIdBase<c1>{
public:
    c1() :ClassIdBase(this) {}
};
class c2: public ClassIdBase<c2>{
public:
    c2() :ClassIdBase(this) {}
};

void zt1(IClassId *wrp){
    printf("%d %d\n",
        ClassIdBase<c1>::getObjptr(wrp),
        ClassIdBase<c2>::getObjptr(wrp));
}

void ztest(){
    c2 w1;
    zt1(&w1);
}

0 536888040


Указатель this конструктору ClassIdBase передается специально, чтобы чтобы компилятор выдал ошибку, если вдруг при копипасте случайно забудем исправить параметр шаблона ClassIdBase, типа так:
Код
class c2: public ClassIdBase<c1>{
public:
    c2() :ClassIdBase(this) {}
};
Go to the top of the page
 
+Quote Post
AVR
сообщение Jun 18 2012, 00:41
Сообщение #144


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Цитата(Forger @ Dec 13 2011, 12:55) *
Идеи Qt дает интересные, но она изначально ориентирована на кучу.
А чтобы приучить ее к статике - нужно изрядно попотеть, а смысл?
Т.е. в эмбеддерских делах пока ей, по-моему, пока нет места.


шутки шутками, а я на полном серьезе просто воткнул Linux на ARM SAM9G45, зарядил туда Qt и спокойно пишу на своей любимой библиотеке

для участков, критичных к производительности и памяти можно спокойно обойти использование Qt-шных классов как раз по названной Вами причине, но все остальное, что не надо чтобы шустрило, пишется на Qt и экономится время и нервы

в моей гипер-мега-системе два ARM-а разных классов (второй Cortex-A9), один x86, ну и еще телефон на базе Android - с помощью Qt я спокойно пишу код который совместим со всеми этими платформами и любыми ОС в широком смысле

ЗЫ
некоторые даже предпочтут питон или даже Mono/C# для своих проектов, ускоряя критичные участки нативщиной =)


--------------------
Go to the top of the page
 
+Quote Post
brag
сообщение Jun 18 2012, 06:46
Сообщение #145


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



AVR, все так, только linux і Qt не вдуть на проц с 64кб озу sm.gif а городить тяжеловес как-то не логично,особенно,если от батарейки должен работать.. Хотя может скоро и можно будет себе такое позволить - даешь дешевые китайские платы,дешевые армы, дешевый фен шоб паять BGA есть sm.gif)
Go to the top of the page
 
+Quote Post
AVR
сообщение Jun 18 2012, 19:27
Сообщение #146


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Цитата(brag @ Jun 18 2012, 10:46) *
AVR, все так, только linux і Qt не вдуть на проц с 64кб озу sm.gif а городить тяжеловес как-то не логично,особенно,если от батарейки должен работать.. Хотя может скоро и можно будет себе такое позволить - даешь дешевые китайские платы,дешевые армы, дешевый фен шоб паять BGA есть sm.gif)

всё зависит от задачи и величины партии, а чтобы работал от батарейки - есть специальные меры в ОС Linux для этого... вот сколько стоит 32 Мб DDR2? а теперь берете калькулятор и считаете - вам проще потратить три копейки и влепить ОСь Linux и кучу дешевой рамы или страдать дедовским способом? sm.gif

в общем, для мелких и средних партий я сторонник полновесной ОС (Linux лишь одна из таких), быть может такие проекты и есть то большинство...


--------------------
Go to the top of the page
 
+Quote Post
dxp
сообщение Jun 19 2012, 04:48
Сообщение #147


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (AVR @ Jun 19 2012, 02:27) *
всё зависит от задачи и величины партии, а чтобы работал от батарейки - есть специальные меры в ОС Linux для этого... вот сколько стоит 32 Мб DDR2? а теперь берете калькулятор и считаете - вам проще потратить три копейки и влепить ОСь Linux и кучу дешевой рамы или страдать дедовским способом? sm.gif

в общем, для мелких и средних партий я сторонник полновесной ОС (Linux лишь одна из таких), быть может такие проекты и есть то большинство...

А не оценивали, как влияет на энергопотребление использование такой взрослой оси (да ещё и + Qt)?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AVR
сообщение Jun 19 2012, 20:34
Сообщение #148


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Цитата(dxp @ Jun 19 2012, 08:48) *
А не оценивали, как влияет на энергопотребление использование такой взрослой оси (да ещё и + Qt)?
не совсем понял, это скорее намек или вопрос? я полагаю что энергопотребление при работе Linux и Qt будет несколько выше

я сравнивал официальные отчеты от Ti для OMAP3 - при максимальной нагрузке - разницы между потреблением с ОС и без нее - не нашел, при отсутствии нагрузки - да, у Linux было процентов на 15 выше, не более

но как и во всем, есть недосказанные моменты - у Linux есть специальные средства для отладки энергопотребления системы, чтобы всегда знать что не дает держать процессор в глубоком сне и минимальном потреблении, да и сама ОС Linux жрет скорее оперативку, чем процессор - что приятно

а учитывая HRT возможности Linux-а с его максимум 25 мкс что я видел в одном из тестов - вообще универсальная ОСь получается - ни за что ее не променяю, и подкормлю сотней милливатт если надо sm.gif

P.S.
понимаю какое отвращение могут вызвать мои слова у профессионалов, пишущих на голом железе для экономии энергии, но мне-то хорошо - ценой некоторого потребления и стоимость DDR2 - получаю платформу для легкой и быстрой разработки


--------------------
Go to the top of the page
 
+Quote Post
brag
сообщение Jun 19 2012, 22:02
Сообщение #149


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



32мб ddr2 не так уж и дешево, и проц под это дело в том числе. плата дорогая, сама требующая больше времени для отладки и оборудования дорогого нередко - частоты не те уже, хотя и не свч. какраз на мелкосерийке выйдет дорого - Китай + дорогая пайка бга корпусов(ну запаяю я феном парочку образцов, но на продажные девайсы никогда такое бы не делал). размер. вес. потребление, особенно,если железка алгоритмы выполняет, а не просто висит в глубоком сне в ожидании нажатие кнопочки...
Потом этот весь софt сам кишит багами(а свои баги ловить проще,чем чужие), вон я недавно даже в релизе компилятора gcc баг поймал, компилер иногда удалял запись в регистры периферии, при чем по словам разработчиков, баг есть и в более ранних версиях. пруф-линк http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53085
И как ни странно - обучение работы с тем софтом(чего только стоит драйвер написать, а если тайм критикал + многопоточность - как говорят буржуи - synchronization will kill you) и реализацией задач, которые легко ложатся на простые Cortex-M3 ~70mhz соизмеримо с их реализацией на этом самом голом железе, а знания C++, умение программировать в ОО нужно там и там.
вобщем всему свое место
Go to the top of the page
 
+Quote Post
AVR
сообщение Jun 19 2012, 22:21
Сообщение #150


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Цитата(brag @ Jun 20 2012, 02:02) *
вобщем всему свое место
спасибо, интересное мнение

ясно одно - PoP у нас уже есть, так что скоро все эти разговоры про сложность разводки DDR2/3 для возможности запуска полновесной ОС типа Linux уже не будет стоять так остро, останется лишь вопрос цены, но объемы оперативной памяти растут, а "минимальные системные требования" у Linux с годами растут крайне медленно

насчет багов, я бы не был так категоричен про "кишащий багами софт", в экзотических местах такое может быть - но на то и есть отладка

не соглашусь и с временем обучения работы с софтом - и чего же стоит драйвер написать? правильно ли я понял что данная оценка из личного опыта?


--------------------
Go to the top of the page
 
+Quote Post

13 страниц V  « < 8 9 10 11 12 > » 
Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 15:17
Рейтинг@Mail.ru


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