Arlleex 172 4 июля Опубликовано 4 июля · Жалоба 7 часов назад, Forger сказал: у себя в библиотеке под разное железо я вообще отказался от такой записи, а просто явно указываю экземпляр какого пина мне нужен и можно сразу в каком режиме, например: Не угадали, я не пины МК настраиваю) Это описание пинов внешнего по отношению к МК устройства. Это имя используется при инстанцировании шаблонных классов. Поэтому я не хотел писать кучу объявлений using Pin::RESET и т.д., т.к. решение не универсальное - если элементов энума будет три десятка, то и экран из трех десятков таких объявлений создаст, по сути, не нужную простыню. 2 минуты назад, andrew_b сказал: Крайноз головного мозга это ржачно. Че? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 231 4 июля Опубликовано 4 июля · Жалоба 3 часа назад, EdgeAligned сказал: Основа - класс GpioA со статическими шаблонными методами template<uint16_t Value> static void SetPins() {} и тд, и наложенный поверх шаблонный класс template<typename TPort, int PinPos> class Pin со статическими методами static void High() { TPort::template SetPins<1 << PinPos>(); и т.д. } У меня: #define PIN_LED A, 3 ... Pclr(PIN_LED); Pset(PIN_LED); И работает без всяких классов и шаблонов. Чисто на одних макросах. 3 часа назад, EdgeAligned сказал: получение максимально быстрого кода (при включенной оптимизации) Только скромно забыли упомянуть, что метод типа: 3 часа назад, EdgeAligned сказал: static void High() { TPort::template SetPins<1 << PinPos>(); } компактным "сворачиваясь в пределе до одной ассемблерной инструкции" видимо может быть только при максимальной оптимизации. А если хотя-бы стоит "средняя" оптимизация, то результат будет ОЧЕНЬ далёк от одной инструкции. Скорее всего породит функцию. И вызывающая функция тоже утяжелится. А вот при макросе - функции не будет даже при полностью выключенной оптимизации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 4 июля Опубликовано 4 июля · Жалоба 3 часа назад, EdgeAligned сказал: По поводу пинов, я, почитав и перебрав разные варианты, пришел к такому Мне не управление пинами МК надо. Это энумы - как часть некого набора классов драйвера внешнего устройства, у которого уже есть лапы RESET и ENABLE. И мой вопрос про то, можно ли неким аналогом using namespace подключить имена не в первую общую "корневую" область видимости, а прямо в ту, где эта директива написана. Т.е. чтобы void func1() { u32 reset = RESET; // берется RESET из stm32f4xx.h } void func2() { // вот как? using что-нибудь, но чтобы имена вставились СЮДА, а не в :: u32 reset = RESET; // берется Pin::RESET } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 4 июля Опубликовано 4 июля · Жалоба 12 минут назад, Arlleex сказал: https://github.com/fcayci/stm32f4-bare-metal/blob/99256dfe4b8630d707743d8917f326cf600c9eeb/include/stm32f4xx.h#L201 Аа... понятно. Я сделал свой stm32.h в который поместил все #include "stm32f????.h Больше ничего полезного в этом вашем stm32f4xx.h нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 4 июля Опубликовано 4 июля · Жалоба Только что, jcxz сказал: У меня: У меня на макросах тоже много всякого есть. Но это не то. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 16 4 июля Опубликовано 4 июля · Жалоба 7 minutes ago, Arlleex said: Че? Крайноз (от слова "крайний") головного мозга -- болезнь, проявляющаяся в использовании слова "крайний" вместо "последний". Крайнозники -- забавные существа, поржать над ними святое дело. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 4 июля Опубликовано 4 июля · Жалоба Только что, andrew_b сказал: Крайноз (от слова "крайний") головного мозга -- болезнь, проявляющаяся в использовании слова "крайний" вместо "последний". Крайнозники -- забавные существа, поржать над ними святое дело. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 81 5 июля Опубликовано 5 июля · Жалоба Про макросы - да, я тоже так делал, и это работает. Однако, коль уж начал жить по-новому, но и мыслить тоже желательно по-новому 🙂 В том плане, что появилась возможность сделать вот так: template<typename SPI, typename CS, typename DC> class XXXX { public: static void Xxxxx() { CS::Low(); DC::Low(); SPI::Write(xxx); ... } } На мой взгляд, это работает неплохо. К тому же, можно, используя одно описание (шаблон) класса для нескольких физических устройств, сидящих на разной периферии. А без оптимизации даже базовый Си работает значительно медленнее. Оптимизация ведь заставляет компилятор использовать более широкий набор инструкций и иначе строить код. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 81 5 июля Опубликовано 5 июля · Жалоба В 04.07.2024 в 11:52, Arlleex сказал: подключить имена не в первую общую "корневую" область видимости, а прямо в ту, где эта директива написана. Начнем издалека: namespace N { void Foo() { } } namespace M { void FooM() { using namespace N; Foo(); } } Однако, если Foo() определена в глобальной области видимости ::, то нужно конкретно указывать, какую из Foo() вы вызываете - N::Foo(); или ::Foo(); А теперь с энумераторами: enum En { RESET = 0, SET = 1 }; namespace N { enum En { RESET = 1, SET = 0 }; } void Foo() { En st1 = SET; N::En st2 = N::SET; } Собственно, о чем и сообщает строчка ambigous: RESET из enum в <stm32f4xx.h> или из Hardware::Pin? в которой так и написано - "откуда вы вызываете RESET, из энумератора или из Hardware::Pin?" То есть, когда появляется неоднозначность вызова, нужно указывать полное имя, включая неймспейсы. Глобальную область видимости отключить нельзя (насколько мне известно). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 172 5 июля Опубликовано 5 июля · Жалоба 2 часа назад, EdgeAligned сказал: То есть, когда появляется неоднозначность вызова, нужно указывать полное имя, включая неймспейсы. Глобальную область видимости отключить нельзя (насколько мне известно). Так я и хочу, чтобы был способ, аналогичный using namespace, но чтобы вкладывал имена не в область видимости наименьшего общего предка, а именно туда, где этот using namespace написан. Ну не хочется же мне размазывать все эти уточнения Hardware::RESET и т.д. Подключение пространств имен в плюсах - и даже тут разработчики языка запутали. Вот пример, куда реально будут вложены имена при неквалифицированном поиске И как это выглядит визуально: пишем using namespace N1, подразумевая, что в области видимости test() будут "видны" имена из N1. Однако имена из N1 на самом деле вбрасываются в NC. И когда в test() вызывается foo(), происходит поиск этого имени, начиная с текущего N2 и вверх по иерархии, пока не наткнется на этот самый "появившийся" N1::foo. А using namespace NA вообще подключает имена из NA в глобальную область. Соответственно, я акцентирую внимание на фундаментальной недоработке языка - вроде, пишем строчку, которая чисто по логике и внешнему виду говорит нам, чего она делает, а делает она совсем не то, и настолько не то, что придется каждый раз "разворачивать" вот такое визуальное дерево в голове и думать, чего ж там наподключалось в итоге и куда. Максимум что дает язык - возможность "сократить" длиннющие имена вложений в нечто одно using Hardware::Pin; ... i = Pin::RESET; Но мне и этот Pin:: выкинуть бы. Ведь итак понятно, что подключен энум из Hardware. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 21 11 июля Опубликовано 11 июля · Жалоба Приветствую, коллеги. Вот и меня жизнь занесла в кресты )) Пятничная задачка. Сделать на плюсах простейшую tinyFSM. Буквально в несколько строчек. Полез искать в интернетах и нашел вот это: https://etlcpp.com/state_chart.html примерно как я на сях делал. И вообще на сайте много чего интересного. Ну а вопрос отпал в процессе оформления ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 12 июля Опубликовано 12 июля · Жалоба По теме "FSM на плюсах" меня в своё время очень впечатлил доклад одного товарища на cppcon. Там под капотом std::variant, для итерации по состояниям используется std::visit(), и проверка полноты таблицы переходов осуществляется на этапе компиляции. Клёво получается. И очень быстро. Я даже реализовал парочку таких машин для интереса. Но в реальных проектах не применил - не дошли руки. ЗЫ. Вот презентация от этого доклада. effective_replacement_of_dynamic_polymorphism_with_stdvariant__mateusz_pusz__cppcon_2018.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 21 15 июля Опубликовано 15 июля · Жалоба Вот это для меня пока бессмысленный набор символов. Нет, все понятно ) но что конкретно ... Стареем.. А вообще спасибо большое, именно то, что нужно, включая конкретную реализацию: парсинг протокола. Знать бы ещё, как плюсик в карму занести ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 22 15 июля Опубликовано 15 июля · Жалоба 43 minutes ago, MrYuran said: Знать бы ещё, как плюсик в карму занести ) Нажать на "сердечко" справа снизу под нужным постом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 81 15 июля Опубликовано 15 июля · Жалоба Поздравляем со вступлением в общество "упоротых плюсоводов" 🙂 вон те скобочки [](){} означают запись лямбда-функции. Да, это такой упоротый синтаксис, называется "безымянная функция", или лямбда-фукнция. А две && означают правостороннюю ссылку. auto&& v - это принимаемый в лямбду параметр по правосторонней ссылке. в { } записана реализация функции, в виде вызова некоей v.foo(), Работает это в составе двух функциц для "динамического полиморфизма". Я, если честно, еще сам не разбирался конктерно с сей фигней, просто читал как-то. Динамический полиморфизм с использованием std::variant и std::visit / Хабр (habr.com) 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться