嵌入式系统 - 轮询
我有大约6个传感器(GPS,IMU等),我需要不断收集数据。出于我的目的,我需要从每个(在很短的时间范围内)读取一个完整的数据包。现在我正在使用中断,但是这会导致来自某些传感器的更多数据,而且如前所述,我需要将数据匹配起来。嵌入式系统 - 轮询
移动到基于轮询的系统中,我可以按设定的顺序轮询每个传感器吗?这样我可以从每个“周期”的每个传感器获取数据。
但是,我担心轮询的速度,因为这个系统需要接近实时运行。
轮询结合“主定时器中断”可能是你的朋友在这里。假设您的“最慢”传感器可以提供20ms间隔的数据,并且可以更快地读取其他数据。这是50更新每秒。如果这个距离足够接近实时(可能对于IMU是近距离的),那么你可能会这样做:
- 设置一个20ms定时器。
-
当计时器熄灭,设置一个标志中断服务程序中:
volatile uint8_t timerFlag = 0; ISR(TIMER_ISR_whatever) { timerFlag = 1; // nothing but a semaphore for later... }
-
然后,在你的主循环行为时
timerFlag
说,它的时间:while(1) { if(timerFlag == 1) { <read first device> <read second device> <you get the idea ;) > timerflag = 0; } }
通过这种方式,您可以读取每个设备并保持其读数同步。这是解决嵌入式空间中这个问题的典型方法。现在,如果你需要的数据速度超过20ms,那么你缩短了计时器等等。像这样的情况下,最大的问题是“你能轮询多快”与“你需要轮询多快”。 “只有实验并了解各种设备的特性和时间才能告诉你。但是,当所有时机“合适”时,我提出的是一个通用解决方案。
编辑,采用不同的方法
更基于中断的例子:
volatile uint8_t device1Read = 0;
volatile uint8_t device2Read = 0;
etc...
ISR(device 1)
{
<read device>
device1Read = 1;
}
ISR(device 2)
{
<read device>
device2Read = 1;
}
etc...
// main loop
while(1)
{
if(device1Read == 1 && device2Read == 1 && etc...)
{
//< do something with your "packet" of data>
device1Read = 0;
device2Read = 0;
etc...
}
}
在这个例子中,你的所有设备可以中断驱动,但主循环处理仍然是制约,由最慢的中断节奏来调节。无论速度或延迟如何,均可使用每个设备的最新完整读数。这种模式更接近您的想法吗?
@Clifford确实。在这样的情况下,我所做的是外围设备采样速率大不相同的情况,就是使用计数器“减速”timerFlag。平衡机器人的IMU可能需要50次更新/秒才能保持直立,而GPS只能轮询50次。 – TomServo
这就是为什么我不喜欢投票。使用这种方法,您必须计算所有传感器组合的数据处理延迟,并确保第一个轮询间隔不超过20ms(作为示例)。只要您将来添加新的传感器,或者传感器在数据处理或轮询间隔方面发生变化,您的所有环路方案就会陷入瘫痪,变得完全不可维护且不可扩展。 – Alex
@亚历克斯同意。我更喜欢在可能的情况下中断。然而,OP的问题是关于投票的问题,事实是,有可能这样做。 OP可能没有兴趣在这里扩展任何东西,只是一次性的解决方案。因此,无需判断我用可能的解决方案回答了她的问题。 – TomServo
轮询是一个相当不错的,容易实现的想法,以防您的传感器可以(你期望的输出频率比较)提供的数据几乎瞬间。如果数据源需要大量(甚至可变)时间来提供读数或需要异步“启动/收集”循环,它确实会陷入恶梦。您必须对轮询周期进行排序以适应“最慢”数据源。
如果您知道每个数据源的平均“数据转换率”,可以采用什么方法来设置多个定时器(每个数据源),这些定时器在poll time - data conversion rate
处触发,并从这些数据源中启动测量定时器ISR。然后在poll timer + some safety margin
上触发最后一个计时器,收集所有转换结果。另一方面,只要你没有任何合理的处理浪费的CPU/CPU资源,你从“快速”数据源中看到的“有太多测量结果”的明显问题就不会对我造成太大的影响,传感器负载。
如果您有一些浪费的周期,最后一个更简单的方法是:简单地将数据源从“最慢”排序到“最快”,然后按照该顺序开始测量,然后等待结果以相同顺序和民意调查。
嗯!?轮询和中断混合。我喜欢。好的方法,将牢记在心。 – Alex
所以问题是...?测试你的投票循环时间,看看它是否符合你的要求... – LPs
我个人不喜欢投票。你的传感器没有中断吗? – Alex
既不仅仅是轮询,也不是中断只与实时有关,你必须做你的系统工程,这会给出所有的答案。轮询当然是最容易的,你可以确定每条事件路径的时间,只要最慢的一条不干扰其他条件的要求,你就很好。有时候你可以只通过轮询来做到这一点,或者只能打断它,但可能会在中间的某个地方结束。中断并不意味着你在那里处理它们,有时候不好,所以没有人回答。 –