【问题标题】:Implementing correct inter-module synchronization in Linux kernel在 Linux 内核中实现正确的模块间同步
【发布时间】:2012-04-02 10:50:05
【问题描述】:

我正在为某个基于 ARM 的 Linux 板实现自定义串行总线驱动程序(实际上是自定义 UART 驱动程序)。该驱动程序应能够通过自定义协议与总线另​​一端的某个 MCU 进行通信。驱动程序不会(实际上不得)将其任何功能暴露给用户空间,也根本不可能在用户空间中实现它(因此,需要自定义驱动程序而不是使用库存 TTY 子系统)。

驱动程序将实现通信协议和UART读/写,它必须向其用户导出一组更高级别的函数以允许他们与MCU通信(例如read_register()drive_gpios(),所有这东西)。这个模块只有一个用户。

调用模块必须等待操作完成(前面提到的read_register() 和其他)。我目前正在考虑使用信号量:用户模块将调用我的驱动程序函数,该函数将启动传输并等待信号量;我的驱动程序的 IRQ 处理程序将向 MCU 发送请求并读取答案,完成后,发送到信号量,从而唤醒调用模块。但是我对内核编程并不是很熟悉,而且我对众多可能的替代实现(tasklet?等待队列?)感到困惑。

问题是:我的基于信号量的方法是否可行,还是过于幼稚?有哪些可能的替代方案?有没有我可能遗漏的陷阱?

【问题讨论】:

  • 信号量应该按照我的理解来完成这项工作,为了更好地理解 linux 内部结构,请参阅好书“linex kernel development 3rd edition”,它以免费 pdf 的形式提供并且是最新的(.39 内核我相信)。那本书并不深入,但它解释了基本原理并显示了选项。玩得开心。
  • 一本好书,谢谢!如果其他人有兴趣,我还建议获得 Linux Drivers Development 和 Linux Kernel Module Development(两者都可以在线免费获得)

标签: c linux embedded driver kernel-module


【解决方案1】:

传统上,Linux 中的 IRQ 处理分为两部分:

  1. 所谓的“上半部分”实际上是在 IRQ 上下文中工作(IRQ 处理程序本身)。这部分必须尽快退出。所以它基本上检查中断源,然后开始下半部分。

  2. “下半部分”。它可以实现为工作队列。这是完成实际工作的地方。它在正常上下文中运行,因此可以使用阻塞函数等。

如果您只想在工作线程中等待 IRQ,最好使用名为 completion 的特殊对象。它正是为此任务而创建的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 2011-11-24
    • 2012-04-11
    • 2013-12-17
    • 1970-01-01
    • 2013-08-09
    相关资源
    最近更新 更多