Arlleex 158 Четверг в 05:43 Опубликовано Четверг в 05:43 · Жалоба 7 часов назад, Forger сказал: у себя в библиотеке под разное железо я вообще отказался от такой записи, а просто явно указываю экземпляр какого пина мне нужен и можно сразу в каком режиме, например: Не угадали, я не пины МК настраиваю) Это описание пинов внешнего по отношению к МК устройства. Это имя используется при инстанцировании шаблонных классов. Поэтому я не хотел писать кучу объявлений using Pin::RESET и т.д., т.к. решение не универсальное - если элементов энума будет три десятка, то и экран из трех десятков таких объявлений создаст, по сути, не нужную простыню. 2 минуты назад, andrew_b сказал: Крайноз головного мозга это ржачно. Че? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 211 Четверг в 05:50 Опубликовано Четверг в 05:50 · Жалоба 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 158 Четверг в 05:52 Опубликовано Четверг в 05:52 · Жалоба 3 часа назад, EdgeAligned сказал: По поводу пинов, я, почитав и перебрав разные варианты, пришел к такому Мне не управление пинами МК надо. Это энумы - как часть некого набора классов драйвера внешнего устройства, у которого уже есть лапы RESET и ENABLE. И мой вопрос про то, можно ли неким аналогом using namespace подключить имена не в первую общую "корневую" область видимости, а прямо в ту, где эта директива написана. Т.е. чтобы void func1() { u32 reset = RESET; // берется RESET из stm32f4xx.h } void func2() { // вот как? using что-нибудь, но чтобы имена вставились СЮДА, а не в :: u32 reset = RESET; // берется Pin::RESET } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 128 Четверг в 05:52 Опубликовано Четверг в 05:52 · Жалоба 12 минут назад, Arlleex сказал: https://github.com/fcayci/stm32f4-bare-metal/blob/99256dfe4b8630d707743d8917f326cf600c9eeb/include/stm32f4xx.h#L201 Аа... понятно. Я сделал свой stm32.h в который поместил все #include "stm32f????.h Больше ничего полезного в этом вашем stm32f4xx.h нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 158 Четверг в 05:53 Опубликовано Четверг в 05:53 · Жалоба Только что, jcxz сказал: У меня: У меня на макросах тоже много всякого есть. Но это не то. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 15 Четверг в 05:59 Опубликовано Четверг в 05:59 · Жалоба 7 minutes ago, Arlleex said: Че? Крайноз (от слова "крайний") головного мозга -- болезнь, проявляющаяся в использовании слова "крайний" вместо "последний". Крайнозники -- забавные существа, поржать над ними святое дело. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 158 Четверг в 06:01 Опубликовано Четверг в 06:01 · Жалоба Только что, andrew_b сказал: Крайноз (от слова "крайний") головного мозга -- болезнь, проявляющаяся в использовании слова "крайний" вместо "последний". Крайнозники -- забавные существа, поржать над ними святое дело. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 74 15 часов назад Опубликовано 15 часов назад · Жалоба Про макросы - да, я тоже так делал, и это работает. Однако, коль уж начал жить по-новому, но и мыслить тоже желательно по-новому 🙂 В том плане, что появилась возможность сделать вот так: template<typename SPI, typename CS, typename DC> class XXXX { public: static void Xxxxx() { CS::Low(); DC::Low(); SPI::Write(xxx); ... } } На мой взгляд, это работает неплохо. К тому же, можно, используя одно описание (шаблон) класса для нескольких физических устройств, сидящих на разной периферии. А без оптимизации даже базовый Си работает значительно медленнее. Оптимизация ведь заставляет компилятор использовать более широкий набор инструкций и иначе строить код. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 74 11 часов назад Опубликовано 11 часов назад · Жалоба В 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 158 8 часов назад Опубликовано 8 часов назад · Жалоба 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться