内核模块使用周期性内核定时器(jiffies 或 hrtimer)从 UART 收集数据

kernel module to collect data from UART with periodic kernel timer (jiffies or hrtimer)

我正在使用 linux kernel-2.6.35.3 并使用所有 3 个 uart 端口进行通信的 imx283 平台上工作。

我想从 UART-1 收集数据,但需要有一个准确的间隔。

数据是从传感器收集的。

我需要向传感器发送命令以获取数据。

间隔可以从 10 毫秒到 2 秒。

我需要内核模块的一些帮助,我可以使用内核定时器并从 uart 收集数据吗?

内核计时器的准确性很高,所以我是否可以使用它们。

谢谢,

使用 rs232 的标准驱动程序,从发出 write(2) 系统调用到内核驱动程序开始向串行线路输出字节(记住驱动程序是 运行已经在内核模式下)。为此编写驱动程序或内核模块很容易出错,必须由您维护,并且您需要精通内核编程才能做好它并且不会在途中崩溃(您必须应对标准驱动程序尝试使用该端口,因为它是由驱动程序自动完成的,您的驱动程序必须保留该端口供自己使用,以免干扰它)。只有在你完全填满缓冲区的情况下,你的进程将不得不等待缓冲区变空,但是根据定义,这不会发生,因为你无法补偿(你是填充输出行的速度比字符消失的速度快,这将使您的进程在缓冲区已满时阻塞),并且在这种情况下完全成为实时计时器。在输入时,您有一个类似的过程。您将有一个输入字符触发一些中断以将其从设备带到缓冲区,这通常(如果您在 termio 上将 VMIN 配置为 1)意味着您的进程将在每个字符读取时立即被唤醒(每个字符一进来)我建议你使用 VMIN 设置为 1 和 VTIME 设置为 0(阅读标准 termios(3) 手册页以获得串行驱动程序的完整解释) 在收到每个字符后立即唤醒您的进程。您的进程将被唤醒和安排,具体取决于系统负载和 cpu 速度,但通常这意味着需要及时使用以正常更新 cpu。您可以在来自 read(2) 调用后立即为读数添加时间戳,或者尝试在单独的 ioctl(2) 调用中从内核获取读取时间戳以检查何时及时收到字符(我知道这个在 linux 中是可能的,至少对于套接字而言,无需为此编写模块)(但当它从远程端传输时,请考虑这一点)但我认为获得毫秒计时,这就足够了在用户模式下做所有事情,而不是让进入内核模式的事情复杂化。 RS232 线路不是为实时设计的,所以你正在尝试的事情可以在毫秒分辨率下进行,而无需在内核端编程。

此外,在用户模式下完成所有操作允许您的程序从一个系统移动到另一个系统,而无需在尝试您的软件之前进行复杂的内核模块安装,甚至更多....知道如何使用 tty 驱动程序允许您在非 linux 系统(例如 BSD、Solaris 或 MAC)中 运行 您的代码