You need to enable JavaScript to run this app. 如何在内核空间直接读取CDC协议模拟TTY的USB stick数据
优惠活动
大模型
产品
解决方案
定价
更多

如何在内核空间直接读取CDC协议模拟TTY的USB stick数据

CDC模拟串口USB Stick内核空间直接读取数据方案

实现思路

无需完全从零编写全新USB驱动,优先基于内核原生cdc_acm驱动做定制修改,是成本最低、兼容性最高的方案,仅在设备存在私有CDC扩展的场景下考虑独立编写驱动。

方案1:修改内核cdc_acm驱动导出内核态数据

内核自带的drivers/usb/class/cdc-acm.c驱动已经完整实现了CDC ACM类设备的枚举、URB收发、串口协议解析逻辑,只需在数据接收路径插入自定义留存逻辑即可:

  • 找到驱动中acm_rx_bulk函数,该函数是USB批量端点接收数据的回调入口,所有设备上传的原始数据都会先进入该函数处理
  • 在函数将数据拷贝到tty层缓存之前添加你的自定义逻辑,示例修改如下:
// 原有代码:获取URB实际接收数据长度
int count = urb->actual_length;
if (count == 0)
    goto exit;

/* 新增自定义逻辑开始 */
unsigned long flags;
// 提前初始化自旋锁保护自定义缓存区,防止并发访问冲突
spin_lock_irqsave(&custom_buffer_lock, flags);
// 将数据拷贝到你预先分配的内核虚拟地址缓存区
memcpy(custom_kernel_buffer, urb->transfer_buffer, min(count, CUSTOM_BUF_MAX_LEN));
// 可按需添加时间戳标记、数据预处理逻辑
spin_unlock_irqrestore(&custom_buffer_lock, flags);
/* 新增自定义逻辑结束 */

// 原有代码:将数据送入tty层,不影响原有/dev/ttyACM*设备的用户态访问能力
tty_insert_flip_string(&acm->port, urb->transfer_buffer, count);
tty_flip_buffer_push(&acm->port);
  • 如果需要其他内核模块调用该数据,可导出访问接口:
// 内核态数据读接口
int read_cdc_stick_data(u8 *out_buf, int read_len)
{
    unsigned long flags;
    int copy_len;

    spin_lock_irqsave(&custom_buffer_lock, flags);
    copy_len = min(read_len, CUSTOM_BUF_MAX_LEN);
    memcpy(out_buf, custom_kernel_buffer, copy_len);
    spin_unlock_irqrestore(&custom_buffer_lock, flags);

    return copy_len;
}
EXPORT_SYMBOL_GPL(read_cdc_stick_data);
  • 最后修改驱动的id_table仅匹配你的设备VID/PID,避免影响其他CDC ACM设备,重新编译模块替换系统原有cdc_acm模块即可生效。

方案2:独立编写自定义USB CDC驱动

如果不希望修改公共内核驱动,可独立编写专属驱动:

  • 驱动初始化时调用usb_register注册USB驱动,在id_table中填写你的设备VID、PID作为匹配规则
  • 在probe回调中完成端点查找、接收URB初始化,提交URB到USB核心
  • 在URB接收回调中直接处理设备上传数据,存入自定义缓存区并导出访问接口
  • 该方案完全不依赖cdc_acm驱动,可自主控制全流程,适合有高实时性、特殊安全要求的场景。

关键注意事项

  • URB回调函数运行在原子上下文,不能调用任何可能休眠的函数,内存分配必须使用GFP_ATOMIC标记
  • 多核心并发访问共享缓存区必须加锁,避免数据错乱
  • 所有内存拷贝操作必须做边界检查,避免越界访问导致内核崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 23:00:03