linux 如何在内核模块中断中触发函数

ttp71kqs  于 5个月前  发布在  Linux
关注(0)|答案(2)|浏览(45)

我试图写一个Linux内核模块,它等待硬件触发,然后通过DMA将一些数据移动到外部存储器。
我已经在内核模块中识别出了硬件触发器,现在我需要让它执行DMA。问题是执行DMA的函数涉及到一个点,它在DMA完成之前一直处于休眠状态。这在中断中是不允许的,所以我不能在中断服务例程中直接调用该函数。
有没有一种方法可以设置某种信号,使内核模块知道下次有机会调用DMA函数,但不在中断上下文中这样做?

e4yzc0pl

e4yzc0pl1#

会建议你通过注册一个回调来使用下半部分。Linux是这样工作的,上半部分/下半部分。
上半部分服务于中断和清除中断控制寄存器,并对已注册的回调(即下半部分)进行排队,它可以休眠。
建议你在罗伯特·洛夫的书中读一读。这是一个很好的开始。

https://doc.lagout.org/operating%20system%20/linux/Linux%20Kernel%20Development%2C%203rd%20Edition.pdf

字符串
查看linuxkernel org上的任何i2c客户端驱动程序源代码以供参考。

https://elixir.bootlin.com/linux/latest/source/drivers/misc/fsa9480.c#L394


在那里注册DMA后数据处理的回调。
这只是下半部分如何帮助你开发驱动程序的要点。希望它能对你有任何帮助。

798qvoo8

798qvoo82#

你可以从你的上半部分中断处理程序调用一个下半部分例程,它可以像工作中断一样休眠:
因为工作队列允许用户创建内核线程并将工作绑定到内核线程。因此,这将在进程上下文中运行,工作队列可以睡眠。延迟到工作队列的代码具有进程上下文的所有常见优点。最重要的是,工作队列是可调度的,因此可以睡眠。
另一种方式,你可以使用线程中断,它的调度方式与用户空间进程相同,因此也可以睡眠:
Register threaded interrupt

相关问题