Перейти к содержанию
    

Плавный переход C -> C++ под МК

7 часов назад, Forger сказал:

у себя в библиотеке под разное железо я вообще отказался от такой записи, а просто явно указываю экземпляр какого пина мне нужен и можно сразу в каком режиме, например:

Не угадали, я не пины МК настраиваю) Это описание пинов внешнего по отношению к МК устройства. Это имя используется при инстанцировании шаблонных классов.

Поэтому я не хотел писать кучу объявлений using Pin::RESET и т.д., т.к. решение не универсальное - если элементов энума будет три десятка, то и экран из трех десятков таких объявлений создаст, по сути, не нужную простыню.

2 минуты назад, andrew_b сказал:

Крайноз головного мозга это ржачно.

Че?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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>(); }

компактным "сворачиваясь в пределе до одной ассемблерной инструкции" видимо может быть только при максимальной оптимизации. А если хотя-бы стоит "средняя" оптимизация, то результат будет ОЧЕНЬ далёк от одной инструкции. Скорее всего породит функцию. И вызывающая функция тоже утяжелится. А вот при макросе - функции не будет даже при полностью выключенной оптимизации.  :unknw:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, EdgeAligned сказал:

По поводу пинов, я, почитав и перебрав разные варианты, пришел к такому

Мне не управление пинами МК надо. Это энумы - как часть некого набора классов драйвера внешнего устройства, у которого уже есть лапы RESET и ENABLE.

И мой вопрос про то, можно ли неким аналогом using namespace подключить имена не в первую общую "корневую" область видимости, а прямо в ту, где эта директива написана.

Т.е. чтобы

void func1() {
  u32 reset = RESET; // берется RESET из stm32f4xx.h
}

void func2() {
  // вот как? using что-нибудь, но чтобы имена вставились СЮДА, а не в ::
  
  u32 reset = RESET; // берется Pin::RESET
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 минут назад, Arlleex сказал:

Аа... понятно. Я сделал свой stm32.h в который поместил все #include "stm32f????.h

Больше ничего полезного в этом вашем stm32f4xx.h нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что, jcxz сказал:

У меня:

У меня на макросах тоже много всякого есть. Но это не то.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 minutes ago, Arlleex said:

Че?

Крайноз (от слова "крайний") головного мозга -- болезнь, проявляющаяся в использовании слова "крайний" вместо "последний".

Крайнозники -- забавные существа, поржать над ними святое дело.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что, andrew_b сказал:

Крайноз (от слова "крайний") головного мозга -- болезнь, проявляющаяся в использовании слова "крайний" вместо "последний".

Крайнозники -- забавные существа, поржать над ними святое дело.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Про макросы - да, я тоже так делал, и это работает. Однако, коль уж начал жить по-новому, но и мыслить тоже желательно по-новому 🙂 В том плане, что появилась возможность сделать вот так:

template<typename SPI, typename CS, typename DC>
  class XXXX {
  public:
  static void Xxxxx()
  {
    CS::Low();
    DC::Low();
    SPI::Write(xxx);
    ...
   }
}

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 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?"
То есть, когда появляется неоднозначность вызова, нужно указывать полное имя, включая неймспейсы. Глобальную область видимости отключить нельзя (насколько мне известно).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...