找回密码
 立即注册

使用微信账号登录

只需一步,快速开始

查看: 9|回复: 0

[Nordic] 使用NORDIC芯片nRF5340开发,初始化gpiote_in_init时返回错误0x0bad0002,排查方法

[复制链接]
连续签到天数:1天
签到总天数:5天
签到总奖励:23金币
发表于 昨天 15:54 | 显示全部楼层 |阅读模式

马上注册,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册  

×
​  
遇到的错误 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}

楼主热帖
积分商城 - 让您的金币更有价值!||官方Q群 - 让您的沟通更加及时!
您需要登录后才可以回帖 登录 | 立即注册  

本版积分规则

小黑屋|手机版|我爱蓝牙网 - 52Bluetooth

GMT+8, 2025-12-18 01:13 , Processed in 0.206191 second(s), 9 queries , Gzip On, MemCached On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表