1

我在 ARM 处理器上运行嵌入式 linux 3.2.6。我正在使用修改版的 atmel 串行驱动程序来控制我设备上的 4 个 USART 端口。当我使用用内核编译的驱动程序时,一切正常。但我想将驱动程序作为内核模块运行。我进行了所有必要的更改并禁用了内部驱动程序,一切似乎都很好。4 个 tty 设备注册成功,我可以看到我的所有探测和初始化功能都正常工作。

所以这就是问题所在:当我尝试写入任何设备时,我的“开始传输”函数被调用,但随后等待来自 usart 的中断,该中断从未发生。所以写入只是挂起,使用逻辑分析仪我可以看到 RTS 被断言但 tx 线上没有字节显示。我知道我对 request_irq 的调用成功,但我从未在 /proc/interrupts 中看到任何 irq 条目。在驱动程序中,我还尝试使用 request_irq 为 gpio 线注册一个单独的中断处理程序,这工作正常。

我知道这是一个可能很难诊断的问题,但我正在寻找任何可能的建议,这些建议可以引导我朝着正确的方向寻找解决方案。如果您需要任何澄清,请告诉我。谢谢

4

2 回答 2

1

症状读起来就像没有启用(或关闭)的外围时钟:可以初始化设备而不会出现错误,并且可以设置 I/O 操作,但设备不执行任何操作;它玩死了。由于没有 I/O启动,您永远不会收到指示完成的中断!

要检查的另一件事是文件中硬件配置结构的条件编译指令arch/arm/mach-xxx/zzz_devices.c
确保串行端口结构具有以下内容:

#if defined(CONFIG_SERIAL_ATMEL) || defined(CONFIG_SERIAL_ATMEL_MODULE)

而不仅仅是

#if defined(CONFIG_SERIAL_ATMEL) 

附录

我可能是错的,但时钟不应该对导致中断的 CTS 引脚产生任何影响,对吧?

不对。
这些数字电路是同步状态机:没有时钟,就无法处理输入引起的状态变化。
此外,SoC 和现代 uController 使用外设时钟作为这些集成外设的开/关开关。硅芯片上的功能(即外围设备)通常比实际可用的要多得多,这主要是由于板上的引脚数量不足。因此,禁用未使用设备的时钟以降低功耗。

你太专注于中断。
您没有可解决的中断问题;这些是次要故障。
尝试传输时缺乏输出更为重要和具有启发性。
根本原因可能是 USART 设备的配置有缺陷,因为传输位是已配置和运行的 USART 的自动操作。
如果不工作与工作之间的区别是可加载模块静态链接,那么根本原因将是一些基本(和微不足道)的东西,就像我的两个建议一样。

此外,您对 的缺乏确认 #if defined(),例如您没有回应“哦,是的,我们已经知道了”,会引发一个巨大的危险信号,上面写着“先修复我!”

附录 2

在发现无法使用 Atmel 串行驱动程序配置/构建为可加载模块后,我很想删除此答案make menuconfig(这是一半答案的前提)。(当然,该Kconfig文件可以被破解以使配置变量三态而不是布尔值来克服模块限制。)我已经为 OP 留下了评论。但我也想保留对 Stratton 先生的评论,指出.config文件中的符号是如何(不)使用的。

于 2012-12-01T07:17:03.873 回答
1

所以我终于解决了我的问题。感谢您的回复,他们都没有直接解决我的问题,但他们确实提示进一步检查我的代码。经过一些试验和错误,我终于让它工作了。我最初将每个 usart 的 platform_device 结构从 /mach-at91/xxx_devices.c 移动到我的可加载模块。好吧,由于某种原因,结构没有获得正确的数据以映射到硬件,我想是因为它没有正确链接来自内核的符号(虽然从未收到错误消息),所以一些注册功能不是' t 甚至被调用。我最终将结构和 platform_device_register 调用移回设备文件。我还决定使用原始的 atmel_serial.c 驱动程序来保留内置控制台的驱动程序。我必须在设备文件和内置 atmel_serial.c 文件中更改控制台的 platform_device 名称,以免它与我的 usart 端口驱动程序冲突。我发现将 usart 的 platform_device 和 platform_driver 名称从“atmel_usart”以外的任何名称更改都会导致 usart 传输失败。我真的不明白为什么,但我只是把它留作 atmel_usart 所以它可以工作。

再次感谢所有回答我问题的人。

于 2012-12-04T18:21:09.363 回答