我假设您的板上 I2C/GPIO/PWM/UART 接口具有特定于平台的驱动程序(它应该是 BSP[Board-support-package] 的一部分)。
只是你不想使用内核设备驱动框架,想从用户空间做事。我曾经遇到过这种情况,因此我知道这可能是多么诱人,尤其是如果您不精通内核设备驱动程序。
一个。 SPEED:你提到了。但是,你可能没有完全理解原因。
速度效率来自于避免内核和用户空间进程之间的上下文切换。这是一个例子:
/* A loop in kernel code which reads a register 100 time */
for (i = 0 ; i < 100 ; i++ )
{
__kernel_read_reg(...);
}
/* A loop in User-space code which reads a register 100 time */
for ( i= 0 ; i < 100; i++)
{
__user_read_reg(...);
}
*_read_reg() 的功能是相同的。假设 __user_read_reg() 将通过一个典型的系统调用过程,它必须为每个单独的 __user_read_reg(...) 做一个上下文切换,这太昂贵了。
您可能会争辩说,“我们可以 mmap() 硬件寄存器并避免此类操作的系统调用”。
当然,你可以这样做,但我想说的是:
接近硬件的事情(例如:寄存器读取或写入或处理中断)应该尽可能快地完成。上下文切换所涉及的延迟会影响性能。
b. 现有/经过测试/完善的子系统:
如果您在 Linux 内核中看到 I2C 子系统,它提供了一个经过良好测试的、健壮的框架,可以轻松重用。您不必在用户空间中编写完整的 I2C 子系统(处理所有设备类型、速度、各种配置等)。
在使用内核设备驱动程序时,重用“已经完成的工作可能是一大优势。
c。 从基于轮询的方法转变为基于中断的机制
如果您不在内核驱动程序中处理中断,您必须在用户空间进程中使用某种轮询机制。根据系统的不同,它可能不是处理硬件更改的非常可靠的方式。对于快速设备来说绝对不准确/可靠。
一般来说,基于中断的机制,您尽可能快地处理关键更改(硬件中断上下文)并将非关键工作负载移动到用户空间或其他一些内核机制是更可靠的方法处理设备。
当然,除了以上三个之外,还可以有更多的论点和反论点。
您可能感兴趣的另一个主题在这里:
Userspace vs kernel space driver