我有一个运行在Linux上的小程序(在embedded式PC上,双核Intel Atom 1.6GHz,运行Linux 2.6.32-5的Debian 6),它通过一个FTDI USB转串口转换器与外部硬件通信(使用ftdi_sio
内核模块和一个/dev/ttyUSB*
设备)。 本质上,在我的主循环运行
clock_gettime()
使用CLOCK_MONOTONIC
select()
,超时时间为8毫秒 clock_gettime()
像以前一样 clock_gettime()
调用的时间差 为了具有某种“软”实时保证级别,该线程以最高优先级(最高显示为“RT”)的forms作为SCHED_FIFO
运行。 它是系统中唯一以此优先级运行的线程,没有其他进程具有这种优先级。 我的进程有另外一个SCHED_FIFO
线程,优先级较低,而其他所有线程都在SCHED_OTHER
。 两个“实时”线程不受CPU限制,除了等待I / O和传递数据之外,没有什么限制。
我正在使用的内核没有RT_PREEMPT补丁(我将来可能会切换到该补丁)。 我知道,如果我想要“适当的”实时,我需要切换到RT_PREEMPT,或者更好,Xenomai或类似的。 但是,我想知道在“香草”内核的下列时间exception之后是什么:
select()
调用的大约0.03%定时超过10毫秒(请记住,超时为8毫秒)。 cron.daily
正在执行)。 所以,我的问题是:在这种极端情况下可能涉及哪些因素? 这只是在Linux内核本身内部发生的事情,也就是说,我必须切换到RT_PREEMPT,还是非USB接口和Xenomai,才能获得更可靠的保证? 可以/proc/sys/kernel/sched_rt_runtime_us
咬我吗? 还有其他因素我可能错过了吗?
另一种解决这个问题的方法是,我还能做些什么来减less这些延迟exception, 而不必切换到“更难”的实时环境?
更新 :我观察到一个约118.4毫秒的新“最糟糕的情况”(一次总计约2500万次select()
调用)。 即使我没有使用任何types的实时扩展内核,我也有些担心,截止date可能会在十分之一秒内被忽略。
没有更多的信息,很难指出具体的东西,所以我只是在这里猜测:
对于1.6GHz的CPU来说,118ms似乎相当多。 但是一个意外锁定CPU一段时间的驱动就足够了。 如果可以,请尝试禁用某些驱动程序或使用不同的驱动程序/硬件组合。
sched_rt_period_us
和sched_rt_period_us
设置为合理的值,并且您的代码按照您的预期sched_rt_period_us
, sched_rt_period_us
应该是个问题。 不过,我会删除RT线程的限制,看看会发生什么。
你还能做什么? 写一个设备驱动程序! 这并不难,中断处理程序比实时线程获得更高的优先级。 切换到实时内核可能更容易,但YMMV。