真实面经题目 · 原创解析
驱动里申请 GPIO 或中断一般调用哪些接口,为什么不能直接操作寄存器?
这题考内核资源管理意识,回答要说明 GPIO 和 IRQ 应通过 descriptor、设备树和 devm 接口申请,不能绕过 pinctrl/irqchip 直接写寄存器。
真实面经题目 · 原创解析
这题考内核资源管理意识,回答要说明 GPIO 和 IRQ 应通过 descriptor、设备树和 devm 接口申请,不能绕过 pinctrl/irqchip 直接写寄存器。
驱动里用 GPIO 通常优先走 descriptor API,比如 devm_gpiod_get 或 devm_gpiod_get_optional,从设备树的 xxx-gpios 属性拿到描述符,再用 gpiod_direction_input/output、gpiod_set_value_cansleep、gpiod_get_value 等操作。申请中断一般先通过 platform_get_irq、gpiod_to_irq 或 fwnode 接口拿 IRQ 号,再用 devm_request_irq 或 devm_request_threaded_irq 注册处理函数,必要时配置触发边沿和 threaded handler。不能直接操作寄存器的原因是 Linux 内核要统一管理资源所有权、pinctrl 复用、GPIO controller、irqchip、时钟电源、并发访问和跨 SoC 可移植性。直接写寄存器可能和其他驱动抢引脚、破坏电源管理、绕过中断层级和锁,还会让同一驱动无法适配不同板子。
descriptor API 把板级编号、极性、控制器差异隐藏起来。驱动只关心这是 reset、enable 或 interrupt 引脚,不需要硬编码 SoC GPIO 编号。
中断号可能来自设备树 interrupts,也可能由 GPIO 转换而来。request_threaded_irq 可以把快速顶半部和可睡眠的线程化处理分开,适合大多数外设中断。
引脚要先复用成 GPIO 或外设功能,再由 GPIO 子系统控制电平。直接写 GPIO 寄存器可能忽略引脚复用、电气配置和低功耗状态。
内核通过 request 模型知道哪个驱动拥有哪个引脚和中断,能处理卸载、错误清理、共享限制和调试信息。直接写寄存器会破坏这个可见性。
如果 GPIO 控制器操作可能睡眠,例如挂在慢速总线上,就要用 cansleep 版本,并且不能在硬中断上下文调用。
中断处理需要访问慢速总线、睡眠锁或较长处理时,用 threaded IRQ 把耗时工作放到线程上下文,顶半部只做快速确认。
我会先看 dmesg 和返回码,再查 /sys 下设备、驱动和资源状态,必要时加 trace/ftrace 或最小日志,先证明问题出在设备生成、匹配、资源获取、回调路径还是用户态交互。