Linux UART IMX8如何快速检测框架端?

发布于 2025-02-05 04:18:30 字数 356 浏览 3 评论 0 原文

我的PCB上有一个运行Linux的IMX8模块,我想了解如何修改UART驱动程序以允许我能够从我的用户空间C应用程序中非常快速(小于2ms)检测帧的末端(小于2ms)的提示或指示。 。 UART框架没有任何特定的结尾字符或框架长度。 我从SIM卡中读取的标准VTime 100ms太长了

,我无法控制数据,无法控制数据的大小或内容。我只需要很快地检测框架的末端即可。帧可以是3个字节或500个。SIM卡对收到的数据反应,通常我将其发送几个字节,然后在几个MS之后响应几个MS,并带有一个未知长度的字符串。我正在使用IMX8MP,

我考虑使用空闲中断来检测框架端。在接收到任何字节时打开它,一旦闲置中断开火,就会关闭。如何将此信号传播回用户空间?还是现有的方法可以这样做?

I have an imx8 module running Linux on my PCB and i would like some tips or pointers on how to modify the UART driver to allow me to be able to detect the end of frame very quickly (less than 2ms) from my user space C application. The UART frame does not have any specific ending character or frame length. The standard VTIME of 100ms is much too long

I am reading from a Sim card, i have no control over the data, no control over the size or content of the data. I just need to detect the end of frame very quickly. The frame could be 3 bytes or 500. The SIM card reacts to data that it receives, typically I send it a couple of bytes and then it will respond a couple of ms later with an uninterrupted string of bytes of unknown length. I am using an iMX8MP

I thought about using the IDLE interrupt to detect the frame end. Turn it on when any byte is received and off once the idle interrupt fires. How can I propagate this signal back to user space? Or is there an existing method to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

許願樹丅啲祈禱 2025-02-12 04:18:30

等待“闲置”是一种糟糕的方法。

使用 termios 使用0和 vtime of 0和 vmin 1的原始模式。这将允许用户空间应用在单个单一时立即获得控制字节到达。请参阅:

  1. 如何用中断的序列方式读取?
  2. 如何做我使用termios.h来配置串行端口以传递原始字节?
  3. 如何使用.net core在Linux上以.NET Core 打开TTY设备

但是,您需要一种“协议”,因此您可以知道要阅读多少以获取完整的数据包。您将所有数据都带有具有(例如)类型和有效载荷长度的结构。然后,您发送“有效载荷长度”字节。接收器获取/读取固定长度结构的固定,然后读取有效载荷,即“有效载荷长度”字节长。此结构是始终发送的(在中,两个方向)。

请参阅我的答案:用于工作示例。

您所拥有的/需要类似于使用流插座进行套接字编程,只是较低级别是UART而不是实际的套接字。

我的示例代码使用插座,但是如果将低级别更改以在原始模式下打开UART(如上所述),则将非常相似。


更新:

框架完成后的速度有多快,我将在应用程序级别上拥有数据?当我尝试阅读当前在512字节块中读取的随机长度帧时,有时会一口气读取所有帧,而其他时候它会读取框架分解为块。 -
ENGO

我的链接中,在最后一个代码块中,有一个 XRECV 函数。它显示了如何读取块中的部分数据。

这就是您需要做的。

您的帖子中缺少的内容:

  1. 您没有发布 imx8 板/配置。并且, 您拥有的sim卡(协议是特定于卡片)。

  2. ,并且您没有发布其他代码[或任何代码]驱动设备并说明问题的代码。

  3. 在[UART]设备为“空闲”之前,必须在不接收字节的情况下经过多少时间?也就是说,(例如)设备发送100个字节,然后完成。在考虑设备为“空闲”之前,有几个字节时间等待?

  4. UART运行的速度是多少?

  5. 对设备的详尽描述,其功能以及您打算使用它的方式。

UART设备没有“空闲”中断。从某些 IMX8 文档中,DMA设备可能具有“空闲”中断,并且UART可以由DMA控制器驱动。

但是,我查看了一些Linux内核IMX8设备驱动程序,并且不支持闲置中断。

我需要一口阅读所有内容,并在几百微秒内获取这些数据。

基于调度粒度,不可能保证一个过程在给定的时间内运行。

有可能帮助这一点。您可以更改使用R/T调度程序的过程(例如 sched_fifo )。另外,您可以使用 sched_setaffitiation 将进程锁定到给定的CPU核心。有一个相应的调用将IRQ中断锁定到给定的CPU核心。

我认为SIM卡的作用像是[被动]设备(例如磁盘)。也就是说,您将其发送给命令,然后发回响应或进行转移。

基于您给出的命令,您应该知道它将寄回多少个字节。或者,它应该告诉您将发送多少个可选字节(类似于我链接中的 struct )。

您所描述的方法(例如)等待空闲,然后“竞赛”以获取/处理[您不知道长度]的数据充满了问题。

即使您可以使它工作,它也不可靠。在某个时候,系统活动将足够高以延迟您的流程唤醒,您会错过窗口。

如果您正在阅读数据,为什么必须在固定的时间内(例如100 US)处理数据?如果您,会发生什么?设备会起火吗?

没有更多的具体信息,可能还有其他方法可以做到这一点。

我已经对此类系统进行了编程,以依靠数据竞赛。他们不可靠。丢失数据。或者,对于某些电机控制应用,设备锁定。补救措施是重新设计事物,以便有一些积极/确定的交流方式可以容忍延误。

否则,我认为您“恋爱了”“闲置中断”的想法,使这个问题成为一个问题: https://meta.stackexchange.com/questions/66377/what-is-the--xy-problem

Waiting for an "idle" is a poor way to do this.

Use termios to set raw mode with VTIME of 0 and VMIN of 1. This will allow the userspace app to get control as soon as a single byte arrives. See:

  1. How to read serial with interrupt serial?
  2. How do I use termios.h to configure a serial port to pass raw bytes?
  3. How to open a tty device in noncanonical mode on Linux using .NET Core

But, you need a "protocol" of sorts, so you can know how much to read to get a complete packet. You prefix all data with a struct that has (e.g.) A type and a payload length. Then, you send "payload length" bytes. The receiver gets/reads that fixed length struct and then reads the payload which is "payload length" bytes long. This struct is always sent (in both directions).

See my answer: thread function doesn't terminate until Enter is pressed for a working example.

What you have/need is similar to doing socket programming using a stream socket except that the lower level is the UART rather than an actual socket.

My example code uses sockets, but if you change the low level to open your uart in raw mode (as above), it will be very similar.


UPDATE:

How quickly after the frame finished would i have the data at the application level? When I try to read my random length frames currently reading in 512 byte chunks, it will sometimes read all the frame in one go, other times it reads the frame broken up into chunks. –
Engo

In my link, in the last code block, there is an xrecv function. It shows how to read partial data that comes in chunks.

That is what you'll need to do.

Things missing from your post:

  1. You didn't post which imx8 board/configuration you have. And, which SIM card you have (the protocols are card specific).

  2. And, you didn't post your other code [or any code] that drives the device and illustrates the problem.

  3. How much time must pass without receiving a byte before the [uart] device is "idle"? That is, (e.g.) the device sends 100 bytes and is then finished. How many byte times does one wait before considering the device to be "idle"?

  4. What speed is the UART running at?

  5. A thorough description of the device, its capabilities, and how you intend to use it.

A uart device doesn't have an "idle" interrupt. From some imx8 docs, the DMA device may have an "idle" interrupt and the uart can be driven by the DMA controller.

But, I looked at some of the linux kernel imx8 device drivers, and, AFAICT, the idle interrupt isn't supported.

I need to read everything in one go and get this data within a few hundred microseconds.

Based on the scheduling granularity, it may not be possible to guarantee that a process runs in a given amount of time.

It is possible to help this a bit. You can change the process to use the R/T scheduler (e.g. SCHED_FIFO). Also, you can use sched_setaffinity to lock the process to a given CPU core. There is a corresponding call to lock IRQ interrupts to a given CPU core.

I assume that the SIM card acts like a [passive] device (like a disk). That is, you send it a command, and it sends back a response or does a transfer.

Based on what command you give it, you should know how many bytes it will send back. Or, it should tell you how many optional bytes it will send (similar to the struct in my link).

The method you've described (e.g.) wait for idle, then "race" to get/process the data [for which you don't know the length] is fraught with problems.

Even if you could get it to work, it will be unreliable. At some point, system activity will be just high enough to delay wakeup of your process and you'll miss the window.

If you're reading data, why must you process the data within a fixed period of time (e.g. 100 us)? What happens if you don't? Does the device catch fire?

Without more specific information, there are probably other ways to do this.

I've programmed such systems before that relied on data races. They were unreliable. Either missing data. Or, for some motor control applications, device lockup. The remedy was to redesign things so that there was some positive/definitive way to communicate that was tolerant of delays.

Otherwise, I think you've "fallen in love" with "idle interrupt" idea, making this an XY problem: https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文