【发布时间】:2018-02-05 10:17:11
【问题描述】:
我正在实现一个辅助类,它具有许多有用的功能,这些功能将在大量类中使用。但是,其中一些并非设计为在某些代码段内调用(从中断函数,这是一个嵌入式项目)。
然而,对于这个类的用户来说,为什么某些函数被允许而其他函数被禁止从中断函数中调用的原因可能不是很明显,并且在许多情况下,被禁止的函数可能会起作用,但可能会导致非常微妙和难以稍后再查找错误。
对我来说最好的解决方案是,如果从不应调用的代码部分调用有问题的函数,则会导致编译器错误。
我也考虑过一些非技术性的解决方案,但最好是技术性的解决方案。
在文档中用警告指出它。可能很容易被忽略,尤其是当函数看起来很明显时,比如
read_byte(),为什么有人会研究文档,不管函数是否可重入?在函数名中注明。丑陋。谁喜欢
read_byte_DO_NOT_CALL_FROM_INTERRUPT()这样的函数名?在公共头文件中有一个全局变量,包含在每个文件中,在每个中断开始时将其设置为 true,在结束时设置为 false,并且有问题的函数会在开始时对其进行检查,如果已设置则退出。问题:中断可能会相互中断。此外,它不会导致编译时警告或错误。
类似于#3,有一个带堆栈的全局处理程序,以便可以处理嵌套中断。仍然存在仅在运行时工作的问题,并且还增加了很多开销。中断不应为此功能浪费超过一两个时钟周期(如果有的话)。
滥用预处理器。不幸的是,在每个中断的开头使用
#define,在每个中断结束时使用#undef,在有问题的函数开头使用#ifdef这种幼稚的方式不起作用,因为预处理器并不关心范围。由于中断总是无类函数,我可以将有问题的函数设为
protected,并在所有使用它们的类中将它们声明为friends。这样,就不可能在中断中直接使用它们。由于main()是无类的,因此我必须将其大部分放入类方法中。我不太喜欢这个,因为它可能变得不必要的复杂,并且它产生的错误并不明显(所以这个函数的用户可能会封装它们来“解决”问题,而没有意识到 真正的 em> 问题是)。像 "ERROR: function_name() is not to be used from within an interrupt" 这样的编译器或链接器错误消息会更可取。检查函数内的中断寄存器有几个问题。在大型微控制器中,有很多寄存器需要检查。此外,当一个中断标志恰好在一个时钟周期之前设置时,误报的可能性很小但很危险,所以我的函数会失败,因为它认为它是从中断调用的,而中断会在下一个周期。此外,在嵌套中断中,中断标志被清除,导致误报。最后,这是另一个运行时解决方案。
前段时间我确实玩过一些非常基本的模板元编程,但我没有找到一个非常简单和优雅的解决方案的经验。在承诺自己尝试实现模板元编程膨胀软件之前,我宁愿尝试其他方式。
仅使用 C 中可用功能的解决方案也是可以接受的,甚至更可取。
【问题讨论】:
-
听起来你的中断函数做的太多了……
-
不要将函数声明放在定义中断并将警告视为错误的翻译单元中
-
“将在大量类中使用”-让我认为您应该将函数放在基类中,并从该基类继承以引入功能。如果这不起作用,那我错过了什么?
-
中断函数与“正常”函数的区别是什么?您是否处于可以使用某种代码模式装饰所有中断函数的位置?
-
投反对票的人能否说明他们的理由?在如此短的时间内如此大量的反对票通常只在完全无法理解或公然离题的问题中观察到。你认为这是一个XY问题的案例吗?转载请注明。你认为我写的次优解决方案列表很荒谬吗?我可以很乐意删除它们。你认为这个问题应该在另一个网站上问吗?请以接近的投票方式表明它。你认为这不是问题,还是我完全错过了一个非常明显的解决方案?那么请这样回答。
标签: c++ c c-preprocessor