想要确保 tty 写入按给定时间戳推送到硬件(UART)或失败
我需要将一些数据写入串行端口,同时确保如果无法通过给定的“到期时间戳”写入数据,它将返回失败代码。数据来自不同的串行端口,到期时间来自第三个设备。
我最初的计划是在内核空间中实现所有这些,但我得出的结论是,由于它需要访问 3 个设备,因此最好在用户空间中桥接它们;不幸的是,这使得时机变得困难。
尽管花费了大量时间阅读 LDD3 并查看 tty 子系统和相关代码,但我在解决如何实现这一目标时遇到了困难。我实际上想向现有的串行端口/tty 设备添加功能,以便我可以使用 ioctl 或编写指示数据和到期时间的转义序列。
我在这里可以控制内核源代码,因为它已经被分发了,如果我可以仅使用内核模块来实现这一点,那就太好了。如果重新刷新内核是必要的,那就这样吧。
任何人都可以提供有关将此过期写入添加到现有串行/tty组合的指导,或者关于什么可能是更好的方法来解决此问题的其他建议吗?
提前致谢 - 如果信息不够,我们深表歉意,如果需要,我会添加详细信息。
I need to write some data to a serial port whilst ensuring that if it can't be written by a given 'expiry timestamp' that it will return failure code. The data comes from a different serial port, and the expiry time from a 3rd device.
My original plan was to implement all of this in kernelspace, but I concluded that since it needs access to 3 devices it'd probably be better to bridge them in userspace; that unfortunately makes the timing difficult.
Despite spending some significant time reading LDD3 and looking through tty subsystem and related code, I'm having trouble working out how to achieve this. I effectively want to add functionality to an existing serial port/tty device so that I can use ioctl or write an escape sequence indicating the data and expiry time.
I have control over the kernel source here, though since it's already been distributed if I can achieve this solely with a kernel module that would be superb. If reflashing the kernel is essential then so be it.
Can anyone provide either guidance on adding this expiring-write to existing serial/tty combination, or other advice on what might be a better way to go about this?
Thanks in advance - apologies if not enough info, I'll add details if they're required.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我建议完全在用户空间中执行此操作。这背后有两个假设:没有流量控制,并且所需的精度约为 50 毫秒或更差。
缺乏流量控制至关重要:硬件流量控制可能会导致恶意远程设备通过延迟 UART FIFO 中的字节来欺骗您。软件流控制可以阻止设备驱动程序中的数据。完成此操作后,数据将以所需的波特率毫无延迟地流过 UART。如果您确保在每次写入设备之前内核缓冲区为空,您将实现您的计时。
我的解决方案的组成部分是:
SCHED_FIFO
运行应用程序以避免抢占。tcdrain
。要处理其他端口,您需要使用多个线程或带有超时的
select
。如果您使用select
,请记住您的线程将在tcdrain
中被阻塞。如果您需要更精确的计时,请考虑使用专用微控制器。
I propose doing this entirely in userspace. There are two assumptions behind this: you don't have flow control, and the precision required is around 50ms or worse.
The lack of flow control is essential: hardware flow control can allow a hostile remote device to cheat you, by stalling bytes within the UART FIFO. Software flow control can stall data in the device driver. With that out of the way, data will flow through the UART at the required baud rate without delay. If you ensure that the kernel buffers are empty before each write to the device, you will achieve your timing.
The parts of my solution are:
SCHED_FIFO
to avoid pre-emption.tcdrain
before writing.To handle the other ports you'll need to use multiple threads or
select
with timeouts. If you useselect
, remember that your thread will be blocked intcdrain
.And if you need much more precise timing consider using a dedicated microcontroller.