如何安排绝对开始时间的实时任务?

时间:2019-01-17 17:15:50

标签: pthreads real-time linux-rt

对于可识别TSN的通信协议栈和框架,我不仅需要能够以非常精确的时间间隔运行实时线程,而且还能以从ptpd减去的精确时隙开始实时线程。

目前,我是通过将任务延迟/放弃直到开始时间来做到这一点的。对于我的TSN通信的PoC,这已经足够了,但是对于Linux实时扩展,必须有一种更好/更有效的方法。引入的抖动约为两个Beaglebones(运行Linux 4.14.71-ti-r80#1 SMP PREEMPT)之间的800us。

使用循环pthread,我同步了网络生产者任务的开始(注意:vos_前缀表示我的OS抽象方法,实际上与POSIX调用匹配):

for (;; )
{
    /* Synchronize with starttime */
    vos_getTime(&now);                      /* get initial time */
    vos_subTime(&now, &startTime);

    /* Wait for multiples of interval */

    execTime = ((UINT32)now.tv_usec % interval);
    waitingTime = interval - execTime;
    if (waitingTime >= interval)
    {
        ...error checks omitted
    }

    /* Idle for the difference */
    vos_threadDelay(waitingTime); /* pthread_testcancel() inside */

    vos_getTime(&priorCall);  /* get initial time */
    pFunction(pArguments);    /* thread function: send data */
    vos_getTime(&afterCall);  /* get time after function has returned */

    /* get the runtime of pFunction() */
    vos_subTime(&afterCall, &priorCall);

    /* afterCall holds now the time difference... */
    if (afterCall.tv_sec <= MAXSEC_FOR_USECPRESENTATION)
    {
        ...runtime / error handling omitted
    }
}

上面的代码在5毫秒的间隔时间(使用不带RT扩展和策略循环的Linux 4.14)上产生约800us的抖动,这是相当不错的-但是当涉及到多个线程都执行计划的流量时,它是无效的。 ..

对于Linux 4.1.15-ti-rt-r43#1 SMP PREEMPT RT,我计划将SCHED_DEADLINE作为策略使用,但是struct sched_attr不提供启动时间参数。然后,不需要在上面的代码中进行运行时检查。但是:

我如何有效地使用Linux的实时扩展以使线程在确切的绝对时间运行,例如,以绝对实时“ now” + 0.0075s(例如now.0085,now.0095, now.0105 ...),没有上面代码的开销?

1 个答案:

答案 0 :(得分:0)

SizedBox( width: 250.0, child: TypewriterAnimatedTextKit( onTap: () { print("Tap Event"); }, text: [ "Discipline is the best tool", "Design first, then code", "Do not patch bugs out, rewrite them", "Do not test bugs out, design them out", ], textStyle: TextStyle( fontSize: 30.0, fontFamily: "Agne" ), ), ); POSIX函数具有绝对截止日期模式:

>>> def z(x):
...     return (x**3)/(exp(x)-1)
...
>>> z(709)
4.336616682334302e-300
>>> z(710)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in z
OverflowError: math range error