我目前遇到了一个问题,涉及使用任务调度程序的程序和使用延迟的任务。
任务正在运行以下代码:
// 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。
答案 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)