gpt4 book ai didi

C++ 编译时检查微 Controller 引脚是否已从其他源文件初始化

转载 作者:行者123 更新时间:2023-11-27 23:39:12 25 4
gpt4 key购买 nike

通常,微 Controller 引脚可以用端口号和引脚号来标识。两者都是编译时间常数。一个引脚可以有多个功能,如果在一个大项目中使用多个源文件可以初始化相同的引脚和中断在其他模块中实现的功能。

我想实现一个最初为空的编译时间列表,每次初始化一个引脚时,它都会检查该引脚是否已经存在存在于该列表中,如果它存在,它将给出一个静态断言,否则它将在列表中插入引脚信息。运行时不需要列表。

我没有足够的元编程知识,如果有人能给我提供实现它的方向就太好了。如果已经有一些用于这种目的的库,请提供链接

最佳答案

你想要的是不可能的。 C++ 元编程没有状态,它更像是一种函数式语言而不是声明式语言。所以你不能有一个可变列表。唯一的状态可以通过创建新类型来引入,但是没有可用的语法来检查是否声明或定义了特定的非嵌套名称。

多个源文件(编译单元)是独立编译的,所以肯定没有“全局状态”,这使得它更不可能。

另外请注意,您所做的本质上是运行时的。编译器没有工具来检查您是否两次调用初始化函数。这些调用可能隐藏在某些运行时 if-else 决策的背后。而简单的写HAL_GPIO_Init();无论在整个程序中写多少次都不会报错。

我能想到的最简单的事情就是创建一个负责与引脚通信的 C++ 单例类。如果启用,您可以使用 error_codes 或异常来使用专用的 int init_GPIO 方法。您将不得不依赖于测试,而不是 static_assert - 单例工作正常并且 init_GPIO 的返回值不会被忽略。

如果你真的不想打扰单例,这个函数模板也可以:

template<std::size_t GPIO, std::size_t port> int GPIO_init(GPIO_InitStruct& s){
static bool initialized=false;
if(initialized) return <already_called>;
initialized=true;
//Assuming that you want to propagate the return value.
return HAL_GPIO_Init(GPIO, port, s);// Replace with the correct call.
}

如果你需要线程安全的初始化,那么使用:

template<std::size_t GPIO, std::size_t port> int GPIO_init(GPIO_InitStruct& s){
static std::once_flag initialized;
int ret_val = <already_called>;
auto call = [&](){ret_val = HAL_GPIO_Init(GPIO, port, s)};
std::call_once(initialized, call);
return ret_val;
}

关于C++ 编译时检查微 Controller 引脚是否已从其他源文件初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56801581/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com