嵌入式系统 - 轮询

问题描述:

我有大约6个传感器(GPS,IMU等),我需要不断收集数据。出于我的目的,我需要从每个(在很短的时间范围内)读取一个完整的数据包。现在我正在使用中断,但是这会导致来自某些传感器的更多数据,而且如前所述,我需要将数据匹配起来。嵌入式系统 - 轮询

移动到基于轮询的系统中,我可以按设定的顺序轮询每个传感器吗?这样我可以从每个“周期”的每个传感器获取数据。

但是,我担心轮询的速度,因为这个系统需要接近实时运行。

+3

所以问题是...?测试你的投票循环时间,看看它是否符合你的要求... – LPs

+0

我个人不喜欢投票。你的传感器没有中断吗? – Alex

+0

既不仅仅是轮询,也不是中断只与实时有关,你必须做你的系统工程,这会给出所有的答案。轮询当然是最容易的,你可以确定每条事件路径的时间,只要最慢的一条不干扰其他条件的要求,你就很好。有时候你可以只通过轮询来做到这一点,或者只能打断它,但可能会在中间的某个地方结束。中断并不意味着你在那里处理它们,有时候不好,所以没有人回答。 –

轮询结合“主定时器中断”可能是你的朋友在这里。假设您的“最慢”传感器可以提供20ms间隔的数据,并且可以更快地读取其他数据。这是50更新每秒。如果这个距离足够接近实时(可能对于IMU是近距离的),那么你可能会这样做:

  1. 设置一个20ms定时器。
  2. 当计时器熄灭,设置一个标志中断服务程序中:

    volatile uint8_t timerFlag = 0; 
    
    ISR(TIMER_ISR_whatever) 
    { 
        timerFlag = 1; // nothing but a semaphore for later... 
    } 
    
  3. 然后,在你的主循环行为时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... 
    } 
} 

在这个例子中,你的所有设备可以中断驱动,但主循环处理仍然是制约,由最慢的中断节奏来调节。无论速度或延迟如何,均可使用每个设备的最新完整读数。这种模式更接近您的想法吗?

+1

@Clifford确实。在这样的情况下,我所做的是外围设备采样速率大不相同的情况,就是使用计数器“减速”timerFlag。平衡机器人的IMU可能需要50次更新/秒才能保持直立,而GPS只能轮询50次。 – TomServo

+1

这就是为什么我不喜欢投票。使用这种方法,您必须计算所有传感器组合的数据处理延迟,并确保第一个轮询间隔不超过20ms(作为示例)。只要您将来添加新的传感器,或者传感器在数据处理或轮询间隔方面发生变化,您的所有环路方案就会陷入瘫痪,变得完全不可维护且不可扩展。 – Alex

+1

@亚历克斯同意。我更喜欢在可能的情况下中断。然而,OP的问题是关于投票的问题,事实是,有可能这样做。 OP可能没有兴趣在这里扩展任何东西,只是一次性的解决方案。因此,无需判断我用可能的解决方案回答了她的问题。 – TomServo

轮询是一个相当不错的,容易实现的想法,以防您的传感器可以(你期望的输出频率比较)提供的数据几乎瞬间。如果数据源需要大量(甚至可变)时间来提供读数或需要异步“启动/收集”循环,它确实会陷入恶梦。您必须对轮询周期进行排序以适应“最慢”数据源。

如果您知道每个数据源的平均“数据转换率”,可以采用什么方法来设置多个定时器(每个数据源),这些定时器在poll time - data conversion rate处触发,并从这些数据源中启动测量定时器ISR。然后在poll timer + some safety margin上触发最后一个计时器,收集所有转换结果。另一方面,只要你没有任何合理的处理浪费的CPU/CPU资源,你从“快速”数据源中看到的“有太多测量结果”的明显问题就不会对我造成太大的影响,传感器负载。

如果您有一些浪费的周期,最后一个更简单的方法是:简单地将数据源从“最慢”排序到“最快”,然后按照该顺序开始测量,然后等待结果以相同顺序和民意调查。

+0

嗯!?轮询和中断混合。我喜欢。好的方法,将牢记在心。 – Alex