Kat*_*och 2 linux linux-device-driver linux-kernel
Linux 驱动程序是否有可能拥有一个 kthread、中断句柄和系统调用。意味着 linux Kernel 内核是否允许以上三个?
中断处理程序将在中断时保存来自通信通道的接收数据。
Kthread 会将数据传输出通信通道。
系统调用可用于配置驱动程序或获取其状态。
此外,如果中断处理程序和 kthread 正在使用 - 相同的硬件寄存器 - 那么我们如何保护这个关键部分?
中断处理程序将在中断时保存来自通信通道的接收数据。
设备驱动程序的中断服务例程,ISR,通常处理接收条件、传输条件以及错误和状态事件的中断。曾经有设备具有多条中断线,但现在几乎每个设备都只有一条中断线,并且必须查询中断状态寄存器以确定产生中断的条件。
仅将 ISR 用于接收是不寻常的。
Kthread 会将数据传输出通信通道。
与设备驱动程序相关联的线程更有可能是用于“下半部处理”的 tasklet。这是一种将 ISR 中的处理时间最小化的技术,同时对原始数据进行一些处理,尤其是对接收到的数据包/帧。
使用 kthread 传输数据似乎不合常规,并且可能会导致问题(例如可避免的临界区)。如果线程正在执行轮询编程 I/O,因为没有可用的 DMA 和 Tx 中断,那么这种方案可能是合理的。
系统调用可用于配置驱动程序或获取其状态。
Linux 设备驱动程序已经定义了一组入口点:Linux 设备驱动程序入口点
大多数这些入口点是由用户应用程序通过系统调用间接访问的。
不太可能专门为驱动程序创建系统调用。
此外,如果中断处理程序和 kthread 正在使用 - 相同的硬件寄存器 - 那么我们如何保护这个关键部分?
内核中的临界区通常用自旋锁保护。
但是,排除锁会增加延迟并降低系统响应能力。
一个好的系统设计可以避免创建(不必要的)临界区。如果对设备寄存器的访问被分配到中断级和任务级,也许只需要一个备用的自旋锁。
因此,一个 kthread、一个中断处理程序和系统调用可以与 Linux 驱动程序相关联,但不一定是您指定的方式。
但就我而言,我期待使用 mmap 系统调用从驱动程序发送和接收数据。
您需要阐明 use 的含义mmap。
如果您的意思是要访问mmap()目标 SPI 设备(例如 SD 卡或闪存)上的文件,则文件系统或 MTD 层将处理“映射”,设备驱动程序将简单地执行普通读取和写操作。
当我在中断处理程序中接收数据包时,我不能将其直接发送到映射区域吗?(您的建议是--下半部分的 Tasklet 可以很好地接收数据)
如果目标 SPI 设备是接收/传输数据包的通信设备,那么您的程序可能无法mmap()为该数据提供缓冲区。该mmap()功能是对虚拟内存功能的巧妙重新利用。虚拟内存功能用于出现在用户空间内存中的特定文件,而不是将文本和数据交换到/从后备存储(交换区域)。尽管所有设备都表示为一个“文件”,但设备文件可能会stat()在mmap(). 也许可以做到(对于有限的转移),但我从未尝试过。
如果您指的是驱动程序的fops mmap()功能,那么这超出了我的范围。事实上,Linux 源代码树中的 1200 多个驱动程序中只有大约 200 个设备驱动程序似乎实现了特定的fops。
根据您的建议,我将使用 DMA 从 SPI 端口传输数据,为此我们是否必须为此编写一些函数并将函数地址告诉 DMA?
您是否正在为通过 SPI 或 SPI 控制器连接的设备实现驱动程序?
如果它是使用 SPI 的目标设备,那么您可能会通过标准 SPI 接口使用这些SPI 驱动程序之一。您可能会使用诸如
spi_message_init()
spi_message_add_tail()
spi_sync()
Run Code Online (Sandbox Code Playgroud)
启动和监控 I/O 操作。使用该交叉引用网站在其他驱动程序中搜索这些函数名称以获取用法示例。DMA 的使用取决于 SPI 驱动程序。
如果您正在为 SPI 控制器实现驱动程序,则使用其他 SPI 驱动程序作为示例。
您似乎对 I/O 和驱动程序概念有一个扁平化的看法,但Linux 中的功能是在不同的层中实现的。
您似乎也有意避免复制操作。在“计算”中有很多数据的缓冲和复制。通常,将数据从一个缓冲区复制到另一个缓冲区是解决棘手问题(例如受保护内存与未受保护内存)的最简单解决方案。
也许您应该查看现有的高性能 MCP2515 CAN 驱动程序和 WCCD 框架来替换 SocketCAN。作者通过优化 ISR 和最小化关键区域及其锁的使用记录了显着的性能改进。