c++ - 对 avr 端口地址的 constexpr 引用

标签 c++ c++11 c++14 avr constexpr

我正在玩一些 avr 微 Controller 和 C++14。在尝试为 io 引脚实现 C++ 包装器时,我偶然发现了一个错误。

我的想法是,让包装器将 sfr 作为模板参数,以便为编译器轻松优化(不需要额外的函数并使用我可以向编译器指示的模板参数,我的论点应该始终是编译时可评估的)。我想,可以有 constexpr uint8_t& x = ... 变量引用一些编译时已知地址。但以下内容不起作用(定义取自 avr includes):

#include <avr/io.h>

constexpr uint32_t addr[] = { _SFR_IO_ADDR(PORTB) };

constexpr uint32_t GetAddr()
{
    return addr[0];
}

constexpr decltype(auto) Get()
{
    _SFR_IO8(GetAddr());
}

int main() {
    auto addr = GetAddr();
    auto b = Get();

    _SFR_IO8(addr) &= ~(1 << 2);
    b |= (1 << 3);
}

它给我 error: expression '*(volatile uint8_t*)(GetAddr() + 32u)' has side-effectsGet() 函数中。将 decltype(auto) 替换为 uint8_t&(当然)没有帮助。

为什么我无法获得指向内存位置的 constexpr uint8_t 引用 _SFR_IO_ADDR(PORTB) = (volatile uint8_t*)(_SFR_IO8(5u) - 32u) = (volatile uint8_t*)(5u + 32u - 32u)?

最佳答案

我想要将类似的模板化编译时间简化为一条指令。我不得不使用一些模板元编程来完成这项工作。

一个精简的例子:

#include <avr/io.h>

struct A {
  constexpr static volatile uint8_t *const PORT() { return &PORTA; }
  constexpr static volatile uint8_t *const DDR() { return &DDRA; }
};

template <class port, u1 pin> class IOpin {
  constexpr static volatile uint8_t  *DDR = port::DDR();
  constexpr static volatile uint8_t *PORT = port::PORT();
  constexpr static uint8_t mask = 1 << pin;

public:
  inline IOpin() {}

  inline static void output() { *DDR |= mask; }
  inline static void input() { *DDR &= ~mask; }
  inline static void set() { *PORT |= mask; }
}

// Use as type or instance
using myPinType = IOpin<A, 1>;
IOpin<A, 1> myPinInstance;

// Use myPin
myPinType::set(true);
myPinInstance.output();

完整实现:https://github.com/cinderblock/AVR/blob/master/AVR%2B%2B/IOpin.hpp

关于c++ - 对 avr 端口地址的 constexpr 引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41077173/

相关文章:

c++ - 使用 C++ 使用 SDL2_gfx 问题

c++ - 静态转换如何在 C++ 中保持数字的精度?

c++ - 带有 SFML API 的内部编译器错误 Visual Studio Community 2017

c++ - 使用元编程计算log2但是 `compilation terminated`

c++ - std::thread:如何等待(加入)任何给定线程完成?

c++ - 如何缩短模板类的类型名称语法

c++ - 为什么下面的打印树功能不起作用?

c++ - 链接从命令行翻译到 Make 的库

c++ - 如何在C++中正确使用for-range语句语法?

c++ - 使用 Dijkstra 算法找到最佳路径的不可预测的结果