用于同步数据采集的硬件中断

时间:2013-07-01 23:43:46

标签: python linux hardware-interface

我正在寻找一种使用外部TTL脉冲触发数据采集软件的简单方法。我需要与5 Hz参考时钟同步采样来自多个源的数据。此次采集不需要实时优先级,但我希望确保尽快触发我的软件,并确保每个外部时钟周期恰好触发一次。我宁愿通过某种方式从外部触发器获取中断而不需要使用快速轮询循环。据我所知,在Linux等现代操作系统中,不能只使用并行端口引脚作为中断。有什么想法吗?

我还想在我的网络上生成广播数据包,以通知网络上的其他机器发生了触发事件。然而,由于网络延迟,在触发之间的200ms周期内可能没有足够的时间来进行采集。

4 个答案:

答案 0 :(得分:8)

您考虑使用串行设备而不是使用并行端口吗?由于你有一个TTL信号,你可能需要一个电平转换器将TTL转换为RS232 +/- 12V电平。使用串行设备后,您可以使用标准串行ioctl()调用来检测控制信号状态的变化。

具体来说,您可以使用连接的串行设备上的TIOCMIWAIT ioctl来等待DCD线路上的更改,您将连接到时钟源。

您的用户空间应用程序将在TIOCMIWAIT ioctl系统调用中等待,直到您的时钟线上的状态发生更改,此时您的应用程序将变为可运行并从ioctl返回。您可能必须注意确保处理在串行控制信号的上升沿和下降沿上更改状态中断的情况。在某些UART硬件(例如TL16C554A UART)上,您可能只会获得单向转换信号的中断。例如,对于TL16C554A,TIOCMIWAIT只会在任何Ring指示信号变化的上升沿下降。

以这种方式使用串行ioctls还有一个优点,即如果需要,您可以使用支持TIOCMIWAIT的USB串行加密狗(例如PL2303),并且仍然保留用户级软件兼容性,尽管代价是由USB引起的延迟增加。

如果您需要的延迟低于通过用户空间可以实现的延迟,那么您最好编写一个可以处理时序和采样的内核驱动程序模块,但除非绝对需要,否则我不建议使用此路由。开发用户空间代码更容易。

以下是使用TIOCMIWAIT ioctl的一些不完整的示例C代码段。

int serial_fd = open(cmdline.device_name, O_RDWR | O_NONBLOCK | O_NOCTTY);
static const unsigned int ri_flag = TIOCM_RNG;

/* Set up serial port here using tcsetattr.  Set CRTSCTS | CLOCAL to ensure status interrupts
 * are generated.
 */

while (1) {
        /* Wait for positive RI transition.  TIOCMIWAIT takes a mask
         * as argument, only returning when the appropriate signal has changed.
         */
        if (ioctl(serial_fd, TIOCMIWAIT, ri_flag)) {
            fprintf(stderr, "ioctl() failed waiting for RI edge [%s]\n", strerror(errno));
            break;
        }

        /* Do sensor sampling here.  You could use TIOCMGET to first verify that
         * the clock line is in the expected state, eg high, before continuing.
         */
}

答案 1 :(得分:3)

对于如此慢的数据速率,轮询是一种很好的方法。轮询时间为1毫秒。那应该没问题。试图使用硬件中断会造成很大的痛苦。

谷歌的“中断Linux GPIO”,如果你想这么做的话。 :)

https://developer.ridgerun.com/wiki/index.php/How_to_use_GPIO_signals

答案 2 :(得分:2)

我最终使用串行端口CTS线路进行触发,使用每个Austin Phillips答案的TIOCMIWAIT ioctl。由于RS232需要+/- 12V电平,我能够从其他串行控制线获得该电平转换器所需的电源。

Level shifter schematic

可以找到实现此解决方案的Python代码:Python monitor serial port (RS-232) handshake signals

答案 3 :(得分:2)

考虑将外部脉冲源连接到真实(不是USB转RS232转换器)串行端口的“CD”ping。然后你可以使用“PPS api”获得一个确切的时间戳,引脚“尽可能高”。

你可能需要一个TTL信号移位器;并非所有串口都可以正常使用TTL信号电平。

PPS api通常用于计时。例如。将GPS模块的PPS引脚连接到您的电脑,让NTP与之同步。这为您提供了微秒精度。

这个PPS api应该比任何其他用户空间解决方案(例如TIOCMIWAIT ioctl)更准确,因为它在内核中完全处理,当中断(由CD信号改变触发)进入时。 ioctl解决方案至少有一个上下文切换。我对覆盆子pi进行了一些测试,用户空间解决方案至少提供了6us的抖动。

PPS api为您提供检测脉冲时的时间戳。

为什么不使用USB转RS232转换器:我在某处(与计时有关)读取USB设备每+/- 1ms轮询一次。此轮询频率还取决于系统与其他USB设备的繁忙程度,我认为USB设备的内部时钟也可能影响事物。我从来没有测过这个。

相关网址:

关于网络功能:使用UDP广播,不要使用TCP。