nRF52840 BLE 多服务开发中的 NRF_ERROR_NO_MEM 排查与解决实战

问题现象

在基于 nRF5 SDK 的 Heart Rate 示例上添加自定义 LBS(LED Button Service)私有服务后,程序启动后立即进入 Fatal Error → System Reset 循环,串口反复打印:

textapp: ble_lbs_init failed! Error code = 0x00000004

0x00000004 对应 NRF_ERROR_NO_MEM(内存不足)。

根本原因

nRF52840 的 SoftDevice(S140)在初始化时会分配一块 RAM 给协议栈使用。默认配置下,GATT 属性表(Attribute Table)大小有限。当同时启用以下服务和模块时,容易超出限制:

Heart Rate Service (HRS)

Battery Service (BAS)

Device Information Service (DIS)

自定义 LBS 服务(包含至少 2~3 个特征 + CCCD)

Peer Manager + Queued Write + LESC 等安全特性

每个 GATT 服务和特征都需要在属性表中占用空间,LBS 服务初始化时申请内存失败,导致 ble_lbs_init() 返回 NRF_ERROR_NO_MEM。

排查过程关键点

通过 APP_ERROR_CHECK + 日志打印,精确定位到 ble_lbs_init() 失败。

确认错误码为 0x00000004(NRF_ERROR_NO_MEM)。

分析同时运行的 BLE 服务数量和 RAM 使用情况。

发现 Keil 中 IRAM1 Size 设置过大(挤占了 SoftDevice 可用的 RAM)。

最终解决方案(三管齐下)

代码层面增大 GATT 属性表(最重要):Cble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = 0x1400; // 或更高

err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_cfg, ram_start);

Keil 工程配置调整 IRAM1:

将 IRAM1 Size 适当调小(例如 0x3A000 ~ 0x39000),给 SoftDevice 留出更多 RAM。

打印内存信息辅助调试:CNRF_LOG_INFO("SoftDevice RAM start = 0x%08X", ram_start);

NRF_LOG_INFO("Available RAM for app ≈ %d bytes", (256*1024) - (ram_start - 0x20000000));

经验教训与最佳实践

添加自定义服务前,必须评估总的 GATT 属性表占用。

永远不要依赖默认配置,尤其当项目包含多个服务 + Peer Manager 时。

建议在 ble_stack_init() 中主动配置 attr_tab_size、conn_cfg 等关键参数。

开发过程中养成打印 RAM start 地址和可用内存的习惯,能大幅加快调试速度。

对于 nRF52840,推荐至少预留 20~30KB 给应用层使用

相关推荐
上海安当技术3 小时前
固件签名与Secure Boot:安当CAS如何构建汽车固件信任链
网络·汽车·信任链·boot·secure·固件签名·安当cas
上海安当技术4 小时前
诊断接入认证:安当CAS如何堵住汽车网络安全的物理后门
网络·web安全·汽车·access·secure·安当cas·诊断接入认证
ze^04 小时前
【软考信息安全】第2章 网络攻击原理与常用方法
网络·web安全·网络安全
这个DBA有点耶5 小时前
数据库一体机架构演进:从硬件堆叠到软硬深度耦合
服务器·网络·数据库·硬件架构·运维开发·database·数据库架构
arbboter5 小时前
【网络工具】NetProxy网络代理用户手册
开发语言·网络·c#·网络代理·网络异常·代理工具
消失的旧时光-19437 小时前
第一篇:Ktor Client 到底是什么?从 Retrofit 迁移理解 Ktor 网络请求架构
网络·架构·retrofit·ktor·dsl
数据知道7 小时前
反序列化漏洞:Java、PHP、Python 三条线各讲透
java·网络·python·安全·网络安全·php
江畔柳前堤7 小时前
Function Calling 与 Tool Calling:从认知到工程的全景深度解析
开发语言·网络·人工智能·深度学习·算法·机器学习·php
LabVIEW开发8 小时前
LabVIEW 通过以太网控制 Yokogawa WT3000 功率分析仪:tmctl.dll 与原始套接字方案
网络·labview·labview知识·labview功能·labview程序
xiaoxiangsiyan9 小时前
企业日常运维高频应用服务全解
运维·网络·云原生·容器·dns