通过轮询以一定间隔执行代码

时间:2016-08-24 22:38:11

标签: c++ embedded

我尝试在具有有限库函数的嵌入式设备上实现C ++中的周期性事件。我不能使用睡眠或其他延迟,因为它会停止当前的执行。

例如。

do
{
    if(something)
    {
       //Do something
    }

    if(something)
    {
       //Do something
    }

    if(every 5 minutes)
    {
       //Do something only once after 5 minutes
    }
}
while(true)

我不知道该如何解决这个问题。你可以帮我解决这个问题,因为我需要在这个while循环中实现这个吗?我会使用线程,但在这个设备上并不可能,所以我正在寻找另一种方式。

2 个答案:

答案 0 :(得分:3)

当然,建议产生一个单独的线程(我会做的)或使用评论中给出的alarm()是很好的建议,但可能无法在您的设备上使用。但是,专注于您当前的方法,通常的想法是,伪代码:

last action time = current time

while (true) {
   do things.
   if current time - last action time >= 5 minutes then
       perform action
       last action time = current time
       // or last action time += 5 minutes if you want to mitigate drift
   end
}

所以现在你只需要选择自己喜欢的方式来获取当前时间。在桌面平台上,您可以使用例如一些嵌入式平台也可以提供这些内容,time()gettimeofday()GetTickCount()在Windows上等。但是,这可能会有问题:

由于您在评论中提到您正在使用嵌入式设备,"您最喜欢的方式来获取当前时间"将根据平台而有所不同,您只需检查设备文档即可。如果您很幸运,您的MCU可能会提供一种查询CPU计数器的方法,以及您通常从设置中知道的频率。但它可能没有。

如果没有,另一种选择是您的设备提供板载定时器。在这种情况下,您可以配置它并响应周期性中断,在这种情况下,您的两个选项通常是:

  1. 在定时器中断处理程序中执行操作 - 但只有在执行此操作时才执行此操作,并且您采取了适当的中断安全措施。
  2. 在定时器中断处理程序中设置volatile标志,检查主循环中的该标志并执行操作+如果设置了则重置该标志。这通常是一种更简单的方法。
  3. 这样做在架构上与使用alarm()类似。但是,确实存在实现time()和/或gettimeofday()的嵌入式平台。但那些是你的选择。

答案 1 :(得分:0)

这听起来像是在寻找两种不同的功能;一,在不中断执行的情况下发送命令;二,等待一定的时间。首先,您正在寻找异步编程。对于第二个,我建议Boost::io_service。要结合这两者,请查看private void button6_Click(object sender, EventArgs e) { GetNumber gtn = new GetNumber(); gtn.Show(); System.Timers.Timer timer = new Timer(6000); timer.Elapsed += (_, _2) => { Invoke((MethodInvoker)delegate { gtn.Close(); }); }; timer.Start(); } ,这将允许您在使用或不使用计时器的情况下注册异步回调。