如何在Linux内核模块中使用bit-banging生成~100 kHz时钟信号?

时间:2011-01-08 17:01:00

标签: linux-kernel linux-device-driver embedded-linux kernel kernel-module

我正在尝试在GPIO引脚(ARM平台,mach-davinci,内核2.6.27)上生成时钟信号,这将产生100kHz的频率。使用具有高优先级的tasklet来执行此操作。理论很简单,设置gpio高,udelay为5us,设置gpio低,再等5us,但出现奇怪的问题。首先,不能得到这5us的dalay,但它很好,看起来像hw性能问题,所以我移动到句号= 40us(给出~25kHz)。第二个问题是最坏的。每10分钟一次,udelay等待时间比平常长3倍。我认为这是听取这个时间的听力,但这是从协议(这将在此基础上实施)的观点来看是不可接受的。有没有办法暂时禁用心跳过程,比方说,500ms?或者也许我从一开始就做错了?有什么意见吗?

3 个答案:

答案 0 :(得分:2)

您不能将tasklet用于此类工作。 Tasklet可以被中断抢占。在某些情况下,您的tasklet甚至可以在流程上下文中执行!

如果你必须这样做,请使用中断处理程序 - 进入,禁用中断,做你必须做的任何事情并尽可能快地离开。

答案 1 :(得分:2)

在软件中异步生成时钟不是正确的做法。我可以想到两种更好的选择:

  1. 您的处理器可能有一个内置时钟发生器外设,内核尚未被其他驱动程序使用。当你设置其中一个时,你会告诉它运行它的时钟有多快,它只是开始耗尽脉冲。

    获取处理器的数据表并进行研究。

    您可能找不到称为“时钟”本身的外围设备,但可能会找到类似于您可以投入使用的内容,例如PWM外设。

  2. 您正在与之交谈的其他设备实际上可能并不需要常规时钟。一些需要“时钟”线的芯片只需要一条线,当有一个读取位时它会变高,然后在数据线发生变化时变低。如果是这种情况,那么你正在读取的100 kHz频率对于那个频率正好的时钟并不是一个硬性要求,它只是时钟线(以及数据线)速度的上限。被允许过渡。

    如果CPU比时钟快得多,你想把它分成两半:

    • “上半部分”正确设置数据线状态,然后启动时钟线。然后使用中断或内核计时器调度下半部分运行5μs。

    • 在由中断或定时器调用的“下半部分”中,将时钟线重新调低,然后安排上半部分再运行5μs。

答案 2 :(得分:0)

除非您能以比内核计时器更高的优先级运行计时器tasklet,否则您将始终容易受到这种抖动的影响。你真的必须通过bit-ganging来做到这一点吗?使用硬件定时器或PWM发生器要容易得多。将定时器配置为以所需速率运行,将引脚设置为输出,然后就完成了。

如果您需要在每个位周期进行软件控制,您可以尝试通过将您的tasklet设置为在短时间内运行来解决其他任务,例如40 us延迟的四分之三。在tasklet中,禁用中断并轮询时钟,直到到达正确的40 us时隙,设置I / O状态,重新启用中断并退出。但是,这有效地在观看时钟时输入了25%的系统。