【发布时间】:2020-07-06 21:42:42
【问题描述】:
C11 5.1.2.3/5:
当抽象机的处理被收据中断时 信号的对象的值既不是无锁原子的 对象和 volatile sig_atomic_t 类型的对象都未指定,就像 浮点环境的状态。任何对象的价值 由既不是无锁原子对象也不是无锁原子对象的处理程序修改 volatile sig_atomic_t 类型的在处理程序时变得不确定 退出,与浮点环境的状态一样,如果它是 由处理程序修改且未恢复到其原始状态。
这个问题专门针对嵌入式系统,在没有类似操作系统的设置的情况下。
在嵌入式系统上,经典信号(POSIX 风格)不存在。假设我们有一个调用多个函数的中断,所有这些函数都在同一个((半)全局)变量上工作,但这个变量不是在中断外上下文中使用的。类似的东西
static enum State state;
static void setStateTo1(void)
{
state = stateOne;
}
static void setStateTo2(void)
{
state = stateTwo;
}
void ISR(void)
{
if (state == stateOne)
setStateTo2();
else
setStateTo1();
}
两个问题:
- 中断是信号吗?
- 上述代码是否是未定义行为的示例,因为
state不是volatile?
【问题讨论】:
-
如何安装那些“中断处理程序”?如果您为此使用
signal,那么这些是标准意义上的信号处理程序,那么是的,您应该只使用volatile sigatomic_t进行通信。如果这是一组特定于系统的函数,您也必须查看该文档,C 标准无法告诉您任何关于此的内容。 -
正如问题中所述,这是关于嵌入式系统(我将添加标签以使其更清楚),这实际上是处理器决定我们现在要运行此功能,因为有些事件发生
-
我们只能假设 C 语言旨在运行在没有 OP 代码指令、汇编语言或中断的特殊设备上。否则,该语言将对计算机具有标准支持。甚至 C++ 也支持内联汇编,但不支持 C。
-
从纯粹实际的角度来看:由于显示的代码仅从一个线程访问变量(并且 ISR 和它调用的函数是一种线程),我没有看到任何需要将其设为
volatile或原子。话虽如此,您需要确保当 ISR 或任何被调用的函数运行时,它不能再次被调用。这是大多数嵌入式系统的标准,但您可以实现它。并且您需要确保没有其他线程(如main()及其调用的函数)访问此变量。
标签: c embedded language-lawyer interrupt c11