是否可以通过嵌入式 C 中的中断来中断结构的复制过程?

电器工程 微控制器 C 嵌入式 中断
2022-01-13 12:44:30

在驱动程序内部,我有一个函数可以将数据从内部结构复制到应用程序的结构中。

这个过程可以被微控制器中断触发器中断吗?

uint16_t getRawData(struct Data *Data_external)
{
  if(Data_external == NULL)
  {
    return ERR_PARA;
  }
  else
  {
    *Data_external = Data_internal;            // the copy process. Could this be interrupted? 
  }
  return ERR_NONE;
}
4个回答

是的。MCU 中的几乎所有东西都可以被中断请求中断。当中断处理程序完成时,前面的代码将继续,所以它通常不是问题。

在特殊情况下,中断处理程序本身可以被更高优先级的中断(嵌套中断)中断。

如果一系列指令一定不能被中断,那么你需要实现一个临界区(基本上全局禁用中断,完成工作,再次启用)。

请记住,根据目标 CPU 的体系结构,一行 C 语言可以编译为许多汇编指令。例如i++,AVR 上的简单指令会编译为多条指令iuint32_t

任何非原子操作都可能受到中断的干扰。这种编程通常与大多数其他编程非常不同,并且可能会让没有学习过处理器设计或计算机体系结构的人感到困惑。

您可能会想“这永远不会真正发生,复制这段代码需要多长时间,中断的可能性有多大?” 但是对于大多数生产嵌入式应用程序,它会发生,因为该产品已经运行多年而没有更新。

像这样的结构副本的另一个问题是,当它们确实发生时,它们非常难以调试,因为它们仅在中断发生在正确的时间(可能只有一个周期)时才会发生。

中断的全部意义在于它们可以(并且确实)一直发生,并且旨在对发生时恰好正在运行的任何代码产生零影响。保存所有寄存器,根据 CPU 架构,可能会换入完全不同的寄存器组,中断完成它的工作,然后恢复原始寄存器,代码继续正常运行。

当中断服务例程本身尝试访问正在运行的中断代码正在访问的内存时,可能会出现问题。当对时间要求严格的 I/O 进程中断时,可能会出现更细微的错误。这些问题在较旧、较简单、安全性较低的体系结构中很常见,在这些体系结构中,“用户”和“主管/内核”模式代码之间可能几乎没有分离。

这种问题很难识别,而且通常很难重现,但一旦识别出来,使用防御性编程、互斥体/信号量或简单地通过在代码的关键部分禁用中断通常很容易解决。

对一般问题进行了广泛的研究,如果没有尝试和测试多种解决方案,现代多核 CPU 甚至多任务操作系统都是不可能的。

我只是继续,假设你问这个是有充分理由的。

*Data_external = Data_internal;

可以拆分(除了一些不太可能在此处发挥作用的边缘情况)。

我不知道你的 CPU,但我还没有看到一个 CPU 不能在道德上等同于:

cli(); /* mask all interrupts */
*Data_external = Data_internal;
sti(); /* restore interrupt mask */

现在它不能在任何单核 CPU 上拆分,因为在中断关闭时没有任何东西可以中断。这是否是一个好主意取决于很多我根本没有资格评估的事情。

如果您是多核的(我终于记得市场上有多核嵌入式 CPU),请不要这样做。这是毫无价值的。您需要开发适当的锁定。