ARM Linux 内核驱动程序中的关键时序 [英] Critical Timing in an ARM Linux Kernel Driver

查看:31
本文介绍了ARM Linux 内核驱动程序中的关键时序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 MX28 (ARMv5) 上运行 linux,并使用 GPIO 线与设备通信.不幸的是,该设备有一些特殊的时序要求.GPIO 线上的低电平不能持续超过 7us,高电平没有特殊的时序要求.该代码作为内核设备驱动程序实现,并通过直接寄存器写入来切换 GPIO,而不是通过内核 GPIO api.为了测试,我只是生成 3 个脉冲.该过程如下,全部在一个函数中,因此它应该适合指令缓存:

I am running linux on an MX28 (ARMv5), and am using a GPIO line to talk to a device. Unfortunately, the device has some special timing requirements. A low on the GPIO line cannot last longer than 7us, highs have no special timing requirements. The code is implemented as a kernel device driver, and toggles the GPIO with direct register writes rather than going through the kernel GPIO api. For testing, I am just generating 3 pulses. The process is as follows, all in one function so it should fit in the instruction cache:

  • 设置gpio高
  • 保存标记和禁用中断
  • gpio 低
  • 暂停
  • gpio 高
  • 重复 2 次以上
  • 恢复标志/重新启用中断

这是连接到 GPIO 的逻辑分析仪的输出.

Here's the output of a logic analyzer tied to the GPIO.

在大多数情况下,它运行良好,脉冲持续时间不到 1us.然而,大约 10% 的低点会持续很多很多微秒.即使中断被禁用,某些事情也会导致代码流被中断.

Most of the time it works just great, and the pulses last just under 1us. However, about 10% of the lows last for many, many microseconds. Even though interrupts are disabled, something is causing the flow of the code to be interrupted.

我不知所措.RT Linux 在这里可能无济于事,因为问题不是延迟,它似乎是在低电平期间发生的事情,即使在禁用 IRQ 的情况下不应中断它.任何建议将不胜感激,不胜感激.

I am at a loss. RT Linux would likely not help here, because the problem is not latency, it appears to be something happening during the low, even though nothing should interrupt it with the IRQs disabled. Any suggestions would be greatly, greatly appreciated.

推荐答案

IMX25 (ARM926) 上的 ARM 缓存是 16K 代码、16K 数据 L1,长度为 32 字节或 8 条指令.DDR-SDRAM 控制器以 133Mhz 和 16 位总线运行,传输速率约为 300MB/s.缓存填充应该只需要大约 100nS,而不是 9uS;这大约长了 100 倍.

The ARM cache on an IMX25 (ARM926) is 16K Code, 16K Data L1 with a 32byte length or eight instructions. With the DDR-SDRAM controller running at 133Mhz and a 16bit bus the transfer rate is about 300MB/s. A cache fill should only take about 100nS, not 9uS; this is about 100 times too long.

但是,Linux 还存在其他四个问题.

However, you have four other issues with Linux.

  1. TLB 未命中和页表遍历.
  2. 数据中止.
  3. DMA 大师窃取.
  4. FIQ 中断.

LCD 主控不太可能窃取足够的带宽,除非您有一个巨大的显示器.您的显示器是否大于 1/4VGA?如果不是,这只是内存带宽的 10%,这将与处理器一起流水线化.你有以太网或 USB 活动吗?这些外设具有更高的数据速率,可能会导致与 SDRAM 发生这种类型的争用.

It is unlikely that the LCD master is stealing enough bandwidth, unless you have a huge display. Is your display larger than 1/4VGA? If not, this is only 10% of the memory bandwidth and this will pipeline with the processor. Do you have either Ethernet or USB active? These peripherals are higher data rate and could cause this type of contention with SDRAM.

所有这些问题都可以通过编写相关的切换器 PC 并将其复制到 IRAM 来避免.请参阅:iram_alloc.c;这个文件应该可以移植到旧版本的 Linux.XBAR 开关允许同时从 SDRAM 和 IRAM 获取数据.IRAM 仍然可以成为其他 DMA 主机的目标.如果您真的很紧张,请将代码移至系统中其他主机无法访问的 ETB 缓冲区.

All of these issues maybe avoided by writing your toggler PC relative and copying it to the IRAM. See: iram_alloc.c; this file should be portable to older versions of Linux. The XBAR switch allows fetches from SDRAM and IRAM simultaneously. The IRAM can still be a target of other DMA masters. If you are really pressed, move the code to the ETB buffers which no other master in the system can access.

TLB 未命中实际上可能非常陡峭,因为它可能需要运行多个单节拍 SDRAM 周期;仍然这应该低于1uS.您尚未发布代码,因此变量和/或其他变量可能会导致无法屏蔽的数据错误.

The TLB miss can actually be quite steep as it may need to run several single beat SDRAM cycles; still this should be under 1uS. You have not posted code, so it is possible that a variable and/or other is causing a data fault which is not maskable.

如果您有任何使用 FIQ 的驱动程序,即使您屏蔽了正常的 IRQ 中断,它们可能仍在运行.例如,该系统的 ALSA 驱动程序通常使用 FIQ.

If you have any drivers using the FIQ, they may still be running even though you have masked the normal IRQ interrupts. For instance, the ALSA driver for this system normally uses the FIQ.

ETBIRAM 都是 32 位数据路径和低等待状态.任何一种都可能比 DDR-SDRAM 提供更好的响应.

Both the ETB and the IRAM are 32-bit data paths and low wait state. Either one will probably give better response than the DDR-SDRAM.

我们通过使用 FIQIRAM 实现了亚微秒级响应,通过使用位碰撞的另一种协议切换 IMX258 上的 GPIO.

We have achieved sub micro-second response by using a FIQ and IRAM to toggle GPIOs on an IMX258 with another protocol using bit banging.

这篇关于ARM Linux 内核驱动程序中的关键时序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆