【问题标题】:How to prevent a specific function or method from being called from within an interrupt routine?如何防止从中断例程中调用特定的函数或方法?
【发布时间】:2023-04-09 14:09:01
【问题描述】:

在低级嵌入式开发中使用 C++(而不是将 C++ 视为“具有一些额外功能的 C”)的障碍是由中断引起的。通常情况下,时间必须以单个 CPU 周期来衡量,并且某些类在那里没有使用业务。隐式转换、复制构造函数和类似的东西在中断中使用时可能会导致问题,特别是如果它们发生在幕后。另一方面,一些精心设计的类可以在中断中有意义地使用。

这提出了一个问题:是否有一种优雅的方式可以向编译器发出信号,告知编译器特定类、函数或变量(或只是代码行)在中断中使用时应该引发编译错误? (不必如此依赖 cmets 声明 //Never call this from an interrupt!

(如果没有,尝试将这样的内容纳入下一个 C++ 标准是否有意义?我在想constexpr 说明符如何通知编译器函数或变量是什么可以或不能用于。nointerrupt 说明符是否有意义,或者是否已经存在提供该功能的东西?)

【问题讨论】:

  • 我怀疑它会被标准接受为关键字。似乎过于具体的语言功能无法保证它。但我想你可以选择一对属性。 [[is_isr]] 用于例程,[[isr_safe]] 用于(成员)函数来记录它本身。然后可以进行静态分析。
  • C 和 C++ 都没有中断的概念,所以这个特性不能真正进入 C++ 标准。但是,您可以为 clang-tidy 等创建某种 lint,以检查在某些函数中是否仅进行了特定的调用列表。
  • @StoryTeller [[isr_safe]] 听起来很有希望。
  • @DanM。好吧,正如 StoryTeller 已经提到的那样,我认为我们已经在标准之外进行了讨论,但是属性可能是解决问题的好方法。嵌入式(裸机)编程已经需要一些超出 c++ 标准的特殊东西。
  • 如果它确实有效,这似乎是编译器#pragma 的完美用例,因为 a) 它确实不属于 C++ 标准,并且 b) 它确实是编译器-具体的(即使最终结果几乎总是相同的生成代码)。也就是说,正如 Clifford 指出的那样,担心的是这可能会提供一种错误的安全感,因为函数指针和链接器符号之类的东西意味着您可能无论如何都可以绕过这种保护。像这样的事情是我最大的问题是我可以退休的那一天。

标签: c++ embedded interrupt bare-metal isr


【解决方案1】:

与主系统上下文(和任务函数,如果您使用操作系统)一样,中断服务例程只是其他上下文。 要运行哪些代码(类子集的方法)这个问题与(类)库本身的技术是正交的。

RTOS 库通常对可在 ISR(或在具有给定优先级的 ISR)中调用的 API 施加“限制” - 但这些限制“仅”是为了保持数据一致性所必需的,而不是出于硬件技术原因µC 基础设施。

您希望将现有类库的使用限制在某些上下文中,因为某些类实现消耗的资源(时间、堆栈内存空间?)比您在 ISR 中所能承受的要多,但这取决于您的部署SW 项目架构中的决策。

因此,从我的角度来看,最优雅的解决方案是回到 SW 架构级别,创建一个整洁的文档(也许 UML 部署图可能已经对您有很大帮助),并指定在哪个您希望执行哪些代码的上下文。您可能会发现在 ISR 上下文中,只有一小部分代码要执行,因此标记应该在 ISR 上下文中运行的类子集(或类的方法子集)可能是可行的自上而下的视角。您可以通过在专用共享内存区域中设置/重置特定于 ISR 的标志来启动/完成每个 ISR 来备份此过程,并将断言语句添加到检测特定代码是否在不需要的 ISR 中运行的关键类/方法中上下文。

【讨论】:

    猜你喜欢
    • 2021-12-20
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多