我现在有一个微控制器负责处理红外TX载波产生,但我开始想知道我是否可以处理它,并在linux端做这项工作 - 从而降低了嵌入式系统的成本 .
我正在运行飞思卡尔i.mx233(454MHz ARM9),如果我通过 /dev/mem
直接访问注册表,我可以实现相当稳定的5MHz触发到GPIO引脚 .
由于我需要37kHz,我开始寻找降低速度的方法,但似乎至少 nanowait()
对于这个目的来说太粗糙了 . 我找到了一个在for循环中调用rand()的解决方案,我似乎能够很好地生成38,4kHz信号 . 但是根据示波器,有时会出现一些不可接受的抖动 . (我知道这有点浪费资源,但是当TX需要完成时,系统真的没有其他任务)
我的问题:Freescales内核代码(3.8分支)没有CONFIG_PREEMPT_RT补丁,所以这是我应该研究的一件事,但在此之前:
-
我可以通过编写内核模块从内核中驱动GPIO来获得更准确的性能吗?我确实需要从用户空间读取一些数据(要发送的数据),但除此之外,我只需要在GPIO末尾触发指定频率的LED,因此驱动程序应该非常简单 .
-
我可以强制我的驱动程序的优先级,以便其他任务不会中断此gpio触发吗? (数据发送目前大约需要400毫秒,而且很少完成)
-
是否有更好的方法来创建一个每37kHz的中断,这样我就不会使SW停止系统?
微控制器非常适合这类任务,但如果可能的话,避免这种成本开销会很好......
2 回答
“多芯片连接模式”中的i.MX23 PWM完全符合此要求 .
例如,使用“多芯片连接模式”中的一个PWM,假设您使用的是24Mhz时钟,
MATT = 1(启用多芯片附加模式)
MATT_SEL = 1(用户24Mhz时钟)
CDIV = 0x2(或DIV_4,即除以4)
INACTIVE_STATE = 0x2或0x3
ACTIVE_STATE = 0x3或0x2
PERIOD = 175(即176-1)
如果您使用32Mhz时钟,则需要其他CDIV和PERIOD参数才能达到34Khz .
有关示例代码,请参阅"i.MX23 Applications Processor Reference Manual" . 如果我没有弄错,驱动程序代码在
arch/arm/plat-mxc/pwm.c
但它似乎不支持MATT模式 . 您可能需要自己扩展代码 .关于实施 -
以上答案仅涉及CPU . 在实践中,实现该想法的能力取决于电路板设计 . 电路板需要一个连接到GPIO引脚的接头(用于外部连接的引脚),该引脚可以通过pinmux连接到其中一个PWM . 我假设大多数参考设计至少有一个通过接头暴露的PWM可配置GPIO . 问题是,是否只有一个,如果您已经将其用于其他控制目的 .
在确定存在具有自由PWM可配置GPIO的报头后,您需要配置引脚复用器并激活PWM . 上面提到的处理器参考手册中有相关说明 . 大多数系统在引导加载程序
board_init()
(假设U-boot)中执行此配置,尽管它可能在用户空间中也可以在Linux启动后使用一些mmap
技巧完成 .最后,您需要根据
platform-mxc_pwm.c
中PWM模块的接口编写驱动程序 .如果您使用的是i.MX23 EVK 10.05,您可以修改LED PWM驱动程序,因为它已经在引导加载程序和内核级别配置,并将您的设备连接到LED输出而不是LED . (您将需要一名硬件技术人员来帮助您 . )确保使用CONFIG_LEDS_MXS配置内核 .
由于我不了解EVK,因此上述关于实施的评论有些推测 . 也许知道它的人可以改善这一点 .
2013年9月21日更新
使用i.MX23或具有类似ARM CPU内核的任何SoC生成37kHz信号的另一种方法是使用未使用的片上定时器以所需频率生成FIQ中断并写入FIQ中断处理程序以切换GPIO销 . 今年4月30日,Maxime Ripard在他的Free Electrons博客上使用i.MX28 SoC发布了这种方法的complete example . 要使用此方法,您将需要两者未使用的定时器,而不是将FIQ中断用于其他目的,例如使用ARM FIQ的SPI,摄像头或掉电检测驱动器之一 . 您还需要在ARM汇编程序中编写ISR .
获得37 kHz信号的最佳方法是找到一些可以在硬件中生成的串行/音频/ PWM输出 .
可能会提高用户空间进程的优先级,但这对中断或高优先级内核任务没有帮助 . RT内核允许您优先于更多内核任务,但无法帮助抵御所有中断 . 我不知道你是否能够获得低于37 kHz(27μs)的最大延迟;我认为这不太可能 .
在内核中执行此操作会有所帮助,因为您可以禁用中断处理 . 但是,禁用长达400毫秒的中断是不受欢迎的 .