Каков современный C ++ способ иметь константный указатель constexpr на энергозависимую область памяти для встроенных приложений? - PullRequest
0 голосов
/ 02 февраля 2019

При создании библиотек для управления оборудованием на встроенных микропроцессорах обычной задачей является управление битами в определенных местах памяти для управления аппаратными функциями.

В процессорах AVR Atmel (теперь Microchip) предоставляет макросы, которые расширяются до чего-то вродеthis:

#define PORTA (*(volatile uint8_t *)(0x25))

, который включает такие вещи, как:

PORTA |= 1;

Теперь в C ++ 11 (и новее) желательно заменить практически любое использование #define на constexpr.

В более старых версиях компилятора GCC C ++ (4.9.2) компилировалось следующее:

#include <avr/io.h>
constexpr volatile uint8_t *const PortA = &PORTA;

В версии 8.2.0 вышеприведенное не компилируется и выдает ошибки:

error: reinterpret_cast from integer to pointer

Я не ищу объяснений, почему вы не можете использовать reinterpret_cast в контексте constexpr или почему преобразование целых в указатель является недопустимым.

Чтоправильный способ иметь указатель constexpr на volatile память в современном C ++?

Я видел предложения по сохранению адреса памяти PORTA в constexpr uintptr_t, а затемreinterprect_cast это до volatile uint8_t * const на руntime для битовых манипуляций.

Например, это работает и даже компилируется в одну sbi инструкцию в avr-gcc, как и ожидалось.

#include <stdint.h>
constexpr uintptr_t PortA = 0x25;
void set() { *((volatile uint8_t *)(PortA)) |= 1; }

Однако для использования Foo в качестве указателя, которым он предназначен, требуется приличное количество уродливого шаблона.

Это также имеет проблему, которая кажется невозможнойиспользуйте макрос PORTA напрямую.Вместо этого мы вынуждены жестко закодировать адрес памяти 0x25, который нарушает некоторые желательные функции переносимости.

Такое ощущение, что я упускаю что-то очевидное, но мои поиски не принесли ничего полезного.

Например, это похоже на «выражение константы адреса», но, похоже, это относится к обращению к статически распределенным значениям const, что не совсем то, что я хочу.

const char str[] = "FooBar";
constexpr const char * x = str + 2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...