хорош он тем, что за счет смещения считывателей каналов на четверть сектора, гарантированно не будет случая, когда светодиод считываемого канала будет наполовину закрыт шторкой, и не понятно, это еще единица, или уже нуль.
т.е. код Баркера в таких граничных случаях позволяет однозначно считать данные.
Не встречал. Да и что embedded что не embedded — я лишь перечислил малую долю инструментов С++, которые улучшают качество кода. Об этом можно почитать у Макконекела «Совершенный код» — толстенный и полезный талмуд. Конкретно по С++ рекомендую прочесть статьи блога PVS Stduio на хабре и на сайте — там что ни статья — разбирается огромное число примеров простых но серьезных ошибок.
Для Embedded, ИМХО, достаточно не использовать дорогие операции. STL немножко можно, но аккуратно.
Если ARM и в запасе ОЗУ больше 64к — ни в чем себе не отказывайте :)
Сейчас пилю проект на 16МГц ARM Cortex-M3 и 8кбайт ОЗУ (из которых 6 съедают буферы для UART) — вот где боль :)
Для матерых С-шников вроде меня рекомендую книгу Ira Pohl C++ for C programmers. Все перечисленное выше — там подробно разбирается. Но конкретно перечисленное выше — то что реально облегчает мой эмбед-кодинг.
До сих пор эту книгу никак не закажу, но я проходил курс на Coursera в начале года.
А так, наиболее полный источник — это практика :) Практика разгребания чужого кода конечно же :)
Не стоит путать красное с пресным:
C++ это не только абстракция и наследование, но еще и как минимум(краткий список полезных для эмбеддера фич):
0. Пространства имен! Нет, правда, создавая большой проект на С я затрахиваюсь перед каждой функцией добавлять префикс. В С++ это решается с помощью namespace и классов. И когда ты ставишь точку, автодополнение дает тебе список ТОЛЬКО того, что тебе можно.
1. Разделение уровней доступа — если у меня и есть какая-то внутренняя переменная, то в С иногда сложно избежать соблазна не поставить костыль. В C++ внутри класса я просто делаю ее private. Отсюда — приходится продумывать архитектуру приложения — на поддержке кода это очень пригодится.
2. Перегрузка функций и шаблоны. Правда, просто обожаю в С продумывать функции для всех возможных типов данных. И для uint8_t и для int8_t и 16_t и 32_t и float и т.д. и т.п.
3. Безопасное кастование! Сравните static_cast и reinterpret_cast(аналог С-шных скобочек (type_t)var). Мне иногда попадаются просто фееричные преобразования типов в разгребаемом коде, когда они неявно перегоняются из знакового в беззнаковый, из short в long да по нескольку раз… static_cast в отличие от reinterpret_cast в неподобающих случаях вызовет ошибку компиляции и заставит хорошенько подумать. Причем в С ошибка может быть обнаружена только с помощью статического анализа кода(PVS Studio справляется, Clang и cppcheck — как правило нет). Ну может быть он ругнется на сравнение знаковой и беззнаковой переменной в if или в переходе от double к float… или вы скормили const в не cosnt…
4.Перечисляемые типы. Дефайны — зло. Есть тысяча и один кейсов, когда они могут привести к некоторым проблемам, ОСОБЕННО!!! при отсутствии пространства имен. Вы уверены, что своим дефайном вы ничего не переопределили? Или, например, не включили какую-нибудь опцию вида #if defined(FOO)? В том или ином виде enum есть со времен ANSI C, Classname.enum таки гораздо функциональнее.
Список можно продолжать до бесконечности. Самое главное — все что я описал не требует мегабайтов памяти ни в коде ни в оперативке, реализуется абсолютно всеми компиляторами C++ (в отличие от специфичных функций современных стандартов) и реально экономит время и силы.
Так я же не спорю с тем, что это не возможно в принципе. Но развернуться все равно не удастся. Тогда зачем расширять языковые рамки, если потом все время придется себя сдерживать. А еще хуже, что когда вы построите всю абстракцию C++ и дойдете до конкретной реализации, то можете вылететь за пределы ОЗУ и в этот момент поймете, что этот подход вам в принципе не годится (так и было у меня). Поэтому я ставлю себе заранее рамки: для AVR-8 только С и никакого С++.
Мой друг использовал С++ для ATTINY1634-MU, там были несколько каналов PWM, чтение с ADC, чтение пинов для конвигурации. Всё работает. правда он не использовал new и delete. так что не могу с Вами согласиться…
Запретииииить!!!
Использование С++ для 8-битных контроллеров не надо, нельзя, нихт, кайн и т.д. и т.п.
Был опыт правда на ATmega128 (камень более жирный и по ОЗУ и по ПЗУ). Пытался делать некий пользовательский интерфейс на ЖК, с возможностью переконфигурирования (т.е. имелось несколько классов: Window, Label и т.д.). Больше 2-х окон было создать невозможно: тупо заканчивалась память. Вообще у меня сложилось мнение, что для меги надо использовать только С.
Точные резисторы бывают практически в любых корпусах. В своем приборе, о котором я писал на flyback.org.ru/viewtopic.php?p=4174002#4174002 я применил 0805 0.1% 25ppm от SUSUMU (https://ru.farnell.com/webapp/wcs/stores/servlet/Search?catalogId=15001&langId=-20&storeId=10173&categoryId=700000005450&st=RR1220P&pageSize=25&showResults=true) и ничего из под них нормально вымывается смесью изопропилового спирта с калошей. В таких приборах не настолько важна прецизионность, сколько температурная стабильность, а в цепях диф усилителей подобранные пары. Остальное все учитывается при SHORT и LOAD калибровках.
Проблемы у этих приборов 1. не берут малых индуктивностей и емкостей 2. Мал набор измерительных частот обычно 100Гц и 1кГц, желательно?, чтобы были еще 10кГц и особенно 100кГц для измерения ESR (я так понимаю 2-ое для этого прибора не актуально)
Мощность: 2кВт. Масса: ~17кг. Намотали харьковчане. А их цены меня крайне приятно удивили. На всякий случай не буду говорить точную сумму, в которую обошелся мой заказ, т.к. мне показалось, что у них индивидуальный подход к ценообразованию. Скажу лишь, что мелкий трансформатор, мощностью 60Вт с четырьмя вторичными обмотками, обошелся дешевле серийного такой же мощности.
Имелись в виду современные абсолютные энкодеры с аналогичным интерфейсом, коие есть, но гораздо проще найти абсолютный энкодер с профибасом или промэзернетом на выходе.
А если говорить о самом коде Баркера, то он вокруг нас где есть Wi-Fi.
Скрыть эти различия за интерфейсом IPwmChannel. Самый простой вариант — претвориться, что все таймера 16 битные и использовать только старшие 8 бит в 8 битных.
Более высокоуровневый подход — проценты заполнения ШИМ и из процентов пересчитывать в заполнение.
У меня кажысь 9 стоит :(
т.е. код Баркера в таких граничных случаях позволяет однозначно считать данные.
Я тоже записывался.
Для Embedded, ИМХО, достаточно не использовать дорогие операции. STL немножко можно, но аккуратно.
Если ARM и в запасе ОЗУ больше 64к — ни в чем себе не отказывайте :)
Сейчас пилю проект на 16МГц ARM Cortex-M3 и 8кбайт ОЗУ (из которых 6 съедают буферы для UART) — вот где боль :)
Для матерых С-шников вроде меня рекомендую книгу Ira Pohl C++ for C programmers. Все перечисленное выше — там подробно разбирается. Но конкретно перечисленное выше — то что реально облегчает мой эмбед-кодинг.
До сих пор эту книгу никак не закажу, но я проходил курс на Coursera в начале года.
А так, наиболее полный источник — это практика :) Практика разгребания чужого кода конечно же :)
C++ это не только абстракция и наследование, но еще и как минимум(краткий список полезных для эмбеддера фич):
0. Пространства имен! Нет, правда, создавая большой проект на С я затрахиваюсь перед каждой функцией добавлять префикс. В С++ это решается с помощью namespace и классов. И когда ты ставишь точку, автодополнение дает тебе список ТОЛЬКО того, что тебе можно.
1. Разделение уровней доступа — если у меня и есть какая-то внутренняя переменная, то в С иногда сложно избежать соблазна не поставить костыль. В C++ внутри класса я просто делаю ее private. Отсюда — приходится продумывать архитектуру приложения — на поддержке кода это очень пригодится.
2. Перегрузка функций и шаблоны. Правда, просто обожаю в С продумывать функции для всех возможных типов данных. И для uint8_t и для int8_t и 16_t и 32_t и float и т.д. и т.п.
3. Безопасное кастование! Сравните static_cast и reinterpret_cast(аналог С-шных скобочек (type_t)var). Мне иногда попадаются просто фееричные преобразования типов в разгребаемом коде, когда они неявно перегоняются из знакового в беззнаковый, из short в long да по нескольку раз… static_cast в отличие от reinterpret_cast в неподобающих случаях вызовет ошибку компиляции и заставит хорошенько подумать. Причем в С ошибка может быть обнаружена только с помощью статического анализа кода(PVS Studio справляется, Clang и cppcheck — как правило нет). Ну может быть он ругнется на сравнение знаковой и беззнаковой переменной в if или в переходе от double к float… или вы скормили const в не cosnt…
4.Перечисляемые типы. Дефайны — зло. Есть тысяча и один кейсов, когда они могут привести к некоторым проблемам, ОСОБЕННО!!! при отсутствии пространства имен. Вы уверены, что своим дефайном вы ничего не переопределили? Или, например, не включили какую-нибудь опцию вида #if defined(FOO)? В том или ином виде enum есть со времен ANSI C, Classname.enum таки гораздо функциональнее.
Список можно продолжать до бесконечности. Самое главное — все что я описал не требует мегабайтов памяти ни в коде ни в оперативке, реализуется абсолютно всеми компиляторами C++ (в отличие от специфичных функций современных стандартов) и реально экономит время и силы.
Стек и память вообще очень просто контролируются.
Использование С++ для 8-битных контроллеров не надо, нельзя, нихт, кайн и т.д. и т.п.
Был опыт правда на ATmega128 (камень более жирный и по ОЗУ и по ПЗУ). Пытался делать некий пользовательский интерфейс на ЖК, с возможностью переконфигурирования (т.е. имелось несколько классов: Window, Label и т.д.). Больше 2-х окон было создать невозможно: тупо заканчивалась память. Вообще у меня сложилось мнение, что для меги надо использовать только С.
Проблемы у этих приборов 1. не берут малых индуктивностей и емкостей 2. Мал набор измерительных частот обычно 100Гц и 1кГц, желательно?, чтобы были еще 10кГц и особенно 100кГц для измерения ESR (я так понимаю 2-ое для этого прибора не актуально)
Имелись в виду современные абсолютные энкодеры с аналогичным интерфейсом, коие есть, но гораздо проще найти абсолютный энкодер с профибасом или промэзернетом на выходе.
А если говорить о самом коде Баркера, то он вокруг нас где есть Wi-Fi.
Более высокоуровневый подход — проценты заполнения ШИМ и из процентов пересчитывать в заполнение.