树莓派绑定GPIO触发设备失败:platform_get_resource(IORESOURCE_IRQ)返回NULL且platform_device.id为-1
树莓派绑定GPIO触发设备失败:platform_get_resource(IORESOURCE_IRQ)返回NULL且platform_device.id为-1
嘿,我来帮你拆解下这个调试问题,看起来你在树莓派上开发GPIO触发的IIO驱动时遇到了两个关键疑点:platform_get_resource(IORESOURCE_IRQ, 0)返回NULL,还有pdev->id显示为-1。咱们一步步来分析:
首先说下pdev->id = -1的情况——这其实不一定是异常。这个值对应的是内核定义的PLATFORM_DEVID_NONE,通常出现在两种场景:
- 你的平台设备是单实例的,不需要用ID来区分同类型的多个设备;
- 注册平台设备时,用
platform_device_register_simple()这类接口没传入明确的ID,或者设备树里没有为节点指定用于区分的ID属性。
如果你的驱动本来就只需要支持一个触发设备,那这个-1是完全正常的,不用纠结它。
接下来是核心问题:platform_get_resource()拿不到IRQ资源。这说明内核没有为你的平台设备关联对应的中断资源,常见原因有这几个:
1. 设备树配置缺失或错误(如果用设备树描述设备)
如果你的驱动是基于设备树匹配的,必须确保设备树节点里正确定义了中断相关属性:
- 要有
compatible属性,且和你驱动里platform_driver的of_match_table完全匹配; - 要指定
interrupt-parent(通常指向树莓派的GPIO控制器节点&gpio); - 要通过
interrupts属性明确GPIO引脚号和触发类型(比如上升沿、下降沿)。
举个符合要求的设备树节点示例:
my_iio_trigger { compatible = "your-vendor,iio-interrupt-trigger"; interrupt-parent = <&gpio>; interrupts = <17 IRQ_TYPE_EDGE_RISING>; // 这里用GPIO17上升沿触发 };
2. 平台设备注册时未手动添加IRQ资源(如果不用设备树)
如果是通过代码手动注册平台设备,你需要在platform_device的resource数组里显式添加IRQ资源,比如:
#include <linux/gpio.h> static struct resource iio_trigger_resources[] = { { .start = gpio_to_irq(17), // 将目标GPIO转换为内核IRQ号 .end = gpio_to_irq(17), .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING, }, }; static struct platform_device iio_trigger_dev = { .name = "iio-interrupt-trigger", .id = PLATFORM_DEVID_NONE, // 对应id=-1的情况 .num_resources = ARRAY_SIZE(iio_trigger_resources), .resource = iio_trigger_resources, };
3. 驱动与设备的匹配关系异常
即使probe函数能执行,也可能存在匹配不完整的情况——比如驱动用name匹配,但设备注册时的名称和驱动里的platform_driver.name不一致,或者设备树的compatible字符串和驱动的of_match_table不匹配,这会导致资源无法正确关联。
额外调试建议
你可以在probe函数里加一段代码,遍历打印所有设备资源,确认内核到底给你的设备分配了哪些资源:
int i; for (i = 0; i < pdev->num_resources; i++) { struct resource *res = &pdev->resource[i]; pr_info("Resource %d: type=0x%x, start=0x%lx, end=0x%lx\n", i, res->flags, res->start, res->end); }
如果输出里没有IORESOURCE_IRQ类型的资源,那就能确定是资源配置环节出了问题,再针对性排查设备树或注册代码即可。
备注:内容来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

