ViKo 1 19 февраля, 2020 Опубликовано 19 февраля, 2020 · Жалоба Вожусь с bit-band шаблоном для STM32. Чтобы преобразовать bit-band адрес в alias адрес нужно неким образом превратить, например, RCC->CR в число 0x4002'3800, а потом уже добавлять к нему, что надо. Но как взять адрес по указателю на член структуры? Так не получается: const uint32_t ADR = &(RCC->CR); Можно так: constexpr uint ADR = RCC_BASE + offsetof(RCC_TypeDef, CR); Но очень уж много букв. Иначе - никак? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 19 февраля, 2020 Опубликовано 19 февраля, 2020 · Жалоба Может так: const uint32_t ADR = (uint32_t)(&(RCC->CR)); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба 13 часов назад, Darth Vader сказал: Может так: const uint32_t ADR = (uint32_t)(&(RCC->CR)); Так получается. Но не помогает. Шаблону требуются constexpr параметры, а этот ADR он не считает таковым. Попробовал было в шаблоне тип задать, а не значение. RCC->CR. Тоже не берёт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба У меня не получилось иначе, чем constexpr uint ADR = RCC_BASE + offsetof(RCC_TypeDef, CR); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба Ясно. А передать в шаблон RCC_TypeDef и CR тоже не получится, чтобы вычислять смещение в самом шаблоне? Ничего, кроме показанного, не выходит. Выглядит страшно. BitBand<(RCC_BASE + offsetof(RCC_TypeDef, CR)), RCC_CR_HSEON>::setBit(); Слегка поправил. BitBand<RCC_BASE, offsetof(RCC_TypeDef, CR), RCC_CR_HSEON>::setBit(); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба /*!***************************************************************************** @brief BitBand class: read, reset, set bit @note only for Peripherals control @note usage: BitBand<RCC_BASE, offsetof(RCC_TypeDef, CR), RCC_CR_HSEON>::setBit(); */ template <const auto Base, const auto Offs, const auto Bit> class BitBand { private: static_assert((Base & 0xFFF0'0000) == PERIPH_BASE, // Check bit-band region "Address isn't in Bit-band region"); static constexpr auto Reg = Base + Offs; // Register address static constexpr auto calcPos(uint bitm) { // Bit mask position auto pos = 0; while (bitm >>= 1) ++pos; return pos; } static constexpr uint *calcAddr() { // Calculate alias address auto alias_addr = (Reg & 0xF000'0000) + 0x0200'0000 + ((Reg & 0x000F'FFFF) << 5) + (calcPos(Bit) << 2); return (uint *)alias_addr; } public: static auto readBit() { return *calcAddr(); } // read bit static void resetBit() { *calcAddr() = 0; } // reset bit static void setBit() { *calcAddr() = 1; } // set bit }; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба На битбанд, похоже, стало модно забивать. Например, в STM32F7 его уже нет. Штука иногда удобная, но не универсальная, и потому не особо полезная. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба Я, например, так и не понял, чего же в итоге хотел @ViKo... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба 1 час назад, AHTOXA сказал: На битбанд, похоже, стало модно забивать. Например, в STM32F7 его уже нет. Штука иногда удобная, но не универсальная, и потому не особо полезная. Пока упражнялся, понял окончательно. Для переменных в ОЗУ, практически, бесполезно. Ибо адрес нужно вычислять в рантайме. Если не задавать принудительно для компиляции. А это ничуть не быстрее, чем чтение-модификация-запись целого слова. Вот для периферийных регистров битами управлять годится. Но это не частые процедуры. В общем, переделывая наработанное с С на С++, сделал шаблон. А буду ли применять, вопрос. 35 минут назад, Arlleex сказал: Я, например, так и не понял, чего же в итоге хотел @ViKo... Адрес регистра хотел выудить. Выудить-то удалось, а применить в шаблоне - нет. Заменил сложением адреса структуры и смещения регистра в структуре. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба А почему constexpr uint32_t ADR = (uint32_t)(&(RCC->CR)); не работает? Что есть в выражении справа от знака присваивания того, что ещё не известно на этапе компиляции или что может измениться в рантайме? Я ничего такого там не вижу. Всё известно на момент объявления ADR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба 33 минуты назад, Darth Vader сказал: Я ничего такого там не вижу. Вот и я... Но, видимо, @ViKo хочет, чтобы, например, доступ к автоматическим (локальным) переменным структурного типа был в стиле bit-banding-а. Тогда да, только в runtime. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба 43 минуты назад, Darth Vader сказал: А почему constexpr uint32_t ADR = (uint32_t)(&(RCC->CR)); не работает? А вы попробуйте :-) Насколько я понял, правая часть трактуется как reinterpret_cast, а reinterpret_cast запрещён в const-выражениях. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба 28 минут назад, Arlleex сказал: Вот и я... Но, видимо, @ViKo хочет, чтобы, например, доступ к автоматическим (локальным) переменным структурного типа был в стиле bit-banding-а. Тогда да, только в runtime. Он хочет сделать шаблон для bit-band доступа к регистрам периферии. И хочет передавать в шаблон в качестве параметра константу-адрес этого регистра. Но, к сожалению, напрямую это сделать не получается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба 7 минут назад, AHTOXA сказал: Он хочет сделать шаблон для bit-band доступа к регистрам периферии. Понял. Но не понял, все-таки, что мешает... Не, понятно, что компайлер не дает сделать; не совсем понятно же, из каких соображений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 20 февраля, 2020 Опубликовано 20 февраля, 2020 · Жалоба 34 minutes ago, Arlleex said: Но не понял, все-таки, что мешает... Приведение типов. Сначала целого к указателю на структуру, затем указателя к целому числу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться