我有写事件和基于投票的嵌入式系统的经验(对于没有抢占操作系统的微控制器而言)。
在基于事件的系统中,任务通常在队列上接收事件(消息)并依次处理它们。
在基于调查的系统中,任务以一定的间隔轮询状态并响应更改。
你更喜欢哪种建筑?两者能共存吗?
最新情况:提出的要点
基于民意测验的
基于事件的
相关问题
* Looking for a comparison of different scheduling algorithms for a Finite State Machine (@embedded.kyle)
相关信息
*“更喜欢使用活动对象而不是裸线程”(@Miro)
http://www.drdobbs.com/parallel/prefer-using-active-objects-instead-of-n/225700095
*“正确使用线程=隔离+异步消息”(@Miro) http://www.drdobbs.com/parallel/use-threads-correctly-isolation-asynch/215900465
发布于 2012-09-07 07:47:06
在一个光秃秃的MCU平台上,真的没有“事件驱动”这样的东西,不管那些流行词的人想告诉你什么。你能收到的唯一真正的事件就是硬件中断。
根据应用程序的性质及其实时需求,中断可能合适也可能不合适。通常,使用轮询系统实现确定性实时要容易得多。但是,完全依赖轮询的系统很难维护,因为所有定时方面都会紧密耦合。
假设您尝试启动一个LCD,这是缓慢的。在空循环中燃烧CPU周期时,不需要反复轮询一些计时器,您可能会决定在此期间通过总线接收一些数据。然后在LCD上打印接收到的数据。这样的设计创造了LCD启动时间和串行总线之间的紧密耦合,以及串行总线和数据打印之间的另一个紧密耦合。从面向对象的角度来看,这些事情根本不相关。如果你在将来的某个时候加快串行总线的速度,那么突然你就会遇到液晶打印的错误,因为当你试图在它上打印时,它还没有启动。
在一个小程序中,像上面的例子一样使用轮询是非常好的。但是如果程序有增长的潜力,轮询将使它变得非常复杂,并且紧密的耦合最终会导致许多奇怪和致命的错误。
另一方面,多线程和实时操作系统增加了相当多的额外复杂性,这反过来也会导致错误。在哪里划线并不容易确定。
根据个人经验,除了简单的状态机之外,任何小于20-30k LOC的程序都不会从调度和多任务处理中获益。如果程序变得更大,我会考虑一个多任务的实时操作系统。
此外,低端MCU(8位和16位)也不适合运行操作系统.如果您发现需要一个操作系统来处理8位或16位平台上的复杂性,那么您可能一开始就选择了错误的MCU。我对任何试图在任何比32苦的小操作系统上引入操作系统的尝试都表示怀疑。
发布于 2012-09-17 22:05:01
实际上,事件驱动的编程和线程可以结合在一起,由此产生的模式被广泛称为“活动对象”或“参与者”。
活动对象(参与者)被封装,事件驱动的状态机,它们通过相互提交事件来异步通信。活动对象在它们自己的执行线程中处理所有事件(至少在概念上,如果使用协作调度程序),因此它们通过设计避免了大多数并发性风险。
在通用计算中,参与者和活动对象都非常流行(您可以搜索Erlang、Scala、Akka)。Herb写了几篇很好的文章来解释“活动对象”模式:“更喜欢使用活动对象而不是裸线程”(http://www.drdobbs.com/parallel/prefer-using-active-objects-instead-of-n/225700095)和“正确使用线程=隔离+异步消息”(http://www.drdobbs.com/parallel/use-threads-correctly-isolation-asynch/215900465)
赫伯在这些文章的第一篇中说:
“由于许多原因,直接使用原始线程是困难的……Active对象极大地提高了我们对线程代码和操作的推理能力,为我们提供了更高层次的抽象和成语,从而提高了程序的语义级别,并让我们更直接地表达了我们的意图。与所有好的模式一样,我们也获得了更好的词汇表来讨论我们的设计。注意,活动对象并不新鲜: UML和各种库都为活动类提供了支持”
所以,这一切并不新鲜。但是,也许鲜为人知的是,尤其是在嵌入式系统社区中,活动对象不仅完全适用于嵌入式系统,而且实际上是嵌入式系统的完美匹配,它们比传统的实时操作系统更轻。
我已经使用事件驱动的活动对象十多年了,并且已经为嵌入式系统创建了QP系列的活动对象框架(参见http://www.state-machine.com/)。我永远不会回到轮询“超级循环”或原始的RTOS。
发布于 2012-09-06 14:33:14
我更喜欢最适合当前应用程序的架构。
两者都可以在多级队列结构中共存。一个队列在主循环中运行的轮询基础上工作。而另一个,最可能的任务是更高优先级的事件,工作方式是使用基于中断的抢占。
有关不同调度算法的更详细解释和比较,请参见我对this SO question的回答。
https://stackoverflow.com/questions/12299125
复制相似问题