Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как ПРАВИЛЬНО программировать на С++
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2, 3, 4
Serega Doc
Добрый день. Учусь программировать на С++.
И иногда возникают вопросы в правильном проектировании классов.
Сейчас описываю класс для работы с последовательными регистрами 74HC595.
Уже есть класс для работы с SPI.
Где инициализировать SPI блок AT Mega 168 в классе работы с регистром или же глобально во всей программе.
Сейчас SPI будет использоваться только в регистрах.
Но в будущем планирую параллельно регистрам подключить еще и FLASH память (еще один класс по работе с памятью FLASH) на SPI.

Что посоветуете?

Вдогонку PS
И как правильно писать классы для регистров и FLASH наследовать от SPI или же внутри классов объявлять член класса SPI?
Serega Doc
Это глупый вопрос который обсуждали миллион раз?
Mahagam
нет. как-то це-крест-крест не сильно прижился у эмбеддеров.
Dima_G
Цитата(Mahagam @ Jul 27 2010, 15:41) *
нет. как-то це-крест-крест не сильно прижился у эмбеддеров.


Да нет, нормально прижился. Просто тут ИМХО вопросы не конкретно эмбеддерские, а уровня проектирования.
Я так понимаю, у вас стоит вопрос расширивания общего ресурса между несколькими потребителями?
Это обычно решается с помощью драйвера устройства. smile.gif
AHTOXA
Цитата(Serega Doc @ Jul 26 2010, 20:25) *
Где инициализировать SPI блок AT Mega 168 в классе работы с регистром или же глобально во всей программе.


Поскольку к SPI могут обращаться разные устройства, то объект класса SPI надо сделать глобальным. В конструкторы объектов dataflash, HC595, DAC, ADC, которые висят на SPI, в этом случае надо передавать ссылку на класс SPI.

Цитата
И как правильно писать классы для регистров и FLASH наследовать от SPI или же внутри классов объявлять член класса SPI?


Наследовать в этом случае нельзя, а то получится по экземпляру SPI в каждом из объектов.
Serega Doc
Спасибо все заработало. Что бы не плодить тем буду в будущем писать сюда по вопросам проектирования.
Жаль что мне самому не пришла идея использовать указатель на SPI.
ReAl
Ну оно "так и надо по теории". Сама флешка не есть вариантом интерфейса SPI или там контроллера SPI, она только пользуется SPI как транспортом, класс флешки есть пользователем класа SPI, поєтому должен получать его для использования.
Если теперь две одинаковых флешки будут висеть на разных контроллерах SPI (один аппаратный, другой программный или один из них на соответствующем режиме USART), то просто два экземпляра одного и того же класса флешки получат по каналу SPI (по указателю или ссылке) для работы.
Ink
Цитата(AHTOXA @ Jul 27 2010, 12:53) *
Наследовать в этом случае нельзя, а то получится по экземпляру SPI в каждом из объектов.

А не покатит сделать то, что "глобальное", статическим членом класса? Тогда все унаследуется нормально, без лишних сущностей. Или не?
Dima_G
Цитата(Ink @ Jul 29 2010, 19:50) *
А не покатит сделать то, что "глобальное", статическим членом класса? Тогда все унаследуется нормально, без лишних сущностей. Или не?

Объекты от статических членов не будут дублироваться только в случае создавание объектов от одного класса. В случае создания объектов от разных классов, объект SPI будет продублирован.
neiver
У меня есть некоторые интересные наработки на Си плюс плюс под АВР.
Например, виртуальные порты. Можно объединить от одной до 16 произвольно взятых ножек в такой виртуальный порт и манипулировать им как одним целым.
Кому интересно спрашивайте, раскажу подробнее.

typedef PinList<Pa1, Pa2, Pa3, Pb3, Pb4, Pb5> pins;

int main()
{
pins::DirWrite(0xff);
pins::Write(0xff);
}
demiurg_spb
Приведите для интереса asm листинг того, во что это скомпилится:
Цитата(neiver @ Jul 29 2010, 19:03) *
typedef PinList<Pa1, Pa2, Pa3, Pb3, Pb4, Pb5> pins;
pins::Write(0xff);

Мысль сама по-себе очень удачная. Вы молодец!
Dima_G
Цитата(neiver @ Jul 29 2010, 22:03) *
У меня есть некоторые интересные наработки на Си плюс плюс под АВР.
Кому интересно спрашивайте, раскажу подробнее.

Интересно rolleyes.gif
Выложите пожалуйста реализацию
neiver
Для
Код
typedef PinList<Pa1, Pa2, Pa3, Pb3, Pb4, Pb5> pins;
pins::Write(0xff);

листинг не очень интересный - всё заоптимизировалось в доску smile.gif поскольку все значеня известны на момент компиляции:
Код
in    r24, 0x1b; 27
ori    r24, 0x0E; 14
out    0x1b, r24; 27

in    r24, 0x18; 24
ori    r24, 0x38; 56
out    0x18, r24; 24


Гораздо интереснее вот так:
Код
typedef PinList<Pa1, Pa2, Pa3, Pb3, Pb4, Pb5> pins;
pins::Write(PORTC);

Вместо PORTC можно подставить любое выражение невычисляемое на этапе компиляции.
Код
in    r18, 0x15; 21

in    r25, 0x1b; 27
mov    r24, r18
add    r24, r24
andi    r24, 0x0E; 14
andi    r25, 0xF1; 241
or    r24, r25
out    0x1b, r24; 27

in    r24, 0x18; 24
andi    r18, 0x38; 56
andi    r24, 0xC7; 199
or    r18, r24
out    0x18, r18; 24


Как-то так. Если различных портов в списке будет больше и ножки в них не будут упорядочены, то листинг соответственно будет больше.

Пример 1
Пример побольше
Реализация

Всё это реализовано на основе списков типов и с помощью очень злой и черной шаблонной магии smile.gif
Ink
Цитата
Объекты от статических членов не будут дублироваться только в случае создавание объектов от одного класса. В случае создания объектов от разных классов, объект SPI будет продублирован.

Нифига не понял. Вот пример:

Код
#include <iostream>

class A
{
  public:
  static int X;
  void printx() {std::cout << X << std::endl;};
  void setx(int x) {X=x;};
};
int A::X=0;


class B : public A
{
  public:
  void printx() {std::cout << X << std::endl;};
  void setx(int x) {X=x;};
};

class C : public A
{
  public:
  void printx() {std::cout << X << std::endl;};
  void setx(int x) {X=x;};
};


int main()
{
  A a;
  B b;
  C c;

  a.setx(10);
  a.printx();
  b.printx();
  c.printx();

  b.setx(20);
  b.printx();
  a.printx();
  c.printx();

  return 0;
}


Одна статическая переменная в базовом классе. От базового наследуются 2 класса, каждый видит одну и ту же переменную, так же, как если бы она была глобальной. Как бывает еще?

Ответ проги:
10
10
10
20
20
20









sergeeff
Цитата
Нифига не понял.

Если вы посмотрите на sizeof(A) и наследуемые классы, то увидите, что int Х в них нет. А если уберете static, то размер классов увеличится.

Вот об этом и разговор.
Mahagam
программисты на Си обсуждают и решают проблемы конкретных контроллеров, конкретного железа. це-крест-крест добавляет к этим проблемам ещё и проблемы собственно языка. начинаются обсуждения проблем что и как откуда наследуется инкапсулируется и полиморфируется. за деревьями не видно леса.
ну почему я не удивлён.
MrYuran
Цитата(Mahagam @ Aug 2 2010, 13:51) *
программисты на Си обсуждают и решают проблемы конкретных контроллеров, конкретного железа. це-крест-крест добавляет к этим проблемам ещё и проблемы собственно языка.

Всё зависит от сложности и размера проекта.
С определённого момента дополнительные возможности, которые даёт язык, перекрывают его "проблемы".
Ink
Цитата
Если вы посмотрите на sizeof(A) и наследуемые классы, то увидите, что int Х в них нет. А если уберете static, то размер классов увеличится.

Вот об этом и разговор.

Естественно X там нет, он лежит отдельно от всего в единственном экземпляре. Но я не понимаю вот этого:
Цитата
В случае создания объектов от разных классов, объект SPI будет продублирован.

Это как так может быть? С чего создастся два разных Х?

Цитата(Mahagam @ Aug 2 2010, 13:51) *
це-крест-крест добавляет к этим проблемам ещё и проблемы собственно языка.

Конечно. И ровно то же самое говорят упертые ассемблерщики в сторону цешников (и справедливо, если на все смотреть плоско!). Смотрите на мир шире, не зря эти языки были придуманы, не зря существуют методы проектирования ПО. Естественно, что для простого SPI не нужно городить классы, но когда у вас будет огромный проект, вы встряните и будете долго понимать, как же так получилось непонятно.

Думается мне, что это не "проблемы языка", а банально проблемы от незнания языка. Это не характеризует язык.
Mahagam
я и смотрю широко. война с конструкциями языка (и только с конструкциями языка) - удел програмеров це++
sergeeff
Цитата(Mahagam @ Aug 3 2010, 10:53) *
я и смотрю широко. война с конструкциями языка (и только с конструкциями языка) - удел програмеров це++


В 1981 году мы делали статистический анализатор кардиоинтервалов на К580ИК80. У меня (единственного программиста) не было абсолютно ничего кроме блокнотика с клетчатой бумагой, таблицы мнемоники команд и программатора УФ ПЗУ. Все это было сделано, работало и получило награду на выставке в Женеве. Но ...!!! После этого я зарекся заниматься таким программированием. Мне ночами снились квадратики с кодами. Думается это одна из причин появления языков высокого уровня. Вторая причина - переносимость. Третъя - документированность (имею в виду, что если с вами что-то случается, то вашу работу легче кому-то подхватить).

А причин бесконечных ратований за ассемблер, на мой взгляд, две:
1. Понятность ассемблера для "железячника".
2. Лень изучения языков высокого уровня применительно к конкретному процессору.
Mahagam
где вы ратование за ассемблер увидели????
sergeeff
Цитата(Mahagam @ Aug 2 2010, 12:51) *
программисты на Си обсуждают и решают проблемы конкретных контроллеров, конкретного железа. це-крест-крест добавляет к этим проблемам ещё и проблемы собственно языка. начинаются обсуждения проблем что и как откуда наследуется инкапсулируется и полиморфируется. за деревьями не видно леса.
ну почему я не удивлён.


Или я чего-то не так понял?
Mahagam
и где я упоминал ассемблер???
поясняю - программеры на Си воюют только с железом и со своими алгоритмами. си плюс плюс - кагбэ намекает, что проблем будет в два раза больше. а именно: секас с инкапсуляцией, наследованием, полиморфизмом (ну три кита проблем smile.gif )
neiver
Вы, видимо мало на С++ программировали...

На С++ можно писать более эффективные программы (по размеру/памяти/скорости) чем на чистом Си (применительно к 8-ми битникам в частности). И Наследование, инкапсуляция и полиморфизм (как динамический так и (особенно) статический) в этом только помошники а не проблемы. Это всего лишь средства языка, которые быдучи примененными к месту дают положительный результат. Ну а при неумелом использовании... Всё зависит от программиста.
sergeeff
Цитата(Mahagam @ Aug 3 2010, 14:15) *
и где я упоминал ассемблер???
поясняю - программеры на Си воюют только с железом и со своими алгоритмами. си плюс плюс - кагбэ намекает, что проблем будет в два раза больше. а именно: секас с инкапсуляцией, наследованием, полиморфизмом (ну три кита проблем smile.gif )


Да, витиевато пишите. Сейчас только ваша мысль прояснилась.

По поводу С++. Очень хорошо на форуме сказал автор scmRTOS: С++ ничего не добавляет, если вы сами этого не просите.
Ink
Цитата(Mahagam @ Aug 3 2010, 15:15) *
программеры на Си воюют только с железом и со своими алгоритмами.

Это тоже ошибочное мнениеsmile.gif Программеры на си, которые воюют, они воюют и с си! Потому что не знают языка! А те, кто знает, те не воюют, точно так же как и с си++.
Mahagam
во налетели. smile.gif
ещё раз. чисто наблюдения показывают, что вопросы касаемые конструкций и возможностей языка у программистов Си практически не обсуждаются. зато активно муссируются у плюсистов. выводы какие?
sergeeff
Цитата(Mahagam @ Aug 3 2010, 15:50) *
во налетели. smile.gif
ещё раз. чисто наблюдения показывают, что вопросы касаемые конструкций и возможностей языка у программистов Си практически не обсуждаются. зато активно муссируются у плюсистов. выводы какие?


Учите матчасть!
MrYuran
Цитата(Mahagam @ Aug 3 2010, 16:50) *
во налетели. smile.gif
ещё раз. чисто наблюдения показывают, что вопросы касаемые конструкций и возможностей языка у программистов Си практически не обсуждаются.

А что там особо обсуждать, разве что правила глянуть в спорных ситуациях.
Фактически, макронадстройка над ассемблером, с нелинейным преобразованием.
Нет возможностей - нет вопросов.
Хотя нет, был недавно вопрос - ARV со своими менюшками колдовал.
Никак эта дикая смесь структур и юнионов не хотела в флешь ложиться...
Dima_G
Цитата(Ink @ Aug 3 2010, 14:08) *
Это как так может быть? С чего создастся два разных Х?

Прошу прощения smile.gif
Почему-то показалось, что вы хотите не наследоваться от базового класса, а создавать статические члены в "потребителях" SPI smile.gif
Mahagam
QUOTE (sergeeff @ Aug 3 2010, 15:59) *
Учите матчасть!

смотрю, плюсисты никак не выучат. вечно проблемы с языком возникают biggrin.gif
ReAl
Цитата(Mahagam @ Aug 3 2010, 15:50) *
ещё раз. чисто наблюдения показывают, что вопросы касаемые конструкций и возможностей языка у программистов Си практически не обсуждаются. зато активно муссируются у плюсистов. выводы какие?
Ещё раз. Чисто наблюдения показывают, точнее, показали лет 12-16 назад, что вопросы, касаемые конструкций языка, у программистов на асм практически не обсуждаются, зато активно муссируются у С-шников. Помнятся по SU.CROSSTOOLS да RU.EMBEDDED имено такие "болезни роста" и точно так же многие тогда говорили, что фигня это всё и ассемблерщики борятся с железом и задачей, а С-шники с языком и компилятором. И много приходилось спорить и доказывать, что борьба с компилятором - просто от незнания основ языка в духе правил приведения типов.
Но по мере увеличения числа знающих С эти вопросы отпали, место С во встроенных системах никто не оспаривает. Сейчас слово "асм" заменилось на "С", "С" на "С++" и наблюдаем второй виток. От тех, кто не видел первого?
Mahagam
стандартов на языки понаделали давно. с появлением стандартов на си - все болезни роста пропали.
на плюсы вроде как уже 12 лет первому стандарту, а проблемы языка - остались.
похоже этот "виток" превратился в вечное кольцо.
MrYuran
Цитата(Mahagam @ Aug 3 2010, 20:13) *
на плюсы вроде как уже 12 лет первому стандарту, а проблемы языка - остались.

Поэтому пора уже думать об С#
ReAl
Цитата(Mahagam @ Aug 3 2010, 19:13) *
стандартов на языки понаделали давно. с появлением стандартов на си - все болезни роста пропали.
на плюсы вроде как уже 12 лет первому стандарту, а проблемы языка - остались. похоже этот "виток" превратился в вечное кольцо.
В упомянутые времена разговоров про "С-шники воюют с компилятором" языку С тоже много лет было, стандарту C89 было много лет, С99 был на подходе.
Но в нише мелкоконтроллеров он был многим в новинку, болезни роста не от возраста языа зависят, а от времени его применения в нише, так как это болезни роста не языка как такового.
Многие из тех, кто много лет просидел в этой нише на ассемблере - просто не воспринимали С. Вопросы "рискнувших" (в смысле применения С) укрепляли их в вере в то, что "С-шники борятся ..." дале по тексту. Но "рискнувшие" прошли свою фазу освоения языка и все те вопросы остались, но они теперь ассоциируются не со всеми, применяющими С, а только с новичками. А "тогда" практически все новичками и были, С был уделом программистов на "достаточно больших машинах", а "в эмбеддед ему не место" (хотя я удивлялся — почему на "ДВК-2" с 56К озу на всё про всё вместе с ОС ему за десять лет до этого было место, а на 8051 с 16-20-32К ПЗУ для автономной программы — так не место).
sergeeff
Цитата(MrYuran @ Aug 3 2010, 20:05) *
Поэтому пора уже думать об С#


С его то идеологией уборки мусора?
MrYuran
Цитата(sergeeff @ Aug 3 2010, 21:44) *
С его то идеологией уборки мусора?

А что там с идеологией не так?
Стековый язык, с уборкой проблем быть не должно
sergeeff
Цитата(MrYuran @ Aug 3 2010, 21:12) *
А что там с идеологией не так?
Стековый язык, с уборкой проблем быть не должно


http://msdn.microsoft.com/en-us/library/ms...28VS.90%29.aspx :

Цитата
In C#, garbage collection is handled by the common language runtime (CLR) with similar functionality to that of the JVM. The CLR garbage collector periodically checks the memory heap for any unreferenced objects, and releases the resources held by these objects.
Savrik
Управляеймый код, конечно, хорошо в своей области, но, как правило, во встраваимых системах программист привык быть уверенным в том, что и как делает программа. А если забывать за собой убирать - наверное, стоит сменить профильsmile.gif
Оффтоп. Почему C# не такой популярный? потому, что его разрабатывал мужик без бороды.
Mahagam
ReAl
при чём тут ниша и контроллеры? если обсуждаются проблемы именно языковых конструкций. зайдите на любой форум программеров - война с языком идёт вечно. причём чуть ли не с базовыми конструкциями.
sergeeff
Цитата(Mahagam @ Aug 4 2010, 10:49) *
ReAl
при чём тут ниша и контроллеры? если обсуждаются проблемы именно языковых конструкций. зайдите на любой форум программеров - война с языком идёт вечно. причём чуть ли не с базовыми конструкциями.


"С войной покончили мы счеты —
Бери шинель, пошли домой!"
Rst7
QUOTE
(хотя я удивлялся — почему на "ДВК-2" с 56К озу на всё про всё вместе с ОС ему за десять лет до этого было место, а на 8051 с 16-20-32К ПЗУ для автономной программы — так не место).


Потому что на архитектуру PDP-11 ложится идеально. А на 51 - увольте wink.gif
Serega Doc
Добрый день.
Неожиданно был удивлен что здесь из-за такого вопроса получился холивар.
Считаю что разработчик сам должен для себя решить на каком языке и с какой эффективностью он будет реализовывать проект.
Так что считаю вообще спор бессмысленным. И прошу его прекратить.

И если можно ответить еще на один вопрос.
Можно ли каким либо образом сделать переход из одного метода класса в другой не вызовом его через Call а переходом через Jmp.
Вернее что бы компилировалось так. А то сейчас у меня два метода которые возвращают один и тот же тип WatcherState
Но при этом один просто выполняет проверки и возвращает значение
Второй же более длинный по времени выполнения выполняет расчет и так же возвращает WatcherState
Вот как я это пока написал
Код
if (Tvalue == TimerValue)
    {
        return Next();
    }
    else
    {
        return WAIT;
    }

Что можете посоветовать?
Ink
Цитата(Serega Doc @ Aug 5 2010, 08:10) *
Можно ли каким либо образом сделать переход из одного метода класса в другой не вызовом его через Call а переходом через Jmp.

Может я ошибаюсь, но сдается мне, что никак так не сделать. Либо как-то в отдельно взятом компиляторе, но все равно сомневаюсь. Очень.
А инлайн не подходит?
neiver
А чем собственно call не угодил? Хотите пару тактов и пару байт в стеке съэкономить? Если это действительно важно - можно сделать эти функции члены (в С++ нет методов) inline? Например написать их реализацию в объявлении класса. Если функции маленькие, то возможно удастся съэкономить и побольше, за счет отсутствия вызовов и передачи аргументов.
Serega Doc
Спасибо за рекомендации.
inline я активно использую в header файле.
И для данной функции это бессмысленно из-за дублирования кода.

Я в принципе тоже так думал что нет такой возможности. Но надеялся что я чего-то не ведаю.
Еще раз спасибо.
XVR
Цитата(Mahagam @ Aug 4 2010, 11:49) *
ReAl
зайдите на любой форум программеров - война с языком идёт вечно. причём чуть ли не с базовыми конструкциями.
Заходил. Видел борьбу начинающих со своей безграмотностью, борьбы ПРОГРАММИСТОВ с С++ не видел rolleyes.gif
alexvok
Посоветуйте пажалуйста книгу
С++ с примерами для AVR
demiurg_spb
Цитата(alexvok @ Aug 19 2010, 14:32) *
Посоветуйте пажалуйста книгу
С++ с примерами для AVR
Боюсь, что таковых не имеется...
neiver
Примеры есть у меня, есть и свой подход к программированию для систем с сильно ограниченными ресурсами на С++(на примере AVR).
Будет свободное время - напишу статейку по этой теме (если будут желающие её читать smile.gif ).
А так вкратце могу сказать, что программы на С++ получаются компактнее, быстрее и легче читаются аналогичных программ на Си.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.