## 堆损坏 > 链路层的堆已损坏。 ---- 链路层的堆有一个内部完整性检查机制:每个内存块都有一些魔术数字。当这些数字与预期不同时,说明该块必然损坏, 所以触发断言。 ### 如何处理? * 您是否使用 `ll_malloc` 从链路层的堆中分配缓冲区?检查是否写入了过多的字节。 * 寻找野指针。 * 二分或回退到旧版本,以定位导致问题的代码。 * [转储内存](/user_guide/dive-into-sdk.html#memory-dump)并联系我们以获得进一步的支持。
## 内存不足 > 控制器无法分配内存。 ---- 控制器无法为链路层的控制过程或内部消息分配内存。 ### 如何处理? 您是否使用 `ll_malloc` 分配了太多的内存?请减少分配量。 提示:调用 `ll_get_heap_free_size` 来检查链路层的堆的剩余字节数。
## 内存损坏 > 进程间通信的变量已损坏。 ---- 控制器内部的进程间通信的变量已损坏。 这些变量的内存位置:在为 `platform.bin` 保留的 RAM 范围的末尾附近。 ### 如何处理? * 寻找野指针。 * 二分或回退到旧版本,以定位导致问题的代码。 * [转储内存](/user_guide/dive-into-sdk.html#memory-dump)并联系我们以获得进一步的支持。
## 内存损坏 > 多任务处理的相关变量已损坏。 ---- Controller 内用于多任务处理的变量已损坏。 这些变量的内存位置:在为 `platform.bin` 保留的 RAM 范围的末尾附近。 ### 如何处理? * 寻找野指针。 * 二分或回退到旧版本,以定位导致问题的代码。 * [转储内存](/user_guide/dive-into-sdk.html#memory-dump)并联系我们以获得进一步的支持。
## 内存损坏 > HCI 的变量已损坏。 ---- 内部主机控制器接口 (HCI) 的变量已损坏。 ### 如何处理? * 寻找野指针。 * 二分或回退到旧版本,以定位导致问题的代码。 * [转储内存](/user_guide/dive-into-sdk.html#memory-dump)并联系我们以获得进一步的支持。
## FreeRTOS 特定:任务函数退出 > 一个实现任务的函数已退出。 ---- 一个实现任务的函数不能退出或尝试返回到它的调用者,因为无法返回(无调用者)。 ### 如何处理? 如果一个任务想要退出,它应该调用 `vTaskDelete(NULL)`。
## FreeRTOS 特定:在 ISR 中调用不安全的 API > 一个不是中断安全的函数在 ISR 中被调用。 ---- 一个不是进入临界区的中断安全版本的函数,在中断上下文中被调用了。 只有以 "FromISR" 结尾的 API 函数才能在中断中使用。 ### 如何处理? * 调用以 "FromISR" 结尾的对应函数; * 使用 `IS_IN_INTERRUPT()` 来测试是否在中断中,并调用正确的 API 变体。
## FreeRTOS 使用违规 > 各种 FreeRTOS 使用违规的情况。 ---- 示例: * 在没有调用 `vPortEnterCritical()` 的情况下,调用 `vPortExitCritical()` * 中断优先级高于 `configMAX_SYSCALL_INTERRUPT_PRIORITY`,并且在 ISR 中, 调用了一个 “FromISR” 函数。 ISR 安全的 FreeRTOS API 函数必须只从分配了等于或低于 `configMAX_SYSCALL_INTERRUPT_PRIORITY` 的优先级的中断中调用, 即优先级的值等于或大于 `configMAX_SYSCALL_INTERRUPT_PRIORITY`。
## 格式错误的 HCI 命令 > 参数过长 ---- HCI 命令的参数超过了最大长度。有些 HCI 命令有一个可变的参数个数,但有一个上限。 以 _LE Set Extended Scan Parameters_ 为例。它最多接受两种主广播信道上的 PHY 类型。 相应的 GAP API 是 `gap_set_ext_scan_para`,如果传递了一个大于 2 的值作为 `config_num`,就会触发这个断言。 ```c /** * ... * @param config_num 配置数量最多为 2。它表示主机将配置多少种 PHY * ... */ uint8_t gap_set_ext_scan_para(const bd_addr_type_t own_addr_type, const scan_filter_policy_t filter, const uint8_t config_num, const scan_phy_config_t *configs); ``` ### 如何处理? 查看 [BLE 编程指南](/application-notes/pg_ble_stack_cn/index.html),不要向 `gap_set_ext_scan_para`、`gap_ext_create_connection` 等传递无效的参数。
## 无效的内部ACL数据包长度 > 分配的ACL数据包长度比数据短 ---- 发送ACL数据(任何L2CAP数据或信令)时,首先在链路层分配内部数据包,然后填充数据。填充数据时,发现内部数据包的总长度实际上比数据短。 这个断言的**最可能的原因**是栈API的线程安全性被破坏,即栈API从另一个线程(任务)调用。 ### 如何处理? 确保栈API的线程安全性没有被破坏。查看 [BLE 编程指南](/application-notes/pg_ble_stack_cn/index.html) 以了解更多细节。 提示: * 使用 _Afx Tool_ 自动检查;或者, * 在由 Keil 生成的 _静态调用图_ 中手动搜索这种情况。
## 内存不足 > 从一个内部堆中分配内存失败 ---- 当堆上的分配失败时(堆内存不足),会触发事件 `PLATFORM_CB_EVT_HEAP_OOM`。 参数 `(void *data)` 是从一个整数转换而来,用于标识哪个项目OOM。 | #Id | 堆类项目 | |:------:|:--------------------- | | 0 | FreeRTOS 的堆 | | 1 | 链路层的堆 | | 2 | 链路层的任务池 | 堆 #0 上的 OOM 只发生在内置 FreeRTOS 的包中。链路层的任务池不太可能耗尽。 ### 如何处理? * FreeRTOS 的堆: 检查与 FreeRTOS 的堆使用(`pvPortMalloc`/`vPortFree`)相关的内存泄漏; 如果堆大小不足以满足应用程序的需求,使用 NoOS 变体并外部构建 RTOS。 * 链路层的堆: 检查与链路层的堆使用(`ll_malloc`/`ll_free`)相关的内存泄漏; 利用 `ll_get_heap_free_size` 避免将过多的数据(`att_server_notify`/`gatt_client_write_value_of_characteristic`/…)送入 BLE 协议栈中。
## 内部错误或未识别的错误 ---- 联系我们以获得进一步的支持。