Arduino,延迟任务调度程序

时间:2014-04-26 14:59:56

标签: c++ arduino embedded interrupt scheduler

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

任务正在运行以下代码:

// 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。

2 个答案:

答案 0 :(得分:2)

假设调度程序是协作的,并且您发布的这些代码片段在某种“大循环”中以某种方式被调用,那么,大多数非平凡的任务通常将被实现为状态机。给出:

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 } 会澄清?但是,如果它们实际上是相同的,那么代码就是:

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 ;
    }
}

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

// 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 ; } } 不同;也许{{1}}会澄清?但是,如果它们实际上是相同的,那么代码就是:

{{1}}

很难看出“调度程序”在这种情况下实现了什么。

答案 1 :(得分:0)

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