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

Zephyr OS新增USB接口字符串描述符索引配置问题咨询

Zephyr OS USB自定义字符串描述符索引异常解决方案

问题根因

Zephyr USB设备栈按字符串描述符在链接段中的排布顺序,从0开始依次分配索引:

  • 索引0固定为语言ID描述符
  • 索引1、2、3分别对应内置的厂商、产品、序列号字符串描述符
  • 以上内置描述符全部注册在usbd_str_descr_primary段,栈初始化时优先遍历该段分配索引

使用USBD_STRING_DESCR_DEFINE(primary)将自定义描述符加入primary段时,若自定义描述符所在源文件的链接顺序早于内置usb_descriptor.c,就会被排到段前部,抢占低索引值(返回索引0就是抢占了语言ID描述符的位置),直接破坏描述符结构导致枚举异常。

可落地解决方案

方案1:使用非primary段注册(官方推荐,无兼容性问题)

不要将自定义字符串描述符注册到预留的primary段,改用自定义段名即可。栈会在遍历完所有primary段内置描述符后,再遍历其他自定义段的描述符分配索引,天然保证自定义描述符索引从4开始。
修改后的代码示例:

// 仅需将宏参数的primary替换为自定义段名,例如webusb、user均可
USBD_STRING_DESCR_DEFINE(webusb) struct webusb_iface_descriptor webusb_string_descr = {
    /* webusb iface String Descriptor */
    .bLength = sizeof(struct webusb_iface_descriptor),
    .bDescriptorType = USB_DESC_STRING,
    .bString = WEBUSB_IFNAME,
};

void webusb_init() 
{
    int idx = usb_get_str_descriptor_idx(&webusb_string_descr);
    if (idx > 0) {
        webusb_desc.if0.iInterface = idx;
    }
}

该方案不需要修改任何链接器配置、CMake规则,适配所有Zephyr 3.0及以上版本,不会随版本迭代出现排序异常。

方案2:调整primary段链接顺序(不推荐)

如果必须将自定义描述符放到primary段,需要通过链接规则保证内置usb_descriptor.c的目标文件排在自定义目标文件之前:

  • 可以在应用的CMakeLists.txt中,将包含自定义描述符的源文件添加到链接列表的末尾
  • 也可以修改链接脚本,对usbd_str_descr_primary段添加SORT_BY_NAME规则,通过给自定义描述符的符号名加后缀的方式调整排序
    该方法依赖版本内置文件的链接、命名规则,版本升级后容易失效,非特殊场景不建议使用。

注意事项

  • 禁止手动硬编码字符串索引值,现有通过usb_get_str_descriptor_idx()动态获取索引的写法完全正确,描述符排序正常后会自动返回符合预期的索引值
  • 自定义字符串描述符不要使用primary作为段名,避免和内置描述符抢占排序位置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:15:24