request_threaded_irq 的“处理函数”中的 I2c 读取和写入操作如何影响整个驱动程序?

2024-02-10

我有一个带有 request_threaded_irq 的处理函数和线程函数的驱动程序代码,与此类似:

irq-handler fn()
{
      /*disable device interrupt*/
      i2c read from register;
      set disable bit to client-device-interrupt 
      i2c write back;
      return IRQ_WAKe_THREAD;
}



irq-thread fn()
{
      i2c read from register;
      ....
      ....
      /*enable device interrupt*/
      i2c read from register;
      set enable bit to client-device-interrupt 
      i2c write back;
      /*Rest of the operation*/
      ..........
      ..........
      return IRQ_HANDLED;
}

我对上述实施没有什么疑问。

  1. “handler fn”中的 2 i2c 操作会花费大量时间吗?

  2. 我是否需要在“handler fn”原子中进行位操作?

  3. 我是否应该将“启用设备中断”之前执行的操作从“线程 fn”移动到“处理程序 fn”(这将花费我 4 个以上的 i2c 操作和一位操作)? - 原因是,按照上面的代码实现,我可能会错过中断。

  4. 如果我这样做(按照问题 3)。它如何影响其他设备中断。(因为我有一个基本疑问:硬 IRQ 上下文中的“handler fn”是否在禁用中断的情况下运行)

请为我提供针对上述情况的良好且最佳的解决方案。

提前致谢。


I2C 读/写传输不是确定性的。

该协议允许外围从 IC 执行时钟拉伸 http://en.wikipedia.org/wiki/I%C2%B2C#Clock_stretching_using_SCL从而允许他们“抓住”主人直到他们准备好。 然而,这不是常见情况,因此每个 I2C 传输通常在大多数情况下以预定间隔完成。然而,这并不能保证,因此在 ISR 中执行多次 I2C 传输并不是一个好主意。

This link http://lists.kernelnewbies.org/pipermail/kernelnewbies/2011-March/001118.html包含关于线程 irq 的基础知识及其正确用法的很好的解释。


上述场景的最佳设计?

使用线程中断处理程序方法不会有太多好处,因为尝试启用/禁用设备上的中断会增加延迟。

在您当前的情况下(来自单个设备的单个中断),可以坚持常规request_irq()注册中断服务程序(ISR)。

ISR code :
1. 在 ISR 中,调用disable_irq()以防止进一步的中断。
2. 安排一个下半部分处理函数(工作队列是一个不错的选择)。
3. 返回IRQ_HANDLED来自ISR。

下半部分处理程序 code :
4. 执行 I2C 传输。
5. 打电话enable_irq()并退出。


NOTE :
实现相同设计的另一种方法是使用没有 ISR 的线程中断。这实现了与上述设计相同的效果,并且无需在代码中单独定义/初始化/清理下半部处理程序。

In 这种方法一 http://lxr.free-electrons.com/source/drivers/input/touchscreen/qt602240_ts.c?v=2.6.38#L1283将把所有 I2C 读/写代码放在IRQ线程函数 http://lxr.free-electrons.com/source/drivers/input/touchscreen/qt602240_ts.c?v=2.6.38#L677并将其传递给request_threaded_irq()随着handler = NULL即空 ISR。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

request_threaded_irq 的“处理函数”中的 I2c 读取和写入操作如何影响整个驱动程序? 的相关文章

  • 在中断时获取 current->pid

    我正在Linux调度程序上写一些东西 我需要知道在我的中断到来之前哪个进程正在运行 当前的结构可用吗 如果我在中断处理程序中执行 current gt pid 我是否可以获得我中断的进程的 pid 你可以 current gt pid存在并
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • Linux内核页表更新

    在linux x86 中分页 每个进程都有它自己的页面目录 页表遍历从 CR3 指向的页目录开始 每个进程共享内核页目录内容 假设三个句子是正确的 假设某个进程进入内核 模式并更新他的内核页目录内容 地址映射 访问 权利等 问题 由于内核地
  • 了解 U-Boot 内存占用

    我不明白加载 U Boot 时 RAM 中发生了什么 我正在开发 Xilinx Zynq ZC702 评估套件 并尝试使用 U Boot 在其上加载 Linux 内核 于是我使用Xilinx工具Vivado和SDK生成了一个BOOT bin
  • Linux 中热插拔设备时检测设备是否存在

    我正在运行 SPIcode http lxr free electrons com source drivers spi spi omap2 mcspi c在熊猫板上 我想知道其中的哪个功能code http lxr free electr
  • 在网络处理中使用自旋变体

    我编写了一个与网络过滤器挂钩交互的内核模块 网络过滤器挂钩在 Softirq 上下文中运行 我正在访问全局数据结构 哈希表 来自软中断上下文以及进程上下文 进程上下文访问是由于sysctl文件用于修改哈希表的内容 我正在使用 spinloc
  • 在 /dev/input/eventX 中写入事件需要哪些命令?

    我正在开发一个android需要将触摸事件发送到 dev input eventX 的应用程序 我知道C执行此类操作的代码结构如下 struct input event struct timeval time unsigned short
  • 什么是遗留中断?

    我正在开发一个项目 试图弄清楚 ARM 架构的全局中断控制器中如何处理中断 我正在使用 pl390 中断控制器 我看到有一条线被称为传统中断 它绕过了分配器逻辑 假设有 2 个中断可以被编程为传统中断 任何人都可以帮助解释一下什么是遗留中断
  • ftrace:仅打印trace_printk()的输出

    是否可以只转储trace printk 输出于trace文件 我的意思是过滤掉函数跟踪器 或任何其他跟踪器 中的所有函数 一般来说 您可以在选项目录中关闭选项 sys kernel debug tracing options Use ls显
  • 如何访问 mmaped /dev/mem 而不导致 Linux 内核崩溃?

    我有一个简单的程序 尝试访问用户空间中的物理内存 其中内核存储第一个结构页 在 64 位机器上 该地址是 内核虚拟地址 ffffea0000000000 物理地址 0000620000000000 我正在尝试通过用户空间中的 mmap 访问
  • 在许多驱动程序文件夹中创建 build-in.o

    我正在用我的自定义驱动程序构建内核 成功构建后 我发现了许多 build in o 文件 任何人都可以详细说明这些文件是如何在这里结束的吗 我只能怀疑这些与更高级别的 makefile 有关 built in o 文件是未构建为模块的内核的
  • 编译内核进行页表遍历时出现错误

    我正在执行页表遍历 当我准备更新内核时出现错误 kernel sys c In function do sys get page info kernel sys c 2745 23 error passing argument 1 of p
  • 我的属性太活泼了,我该怎么办?

    在 Linux 设备驱动程序中 创建 sysfs 属性probe太活泼了 具体来说 它经历了与用户空间的竞争条件 http kroah com log blog 2013 06 26 how to create a sysfs file c
  • 如何从外部模块导出符号?

    我在内核源代码树之外进行编码 有两个模块 第一个printt有一个功能printtty 将字符串打印到当前 tty 以及第二个模块hello这会调用printtty 在初始化期间 我已经添加了EXPORT SYMBOL printtty 在
  • /proc/kmsg 和 dmsg 有什么区别?

    我们通常这样做cat proc kmsg or dmesg从用户空间查看内核日志 我明白了dmesg是一个循环缓冲区 它从kmsg 但是kmsg也不是循环缓冲区 它们之间有什么区别和联系呢 宽松地说 dmesg 是一个转储 proc kms
  • 未找到 DEADLINE 调度策略

    我想在 C 中实现 DEADLINE 调度策略 我知道该功能已实现Linux 3 14 10我正在使用 Ubuntu 14 04Linux 3 17 0 031700 lowlatency 201410060605 SMP PREEMPT这
  • 如何使用 ioread64() 和 iowrite64() 访问 IO 内存?

    背景 我目前正在编写一个设备驱动程序教育设备 https github com qemu qemu blob master hw misc edu c在 qemu RISC V 中 由此question https stackoverflo
  • 在 Linux 内核中使用断言

    我有一个问题assert 在Linux中 我可以在内核中使用它吗 如果不是 例如 如果我不想输入 NULL 指针 您通常会使用什么技术 对应的内核宏是BUG ON and WARN ON 前者适用于当您想让内核恐慌并使系统崩溃 即不可恢复的
  • 编译Linux内核模块时出现错误:“CONFIG_X86_X32已启用,但没有binutils支持”和不需要的“n”字符

    我想得到Rasta Ring0 调试器 http rr0d droids corp org 在我的 x86 64 Linux 中编译的 0 3 版本 它是一个 Linux 内核模块 我已将 32 位内联汇编替换为 64 位汇编 如我的问题中
  • 为什么 Linux 原始套接字的 RX 环大小限制为 4GB?

    背景 我试图mmap 我的原始套接字的 RX 环形缓冲区64 bitLinux 应用程序 我的环由 4096 个块组成 每个块大小为 1MB 总共 4GB 请注意 每个 1MB 块中可以有许多帧 如果您好奇 请参阅此文档了解背景信息 htt

随机推荐