我有一个在我的PCB上运行Linux的imx8模块,我想要一些关于如何修改UART驱动程序的提示或提示,这样我就能够非常快地从我的用户空间C应用程序中检测到帧的结束(小于2ms)。UART帧没有任何特定的结束字符或帧长度。100 is的标准VTIME太长了
我是从Sim卡上读取的,我对数据没有控制,对数据的大小或内容也没有控制。我只需要非常快地检测到帧的末端。帧可以是3个字节或500个字节。SIM卡对它接收到的数据作出反应,通常我会向它发送几个字节,然后它会用一个不间断的字节字符串来响应几毫秒的未知长度。我使用的是iMX8MP
我想过使用空闲中断来检测帧结束。当接收到任何字节时,打开它,并在空闲中断触发时关闭它。如何将此信号传播回用户空间?或者,是否有一种现有的方法来做到这一点?
发布于 2022-06-08 01:29:48
等待“空闲”是一种很糟糕的方法。
使用termios设置原始模式,VTIME为0,VMIN为1。这将允许用户空间应用程序在单个字节到达后立即获得控制。请参见:
但是,您需要某种“协议”,这样您就可以知道要读取多少才能得到完整的数据包。在所有数据的前面加上一个包含(例如)的结构类型和有效载荷长度。然后,发送“有效负载长度”字节。接收方获取/读取固定长度的结构,然后读取“有效负载长度”字节长的有效载荷。这个结构总是发送(两个方向)。
参见我的回答:thread function doesn't terminate until Enter is pressed作为一个有用的例子。
您所拥有/需要的类似于使用流套接字进行套接字编程,只不过较低级别是UART而不是实际的套接字。
我的示例代码使用套接字,但是如果您在原始模式(如上)中更改低级别打开您的uart,它将非常类似。
更新:
,在帧完成后,我会以多快的速度获得应用程序级别的数据?当我尝试读取当前以512字节块读取的随机长度帧时,它有时会一次读取所有帧,而另一些时候它会将帧读成块。- Engo
在我的链接中,在最后一个代码块中,有一个xrecv函数。它展示了如何读取以块形式出现的部分数据。
这就是你需要做的。
你的职位上丢失的东西:
imx8板/配置。以及,您拥有哪种SIM卡(协议是特定于卡的)。uart设备没有“空闲”中断。从某些imx8文档中,DMA设备可能有一个“空闲”中断,uart可以由DMA控制器驱动。
但是,我查看了一些linux内核imx8设备驱动程序,并且不支持空闲中断。
,我需要一次读取所有数据,并在几百微秒内得到这些数据。
基于调度粒度,可能无法保证一个进程在给定的时间内运行。
有可能对此有所帮助。您可以更改进程以使用R/T调度程序(例如,SCHED_FIFO)。此外,您还可以使用sched_setaffinity将进程锁定到给定的CPU核心。有一个相应的调用来锁定IRQ中断到给定的CPU核心。
我假设SIM卡的作用就像被动设备(如磁盘)。也就是说,您向它发送一个命令,它将返回一个响应或执行一个传输。
根据您给出的命令,您应该知道它将发送多少字节。或者,它应该告诉您它将发送多少个可选字节(类似于我链接中的struct )。
你所描述的方法(例如)等待空闲,然后“比赛”来获取/处理那些你不知道长度充满问题的数据。
即使你能让它开始工作,它也是不可靠的。在某种程度上,系统活动将足够高,以延迟唤醒您的进程,您将错过窗口。
如果你正在读取数据,为什么你必须在一个固定的时间内处理这些数据(例如100美元)?如果你不去怎么办?这个装置着火了吗?
如果没有更具体的信息,可能还有其他方法可以做到这一点。
在此之前,我已经对这样的系统进行了编程,它依赖于数据竞赛。他们不可靠。要么丢失数据。或者,对于一些电机控制应用,设备锁定。补救办法是重新设计一些东西,以便有一些积极/明确的沟通方式来容忍拖延。
否则,我认为你“爱上”了“空闲中断”的想法,使这成为一个XY问题:https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem
https://stackoverflow.com/questions/72538067
复制相似问题