什么是微控制器上Modbus主站的正确非阻塞算法

时间:2016-04-21 01:09:01

标签: algorithm modbus

Modbus是一种请求和响应类型的串行通信。基本上主设备发出请求和一个从设备响应。

我正在修改微控制器上的代码,微控制器是modbus网络上的主单元。该装置还有一个小点阵液晶显示屏和一些用户界面按钮。微控制器以16MHz运行。

问题是主机发出请求后,它不知道从机响应的时间,所以可能需要等待相对较长的时间。然而,由于该单元具有按钮和LCD,因此用户在按下按钮时会感到滞后,因此不能在某个时间点等待。原始代码使用的是RTOS。它分离用户界面任务和串行通信任务,所以它没有问题。现在我需要将其更改为非RTOS代码。我已经实现了一个系统计时器,它将在每1ms中断。这样做的正确(或常见)方式是什么?

1 个答案:

答案 0 :(得分:1)

只需一个任务就可以做很多事情,特别是如果你有中断的话。单个非常简单的任务和RTOS之间的中间位置是循环执行程序。有关从循环执行到完全抢占式多任务操作系统的功能范围的简要概述,请参见http://www3.nd.edu/~cpoellab/teaching/cse40463/slides10.pdf。如果你搜索这个短语和相关的短语,你会发现更多,包括非常复杂的方案,以确保系统永远不会错过它的截止日期。如果您是飞机飞行控制系统,忘记每隔X毫秒检查一次飞机俯仰角会导致其他地方出现问题: - )

重写自然是多线程的代码的一种方法是维护系统状态的模型,例如每个表示modbus连接的对象集合,由连接id索引。然后为可能发生的每种事件编写一个例程,包括时钟中断的到来。当该事件发生时,这些例程通常会计算出涉及哪个连接,从主集合中检索它(或者从头创建它并在必要时输入它)执行与该特定类型的事件相关的工作,然后返回。

保持未来事件的队列(按时间编制索引)以及创建一个表示将来某些事情要执行的对象的例程通常很方便(例如调用方法来检查a的到期时间) timeout)并将此对象放在队列中。

您需要担心在事件服务例程中途调用中断处理。处理此问题的一种方法是在可能导致问题时锁定中断。另一种方法是让中断例程只是将一个对象放在队列中,以便以后检查其他东西,或者只是设置一个标志。然后,当您检查队列中的项目并将其删除时,您只需要锁定中断。

以这种方式实现了许多通信协议。即使在真正的多任务操作系统中,您通常也不希望每次需要创建新连接时都必须创建新线程。这个问题的两个主要问题是代码不如每个对象有一个线程的代码清晰,因为自然结合在一起的东西被切割成大量的事件服务事件,并且如果任何事件服务方法烧掉大量的cpu,系统将停止运行,因为在此过程中不会发生任何其他事情。