Шаблоны проектов на C++ для AVR [GCC, IAR]

Шаблоны проектов для микроконтроллеров: ATmega48, ATmega16, ATmega32, ATmega128.

Хотел оформить в виде ссылки, да забыл стиль поста выбрать. Подробности и обсуждение на форуме тут: Шаблоны проектов на C++ для AVR [GCC, IAR]
  • -1
  • 21 ноября 2012, 22:35
  • uni

Комментарии (120)

RSS свернуть / развернуть
А не боишься, что тебя сейчас холиварщики заминусуют? ;) От таких слов как «шаблон» и «С++» у некоторых рвется попа.
+2
  • avatar
  • a9d
  • 21 ноября 2012, 23:06
Нет, конечно, у меня же уже опыт есть. Притом, это не такие шаблоны как у neiver. Это проектные шаблоны.
Кроме того, холиварщики все как один переходят на более мощные и продвинутые камешки arm, вот к ним и вопрос тогда будет: на кой чёрт вам arm'ы, если вы не хотите использовать их мощу по прямому назначению — использовать более продвинутый объектный код.
0
«Моща» и «продвинутый объектный код», строго говоря, никак не связаны. Совершенно ничего не мешает писать такой код под тиньки, например.
+1
В смысле, под чьи тиньки? Я себя ограничил ATmega48, т. е. 4К и ниже решил не опускаться ибо это не даёт хоть какого-то мизерного запаса по модификации проекта. И то 4K было в качестве эксперимента и я решил оставить шаблон.

Реальные проекты на C++, c которыми я имел дело, были на 128 меге с десятками классов. По-нормальному, к шаблону должны прилагаться дополнительные классы для работы с периферией, выполненные в едином стиле. Их есть у меня, потом выложу несколько.
0
Тиньки я знаю только атмеловские.

Я, собственно, несколько о другом. Классы в embedded нужно применять акуратно, а наибольшую ценность представляют не классы, а шаблоны С++. Именно они позволяют делать эффективный и компактный код. И, что самое приятное, такой подход хорошо работает и на камнях с небольшими ресурсами. Именно по этой причине я написал, что зависимости между «мощой» и «продвинутым объектным кодом», строго говоря, нет.
0
А почему у Вас отдельный набор файлов для «ATmega48, ATmega16, ATmega32, ATmega128»? Директивы условной компиляции рулят, можно создать «универсальный» шаблон а не плодить кучу одинаковых сущностей. Более того, у Вас в руках настоящие шаблоны (templates) С++, там вообще можно разгуляется.
0
И зачем в шаблонах нужен «windows.h»
С дефайнами типа


#define WM_SETFOCUS                     0x0007
#define WM_KILLFOCUS                    0x0008
#define WM_ENABLE                       0x000A
#define WM_SETREDRAW                    0x000B
#define WM_SETTEXT                      0x000C
#define WM_GETTEXT                      0x000D
#define WM_GETTEXTLENGTH                0x000E
#define WM_PAINT                        0x000F
#define WM_CLOSE                        0x0010
#define WM_QUIT                         0x0012
0
Это тормоз, что бы не разогнаться слишком быстро.
+2
:) нет, это не тормоз, это я реализовал обработку событий в стиле windows, практически один в один. Вот от того проекта и осталось. Кроме того я хочу внедрить обработку ошибок на основе формата HRESULT. Сделать это так, чтобы весь проект использовал только этот стиль работы с ошибками. Тут ещё надо поработать.

Где-то была ссылка с проект PBIIDemo, там можно посмотреть как реализована обработка потока сообщений, очередь в стиле windows. Потом покажу подробнее, если будет интересно. У меня всё было желание совместить мой проект с какой-нибудь ОС, чтобы был законченный вид, но пока ещё до этого не дошёл.
0
Кроме того я хочу внедрить обработку ошибок на основе формата HRESULT. Сделать это так, чтобы весь проект использовал только этот стиль работы с ошибками. Тут ещё надо поработать.
Это будет самое сложное. Но если есть желание двигаться в этом направлении, могу посоветовать такую вот штуку, которая оказалась весьма удобна именно для работы с ошибками в таком стиле:


int rc = 0;

do 
{
    ...
    if((rc = someObject.someMethod(param1, param2)) != 0)
      break;
    ...
    if((rc = someOtherObject.someOtherMethod(param3, param4)) != 0)
      break;

} while(0);

// error handling
if (!rc) 
    return 0;
...


По сути это импровизированный try-catch но без соответствующего оверхеда (ценой некоторого количества затрат ручного труда). Из полезных особенностей — код и обработка ошибок становятся унифицированными по всему коду, а непосредственно ошибки обрабатываются в одном месте, там где это удобнее\нужнее. То, что не обработано просто отдаем наверх, пусть разбирается вызывающий метод. Другая, не менее (а то и более) полезная особенность — код не превращается в этажерку вложенных if-ов, помимо if...break остальной код пишется так, как если бы никаких ошибок не было, в силу чего он легко читается и остается практически на одном уровне вложенности.

Потом покажу подробнее, если будет интересно.
Спасибо, не нужно, свою первую вариацию на тему turbovision я написал 20 лет назад.
0
Ну, вариации на тему единообразной обработки ошибок можете показать ещё? TV тут не причём, если посмотреть на конец заголовочника windows.h, то там можно заметить зачатки моих мыслей как совместить формат HRESULT с микроконтроллерной системой. Не знаю, может я не совсем ясно выразился, но HRESULT, это не просто структура, а целая система единообразной работы над ошибками до появления SEH. В этом заголовочнике находятся специальные макросы для работы с различными частями HRESULT, а сама структура имеет аппаратное деление с кодами источника ошибки. Так вот одна из проблем у меня была — как распределить битовое пространство HRESULT для типовых источников ошибок в мк или плк, что видно по первым наброскам констант.

На структурную обработку я не решился, но подумаю над вашим примером.
0
То, что я привел выше — ключевой элемент. Причем программу следует разбивать на методы/функции таким образом, что бы в каждой было не более одного такого блока внутри. Непосредственно обработка тоже унифицирована — сначала отсеиваем все, что не будем обрабатывать и сразу вернем наверх, а затем уже, собственно, обработка. При желании вокруг этого блока и обработки ошибок можно обернуть бесконечный цикл и получить retry.
По поводу структурного HRESULT. Я бы этого не делал. Причина предельно проста — пользы от сложной внутренней структуры мало, а обработку и возврат ошибок она сильно усложняет.
0
Я могу привести другие причины — windows с такой технологией проработала десятилетия и многие программисты (опытные) без проблем переймут её на вооружение. Примеры использования есть в практически в любой статье MSDN, касающейся Win32. Не надо ничего особого придумывать, а можно просто промасштабировать до размеров мк.

Я понял ваш пример, да это интересно. Вы указали минусы HRESULT, да они есть и потому придумали SEH. Но и в вашем подходе при глобальном применении должны быть не только плюсы, так в чем минусы?
0
Я могу привести другие причины — windows с такой технологией проработала десятилетия
Это совершенно ничего не говорит о качестве самой технологии.
Не надо ничего особого придумывать, а можно просто промасштабировать до размеров мк.
Смена масштабов зачастую приводит к получению совершенно других результатов.
Я понял ваш пример, да это интересно. Вы указали минусы HRESULT, да они есть и потому придумали SEH. Но и в вашем подходе при глобальном применении должны быть не только плюсы, так в чем минусы?
Минус в том, что подход требует определенной дисциплины в применении. Ну и требование разбивки на функции многим не нравится. Поклонники индусского кода типа «все в одной функции» и бесконечных свичей сильно страдают.
0
А goto не кошерно? ;) Ведь то же самое.
0
Нет, не тоже самое. Этой штукой пользоваться гораздо удобнее. Впрочем, ничего не мешает вам попробовать оба варианта и выбрать самостоятельно. Хотя, вроде как, это противоречит подходу «зачем изобретать велосипед».
0
goto — это стандартная вещь и поклонники индусского кода типа «все в одной функции» и бесконечных свичей вовсе не страдают, а именно его и используют. Достаточно взглянуть на какие-нить исходники свободного ПО.

Мы это уже обсуждали и показывали кучу кода, я в частности: lcp.c
0
Описанный выше способ никак не способствует использованию goto и мало его напоминает. Во всяком случае на практике.
0
С точки зрения ассемблера и логики работы разве есть разница? Если эта вещь компилируется в одно и тоже, то в чём тогда разница?
0
Вы пищете сразу в машинных кодах? Или, все-таки, на языке высокого уровня? Если на выходе одно и тоже, тогда в чем разница? Ответ на мой и на ваш вопрос одинаков. Надеюсь вы его знаете.
0
Это означает, что ваш подход обычен и отличается от goto только по форме. В этом нет ничего страшного, в Си можно многие вещи записать по-разному.

Из равных методов описания алгоритма выбирай общеупотребительный — так? Тем более, если планируешь вставлять его в каждую (!) функцию или метод.

На ЯВУ, вообще говоря, результаты отличаются. Я лично обобщил только конкретную реализацию конкретного подхода к ветвлению. Ваш вариант выхода из области видимости do {} интересен, но ровно до того момента, пока не понимаешь что это тоже самое, что и с goto. Дальше идут холивары по поводу goto, мы их уже проходили.
0
Это означает, что ваш подход обычен и отличается от goto только по форме.
Программа написанная в машинных кодах и на С тоже отличается только по форме.
0
Поскольку никаких признаков понимания у вас не заметно, а другим может быть интересно, я, все-таки, разжую: да, формально разница только в форме. Собственно, по большому счету к разнице в форме сводится различие одинаковых программ написанных на разных языках. Но программу не только пишут, но еще читают, отлаживают и сопровождают. Вот в этот момент разница в форме и становится существенной и принципиальной. Да, тот подход, который я описал вполне можно сделать на goto. Но goto не используется. Не используется вовсе не из идеологических соображений, а из банального удобства. break короче goto label, метку не нужно писать, а значит нет риска забыть это сделать. do {} while(0) дает хорошо заметный отступ, а значит блоки кода и обработки ошибок хорошо различимы визуально. Блок дает возможность разместит переменные (в том числе классы с дестракторами) внутри блока кода, а значит гарантировать, что к моменту обработки ошибок все, что нужно уже зачищено, а области видимости четко разделены. Иначе говоря, такой подход дает совершенно четкую и однозначную структуру метода/функции — общие переменные — блок кода с локальными для него переменными — код обработки ошибок. Все вместе это упрощает и написание, и чтение, и сопровождение кода как автором, так и теми, кто будет читать этот код после него. Вот такие вот пироги. А так да, разница только в форме.
+1
Это всё очень хорошо, но у меня есть сомнения, что оптимизирующий компилятор будет того же мнения обо всём этом, когда поймёт, что передним while(0).
Кроме того, учитывая особенности реализации локальных переменных внутри функции на мк, у меня есть сомнения, что зачистка РОН на что-то повлияет. Т. е. область видимости не влияет на указатель стека, как это было бы на больших системах.
Конструкторы, деструкторы — это для тех мк, у кого на борту полно ОЗУ, в данной конкретной теме это совершенно не нужно. Поэтому в классах для мк их нет, а все методы статические. Никаких экземпляров и прочего динамического кода.

Так есть у меня признаки понимания или нет ;)
Лично мне бы хотелось реализации подхода с применением объектности и шаблонности для единообразной работы с ошибками. Ведь даже банальный HRESULT — это эпоха процедурного программирования и, если уж я взялся за объектный Си, то нужно придумать что-то поинтереснее процедурного подхода.
0
Это всё очень хорошо, но у меня есть сомнения, что оптимизирующий компилятор будет того же мнения обо всём этом, когда поймёт, что передним while(0).
Такой код вполне хорошо оптимизируется.
Конструкторы, деструкторы — это для тех мк, у кого на борту полно ОЗУ, в данной конкретной теме это совершенно не нужно
ОЗУ тут ни при чем, класс может быть такого же размера как и банальный int, а уж деструктор ничем не отличается от других методов и вполне может быть статическим. Что не помешает компилятору его вызвать.
Никаких экземпляров и прочего динамического кода.
Боже, какую чушь вы несете… Нет, пожалуй на этом я прекращаю писать в этом топике.
Так есть у меня признаки понимания или нет ;)
Чего нет, того нет.
0
Пока неадекватные ответы я вижу только у вас :) бревна не замечаете
-2
Насколько я понимаю, банальный int для 8битного AVR это uint8_t, а теперь приведите практический пример реализации класса с конструктором по умолчанию, который бы влез в 1 байт. Жду.
0
Я, вообще-то, не собирался сюда писать вообще. Но раз пошла такая пьянка, не могу не уважить человека. Пожалуйста, вот вам класс размером в один байт:


Код:
----------------
#include <stdio.h>

class OneByte {
        unsigned char data;
    public:
        OneByte():data(0x5A) { printf("Constructor invoked\n");}
        ~OneByte() { data = 0; printf("Destructor invoked\n");}
        unsigned char getData() {return data;}
};

int main(int argc, char** argv) {
    do {
        OneByte one;
        printf("Data: %0x\nSizeof: %u\n", one.getData(), sizeof(one));
    } while(0);
    return 0;
}
----------------
Вывод:
Constructor invoked
Data: 5a
Sizeof: 1
Destructor invoked
----------------


В следующий раз, когда вам приспичит пообсуждать высокие материи вроде подходов к написанию программ, вам стоит убедиться, что вы, хотя бы, дочитали до конца учебник по языку, о котором собираетесь рассуждать.
На этот раз действительно все.
0
О, хосподи (!) Человек не понимает даже что от него хотят ;) И это класс в 1 байт (!)


000000b0 <_ZN7OneByteC1Ev>:
#include <stdio.h>

class OneByte {
        unsigned char data;
    public:
        OneByte():data(0x5A) { printf("Constructor invoked\n");}
  b0:	df 93       	push	r29
  b2:	cf 93       	push	r28
  b4:	00 d0       	rcall	.+0      	; 0xb6 <_ZN7OneByteC1Ev+0x6>
  b6:	cd b7       	in	r28, 0x3d	; 61
  b8:	de b7       	in	r29, 0x3e	; 62
  ba:	9a 83       	std	Y+2, r25	; 0x02
  bc:	89 83       	std	Y+1, r24	; 0x01
  be:	e9 81       	ldd	r30, Y+1	; 0x01
  c0:	fa 81       	ldd	r31, Y+2	; 0x02
  c2:	8a e5       	ldi	r24, 0x5A	; 90
  c4:	80 83       	st	Z, r24
  c6:	80 e6       	ldi	r24, 0x60	; 96
  c8:	90 e0       	ldi	r25, 0x00	; 0
  ca:	0e 94 d1 00 	call	0x1a2	; 0x1a2 <puts>
  ce:	0f 90       	pop	r0
  d0:	0f 90       	pop	r0
  d2:	cf 91       	pop	r28
  d4:	df 91       	pop	r29
  d6:	08 95       	ret

000000d8 <_ZN7OneByteD1Ev>:
        ~OneByte() { data = 0; printf("Destructor invoked\n");}
  d8:	df 93       	push	r29
  da:	cf 93       	push	r28
  dc:	00 d0       	rcall	.+0      	; 0xde <_ZN7OneByteD1Ev+0x6>
  de:	cd b7       	in	r28, 0x3d	; 61
  e0:	de b7       	in	r29, 0x3e	; 62
  e2:	9a 83       	std	Y+2, r25	; 0x02
  e4:	89 83       	std	Y+1, r24	; 0x01
  e6:	e9 81       	ldd	r30, Y+1	; 0x01
  e8:	fa 81       	ldd	r31, Y+2	; 0x02
  ea:	10 82       	st	Z, r1
  ec:	84 e7       	ldi	r24, 0x74	; 116
  ee:	90 e0       	ldi	r25, 0x00	; 0
  f0:	0e 94 d1 00 	call	0x1a2	; 0x1a2 <puts>
  f4:	0f 90       	pop	r0
  f6:	0f 90       	pop	r0
  f8:	cf 91       	pop	r28
  fa:	df 91       	pop	r29
  fc:	08 95       	ret

Когда вы пишите для мк, студент, то размер имеет значение и не только тот, который находится в ОЗУ. Пример, который от вас требовался, а именно, класса в один байт выглядит на самом деле вот так (правда он бесполезный):


class C { public: };

int main() {
    C A1;
}

С точки зрения ресурсов ОЗУ для него будет резервироваться 1 байт и 0 байт флеш, но если я немного его изменю:

class C { public: С() {} };

int main() {
    C A1;
}

То этот пример уже будет, как и ваш, занимать уже n-е количество ресурсов мк. Вы, видимо, очень далеко находитесь от программирования мк, раз таких элементарных вещей не понимаете. Любой товарищ, который пишет на ассемблере, за такой ОДИН БАЙТ будет смотреть на вас очень косо, как на не совсем вменяемого.

На всякий случай поясняю для особо одарённых. Мои шаблоны построены так, чтобы минимизировать занимаемые ресурсы мк в целом, т.е. я учитываю в ресурсах как флеш, так и озу и их ценность для меня равнозначна, хотя над ОЗУ я конечно дрожу больше. Ибо я прекрасно понимаю товарищей, которые пишут на ассемблере или на си и умеют эти байты считать (правильно).
-3
class C { public: };

int main() {
    C A1;
}


С точки зрения ресурсов ОЗУ для него будет резервироваться 1 байт

Нет, не будет.
0
Я прав или прав или прав?

class C { public:};
C A1;
int main(){ return 0; }

AVR Memory Usage
----------------
Device: atmega16

Program:     146 bytes (0.9% Full)
(.text + .data + .bootloader)

Data:          1 bytes (0.1% Full)
(.data + .bss + .noinit)

class C { public:};

C A1;
C A2;

int main(){ return 0; }

AVR Memory Usage
----------------
Device: atmega16

Program:     146 bytes (0.9% Full)
(.text + .data + .bootloader)

Data:          2 bytes (0.2% Full)
(.data + .bss + .noinit)

class C { public:};

C A1;
C A2;
C A3;

int main(){ return 0; }

AVR Memory Usage
----------------
Device: atmega16

Program:     146 bytes (0.9% Full)
(.text + .data + .bootloader)

Data:          3 bytes (0.3% Full)
(.data + .bss + .noinit)


Только не надо истерик. Я понимаю, что креатива я тут не дождусь, а пожеланий хоть отбавляй.
0
Я говорю о оригинальном коде:

class C { public: };

int main() {
    C A1;
}


Мне стало интересно как поведет себя компилятор (естественно с выключенной оптимизацией).
Он не выделяет память в стеке.

0000002c <main>:
  2c:   df 93           push    r29
  2e:   cf 93           push    r28
  30:   0f 92           push    r0
  32:   cd b7           in      r28, 0x3d       ; 61
  34:   de b7           in      r29, 0x3e       ; 62
  36:   80 e0           ldi     r24, 0x00       ; 0
  38:   90 e0           ldi     r25, 0x00       ; 0
  3a:   0f 90           pop     r0
  3c:   cf 91           pop     r28
  3e:   df 91           pop     r29
  40:   08 95           ret


В Вашем новом примере – а Вы сделаете переменную статической, дабы
запретить экспорт.

class C { public:};
static C A1;
int main(){ return 0; }

avr-gcc.exe -O0 test.cpp
avr-size.exe a.out

   text    data     bss     dec     hex filename
     66       0       0      66      42 a.out
0
А если так:


class C { public:};

int main(){

	C A1;
	C A2;
	C A3;
	C A4;
	C A5;

}

Влияет или нет?
0
Упс. Я был не прав.
30:   0f 92           push    r0
 …
  3a:   0f 90           pop     r0

Я решил, что компилятор просто хочет сохрнанить значение r0. Оказалось, он таким способом выделяет память/чистит память.
0
Наконец-то, хоть один луч в тёмном царстве. Просто на стеке это было не очевидно и я привёл пример с глобальной переменной, где компилятор это показывает в результатах компиляции.

Отличие моего подхода от верхнего «однобайтового» класса в том, что я изучают ассемблерные листинги и мне не нужно использовать килобайтные коды с printf() и sizeof(), чтобы понять структуру памяти в ОЗУ. Точно такой же подход у тех людей, кто пришёл в мк снизу. Они хорошо считают байты, разбираются в листинге кода, ибо им асм знаком и они бы меня живо вывели на чистую воду, показав такой пример и попросив объяснить, а куда это девается столь драгоценное ОЗУ?

Человек, который бы не следил за этим делом или упускал это из виду мог бы на IAR'е долго возится под отладчиком, выискивая срыв стека. Там приходится просчитывать глубину вложенных вызовов и работу на стеке гораздо точнее, чем с gcc. Поэтому я так внимателен к таким вещам, ибо на мк с небольшим количеством ОЗУ нельзя в настройках компилятора выставлять произвольные цифры. Так никакого ОЗУ не напасёшься. И из всего этого и вытекает способ использования объектного Си, т.е. форму записи классов и методов.
0
Отличие моего подхода от верхнего «однобайтового» класса в том, что я изучают ассемблерные листинги
Точно такой же подход у тех людей, кто пришёл в мк снизу.

Поверьте, не вы один изучаете ассемблерные листинги и следите за стеком. Даже очень высокоуровневым программистам иногда приходится лезть в асм, барьеры памяти и т. д… Я не считаю, что те, кто пришел «снизу» это тру, а те кто «сверху» — никогда не смогут нормально писать для МК. ИМХО – это миф. Дело в профессионализме а не в том кто откуда пришел.
+1
Поэтому в классах для мк их нет, а все методы статические. Никаких экземпляров и прочего динамического кода.

Вы бы разобрались, для начала, в каких случаях при использовании С++ для классов будет генерироваться тот самый «дополнительный» код, которого Вы так боитесь. При грамотном использовании, этого дополнительного кода не будет.

А экземпляры – используются (например как локальная переменная внутри функции). И никакой избыточности не будет, затраты ОЗУ будут аналогичны если бы я создал локальную переменную типа struct с аналогичным набором полей.

В проектах на МК избегают динамического выделения памяти, исключений, виртуальных функций – это да.
0
Я вспомнил, где я ваш подход видел. Так работает комплексная обработка ошибок в VB6. Там тоже нет SEH, так как тогда его ещё не было и для централизованной обработки ошибок приходится делать обёртку кода в каждой функции. Можно посмотреть это даже на конкретном примере. Вот тут: CParser.cls.

Там, конечно, нет пустого цикла, а вместо него используется конструкция языка On Error GoTo ОбработкаОшибки, но вот всё остальное я делаю таким же извращённым способом, т.е. буквально в каждой функции у меня весь код обёрнут в такую обёртку, а в локальной метке ОбработкаОшибки: находится локальный обработчик для каждой функции. Только я чуть усовершенствовал подход и у меня есть глобальная переменная с ветором ошибок, куда я складываю все ошибки вложенных функций. При разворачивании наверх самая верхняя функция может вывести источник ошибки, взяв самый первый элемент вектора ошибок.

Я думаю, что ваш подход можно было бы совместить с HRESULT. В мк всё равно следить за ошибками придётся глобально. Меня ведь и общее кодирование ошибочных состояние тоже интересовало, т.е. не отдельные коды для каждого модуля, а общие коды, только тогда можно сделать общую обработку ошибок в системе единообразно.
0
Да, кстати, можно было бы здесь банальное goto использовать без do while(0). Тогда этот подход становится понятен и простым смертным.
-1
Он и без этого понятен и простым смертным, при условии, конечно, что учебник по С они читали, а не курили.
+2
Глобальные переменные — поиск приключений на свою задницу в многозадачной системе. А RTOS по мере роста сложности задач рано или поздно становится нужна. Если вы хоть раз ловили race condition или другие ошибки синхронизации, то поймете о чем идет речь. Ну или, опять-таки, ничего не мешает вам приобрести подобный опыт самостоятельно, наступив на эти грабли.
0
Исключительность моего подхода в VB6 заключается в том :) что там всего один поток. Да, увы, на vb6 нет средств для проектирования многопоточных приложений. Уж кто как не пробовал, всех ждало фиаско. Потому там можно совершенно свободно использовать глобальные переменные. Там невозможно такое исключение в пределах самой программы.

Такие вот издержки опыта работы в винде.
0
Я же вам не об VB рассказываю, а о C/C++.
0
Вообще-то это другой подход. ON ERROR это глобальный обработчик, что несколько не то. Впрочем, единый набор кодов ошибок имеет место быть. Хотя, пожалуй, на этом сходство и заканчивается.
0
Да, это вот вопрос не в бровь, а в глаз. Действительно, можно использовать и препроцессор, можно использовать и шаблоны C++.
Что касается препроцессора, то когда я представил размер универсального файла, у меня отпало бы желание в нём ковыряться, но это не самое страшное. Можно ведь посмотреть на известные библиотеки, которые есть в сети, и увидеть, что из-за различий даже в линейке ATmega, приходится распихивать препроцессор ровным слоем по всему исходнику. Ведь, если посмотреть получше, то видно, что управляющие регистры, а особенно их биты в огромном количестве имеют различные имена с чередаванием цифирок 0, 1, 2 и буковок A, B, или вообще жуть, когда от одной меги к другой биты конфигурации прыгают их одного регистра в другой. Не то, чтобы невозможно это было всё условно отфильтровать, просто получившаяся нестандартная каша, как мне кажется, вызовет только отторжение. Ведь придётся придумывать обобщающие названия для всех конфигурационных регистров, их битов и так далее. Это нетривиальная задача.
Я мог бы показать на примере, но попозже, хотя это можно понять, сравнивая одни и те же места в меге48, к примеру, и меге128. Даже с моим подходом я не всегда могу адекватно оформить методы начальной инициализации периферии мк, так как у младших моделей всё понапихано в общие регистры, а у старших чуть ли не по отдельным регистрам всё находится. Вот из-за этого и проблемы.

А что касается шаблонов на C++, то я решил подождать экспериментов на эту тему товарища neiver, который в этом деле подкован. Сами эксперименты впечатлили, но вот что касается их практического применения в комплексе, этого я пока не видел. Т. е. чтобы всё было в едином стиле, не только конфигурация мк, но и, к примеру, работа с LCD или по i2c с RTC. Свои такие примеры я показать могу и они не требуют каких-то особых знаний от тех, кто программирет на чистом Си. Я больше использую объектность для удобного разделения кода на части: этот модуль отвечает за конфигурацию, этот за вывод в usart, этот за работу с LCD, а этот за работу с RTC.

Сам я начинал с IAR'а, хотя и заглядывал в gcc, та простота, с которой в iar можно работать с флеш подкупает, ибо достичь того же в gcc так же просто нельзя, но вот с переходом на объектный Си удалось победить эту проблему и сейчас мне больше нравится писать на gcc, чем на iar. Откровенно говоря, я терпеть не мог iar'овской ide, она до сих пор меня порой выводит из себя из-за проблем с копипастингом, поэтому писал я в vs, а компилировал и отлаживал в iar. А тут уже и avr studio подросла и перестала быть убожеством и можно трудиться практически наравне с пк'шными средами разработки.
0
Сами эксперименты впечатлили, но вот что касается их практического применения в комплексе, этого я пока не видел. Т. е. чтобы всё было в едином стиле, не только конфигурация мк, но и, к примеру, работа с LCD или по i2c с RTC.
Насчет примеров не скажу, но вот библиотека кода у neiver'а весьма приличная, в статьях описана только малая часть ее.
но вот с переходом на объектный Си
Объектный С и С++ — это совершенно разные вещи.
+1
Ну вот банальная вещь, есть в объектном Си (если разница бы бала, то мог бы её и написать для разнообразия) операции >> и << для работы с потоками. Как при помощи этих операций указать, что в одном случае мне нужна кодировка cp866, а в другом cp1251? Причем 866 по умолчанию. Традиционная перегрузка и метод WriteString(), которые я использую в классе CConsole мне более понятны. Neiver наверняка бы что-нить шаблонное замутил на эту тему, но не факт, что это было бы также просто понять и использовать.

Я использую часть его библиотеки, что явно указано в начале заголовочника SmartPrt.h, использовал бы всё, если бы мог потрогать не экспериментальный, а более приближенный к реальности проект. Дело ведь в чём ещё, я не зря оговариваю единый стиль. Одно дело предложить методику, а другое — переписать PetitFS или freemodbus под неё, чтобы проект не выглядел как набор костылей или франкинштейн. Тому, кто будет потом разбираться, было бы легче, если бы все части кода по форме изложения имели что-то общее. Вот к этому стремлюсь я, стараясь писать классы одинаково или похожими на что-то из пк'шных систем.
0
(если разница бы бала, то мог бы её и написать для разнообразия)
Это два абсолютно разных языка. Общего у них меньше, чем у С++ и C#.
+1
Советую почитать о манипуляторах, именно они используются для настройки текущего состояния потока.

Вот к этому стремлюсь я, стараясь писать классы одинаково или похожими на что-то из пк'шных систем.
Не надо к этому стремиться. Разные системы и разные условия применения, соответственно разные подходы и решения.
+1
Я уважаю опыт, полученный людьми до знакомства с моими исходниками, думаю им будет приятно увидеть что-то знакомое, а не изобретение очередного велосипеда.

Поэтому некоторые мои файлы очень похожи на программирование в стиле windows. Зачем мне изобретать свои константы к какой-нибудь периферии, если я могу их взять из заголовочников windows? Вот именно это я и имел в виду и у меня на этот счет вполне обоснованное свое мнение.
0
Я уважаю опыт, полученный людьми до знакомства с моими исходниками, думаю им будет приятно увидеть что-то знакомое, а не изобретение очередного велосипеда.
А с чего вы рещили, что программирование под винду это «что-то знакомое»? К примеру, за свои четверть века опыта программирования я не написал под винду ни строчки.
0
Можно навести статистику :) там будет видно распределение тех, кто тоже не наваял за 20 лет под винду ни строчки. Мне подсказывает интуиция, что результат будет далеко не в вашу сторону :)
0
Ну попробуйте, приведите. Впрочем, я вам сразу скажу, что ваша интуиция ошибается. Основная масса софта (процентов эдак 80) это вовсе не коробочные продукты под винду, а всевозможный in house софт, где гуйня составляет, в лучшем случае, 10% всего кода, причем не на C/C++, а на чем-нибудь уровнем повыше, в последнее время так вообще преимущественно под веб. Но даже программисты, пишущие исключительно под винду, далеко не все видели в глаза windows.h. Причем это касается даже пишущих на С++.
+1
Рано, рано вы себя в софт записали. Не представляю себе программеров, которые бы за 20 лет не написали ни строчки под винду :) Ну хоть что-то должно же было быть? Откуда, скажите мне, взялись книжки о чём-то кроме ZX Spectrum и IBM PC с DOS в то время? А те, кто начал с DOS, крепко подсели :) потом на Windows 3.10 (3.11) и дальше по наклонной :) Кто куда, в зависимости от точки зрения.
0
Рано, рано вы себя в софт записали. Не представляю себе программеров, которые бы за 20 лет не написали ни строчки под винду :) Ну хоть что-то должно же было быть?
Батники не в счет.
А те, кто начал с DOS, крепко подсели :)
Не все подсели на винду. Вы не поверите, но винда не всегда была такой распространенной. В год выхода 95-й винды OS/2 Warp 3.0, вышедшая чуть раньше, продавалась в Германии лучше винды. После чего мелкомягкие стали выкручивать руки сборщикам компьютеров. Этот факт был потом использован в антимонопольном процессе против них.
0
Вы, видимо, не поняли, что Вам хотел сказать Vga. В объектном С (Objective-C) нет возможности перегрузки операторов. Оператор << часто перегружают в С++ для вывода в поток (так удобно, данный оператор имеет низкий приоритет). Вы, наверное, путаете С++ и Objective-C.
0
Я половину постов тут набрал в iPad2 и у меня есть MacOS виртуалка для начала освоения программирования на objective-c для своего девайса, поэтому я прекрасно понимаю что это такое и что он имел в виду.
Я начал изучать c++ ещё с тех давних пор, когда он назывался си с классами или объектный си и никому не приходило в голову приумножать сущности ради того, чтобы блеснуть кругозором от отсутствия комментов по теме.

Я ничего не путаю и осознанно называю используемый язык объектным си и понимаю под этим именно его объектность как способ формализации ТЗ. Если я захочу указать что-то конкретное, делая ссылку на платформу, то я так и напишу objective-c или c++/cli. Думать же, что тут кто-то может применить objective-c к платформе avr глупо. Тут MacOS то мало кто реально использовал, я уж про c++ молчу.

Есть ведь ещё управляемый объектный си, чего бы его тоже сюда не приплести? Это гораздо ближе, можно даже универсальный код писать одновременно для мк и .net для тестирования. Я знал одного программера, который так и оформлял классы, чтобы модули можно было собрать в билдере и iar. Вот там можно много чего намешать.
0
Извиняюсь, я специально написал, что «Вы, видимо, не поняли» и «Вы, наверное, путаете ». Просто у меня создалось впечатление, что Вы путаете эти 2 языка:

Ну вот банальная вещь, есть в объектном Си (если разница бы бала, то мог бы её и написать для разнообразия) операции >> и << для работы с потоками.

В Objective-C, ЕМНИП, переопределить эти операторы нельзя.

А то, что Вы обладатель iPad – я и так знаю, из Ваших предыдущих постов.

Я начал изучать c++ ещё с тех давних пор, когда он назывался си с классами или объектный си

Наверное, Вы утрируете. «С с классами» был переименован в С++ в начале 80-х. Где-то в то же время, появился Objective-C. Сам я тех времён не помню, был очень молод, материал почерпнут из Wiki :)
0
До России всё доходило с опозданием. У меня была какая-то старая книжка, которая оперировала такими терминами как си с классами и я это запомнил, тогда Страуструпа у меня ещё не было. В то время я не ушёл дальше тестовых примеров, которые даются в любом учебнике.
Реальную MacOS я увидел только в институте, где, кстати, нам преподавали TP7. Никогда бы не подумал, что у меня будет apple'овский девайс и тем более, что я захочу что-то для него сварганить.

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

Сертификат C++

Там преподавал математик из вуза, который раздал всем Страуструпа в оригинале и быстренько пробежался по книжке. Мужик был толковый, у Страуструпа мне понравился калькулятор. У нас было одно из заданий расширить его до применения функций. Там я узнал, что можно из dll экспортировать классы, что для меня было неожиданностью.

После этого я занялся освоением низкоуровневого API Windows и, чтобы было интересней, написал просмотрщик PE-файлов по материалам книжек Румянцева:

Просмотр PE-файла

Оконный интерфейс выполнен по материалам Фень Юаня «Программирование графики в Windows», до меня долго доходило как совмещается объектный подход с процедурным Windows. Там есть одна фишка, которую обычные пользователи билдеров не сразу поймут. Потом Дельфи, Билдер, VC6, MFC в перемешку.

Такая универсальность имеет плюсы и минусы. Плюсы в том, что я могу написать что-то не сложное в любой среде. Мне уже это без разницы. Минусы — я не очень глубоко знаю каждый из инструментов. Хотя это тоже относительно. Но, благодаря своим навыкам, я могу, к примеру, написать переходник для работы с неуправляемым кодом в управляемом пространстве: Mathcad EFI плагин для SMath Studio. Это нетривиальная вещь, но зато я познакомился так с c++/cli, поэтому так смело тут им бросаюсь направо и налево. После этого плагина у меня напрочь отпало желание что-то писать на управляемом объектном си. Там можно мозги свихнуть, т.к. ты должен одновременно держать в уме два языка, два подхода к работе с памятью, два набора операторов.

Так что мой ник выбран совсем не случайно, ему уже лет 12, наверное. Я уже савсем старый :)

ICQ
0
Вы не обижаетесь, но Вы слишком много говорите о себе, своих успехах, и не видите критики.

Вы используете термин, «объектный C», например, на форуме до сих пор висит:
Назначение:
1. Переход на объектный C.
Вам пытаются сказать, что «объектный С» ассоциируется с Objective-C, в Вы, в данном случае, говорите о С++. А Вы говорите, «это не баг, это фича»,

Я начал изучать c++ ещё с тех давних пор, когда он назывался си с классами или объектный си

Я Вам, попытался мягко намекнуть, что С++ получил свое название в 1983, в у вас в профиле стоит год рождения 1980. А вы выкладываете сканы о том, что вы прослушали курс и т. д….

Может, вернемся к теме, и стоит заменить в описании «объектный C» на С++?
+1
Это не критика, а вообще непонятно что. Я тоже посещал Вики, а свои характеристики я привёл, чтобы такие как Vga или вы думали, прежде чем что-то писать. Всё, что вы тут написали, школьнику понятно, который научился кликать мышкой в броузере.

Объектный Си на то и объектный, потому что это новое поколение, парадигма программирования. Это отличительная особенность, которая делает апгрейд парадигме, поднимая процесс с этапа процедурного до этапа объектного. И когда я пишу: ОБЪЕКТНЫЙ СИ, я имею в виду не мелочи в виде тех способов, которые используются для достижения объектности, а я имею в виду, что можно писать образным подходом, когда какому-то реальному объекту вы сопоставляете виртуальный образ (класс на языке C++).

А то, до чего вы тут докапываетесь, не имеет никакого принципиального значения в данной теме. Какое слово из тех что я написал вам непонятно? Вы поколения языковых парадигм знаете? Одна из тех причин, по которой многие до сих пор пишут на Си — это непонимание того как выделить из их одномерного процедурного кода объекты и их признаки.

Я показал на конкретном примере как местный сишный код может стать объектным. Ведь я не пользуюсь даже половиной возможностей C++, а там есть много чего. Кто понял мои шаблоны, тот увидит, что это просто объектная обёртка с некоторыми вкраплениями шаблонов.

Поэтому я ещё раз повторяю, что писать «объектный си» в данном случае можно и нужно и путаницы никакой быть не может.
0
Я тоже посещал Вики, а свои характеристики я привёл, чтобы такие как Vga или вы думали, прежде чем что-то писать.
Прежде чем писать стоило бы подумать тебе. Я предпочитаю делать выводы по словам, а не сертификатам.
. И когда я пишу: ОБЪЕКТНЫЙ СИ, я имею в виду не мелочи в виде тех способов
Есть в Алисе такой персонаж — Шалтай-Болтай…
+1
Это совершенно не заметно. В отличия от тебя, я делаю выводы по делам.
0
Это совершенно не заметно.
Разумеется — ведь ты и не хочешь замечать.
В отличия от тебя, я делаю выводы по делам.
Либо «в отличие», либо «делаю выводы по делам».
0
:) иди оцени свои силы, потом поговорим, любитель сертификатов:
certifications.ru/resume/175618
0
любитель сертификатов
Ты меня с собой путаешь.
+1
Да нет, просто оцениваю не по словам, а по делам. Это самый простой вариант, когда хочешь узнать с кем имеешь дело. Слабо? ;) Возьми, да пройди какие-нибудь, для приличия. А то я тут распинаюсь, а перед кем даже не знаю.
Если пройдёшь тест «Программирование на C++», то я заменю все свои выражения «объектный си» на C++.
0
Это оценка по бумажкам, а не делам. И тест по дельфи вызывает у меня большое сомнение в адекватности этих сертификатов. Впрочем, закончить я его не сумел — на 29-м вопросе он просто повис.
0
Как по мне, вполне нормальные тесты. Они мне понравились больше, к примеру, чем в ИНТУИТ. Я не от любви к тестам часть их прошёл. Меня один работодатель обязал. Иди, говорит, пройди чего-нибудь, мы посмотрим. Не многие из них будут тебя оценивать по коду :) Обычно по проектам, либо по тестам и сертификатам. Проекты не всегда покажешь, если ты был лишь одним из участников команды, а вот сертификаты и тесты показать можно.

Там можно вечно их пересдавать. Как видно по моим, я в день уложился, ну и ещё для комплекта яву попробовал, тогда у меня был опыт. Кстати, сертификаты эти не вечные и чтобы я мог такие ссылки давать, надо подтвердить их опять и сделать очередной срез остатков знаний.

Да, они там не все адекватные, но лучше, чем вообще ничего. Тем более для опытного товарища почему бы и не попробовать?
0
Чтож, тест по С++ определенно адекватней. И я его благополучно провалил (впрочем, с первого раза и без подготовки).
Название: Программирование на C++
Баллы: 58
Баллы в рейтинг: 42.55
Время сдачи: 27 мин. 0 сек.
Среднее время на вопрос: 40 сек.
Сдал лучше, чем: 61%

Знание теории 50%
Теоретические знания находятся на среднем уровне. Однако для дальнейшей эффективной работы может потребоваться дополнительное обучение по данному предмету.
Знание практики 62%
Практические навыки работы развиты хорошо. Решение наиболее распространенных задач в данной области будет проходить без серьезных затруднений.
Сильные стороны:
Базовые конструкции и синтаксис языка.
Работа с памятью.
Общие вопросы программирования на C++.
Пространства имен и область видимости.
Вопросы эффективности кода.
Слабые стороны:
STL.
Анализ теста по темам
1. Базовые конструкции и синтаксис языка. 2/3
2. Работа с памятью. 2/2
3. Средства ООП. 4/8
4. Обработка исключений и RTTI. 2/6
5. Шаблоны. 2/4
6. STL. 1/5
7. Общие вопросы программирования на C++. 5/7
8. Пространства имен и область видимости. 3/3
9. Вопросы эффективности кода. 2/2
0
Я же говорил, что понравится. Я тоже проваливал и далеко не раз. Думал, что за день смогу себе наваять побольше. Но он оказался не таким простым как я думал. Тогда я был кандидатом, где нужно было показать знания C++ Builder'а, но я решил сначала с С++ начать. Потом понял, что быстро я его не сдам и сосредоточил усилия на C++ Builder'е. Билдер я победил и Дельфи тоже, но это не помогло с работодателем, а к остальным тестам интерес угас. Надо будет опять попробовать.
0
Не знаю насчет билдера, а половина вопросов по дельфи — идиотизм вроде «как называется вкладка репозитория, где формы лежат». Сомнительный сертификат, прямо скажем.
0
Неужели Вы думаете, что меряться письками опытом это достойное занятие?
0
Если человек какого-то банального теста пройти не может, где нужно из 40 вопросов ответить правильно только на 28, то зачем тогда нужно разговаривать о высших материях?
0
Если человек какого-то банального теста пройти не может, где нужно из 40 вопросов ответить правильно только на 28

Я, честно говоря, не понял, о каком тесте идет речь, данный сайт я вижу впервые.

Просто Вы предъявили ссылку, на сайт, со списком Ваших сертификатов и «скилов».Это, наверное, круто, но не смущает ли Вас тот факт, что другие пользователи Сообщества (кроме Вас) не выкладывают сканы своих дипломов/справок/табелей за 3-тий класс, и т. д.?
+1
Видимо о том, который я провалил. Тест довольно здравый и точно определил те направления, которые я не изучал :)
Впрочем, «практику» я бы считал несколько иначе. Тогда бы она у меня не получилась выше, чем теория :D
0
Я показал на конкретном примере как местный сишный код может стать объектным.


Вы показали, как код, написанный в стиле С, можно скомпилировть как С++.

Что в Вашем коде претендует на ООП (ну, кроме SmartPtr.h)? Классы, у которых все методы статические? Это подход структурного программирования, написанный в синтаксисе С++ (ну, вынесли вы функции в отдельный неймспейс, ну, даже ограничили доступ к части функций) но где здесь ООП?

У Вас один объект («singleton») использование которого не отличается от вызова функций в С (с отдельным блекжеком и неймспейсом и доступом). Неужели вы думаете, что в этом и состоит преимущество ООП и С++ в частности.
+1
Как в C реализовать следующий конкретный код из примера 2 (ATmega16 + Petit FAT File System Module)


/**
 * Просмотр папки
 */
FRESULT CMCU::ScanFiles( char * path ) {
 
    FLASHSTR_DECLARE( char, szDirContent, " Содержимое папки: " );
    FLASHSTR_DECLARE( char, szHexChars, "0123456789ABCDEF" );

    uint8_t i;   

    // Монтирование FAT32
    res = pf_mount( & fs );

    res = pf_opendir( & dir, path );

    if ( res == FR_OK ) {

        CConsole::WriteString( szDirContent, CConsole::cp1251 );
        CConsole::WriteString( path, CConsole::cp1251 );
        CConsole::WriteString( "\r\n" );

В этом примере метод CConsole::WriteString() может использоваться 2 способами в зависимости от места расположения строки (в ОЗУ или флеш). Это ООП или что? Такой подход очень естественно получается через перегрузку и я его использую везде, где мне нужно вывести строку, например, в классе CLCD вывод на экран индикатора осуществляется совершенно аналогичным способом. Это называется единообразие.

И напрасно вы недооцениваете SmartPtr.h, именно с его помощью мне удалось почти невозможное — совместить один код для двух компиляторов. Я даже не представляю как это можно было сделать, используя C. Многие, кто переходил c IAR'а на AVR-GCC меня поймут в этой части. Ах если бы, ах если бы так просто было перенести проект с iar'а на gcc. Но это очень не просто, когда он жестко закрепился за особенности реализации. Кстати, я слышал, что __flash вроде как и в avr-gcc появился. Возможно перенос упростится.

Ещё одним плюсом, который почему-то обходят стороной, является поддержа C++ многими средами разработки. Причём, эта поддержка позволяет очень хорошо писать проект. Классы можно набросать с помощью помощников и вообще для C++ многие вещи автоматизированы. Диаграммы классов можно строить, не выходя из среды проектирования (в VS2008). Это вообще вещь. Когда проект большой и нужно как-то хоть его обозреть, то можно вызвать этого построителя схемы классов и вуаля, всё как на ладони, без километровых портянок:

Диаграмма классов
0
Как в C реализовать следующий конкретный код из примера 2 (ATmega16 + Petit FAT File System Module)
Насколько я вижу — просто удалить из кода все "::".
В этом примере метод CConsole::WriteString() может использоваться 2 способами в зависимости от места расположения строки (в ОЗУ или флеш). Это ООП или что?
Это обычная перегрузка функций. В С есть, разумеется.
И напрасно вы недооцениваете SmartPtr.h
Он не недооценивает, он как раз и говорит — это единственное, что реально требует С++. Впрочем, этот код, насколько я тебя понял, позаимствован у neiver'а.
Когда проект большой и нужно как-то хоть его обозреть, то можно вызвать этого построителя схемы классов и вуаля, всё как на ладони, без километровых портянок:
Насколько я вижу, портянка тупо разбилась на несколько портянок поменьше, без единой взаимосвязи. Об этом e_mc2 тоже говорил — код в стиле С тупо завернут в классы, используемые как неймспейсы.
+1
Это не портянка :) это реально продаваемое устройство (причём здесь только половина классов) — 8 канальный аналоговый модуль ввода-вывода для АСУТП. Весь код написан при помощи классов в IAR.
0
Про портянку говорил ты. Это раз.
На картинке практически ничего не видно, но полагаю оно такое же объектное, как eXgine (врядли этот проект здесь известен, так что приведу пример):
type ITexture = interface
  LoadTexture(FileName: string): Integer;
  SetTexture(ID: Integer);
  FreeTexture(ID: Integer);
end;

Вот и весь ООП.
0
Да, не многие знают, что interface — это typedef от struct, для этого нужно немного знать COM, где находится это определение. Но у меня такого нет. Сравнение неправомочно.
0
Это Delphi, вообще-то. И если для тебя ООП — это ключевое слово class, то говно твои сертификаты.
0
Так так быстро сдался? После всего одной неудачи :)

Я же ясно растолковал ЧТО для меня такое ОБЪЕКТНЫЙ СИ. Ты пока не достоин того, чтобы я послушал человека, провалившего тест на знание Дельфи и C++.

Ну и не дело называть говном то, чего ты сам сделать не можешь, как-то это выглядит подростково. И ещё успевать раздавать советы направо и налево.
0
Так так быстро сдался? После всего одной неудачи :)
Ты про тест? Я не собираюсь задрачивать его до сертификата. Мне было интересно пройти его один раз.
Ты пока не достоин того, чтобы я послушал человека, провалившего тест на знание Дельфи и C++.
Во первых, теста действительно на Delphi (а не работу с конкретной версией среды) я там не нашел. Во вторых — я его не провалил. Он просто повис.
В третьих, сертификата по С++ я и у тебя не вижу.
Я же ясно растолковал ЧТО для меня такое ОБЪЕКТНЫЙ СИ.
«Когда я беру слово — оно означает именно то, что им хочу сказать». Ну-ну.
Ну и не дело называть говном то, чего ты сам сделать не можешь, как-то это выглядит подростково.
Ты, как обычно, ничего не понял.
+1
Укажите на стандарт C, в котором есть перегрузка.
0
Гм, а в С разве нет перегрузки функций? Впрочем, даже если нет — к ООП она отношения не имеет. Это фишка структурного программирования.
-1
Эх, Vga, я очень редко ставлю минусы, ибо как-то это низко и подло :) Но в данном случае ты оправдано его заслужил. Держи:

Полиморфизм (от греч. «много», и μορφή — форма) в языках программирования — возможность объектов с одинаковой спецификацией иметь различную реализацию.
Кратко смысл полиморфизма можно выразить фразой: «Один интерфейс, множество реализаций».

Полиморфизм-перегрузка
Это частный случай полиморфизма. С помощью перегрузки одно и то же имя может обозначать различные методы, причем методы могут различаться количеством и типом параметров, то есть не зависят от своих аргументов. Метод может не ограничиваться специфическими типами параметров многих различных типов.

Ну, а про то, на чём держится ООП (инкапсуляция, наследование, полиморфизм) ты где-нить уже сам сможешь подробнее прочитать.

А теперь слушаем твое личное уникальное мнение:
Впрочем, даже если нет — к ООП она отношения не имеет. Это фишка структурного программирования.


Быть самоучкой не плохо, но классическое образование, пусть даже дополнительное, никому никогда не мешало. Я начинаю теперь понимать причину твоих неуёмных комментов по любому поводу и без, в особенности, огромного желания всюду ткнуть своё понимание вещей в отличие от общепринятых. И мне даже странно теперь как-то тебя слушать. С одной стороны ты киваешь мне на какой-то там objective-c, который по твоему личному мнению стал единственным воплощением смысла фразы «объектный си», а с другой выдаешь такие перлы, что хоть стой, хоть падай. Ты уж определись как-то и разъедини: вот здесь твоё личное мнение, а здесь общепринятое.
0
Полиморфизм — один из краеугольных камней ООП, но без остальных двух — ООП он не даст. Сам по себе он присутствует и в структурных языках, именно в виде перегрузки функций.
А теперь слушаем твое личное уникальное мнение:
Не уникальное. Вики, конечно, тот еще источник, но со мной вполне согласна.
Впрочем, твои определения мне тоже не противоречат. Там нигде не сказано, что полиморфизм — черта, присущая только ООП.
С одной стороны ты киваешь мне на какой-то там objective-c, который по твоему личному мнению стал единственным воплощением смысла фразы «объектный си»
Нет, ты не понял. «Объектный С» — не фраза, а название. Одного конкретного языка. И этот язык — не С++.
Я начинаю теперь понимать причину… в особенности, огромного желания всюду ткнуть своё понимание вещей в отличие от общепринятых.
Ты приписываешь мне свои черты.
Эх, Vga, я очень редко ставлю минусы, ибо как-то это низко и подло :) Но в данном случае ты оправдано его заслужил
Нет, заслужил его ты.
0
Очередной поток личных мнений :) Вики, да Вики. Это, конечно, уже прогресс, но все мои выше предложения взяты как раз из Вики, из соответствующих статей. Ты бы лучше на ООП посмотрел и статью про Полиморфизм, для разнообразия.

Критерий истины ты знаешь :) Приведи примеры структурных языков с перегрузкой функций, процедур, методов, операторов. Мне интересно посмотреть. Такая даже табличка есть в Вики, но правда для перегрузки операторов. Можешь на неё ориентироваться.
0
О, личные мнения?
Окей.
Тогда обоснуй (пруфлинками, да) твои личные мнения:
«объектный С — это С++»
«полиморфизм — это только ООП»
«перегрузка функций — это ООП».
0
А зачем ты своё мнение приписываешь мне? Это не комильфо.
Для меня объектный Си не только C++, но и любой другой, который основан на синтаксисе Си и парадигме ООП. C++/CLI — это для меня точно такой же объектный Си, как и C++, к примеру. Отличие только в платформе и связанных с этим расширениях или изменениях.

Если бы я хотел сослаться на Objective-C, то так бы и писал: Objective-C, точно также, как я отделяю C++ и C++/CLI. Я очень чётко представляю себе различие всяких этих «закорючек» и к каким следствиям непонимания они могут привести. В данном случае я хочу сделать упор на объектную часть любого расширения Си в сторону ООП. Поэтому так и пишу «объектный Си», рассчитывая на то, что читатель начнёт чтение с заголовка, а не с середины.

Что касается «объектного Си», то относись к этому как к форме описания подхода с использованием богатого русского языка. Нет такого закона, по которому я обязан следовать точному соответствию между англоязычным термином и русскоязычным словосочетанием. Как ГОСТы, есть всего лишь рекомендации, которых следует придерживаться, но выбор всё равно может оставаться за конкретным разработчиком. ГОСТы, несмотря на всю свою суровость, это всего-лишь рекомендации, кто в курсе. Они рекомендуют следовать определённым правилам, но там нет жесткой фиксации — делать только так и никак иначе.

«полиморфизм — это только ООП» — это у тебя что способ передёргивания такой? Зачем так опускаться, ты способен на большее, к копипасту, например, такого рода «на чём держится ООП (инкапсуляция, наследование, полиморфизм)». Попробуй ещё раз.

«перегрузка функций — это ООП» — вроде черным по белому написано, я специально сделал последовательный логический вывод, чтобы ты не мог понять всё по-своему, а увидел последовательную цепочку:

1. ООП (инкапсуляция, наследование, полиморфизм)
2. Полиморфизм — «Один интерфейс, множество реализаций».
3. Полиморфизм-перегрузка

Это я сделал только для того, чтобы ты больше не делал таких скоропостижных заявлений:
к ООП она отношения не имеет
Я сделал логическое опровержение твоего утверждения. Оно для любого, кто слышал об ООП, выглядит глупо, но для тебя это почему-то не очевидно.

Вот с этого можно было и начать, но если с этого начинать, то налицо отсутствие понимания самых элементарных вещей, что в дальнейшем может привести к более сильным заблуждениям, чем вот это:
Это обычная перегрузка функций. В С есть, разумеется.
0
А зачем ты своё мнение приписываешь мне? Это не комильфо.
Для меня объектный Си не только C++, но и любой другой, который основан на синтаксисе Си и парадигме ООП.
ОК, переформулирую. «Объектный С — это и С++ в том числе». Впрочем, здесь и мой вариант «Объектный С — перевод названия Objective-C» — личное мнение, по крайней мере с полпинка не нашел пруфов того, что это официальный перевод.
Ну и переформулирую изначальное предложение — замени «объектный С» на «С++», чтобы избежать разночтений.

Но вот насчет полиморфизма и перегрузки — это не мое личное мнение.
«полиморфизм — это только ООП» — это у тебя что способ передёргивания такой?
Нет. Это конкретизация твоих слов — ты приписываешь перегрузку функций к ООП потому, что это полиморфизм, а полиморфизм — черта ООП. Но это утверждение будет верно только в том случае, если полиморфизм — черта только ООП. Если же полиморфизм присущ не только ООП — утверждение о взаимосвязи перегрузки функций и ООП ложно.
1. ООП (инкапсуляция, наследование, полиморфизм)
2. Полиморфизм — «Один интерфейс, множество реализаций».
3. Полиморфизм-перегрузка
Этот вывод корректен только в том случае, если каждый следущий пункт является подмножеством предыдущего и не является подмножеством чего-либо другого. В данном же случае полиморфизм является подмножеством ОО и структурного программирования, а перегрузка функций — подмножеством полиморфизма и структурного программирования, но не подмножеством ООП (аналогичное подмножество полиморфизма и ООП — это перегрузка методов).
Вот с этого можно было и начать, но если с этого начинать, то налицо отсутствие понимания самых элементарных вещей, что в дальнейшем может привести к более сильным заблуждениям, чем вот это:
Да, насчет возможностей С я заблуждался. Но это не следствие «непонимания элементарных вещей». Просто С не поддерживает эту возможность структурного программирования. К сожалению, чисто структурных языков (известных) осталось немного (я даже затруднюсь с полпинка привести какой-либо, кроме С и Паскаля, причем классического), а остальные (вроде Delphi и C++) мультипарадигменны.
+1
Я дождусь таблички или нет, в конце-то концов? Я понимаю, что ты любишь это дело, но для разнообразия, выполни нижайшую просьбу: приведи табличку процедурных языков с перегрузкой хоть чего-нибудь. Вот чисто из любопытства, для расширения моего кругозора, честное слово, докапываться не буду. Я может тогда с C++ на этот язык перейду, ибо эта фича «структурного программирования» мне очень по душе.
0
Нет, не дождешься. Как я уже сказал, все языки, о наличии в которых перегрузки функций я знаю, являются мультипарадигменными.
Я может тогда с C++ на этот язык перейду, ибо эта фича «структурного программирования» мне очень по душе.
Врядли. Выбор мейнстримовых языков крайне невелик и переходить среди них не на что. Особенно в эмбеде.
0
Впрочем, можешь попробовать составить табличку чисто ООП языков, где есть перегрузка функций. Только врядли это у тебя получится — в них нет функций вообще. В лучшем случае есть методы.
0
Опять Вы не поняли. Я не недооцениваю, «умные указатели», я говорил:

Что в Вашем коде претендует на ООП (ну, кроме SmartPtr.h)?


Автор «SmartPtr.h» — neiver , У него получилась отличная реализация. А Вы здесь причем?
+1
Похоже, что я единственный кто это понял, принял на вооружение, указал на одну ошибку в реализации, а ещё и дополнил вот такой вставкой для удобства (сравните оригинал в статье и ту версию, что использую я):

    inline const T operator []( int value ) {
            
        return * Self( _address + value );

    }

Вот причём я. А вот вы тут пока совсем не причём похоже :)
Человек, который освоил это дело, вполне заслуживает должного уважения.
0
А ты не задумывался о том, что другие не применяют это не потому, что не поняли, а потому, что оно не соответсвует их требованиям?
0
Вот причём я. А вот вы тут пока совсем не причём похоже :)

Вам виднее :)

К neiver я отношусь с искренним уважением (ели не верите, посмотрите мои комментарии). Но, лично мне, не всегда нравиться его подход.

Похоже, что я единственный кто это понял, принял на вооружение, указал на одну ошибку в реализации

Сомневаюсь, что Вы «Тот Самый Единственный». Думаю, многие просто применили концепции, изложенные ним, а не все копипаситли код его примеров.
0
:) Зачем мне его копипастить? Это смешно, я взял его целиком и использовал, а когда не заработало кое-что, то указал на место, где возможна ошибка. Любой нормальный человек хорошую вещь берёт и использует, если она позволяет экономить время и силы.

Как я уже не раз говорил у каждого метода есть плюсы и минусы. И у этой реализации они есть, исключений быть не может. Какие ограничения, недостатки есть у этой конкретной реализации умного указателя, исходя из описанного в статье назначения? Мм?
0
Похоже, что я единственный кто это понял, принял на вооружение
:) Зачем мне его копипастить? Это смешно

Значит В не Вы «Тот Самый Единственный»?

Это все хорошо и весело.
А может, стоит вернуться к началу разговора, и все же исправить «объектный С» на С++?

Нет, Вы не подумайте, что я хочу прервать дискуссию, просто мы очень
отдалились от начальной темы.
0
Это вы от неё отдалились, тема называется «Шаблоны проектов на C++ для AVR [GCC, IAR]».
А чем вы тут занимаетесь — одним вам только и понятно :)

Лично мне интересно было узнать ход мыслей, который при такой тематике кого-то увёл в сторону MacOS, iOS и Objective-C, хотя я нигде «Objective-C» ни разу не упомянул и даже в мыслях не имел. Мне просто не приходит в голову как C++, AVR, GCC, IAR могут быть хоть в чём-то пересекаться с «Objective-C». Без вариантов.

Хотя одно предположение я имею. Когда по теме сказать нечего, но очень хочется, то нужно придумать повод.
0
Я же говри о исправлении на форуме:
Назначение:
1. Переход на объектный C.


Хотя одно предположение я имею. Когда по теме сказать нечего, но очень хочется, то нужно придумать повод.
:) Толсто…
0
Протрите хорошо глаза или наденьте очки, хотя возможно вы уже пользуетесь переводчиком, чтобы читать русский текст в переводе на английском — всё это ваши проблемы. Нигде я не упоминал и не писал «Ojective-C», такого не было и хватит фантазировать. Если у вас возникают какие-то фантазии или иные ассоциации, то я могу это просто понять и посочувствовать.

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

Жду.
0
Хочу посмотреть на ваш практический опыт.
За ним не нужно далеко идти — вот он. То, что он по другой теме и, возможно, тебе не полезен — это уже другой вопрос. Но и твой тоже не универсален — лично я, например, из твоего опыта полезным для себя нашел только список инструментов в readme.txt, скрещивание MSVS 2008 с GCC-AVR (полезность его, впрочем, нивелируется выходом AVRStudio 5/6) и ручку из колпачка.
0
Это очень хорошо, у меня в избранном много статей сообщества, а опыт по теме-то где? Или мы только комментировать умеем и на этом весь практический опыт заканчивается? Где описание трудов праведных по экспериментам в области C++?

Скрещивание MSVS2008 с любым GCC и не очень компилятором тут был уже описан и ты там, кстати, отмечался :) стареем, брат: Готовим микроконтроллерный GCC-тулчейн под вижуал студией

Это стандартная фича студии ещё со времён VS6, где многие пытались ещё тогда писать для AVR в ней. В то далёкое время даже вышла специальная сборка VS6 (говорят от китайцев), в которой можно было писать проект на C для AVR (у меня она была, я пробовал, поэтому давно хотел, чтобы это было не кустарно). Вот именно оттуда, как я думаю, Atmel и переняла идёю, только с новой версией VS. Это была историческая справка.

Atmel Studio 6 — это просто специальная сборка. Я не знаю как туда вставить плагины, которыми я пользуюсь: EA, Visual SVN, DevExpress, сомневаюсь, что это возможно. Так что нивелируется только для тех, кто пишет в голой VS, не зная о полезных расширениях.

Сам я небольшие проекты компилирую и в Notepad++, но его сессии не выкладываю в репозиторий, т.к. там почему-то идёт привязка к полным путям файлов проекта. Мне было бы проще пояснять работу с исходниками именно в тём, а не в VS2008, так как после AVR Studio 4 она выглядит сурово. Далеко не многие перешли на AS6 или вообще собираются из-за её монструозности (800 МБайт один только дистрибутив).

А возможное удобство моих проектных шаблонов может оценить только практик, как, к примеру, это сделали в ветке на электрониксе по этой теме ещё годовой давности. Я, кстати, продублировал эту тему по всем известным форумам: roboforum, electronix, kazus, radiokot, остался только habr, но для него я подберу побольше примеров.

Я специально выбрал примеры не с лампочками и кнопочками, а чуть посложнее, чтобы показать как можно подключить сишные проекты к моим шаблонам и чтобы можно было увидеть комплексный подход. Ведь никто не будет с ходу переписывать что-то своё на мой лад, сначала люди приценяются, пробуют, смотрят как и что устроено, работает ли вообще, а как распробуют, там и видно будет. У меня на подходе ещё несколько примеров: c VUSB, Тетрис, RTOS. Потом поищу ещё какие-нибудь стандартные библиотеки, чтобы это всё крутилось в комплексе.
0
Скрещивание MSVS2008 с любым GCC и не очень компилятором тут был уже описан и ты там, кстати, отмечался :) стареем, брат: Готовим микроконтроллерный GCC-тулчейн под вижуал студией
Я говорил о твоем вкладе. Поскольку меня эта тема интересует — я, разумеется, изучил и твой вклад, и его, и других, какие нашел.
Atmel Studio 6 — это просто специальная сборка. Я не знаю как туда вставить плагины, которыми я пользуюсь: EA, Visual SVN, DevExpress, сомневаюсь, что это возможно.
Не совсем сборка. Это обычная MSVS с правильно интегрированным AVR тулчейном — через средства расширения IDE. Собственно, AVR Studio ставится поверх MSVS, как плагин (каковым, собственно, и является).
В несовместимости расширений я сомневаюсь — как минимум VAX там есть и плагины VCS оно подхватывает, так что должно подхватить и VisualSVN. Впрочем, не пробовал — меня из плагинов только VAX и интересует.
А возможное удобство моих проектных шаблонов может оценить только практик
Я вполне практик. Но твои шаблоны меня интересуют мало, я предпочитаю свои подходы.
как, к примеру, это сделали в ветке на электрониксе по этой теме ещё годовой давности
Что-то не заметно в той теме особого интереса. В трех остальных — вообще никакого интереса не видно, кроме одной спасибки на казусе.
0
Ты бы сначала дату размещения тем посмотрел, а потом оценочные суждения давал. Это здесь ты такой шустрый комментатор, там таких не наблюдается и слава Богу. Надеюсь, что у тебя нет аккаунтов на всех этих площадках :)

Кроме того, все настолько привыкли к C, что показать им как всё их хозяйство может выглядеть по-другому — на это надо время и желание.

Вот тут недавно товарищ на форуме поделился своим проектом: Микрокомпьютер AVRMC. Я посмотрел видео и меня, в свете моего подхода, заинтересовало, а как выглядит его прошивка в оригинале? Код ядра, т.е. сборки всего из всего, меня в общем не удивил. Такой стиль «программинга» я наблюдаю не только здесь, но и в коде большинства других проектов, включая даже freemodbus и Petit FS, где можно было ожидать что-нить такое, что приходит на ум после прочтения книжки «Совершенный код».

Вот типовой стиль программирования на C: !avrmckernel.zip. Я же буду предлагать всем желающим сравнить мой подход с таким же на C, причём не только сам стиль, но и библиотеки. CLCD уже вполне себе рабочая вещь. На её примере уже можно сравнивать, CConsole тоже будут постепенно доделана. Кому будет это интересно, тот попробует.
0
Надеюсь, что у тебя нет аккаунтов на всех этих площадках :)
Есть, на трех из пяти этих форумов. Да, я заметил, что темы свежие. Но казус и кот — хорошо населенные сайты, интересные темы там пухнут как на дрожжах.
На электрониксе же тема старая и для своего возраста — очень вялая. Причем среди там отписавшихся я заинтересованных тоже особо не заметил.
0
На электрониксе это было сопровождение прототипа. До недавнего времени у меня не были проработаны некоторые вещи. Из-за них шаблоны получались не целостными. Даже сейчас не всё ещё доведено до ума в плане даже использования умного указателя. Чтобы его использовать нужно ещё кое-чего доопределить. Для этого я переношу один проект DDS v. 2.0 на основу из своего шаблона. Там есть работа с EEPROM для хранения настроек, но выглядит этот код ужасно, как в общем и всё остальное — в перемешку, включая даже асм, который выдаёт сигнал из таблицы. Проект хороший, но вот оформление — тихий ужас.

Скоро он появится в примерах как проект uDDS, где, кстати, я и класс CLCD для разнообразия применю. Мне нужно подучиться и набить руку, чтобы за вечер, к примеру, я мог бы переоформить любой проект на C в стиле C++, как это я сделал с тремя первыми примерами (их уровня сложности). Правда я там был знаком с предметной областью, в этом случае можно быстро переделать, при наличии нужных классов. Но, к примеру, работу с кучей i2c/spi микросхем, графическими индикаторами, GPS и что-нить в таком духе перенести так просто не получится, пока я не оформлю по аналогии классы. А подключать всё время сишный или асм код — это имеет смысл делать только в переходный период, либо для своего наработанного кода.

Может я слишком лихо начал, это тоже вариант. Лампочки и кнопочки, наверное, не надо было обходить стороной.
0
Что касается препроцессора, то когда я представил размер универсального файла, у меня отпало бы желание в нём ковыряться, но это не самое страшное.

Ну, дык, хотя бы общий код (коего в Вашем случае очень много) можно вынести в оно место. Остальное подключайте в зависимости от директив. Так намного проще и Вам (поддерживать код) и пользователям (мигрировать на другой чип).

А что касается шаблонов на C++, то я решил подождать экспериментов на эту тему товарища neiver

О каких экспериментах идет речь? Ели Вы остановились на С++, — то neiver уже показал эффективность использования шаблонов для реализации «статического» полиморфизма, без использования виртуальных методов (что критично в случае МК).
0
Нельзя вынести, если бы это можно было сделать, то это уже за 10 лет давно за меня сделали. А если бы кто-то и взялся, то ему пришлось бы прикладывать отдельную солидную документацию к своей прослойке, кроме непосредственно datasheet'а.

У arm'ов можно посмотреть на реализацию чего-то подобного универсального, но то, что там что-то существует ещё не факт, что это можно сделать по аналогии на avr.

Эффективность — это когда его стиль я увижу в реализации PetitFS или freemodbus. Вот на основе комплексного проекта можно судить о практичности подхода, а до этого — это всего лишь эксперименты.

Если что-то не реализовано, то нельзя заранее сказать, что это удобно сделано, одна объектность и шаблонность не гарантирует эффективность по умолчанию. Подходов может быть несколько, пока не увидишь живьём не сможешь вывести плюсы и минусы. У моего подхода тоже есть плюсы и минусы.
0
Нельзя вынести, если бы это можно было сделать, то это уже за 10 лет давно за меня сделали.

Что нельзя вынести?
Большинство Вашего кода – одинакова для всех платформ. Разница в MCU.* и ISRList.*. (исправьте меня, если я не прав). Остальные фалы одинаковы. Какой смысл делать для них отдельные «ветки» (branches)?

Эффективность — это когда его стиль я увижу в реализации PetitFS или freemodbus.

А зачем уважаемому neiver реализовывать «PetitFS или freemodbus». Чтобы доказать вам, что его подход эффективен? Ну, дык и так можно оценит избыточность данных при использовании тех или других механизмов С++.
0
А я и не делаю. Да, разные только MCU.*, ISRList.cpp и Configuration.h (здесь флаги для таблицы прерываний), ещё немного Defines.h, т.к. там идёт инклуд с контроллером. Но сам код я пишу именно в MCU.cpp, а не использую его на стороне и это самый главный файл, а всё остальное чисто проектные примочки, что внутри него всё работало.

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

Я могу, к примеру, подключать внешние общие классы и включать их в проект относительными путями, как, к примеру, LCD.cpp|h или Console.cpp|h. Это можно, чтобы убрать дублирование. Скрипты можно тоже сделать общими, оставив только счётчик версии. Я подумаю над этим. Просто у меня не так давно дошли руки обобщить все 4 варианта, до этого они обкатывались в различных несложных проектах и я их «выкусил» оттуда, посрезал лишнее и оформил в виде отдельных проектов.

Нет пределу совершенства, будем думать как сделать попроще.
0
Упертый парень!
Так мы за «шашечки» или «ехать»
все ж реализовано (freemodbus, PetitFS)
подключай, компилируй и пользуйся,
что не нравится ручками подправь.
+1
Где я упёртый, оба модуля подключены к моим шаблонам и «едут» :)

Вот freemodbus поехал: pbiifreemodbus
А вот поехал PetitFS: uSD

Что не нравилось, подправил, как видно ;)
0
зачем тогда здесь голову морочишь?
;)
0
А какой смысл в подходе-методе, если всё остальное сделано на Си? :) Нафик он тогда нужен? Мне вот кое-что не нравится как сделано на Си и я создал свои классы для работы с LCD, RTC, MCU, Console, SystemTime, на то он и подход, чтобы что-то было удобнее с его позиций.

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

Как иначе метод-то перенимать? Обычно автор больше всех его понимает и показывает типовые приёмы, которые можно использовать в своих проектах. Ещё лучше, если автор сопроводит метод какой-то библиотекой. Ты используешь её как документацию и ваяешь свой код.
0
Добавил три примера использования шаблонов (см по ссылке на форум).
Также я нашёл проблему с отладкой в Протеус проекта uVGA, теперь всё моделируется и можно писать Тетрис на ATmega16.

Отладка проекта uVGA в Proteus 7.7 SP2
0
  • avatar
  • uni
  • 23 ноября 2012, 06:42
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.