2012-04-02 105 views
7

我正在为某个基于ARM的Linux板(实际上是一个自定义UART驱动程序)实现自定义串行总线驱动程序。该驱动程序应通过自定义协议启用与总线另一端的某个MCU的通信。驱动程序不会(并且实际上不可能)将其任何功能公开给用户空间,也不可能在用户空间中实现它(因此,需要定制驱动程序而不是使用库存TTY子系统)。在Linux内核中实现正确的模块间同步

驱动程序将执行通信协议和UART读/写,并且它必须向用户输出一组更高级的功能,以允许它们与MCU通信(例如,read_register(),drive_gpios(),所有这些东西) 。这个模块只有一个用户。

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

问题是:我的基于信号量的方法好还是太天真?什么是可能的选择?我可能缺少任何缺陷吗?

+3

信号量应该从我所理解的工作中去理解更好的linux内部请参阅好的书“linex内核开发第3版”,它是免费的pdf并且是最新的(.39内核我相信)。这本书并没有深入,但它解释了基本原则并显示了选项。玩得开心。 – AoeAoe 2012-04-02 11:21:48

+0

一本好书,谢谢!如果其他人有兴趣,我还建议获得Linux驱动程序开发和Linux内核模块开发(两者均可免费在线获取) – 2012-04-02 12:17:40

回答

5

传统IRQ在Linux中处理分两部分完成:

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

  2. “下半部分”。它可能被实现为工作队列。这是实际工作完成的地方。它运行在正常范围内,所以它可以使用阻塞函数等

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