Как стать автором
Обновить
14
0
Александр @Saalur

Пользователь

Отправить сообщение
Решительно поддерживаю автора в стремлении использовать современные плюсы в мк. Но дабы сохранить коллегам автора и ревьюерам его кода зубную эмаль, неизбежно страдающую от зубовного скрежета, когда в проектах под мк они видят «virtual bool init(uint32_t val)», не менее настоятельно советую автору оперативно проштудировать MUST READ минимум:
a) Б. Страуструп «Программирование: принципы и практика использования С++» глава 25;
б) С. Мейерс «Эффективное использование С++ во встроенных системах»
с) Alex Robenko «Practical guide to bare metal c++»
плюс полезно будет посмотреть отличный доклад Карины Дорожкиной с конференции CPP Russia 2019, www.youtube.com/watch?v=Yv4nMocX78Q

Уверен, это даст автору отсутствующее сейчас (на мой взгляд) важное понимание, что у с++ «под капотом» в части использования в ембеде, и как правильно с этим жить. И в итоге поможет ему сойти с ошибочной тропы, которая привела его к написанию этого материала.
PS. Касаемо virtual. Вызов виртуальной функции примерно в 10 раз медленнее обычной (плюс оверхед на хранение таблицы указателей). Смотрим тесты, например здесь (взято у Ф. Пикуса ) quick-bench.com/q/42iKBatMiDjQtRHIcIWb3hLgbU8
Успехов!
Правда ваша, что в статье нужно было привести пример с рантаймовыми данными.
Исправляюсь: gcc.godbolt.org/z/nhhK64drr
(спойлер: тоже все весьма достойно)

Исключительно добротный материал. Проработанная и качественная подача материала, отличное оформление статьи. Номинируйтесь на Технотекст 2021, с удовольствием проголосую.

В далеком уже 2010 г. на плюсах для AVR-ок(!) писали так:

// создаем произвольный список пинов с разных(!) портов
PinList<Pa1, Pa2, Pa3, Pb3, Pb4> MyPins;

// записываем значение в этот список
MyPins::Write(0x55);

// смотрим ассемблерный выхлоп:

//вывод в PORTA
	in	r24, 0x1b
	andi	r24, 0xF1
	ori	r24, 0x0A
	out	0x1b, r24
//вывод в PORTB
	in	r24, 0x18
	andi	r24, 0xE7
	ori	r24, 0x10
	out	0x18, r24

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

Возможно этот простой пример подтолкнет Вас провести ревизию предубеждений касаемо обоснованности С++ во встроенных решениях.

Спасибо за внимание и комментарий!

Вы верно указали на пробелы в статье. Концепт ОС - ну совсем новорожденный. Торопился в публикации поделиться самой идеей "корутины + примитивы синхронизации с универсальным интерфейсом на базе co_await + переключение контекста". Вопросы сравнения с существующими ОС интересуют не меньше вашего, обязательно потестирую, главное чтобы работа оставила время...

Спасиибо за внимание к моей статье и поддержку)

Спасибо за внимание к моей статье и комментарий.

Действительно, писал статью по ощущением моряка на мачте: "Земля! Земля!"

Захватила сама идея: воспроизвести базовый функционал ОС на новейшем стандартном инструменте С++20 - корутинах. Ранее аналогичных материалов не встречал, торопился первым ступить на новые земли... Тщеславен немного, каюсь)

Оценка преимуществ моего подхода (и есть ли таковые по факту) - чуть позже или отдельным материалом, или дополнением к этой статье.

Спасибо за отзыв!

После планируемых тестов и доработок, послесловием к статье, добавлю более приближенный к реальному применению пример.

Ну, фактически отправка символа по SWO это запись в регистр ITM->PORT. А ДМА в режиме MEM_TO_PERIPH для этого и предназначено. Другой вопрос, дотянется ли он до адреса 0xE0000000 (ITM). Не задумывался над этим… Сомневаюсь, но можно будет полюбопытствовать в RM.
AVI-crak, доброе утро! Признателен за ваше внимание к моей статье. Когда около 3-х лет назад я решил сменить профессию и засел за изучение МК и С/С++, неоднократно встречал ваши заметки в разных сообществах. Нередко они помогали разобраться в тех или иных вопросах.
Теперь по существу вашего отзыва:
… нужно делать иначе — использовать внешний буфер для дма при работе с физикой...
Так у меня ровно так и реализовано.
H7 умеет прекрасно умножать и делить, и не только целые числа.
Бесспорно. Вот только основной посыл моей статьи был о том, как заменить именно интерфейс printf-а, используя возможности самого последнего, 20-го плюсового стандарта. И честно указал, что позаимствовал алгоритмы и код конвертации в строку. Можно ли переписать и улучшить заимствованный код с учетом эволюции камней? Весьма вероятно, просто не это основная тема конкретно этой статьи. Ссылку на вашую имплементацию обязательно посмотрю, поэкспериментирую.
При этом печать массивов — самая большая глупость что можно придумать...
Резковато, конечно, но почему? Разве не удобно, напечатав два символа <<, быстро вывести в терминал фрагмент массива с «сырыми» данными любого числового типа? Или, использовав функционал views, прямо в операторе вывода сразу как-то отфильтровать их, выделить поддиапазон etc.?
… время преобразования в строку для одинарной или двойной точности 2us...
У меня за 9 мкс выводится не одно значение, а пример суммарно с 8 значениями разных типов, 2 строковых литерала с операциями выделения поддиапазона и реверса. Вы воспроизвели эти же условия?
Ну и еще раз подчеркну, цель у меня была понять, что могут дать современные плюсы с 20-м стандартом в задаче замены интерфейса printf-a. Насколько универсальным, лаконичным, эффективным и эффектным может выглядеть решение. На мой взгляд, чуть менее 180 строк кода, чтобы получить вполне функциональный аналог стандартного stream-а для embbed-a, это неплохо.
Да, как gnu-arm начнет его поддерживать, как часть 20-го стандарта, обязательно попробую.
Доброе утро! А разве пример в самом начале статьи не очень убедительно это показывает? Когда единственный оператор вывода из двух печатных знаков работает со всеми форматами чисел, строковыми литералами и контейнерами, а также трансформациями над ними? Или я не совсем понял ваше сомнение? Тогда попрошу пример удобного на Ваш взгляд варианта. Спасибо за отзыв!
Убедительно и код «вкусный», спасибо. Но, блин, 45Кб…
Их можно понять, Си в умелых руках — напалм. Вот только лучше компилятора умеют писать единицы, а грамотный плюсовой код даст ассемблерный выхлоп подчас эффективнее, чем на Си. Не уверен, что мне это удалось, но стараться надо — камни становятся мощнее/ жирнее, программы сложнее и уже нужен новый уровень абстракции.
У вас был опыт поднять boost::sml на МК? Моя предыдущая статья почти об этом. Я там пробовал как раз альтернативу sml от чародея из Яндекса — отъела сразу 200Кб + typeid + exceptions. Для МК это перебор. Предполагаю, что у boost::sml будет схожий результат. Если ошибаюсь, поправьте меня.
Нуу, так уж и портит… Я в статье сам отметил, что дефайны не гуд, но в данном кейсе он упрощает настройку пользователю.
В классе ParserInterface необходимо добавить определение функций getDataImpl() и getIDImpl() по умолчанию, на случай если в классе-наследнике одна из них не нужна. Сейчас, если в наследнике «забыть» определить любую из них, будет ошибка компиляции. А так код сохранит работоспособность, просто при вызове из объекта базового класса ParserInterface, параметризованого классом с отсутствующим методом, будет вызвана «заглушка» определенная в базовом классе. Аналог виртуальной функции.
До сторонних пользователей пока далековато :), но буста побаиваюсь… Непрофессионально, но факт.
Кстати, большей частью из-за указанных вами недостатков, упомянутый мной С. Федоров и взялся написать свою библиотеку FSM. Шаблоны это, конечно, нитроглицерин — малейшая неострожность, и компилятор бомбанет, мало не покажется) Но до чего захватывающая штука! В азарте сложно держать баланс между реальными требованиями задачи и использованием шаблонов ради любви к шаблонам.
1

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Зарегистрирован
Активность