Arduino,任务调度程序延迟

Arduino, delay in a task scheduler

本文关键字:延迟 任务调度程序 Arduino      更新时间:2023-10-16

我目前遇到了一个问题,该问题涉及一个使用任务调度程序的程序和一个使用延迟的任务。

一个任务正在运行以下代码:

// Some function
delay(_speedVar);
// Some function
delay(_speedVar);
// End of task.

因为我有另一个任务,只是从UART轮询信息,所以设置_speedVar的值。

// Uart task
if(Serial.available())
{
  _speedVar = Serial.read();
}
// End of task

我的问题是,如果speedVar设置为一个高值,比如说10秒,那么执行某些功能并具有(_speedVar)延迟的任务需要以某种方式中断,并使用新的_speedVar值重新开始。

实际上,我使用的任务调度器没有灵活性。它只允许我创建和销毁任务。我还没有找到一个有更多功能的,而且可能有效的,所以我现在只能使用这个

解决方案的唯一想法是使用中断,但我不确定在使用任务调度程序时如何正确实现这一点。

所有编程都是使用Arduino的Sketch工具在C++中完成的。编程单元是Arduino Uno。

假设调度器是协作的,并且您发布的这些代码片段以某种方式在某个"大循环"中被调用,那么,大多数非琐碎的任务通常会作为状态机来实现。给定:

class cElapsedTime
{
    cElapsedTime()
    {
       zero() ; 
    }
    void zero()
    {
        timestamp = millis() ;
    }
    bool time()
    {
        return millis() - m_timestamp ;
    }
} ;
enum
{
    STATE_A,
    STATE_B
}  state = STATE_A;
cElapsedTime control_task_delay ;

然后在两种状态之间切换,以便在每个延迟周期之后执行不同的代码块。通过将经过的时间与_speedVar电流值连续比较,可以随时更改延迟。如果_speedVar从10秒变为5秒,并且经过的时间为7秒,则延迟代码将立即执行;如果时间延长,延迟也会延长:

if( control_task_delay.time() >= _speedVar )
{
    switch( state )
    {
        case STATE_A :
            // Some function
            control_task_delay.zero()      // Restart delay
            state = STATE_B ;              // Next state
        break ;
        case STATE_B :
            // Some function
            control_task_delay.zero()      // Restart delay
            state = STATE_A ;              // Next state
        break ;
    }
}

在您的代码片段中,不清楚第一个// Some function与第二个不同;也许// Some other function会澄清?然而,如果它们实际上是相同的,那么代码将简单地为:

if( control_task_delay.time() >= _speedVar )
{
    // Some function
    control_task_delay.zero()      // Restart delay
}

您可以看到,这与您在UART轮询任务中应用的原理相同——使用非阻塞测试。也就是说,也许在任何情况下都不需要单独的任务;你可以:

if( Serial.available() )
{
    _speedVar = Serial.read();
}
if( control_task_delay.time() >= _speedVar )
{
    switch( state )
    {
        case STATE_A :
            // Some function
            control_task_delay.zero()      // Restart delay
            state = STATE_B ;              // Next state
        break ;
        case STATE_B :
            // Some function
            control_task_delay.zero()      // Restart delay
            state = STATE_A ;              // Next state
        break ;
    }
}

在您的代码片段中,不清楚第一个// Some function与第二个不相同;也许// Some other function会澄清?然而,如果它们实际上是相同的,那么代码将简单地为:

if( control_task_delay.time() >= _speedVar )
{
    // Some function
    control_task_delay.zero()      // Restart delay
}
if( control_task_delay.time() >= _speedVar )
{
    switch( state )
    {
        case STATE_A :
            // Some function
            control_task_delay.zero()      // Restart delay
            state = STATE_B ;              // Next state
        break ;
        case STATE_B :
            // Some function
            control_task_delay.zero()      // Restart delay
            state = STATE_A ;              // Next state
        break ;
    }
}

在这种情况下,很难看到"调度器"实现了什么。

协作任务调度程序的任务不能包括延迟或阻塞IO操作。相反,你需要计算节拍来匹配你需要的时间(在arduino上,我想你可以使用http://arduino.cc/en/Reference/millis)