马上注册,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册 
×
遇到的错误 0x0bad0002 是 Nordic SDK 中常见的错误码,它表示 "Resource not available"(资源不可用),具体到 nrfx_gpiote_in_init() 函数中,这个错误通常是因为 GPIOTE 模块的输入通道(channel)不够用了。 🔍 错误分析你在代码中调用了:
1nrfx_gpiote_init(7);
这表示你配置了 GPIOTE 模块最多使用 7 个通道(channels)。
然后在初始化输入时:
1err_code = nrfx_gpiote_in_init(pin, &config_in_lotohi, chip1_empty_pin_event_handler);
如果此时系统已经分配了 7 个通道,再尝试初始化第 8 个就会失败,返回 NRFX_ERROR_NOT_AVAILABLE(即 0x0bad0002)。
✅ 你的描述“只用了4个就不够了”说明:虽然你只用了 4 个 pin,但可能有其他地方也占用了 GPIOTE 通道,比如:
- 其他 GPIO 输入/输出中断
- PWM、ADC、SPI 等外设使用的 GPIOTE(如某些驱动自动申请)
- 多次调用 nrfx_gpiote_init() 导致资源重复申请或未释放
✅ 解决方案✅ 方案一:检查并减少 GPIOTE 通道总数(推荐)步骤:
- 确认实际需要多少个 GPIOTE 通道
- 查看所有使用 nrfx_gpiote_in_init() 或 nrfx_gpiote_out_init() 的地方。
- 统计总共用了几个 channel。
- 调整 nrfx_gpiote_init() 的参数
1nrfx_gpiote_init(7); // 当前设置为 7
如果你只需要 6 个,可以改为:
1nrfx_gpiote_init(6);
⚠️ 注意:不要设置得太小,否则会报错。建议根据实际使用情况合理分配。
- 确保没有重复初始化
检查是否多次调用 nrfx_gpiote_init() —— 这会导致内部资源管理混乱。
❌ 错误示例:
1nrfx_gpiote_init(7); // 第一次2...3nrfx_gpiote_init(7); // 第二次,又调了一次!
✅ 正确做法:只调用一次!
✅ 方案二:检查是否有其他模块占用 GPIOTE一些外设会隐式使用 GPIOTE,例如:
- nrfx_pwm(PWM 输出可能用 GPIOTE 控制)
- nrfx_spim / nrfx_spi(某些模式下用 GPIO 中断)
- nrfx_uart(如果启用了 CTS/RTS 流控)
- nrfx_timer(如果通过 GPIO 触发)
👉 建议:
- 打开 nrfx_config.h 查看是否开启了这些外设。
- 使用 nrfx_gpiote_channel_get() 来查看当前已分配的 channel 数量。
- 可以打印调试信息来定位谁占用了 channel。
✅ 方案三:使用 nrfx_gpiote_channel_alloc() 手动分配(高级)如果你知道确切需要哪个 channel,可以用手动方式分配,避免自动分配冲突。
1uint8_t channel;2err_code = nrfx_gpiote_channel_alloc(&channel);3if (err_code == NRF_SUCCESS) {4 // 使用该 channel 配置输入5 nrfx_gpiote_in_init(pin, &config, handler);6}
但这需要更精细控制,适合复杂场景。
✅ 方案四:升级 SDK 或检查板级配置有时是 SDK 版本问题或 nrfx_config.h 配置不当导致默认预留太多 channel。
检查以下文件:
- nrfx_config.h
- nrfx_config_common.h
- platform_nrf5340_icc.c 或类似平台初始化文件
确保:
1#define NRFX_GPIOTE_ENABLED 12#define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 03#define NRFX_GPIOTE_CONFIG_NUM_OF_HIGH_POWER_EVENTS 7
也可以尝试修改 NRFX_GPIOTE_CONFIG_NUM_OF_HIGH_POWER_EVENTS 为更大的值(如 8),但要保证硬件支持。
🛠 调试建议你可以添加如下日志来排查:
1// 在初始化前打印当前可用 channel 数2uint32_t used_channels = nrfx_gpiote_channels_used();3platform_log_err("Used GPIOTE channels: %d\n", used_channels);
或者:
1// 查看当前是否还有空闲 channel2if (nrfx_gpiote_is_channel_free()) {3 platform_log_err("Channel free!\n");4} else {5 platform_log_err("No free channel!\n");6}
✅ 总结解决方案 问题 解决方法
0x0bad0002 表示资源不足 增加 nrfx_gpiote_init() 参数或减少使用
多次调用 nrfx_gpiote_init() 只调用一次
其他外设占用 GPIOTE 检查 PWM、SPI、UART 是否启用
不清楚用了几个 channel 打印 nrfx_gpiote_channels_used() ✅ 推荐修改代码(修正版) 1// 只调用一次 init,全局唯一2static bool gpiote_initialized = false;34void platform_gpiote_init(void)5{6 if (!gpiote_initialized) {7 nrfx_gpiote_init(8); // 改成 8,确保足够8 gpiote_initialized = true;9 }10}1112// 初始化函数中不再重复 init13static void platform_gpiote_chip2_init(uint8_t pin)14{15 nrfx_err_t err_code;1617 // 不要重复 init18 err_code = nrfx_gpiote_in_init(pin, &config_in_lotohi, chip2_empty_pin_event_handler);19 if (err_code != NRF_SUCCESS) {20 platform_log_err("drdy_pin_chip2_init error: %08x \n", err_code);21 } else {22 nrfx_gpiote_in_event_enable(pin, false);23 }24}
|