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

Получить адрес регистра периферии STM32 по указателю на структуру с ним

Вожусь с 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);

Но очень уж много букв. Иначе - никак?
 

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


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

13 часов назад, Darth Vader сказал:

Может так:


const uint32_t ADR = (uint32_t)(&(RCC->CR));

Так получается. Но не помогает. Шаблону требуются constexpr параметры, а этот ADR он не считает таковым.
Попробовал было в шаблоне тип задать, а не значение. RCC->CR. Тоже не берёт.  

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


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

Ясно. А передать в шаблон RCC_TypeDef и CR тоже не получится, чтобы вычислять смещение в самом шаблоне?
Ничего, кроме показанного, не выходит. Выглядит страшно. :crazy:
 

BitBand<(RCC_BASE + offsetof(RCC_TypeDef, CR)), RCC_CR_HSEON>::setBit();

 

Слегка поправил.
 

BitBand<RCC_BASE, offsetof(RCC_TypeDef, CR), RCC_CR_HSEON>::setBit();

 

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


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

/*!*****************************************************************************
  @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
};

 

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


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

На битбанд, похоже, стало модно забивать. Например, в STM32F7 его уже нет. Штука иногда удобная, но не универсальная, и потому не особо полезная.

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


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

1 час назад, AHTOXA сказал:

На битбанд, похоже, стало модно забивать. Например, в STM32F7 его уже нет. Штука иногда удобная, но не универсальная, и потому не особо полезная.

Пока упражнялся, понял окончательно. Для переменных в ОЗУ, практически, бесполезно. Ибо адрес нужно вычислять в рантайме. Если не задавать принудительно для компиляции. А это ничуть не быстрее, чем чтение-модификация-запись целого слова. 

Вот для периферийных регистров битами управлять годится. Но это не частые процедуры. 

В общем, переделывая наработанное с С на С++, сделал шаблон. А буду ли применять, вопрос. 

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

Я, например, так и не понял, чего же в итоге хотел @ViKo...:blush:

Адрес регистра хотел выудить. Выудить-то удалось, а применить в шаблоне - нет. Заменил сложением адреса структуры и смещения регистра в структуре. 

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


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

А почему

 constexpr uint32_t ADR = (uint32_t)(&(RCC->CR));

не работает?

Что есть в выражении справа от знака присваивания того, что ещё  не известно на этапе компиляции или что может измениться в рантайме? Я ничего такого там не вижу. Всё известно на момент объявления ADR.

  

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


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

33 минуты назад, Darth Vader сказал:

Я ничего такого там не вижу.

Вот и я... Но, видимо, @ViKo хочет, чтобы, например, доступ к автоматическим (локальным) переменным структурного типа был в стиле bit-banding-а. Тогда да, только в runtime.

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


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

43 минуты назад, Darth Vader сказал:

А почему

 constexpr uint32_t ADR = (uint32_t)(&(RCC->CR));

не работает? 

А вы попробуйте :-)

Насколько я понял, правая часть трактуется как reinterpret_cast, а reinterpret_cast запрещён в const-выражениях.

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


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

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

Вот и я... Но, видимо, @ViKo хочет, чтобы, например, доступ к автоматическим (локальным) переменным структурного типа был в стиле bit-banding-а. Тогда да, только в runtime.

Он хочет сделать шаблон для bit-band доступа к регистрам периферии. И хочет передавать в шаблон в качестве параметра константу-адрес этого регистра.

Но, к сожалению, напрямую это сделать не получается.

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


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

7 минут назад, AHTOXA сказал:

Он хочет сделать шаблон для bit-band доступа к регистрам периферии.

Понял. Но не понял, все-таки, что мешает...

Не, понятно, что компайлер не дает сделать; не совсем понятно же, из каких соображений.

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


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

34 minutes ago, Arlleex said:

Но не понял, все-таки, что мешает...

Приведение типов. Сначала целого к указателю на структуру, затем указателя к целому числу.

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


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

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

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

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

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

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

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

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

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

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