我正在用 C++ 为 esp32 编写固件,我发现在注册 ISR 时将对象引用作为参数传递非常棒,因为我可以简单地将 ISR 的工作委托给特定对象(本例中为资源),直接从类管理资源属性和功能。但是,我不确定在使用这种技术时要注意什么。
- 它有什么本质上的错误吗?
- 如果没有,在做的时候应该注意什么?
将“this”作为参数传递给 ISR 注册有什么问题吗?
不。
它有什么本质上的错误吗?
不。
如果没有,在做的时候应该注意什么?
对象生命周期。编译器优化。资源共享。锁定。原子访问。特定的硬件语义。此外,esp32 是一个两核平台。这个清单可以继续下去,还有很多关于 esp32 编程的书籍,关于在并行环境中编程以及在代码的主要部分和中断例程之间共享资源的书籍。人们应该了解所有此类与编程相关的主题,以及良好的代码约定、命名和 C++ 语言。
我可以简单地将 ISR 的工作委托给特定对象(在本例中为资源),直接从类管理资源属性和功能。
这已经是错误的了。如果您确实以类的形式为特定的硬件外围设备编写驱动程序,那么 ISR 应该作为静态成员函数在该类中。或者至少与static
函数驻留在同一个翻译单元中,但这违背了使用类开始的目的。
但是,如果您像这样设计程序,那么请确保您可以传递对该类的引用。
它有什么本质上的错误吗?
除了上述之外,是的,这必须是一个具有静态存储持续时间的单例对象。并且在嵌入式系统中使用 C++ 类的静态存储持续时间对象本质上是错误的,因为这些将在微控制器启动期间由 CRT 调用。这反过来又导致所有此类 C++ 程序的启动速度都比 C 等效程序慢。
但同样在这种特殊情况下,如果需要从上电复位点及时启动中断,则 C++ 对象初始化将无法提供必要的实时性能。这使得 C++ 类不适用于看门狗、低压警告、时钟监视器、CPU 异常和其他关键硬件中断等中断。
如果没有,在做的时候应该注意什么?
当您在 ISR 和调用程序之间进行通信时出现的常见重入问题。这种重入机制可以封装在类中。
和往常一样,可能需要对其中涉及的变量进行volatile
限定,以防止不正确的编译器优化,具体取决于编译器的愚蠢程度。这与重入无关。请参阅在嵌入式 C 开发中使用 volatile。