将 IO 寄存器作为模板参数传递

2023-12-12

我想使用 IO 寄存器(== 静态内存地址)作为模板参数。问题是,寄存器通常被定义为扩展为类似于以下内容的宏(*(volatile uint8_t*)(11 + 0x20))我不知何故无法正确使用我的模板。

我想编写如下代码:

Foo<PORTB> foo;

这样我就可以轻松更改类使用的 IO 寄存器,而无需任何运行时开销(这对于微控制器至关重要)。 我在下面提供了一个完整的示例:

#include <stdint.h>
#include <stdio.h>
#include <utility>

#define PORTB  (*(volatile uint8_t*)(11 + 0x20))

template<volatile uint8_t* PortRegister>
class ControllerPtr final
{
public:
    static void SetHigh() { *PortRegister |= 0x2; }
};

template<volatile uint8_t& PortRegister>
class ControllerRef final
{
public:
    static void SetHigh() { PortRegister |= 0x2; }
};


int main()
{
    ControllerPtr<&PORTB> ptr;
    ControllerRef<PORTB> ref;

    ptr.SetHigh();
    ref.SetHigh();

    // Both statements should be equal to:
    // PORTB |= 0x2;
}

每当我试图通过时&PORTB to ControllerPtr,g++ 无法编译:

error: (volatile uint8_t*)((long int)(11 + 32))不是有效的模板参数volatile uint8_t* {aka volatile unsigned char*}因为它不是变量的地址

错误:表达式*(volatile uint8_t*)((long int)(11 + 32))有副作用

尝试通过时的错误有点不同PORTB到像使用的引用类型ControllerRef:

error: *(volatile uint8_t*)((long int)(11 + 32))不是类型的有效模板参数volatile uint8_t& {aka volatile unsigned char&}因为它不是一个具有链接的对象

我实际上不明白为什么这个错误是一个错误,因为我没有看到将静态地址传递给模板有任何问题。


非类型模板参数必须是常量表达式,并且不能有reinterpret_cast在常量表达式内(除非它未被评估)。

由于您已经表示除了通过宏(例如)之外,您无法访问数字地址PORTB,我建议一个解决方法。尽管PORTB不能在模板参数中使用,我们可以合成一个可以在模板参数中使用的唯一类型,如下所示:

struct PORTB_tag {
    static volatile uint8_t& value() { return PORTB; }
};
template <class PortTag>
class ControllerRef final {
  public:
    static void SetHigh() { PortTag::value() |= 0x2; }
};
int main() {
    ControllerRef<PORTB_tag> ref;
    ref.SetHigh();
}

当您有很多端口时,为了节省重复输入,我们可以使用宏:

#define PORT_TAG(port) port_tag_for_ ## port
#define MAKE_PORT_TAG(port) struct port_tag_for_ ## port { \
    static volatile uint8_t& value() { return port; } \
}
template <class PortTag>
class ControllerRef final {
  public:
    static void SetHigh() { PortTag::value() |= 0x2; }
};
MAKE_PORT_TAG(PORTB);
int main() {
    ControllerRef<PORT_TAG(PORTB)> ref;
    ref.SetHigh();
}

http://coliru.stacked-crooked.com/a/401c0847d77ec0e0

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 IO 寄存器作为模板参数传递 的相关文章

随机推荐

  • 严重:缺少字段依赖项:private org.glassfish.jersey.server.wadl.WadlApplicationContext

    谁能帮我 我正在尝试使用 JAX RS 创建一个 Web 服务 但它给了我这个例外 SEVERE Missing dependency for field private org glassfish jersey server wadl W
  • ASP Web API 帮助页面 - 其他页面的链接

    我正在使用 Web API 帮助页面 并且希望能够包含其他方法的链接 我已经看到从Web API 2 帮助页面是否不处理 XML 文档标签 不支持使用 有没有比在文档中编写我自己的 链接并使用中描述的方法更好的选择Web Api 帮助页面
  • 没有主键列的数据表合并

    如何合并目标表包含主键列而源表不包含的表 DataSet enforceConstraints 设置为 false 然后它将合并表 但是当在目标表上执行 GetChanges 时 会发生异常 Dest table contains prim
  • 将一些标签放入

    这是我的代码
  • 哈希映射、哈希集、哈希字典有什么区别?

    有人可以解释一下以下结构之间的区别 Hash Map 哈希表 哈希集 以及 哈希字典 HashMap HashTable 和 HashDictionary 都是字典 将唯一的无序键映射到相应的值 使用哈希码实现 HashSet 表示唯一的
  • 触发对同一个表的 UPDATE 和 SELECT - 错误 1235 (42000)

    我正在尝试实施具有多个递增列的表 不会重用已删除的列值 这篇文章被标记为已经被回答MYSQL表的子集内如何自动递增但是 引用的帖子不符合规定的要求 因为它允许子集增量键被复制 在第一篇文章中 给出了评论 创建一个表来存储每种类型的最后 AI
  • 如何创建带有图标的 C++ 按钮

    我正在尝试制作一个自定义退出按钮 并且我已经在 Photoshop 中为该按钮创建了一个自定义图形 我有此代码定义的按钮 button CreateWindow L BUTTON L WS VISIBLE WS CHILDWINDOW 40
  • iOS 使用 UIActivityViewController 将 GIF 分享到 Messenger

    我正在尝试使用共享不同类型的图像UIActivityViewController到 Facebook Messenger 我在共享图像 png 时没有遇到任何问题 但我无法发送 gif 图像 gif 它给出错误 无法加载内容 我将图像转换为
  • 在 C# 中解析用引号引起来的 CSV 文件

    我见过很多解析 CSV 文件的示例 但这是一种烦人的文件 那么如何解析这种 CSV 1 1 2 2010 样本 adasdad asdada 我在门上大便 臭 所以我该死 AK 在大多数情况下 最好的答案可能是 Jim Mischel 的
  • 如何比较两个列表中的项目 Python 3.3

    我尝试使用cmp list1 list2 了解 Python 3 3 不再支持它 我尝试过许多其他复杂的方法 但没有一个有效 我有两个列表 其中都只包含单词 我希望它检查两个列表中有多少单词 并返回有多少单词 您可以使用以下方法找到集合交集
  • SVN 提交期间互联网连接断开

    在对远程 SVN 存储库进行大量提交期间 如果互联网连接断开 我是否必须再次开始提交 或者它会从中断的地方 继续 吗 Thanks Ojo Subversion 提交是一个原子事务 要么一切都承诺 要么什么都不承诺 您必须再次开始提交
  • 将局部变量设置为函数而不是使用全局变量来优化函数

    在 itertools 模块的文档中我发现了这个评论 def dotproduct vec1 vec2 return sum imap operator mul vec1 vec2 请注意 上述许多配方可以通过替换全局来优化 使用定义为默认
  • 确定 MPMovies 控制器比特率

    有没有办法确定 MPMovieController 正在播放的流的比特率 我正在 iOS 上使用 Objective C 进行编程 可以从event中获取指示的码率 这是按照m3u8的码流的码率 为了计算实际比特率 我将 event num
  • 使用 Javascript 从浏览器截屏?

    我想这是一个奇怪的问题 答案很可能是不可能的 因为这代表着安全漏洞 但我正在寻找一种方法 如果有的话 来获取浏览器内内容的屏幕转储 我不需要整个窗口 但实际上只需要转储标签的渲染状态 它需要跨平台和跨浏览器兼容 这还不能在纯 JavaScr
  • 在 iis 6 和 asp.net mvc 3 中找不到默认角色提供程序

    我正在 ii6 上启动 asp net mvc 3 应用程序 不使用成员资格或角色提供者 我通过手动创建授权cookie来实现授权 并在global asax中处理它 首先 出现了这个错误 创建 App Data 子目录时访问被拒绝 描述
  • ASP.NET 请求是否始终在同一线程上开始请求和结束请求?

    对于来自客户端的给定 HTTP 请求 ASP NET HttpApplication 的 BeginRequest 和 EndRequest 是否始终发生在完全相同的线程上 我问的原因是我看到一些非常奇怪的行为 其中 ThreadStati
  • MongoDB:如何正确地将集合从 MongoDB 导出到我的计算机?

    给定以下数据库和相关集合scows tasks 如何导出 2GB 用于存储目的以腾出空间 我一直在尝试使用各种方法来做到这一点 但没有一个奏效 mongoexport verbose db scows collection tasks ou
  • python readthedocs如何满足sip(或pyqt)的要求

    我想发布我的项目的文档https bitbucket org oaltun opn在 readthedocs org 中 构建失败 日志中显示不同的错误https readthedocs org builds opn 2247789 但第一
  • 如何旋转TextView?

    我想旋转 TextView 但无法获得正确的输出 我正进入 状态textView缺少一些文字 布局中
  • 将 IO 寄存器作为模板参数传递

    我想使用 IO 寄存器 静态内存地址 作为模板参数 问题是 寄存器通常被定义为扩展为类似于以下内容的宏 volatile uint8 t 11 0x20 我不知何故无法正确使用我的模板 我想编写如下代码 Foo