在 C++11 中模拟类似 Arduino 的中断

Sha*_*gle 6 c++ windows simulation arduino interrupt

我正在开发一个粗略的 Arduino 模拟器。它的主要功能应该是测试由控制结构、循环、开关和子程序组成的简单代码。

我的主要想法是自己简单地提供 Arduino 库的功能,例如像digitalWrite()or 之类的功能digitalRead(),它可以从外部应用程序(如虚拟面包板)读取和发送引脚状态。

下图显示了我目前的概念。模拟器基本上是一个线程,它执行setup()一次函数,然后开始执行loop()函数直到停止。它可以从控制(主)线程停止或暂停。

在此处输入图片说明

setup()loop()函数的实现,以及一些变量,由用户提供,不能修改或访问。

到现在为止还挺好。现在我想要模拟中断。当模拟器线程正在执行loop()函数时,外部应用程序会触发一个中断。这应该导致中断处理程序的执行isr(),它也由用户提供并且不能更改。

我有两种不同的方法来解决这个问题:

  1. 暂停模拟器线程,在不同的线程中执行中断处理程序并恢复模拟器线程。
  2. 改用信号处理程序,在发生中断时向进程发送信号。

这两种方法都有自己的问题。对于第一个,我需要以某种方式同步状态,这似乎更像是一个可怕的黑客。对于第二个选项,据我所知,我无法指定哪个线程将执行信号处理程序。

如果可能,解决方案应该与平台无关。但是,该解决方案绝对需要在Windows(MinGW甚至Cygwin)下编译和运行

Jos*_*ose 0

IMO所有中断都可能被视为具有非常低延迟的线程(或基本线程),因此空闲线程是主线程,并且int线程可以抢占主线程但不能被抢占。

\n

所以基本上,目的是执行所有线程,直到满足其中一个 int 线程中的条件,当发生这种情况时,阻塞所有线程(一种临界区域,即互斥体条件变量)直到 int 线程完成它的工作。之后,再次执行所有线程(中断时间越短越好):

\n
void interrupt1_thd(void) {\n    // try_lock the mutex\n    // check the condition of this interrupt\n    // if true, do the job\n    // release the mutex if locked\n\n]\n
Run Code Online (Sandbox Code Playgroud)\n
\n

低端uC看起来很简单(即ATmega328P),没有嵌套中断,也没有优先级。对于更昂贵的 uC(让\xc2\xb4s 说是 ATSAMD51 Cortex M4),事情要复杂得多。现在,线程必须能够触发、阻止所有其他较低或相同优先级的线程,并且能够被较高优先级的线程阻止。基于优先级的线程并不是什么大问题(pthread_setschedparamSetThreadPriority),但是在没有死锁的线程中嵌套互斥体也不是小事,因此condition_variable由于通知的功能,这里更有意义:

\n
Event:                      Int1   Int3   Int2  Int3         Int3\nMain           : -----------                              ---              --------\nTask1 (mid)    :             -------------            ----\nTask2 (high)   :                          ----------\nTask3 (low)    :                                             --------------\nTake mutexLow  :            ---------- by 1 ---------        ---- by 3 ----\nTake mutexMid  :            ---------- by 1 ---------\nTake mutexHigh :                          -- by 2 --\n
Run Code Online (Sandbox Code Playgroud)\n

如果mutexHigh(由高优先级任务)执行,Task1Task3等待,直到Task2通知所有线程。

\n

如果mutexLow被采取(由低优先级任务,如任务3),Task3则执行其工作(包括检查更高的通知),同时Task1Task2检查其条件。

\n

我会避免在不同优先级之间共享资源,以免添加更多同步机制。

\n
\n

所有这一切都取决于您想要模拟的 Arduino 以及您想要达到的模拟级别,不确定您是否想要更深入并包括中断队列以最小化延迟、上下文切换……

\n