我有一个实验盒,每100毫秒左右运行一次,将在TTL线上吐出4微秒长的+ 5V电脉冲。提前知道发生这种情况的确切时间,但这很重要-因此,我想使用本质上运行实验的Red Hat 5.3计算机为TTL提供服务,并创建精美的时间戳。
此刻,我完成的工作是将TTL连接到STATUS_SELECT
linux机器上并行端口(并行端口上的输入线之一)的针脚13中,在实验开始时产生一个进程,用于chrt
更改其预定时间优先级99
(即高),然后以while
循环方式反复轮询并行端口,直到引脚变高。然后,我创建一个准确的时间戳,并以非阻塞方式将其写入磁盘。
显然,这是低效率的-有时该过程被挂起,并且会丢失TTL。由于计算机本身正忙于做其他事情(即从我的实验套件MRI扫描仪中获取数据!),这种情况经常发生。轮询很容易,但可能很糟糕。
我的问题是:当TTL出现时快速执行操作似乎是计算的基础,但据我所知,只有在您是内核模块的情况下,才有可能在Linux上处理中断。并行端口可以生成中断,并且像paraport这样的库可以让您相对快速地构建内核模块,而您必须在其中提供自己的处理程序。
这是处理此问题并为每次TTL创建准确的实验创建准确(±25 ms)时间戳的最佳方法-编写内核模块以提供/ proc中某个位置的最近中断列表,然后读取它们以后可以正常处理吗?这种方法是否行不通,并且CPU效率很低?或者打开一袋蠕虫来处理我不知道的中断优先级?
最重要的是,这似乎应该是一个已解决的问题-是的,如果是的话,那么明智的人希望向我指出正确的方向吗?坦率地说,编写内核模块对于看起来似乎应该很简单的事情来说似乎是很多艰苦而冒险的工作。
“只有在您是内核模块的情况下,才可能在Linux上处理中断”的前提消除了一些相当普遍且有效的策略。
响应用户空间中的中断(特别是很少发生的中断)的简单操作是拥有一个驱动程序,该驱动程序创建了一个内核设备(或在某些情况下为sysfs节点),在该设备中,用户空间中的read()或自定义ioctl()将会阻止直到发生中断。您必须检查默认的并行端口驱动程序是否支持此功能,但这在嵌入式板卡上的GPIO驱动程序中极为常见,并且可以将基本方案借用到并行端口中-如果硬件支持真正的中断。
如果目标是非常精确的计时,则最好自定义内核模块以记录在那里的时间戳,并实现一种机制,其中从用户空间阻止read()直到发生中断,然后获取内核已记录的时间戳作为读取数据-从而避免唤醒用户空间和回叫内核以获得时间的可变延迟。
如果可用的并行端口是不支持它们的部分或间接实现,那么您也可以将真正的本地总线串行端口(如果存在)视为具有备用中断功能的接口。
在您唯一可用的接口是诸如USB之类的间接且高延迟的接口的情况下,或者您想要大量独立于主机和操作系统的接口时,使用外部微控制器确实很有意义。在这种情况下,您可能会尝试从主机系统设置微型时钟,然后在每次看到事件时都向其提供时间戳消息。如果您的实验只需要在给定的实验时段内将时间戳记彼此相对,那么这应该很好。但是,如果您需要在USB延迟之间建立绝对时间同步,则可能必须进行一些仔细的往返测量,然后估算延迟以补偿延迟(有关极端示例,请参见NTP)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句