You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Zephyr中结构体深拷贝出现异常结果的问题求助

问题分析与解决方案:Zephyr BLE中央设备特征UUID存储异常

代码中的致命错误

你的代码存在两个直接导致UUID存储异常的内存分配错误:

  • k_calloc(1, sizeof(new_node)):new_node是指针类型,sizeof(new_node)返回的是指针字节长度(32位系统为4字节,64位为8字节),而非lst_chrc_node_t结构体的实际大小。这会导致分配的内存不足以容纳整个节点,后续赋值会破坏内存结构。正确写法为k_calloc(1, sizeof(lst_chrc_node_t))。
  • new_node->uuid = k_calloc(1, sizeof(new_node->uuid)):同理,new_node->uuid是指针,sizeof得到的是指针大小,而struct bt_uuid结构体需要存储128位UUID数据,远大于指针长度。正确写法为k_calloc(1, sizeof(struct bt_uuid))。

Tentative UUID的含义

Zephyr中的**Tentative UUID(临时UUID)**是针对标准UUID的优化设计:

  • 当BLE外设返回16位或32位的蓝牙SIG标准UUID时,Zephyr不会立即生成完整的128位UUID,而是使用BT_UUID_TENTATIVE类型的结构体。该结构体仅存储短UUID的值,并标记类型为tentative,等到需要完整128位UUID时,再通过短UUID与蓝牙标准UUID基值(00000000-0000-1000-8000-00805F9B34FB)拼接生成。
  • 若直接用*new_node->uuid = *chrc->uuid拷贝tentative UUID结构体,只会复制短UUID部分和类型标记,不会自动扩展为完整128位UUID,这就导致你看到的存储前后UUID不一致——打印时尝试解析完整128位UUID,但实际内存中只有短UUID数据,出现乱码或错误值。

正确实现方式

修复内存分配错误后,使用Zephyr提供的bt_uuid_copy()函数拷贝UUID,该函数会自动处理tentative UUID的扩展逻辑:

typedef struct lst_chrc_node_s {
  sys_snode_t     node;
  struct bt_uuid  *uuid;
  uint16_t        value_handle;
  uint8_t         properties;
  uint8_t         type;
} lst_chrc_node_t;

lst_chrc_node_t *list_create_node(struct bt_gatt_chrc *chrc, uint8_t type)
{
  // 修复:分配结构体大小的内存
  lst_chrc_node_t *new_node = k_calloc(1, sizeof(lst_chrc_node_t));
  if (!new_node)
    return NULL;
  
  // 修复:分配struct bt_uuid大小的内存
  new_node->uuid = k_calloc(1, sizeof(struct bt_uuid));
  if (!new_node->uuid)
  {
    k_free(new_node);
    return NULL;
  }
  
  print_uuid128("UUID that will be store", chrc->uuid);
  // 使用bt_uuid_copy替代直接结构体赋值
  bt_uuid_copy(new_node->uuid, chrc->uuid);
  new_node->value_handle = chrc->value_handle;
  new_node->properties = chrc->properties;
  new_node->type = type;
  print_uuid128("UUID that was stored   ", new_node->uuid);

  return new_node;
}

额外注意事项

  • 销毁链表节点时,需先调用k_free(new_node->uuid),再调用k_free(new_node),避免内存泄漏。
  • 若仅需处理短UUID,可直接存储uint16_t或uint32_t类型的短UUID值,节省内存,但需注意区分UUID的位数类型。

内容的提问来源于stack exchange,提问作者Groux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:05:15