说起来挺有意思的,前几天翻箱倒柜找出一块TI的TMS320DM365开发板,落灰不知道多少年了,记得当年这玩意儿主打低功耗视频处理,1080p能硬解,价格也不贵,很多安防摄像头里都藏着它的芯片,不过看着旁边一堆杜邦线和串口转接板,我心里一沉——这年头谁还天天用串口传数据啊。
插上电,板子亮了,绿灯一闪一闪的,像是跟我打招呼,问题是,我想把板子处理好的视频图像传到电脑上看看效果,串口那几十K的速度,传一张图片都够我泡杯茶了,能不能用USB传?这个念头一冒出来就收不住了,DM365上面确实有个USB 2.0 OTG接口,理论上跑高速模式能到480Mbps,够传视频流了。
说干就干,不过这事儿没想的那么简单,我边折腾边记了些东西,要是你手里也有块类似的板子,或许能少走点弯路。
先搞清楚这USB口到底能干嘛
很多人一上来就急着改代码,结果折腾半天发现方向错了,我当时也是,差点就直接往内核里塞gadget驱动了,后来冷静下来翻了翻DM365的数据手册,发现它的USB控制器其实挺灵活的,能切两种模式:
- Host模式:板子当主机,外接U盘、摄像头这些设备
- Device模式:板子当从设备,连到电脑上,电脑识别它
我们想要的是“板子把数据传给电脑”,那显然得让DM365跑Device模式,电脑是Host,板子是Device,USB线一插,电脑那边得能看到点什么东西才行。
但光知道模式还不够,关键问题是——电脑识别它成什么?如果识别成一个普通U盘,那你只能读写文件,做不到实时视频流传输,我们需要的是一个能支持流式数据传输的协议,这时候有两个主流选择:
| 方案 | 电脑端识别为 | 适用场景 |
| Mass Storage Gadget | U盘/硬盘 | 传文件、回放录像 |
| UVC Gadget | USB摄像头 | 实时视频流预览 |
一看就明白了,咱们要的是UVC Gadget,这样电脑会把DM365当成一个USB摄像头,随便打开个播放器或者浏览器就能看到画面,连驱动都不用装,这个思路一确定,后面的事情就顺了。
内核配置这一关,差点给我整放弃了
DM365跑的是MontaVista Linux,内核2.6.32那会儿的古董版本,好在USB gadget框架已经挺成熟了,但问题出在默认配置上——当初烧进去的内核镜像根本没开UVC支持。
我记得当时是这么一步步摸过去的,首先得确认USB Device Controller驱动还在不在,Davinci平台用的是musb控制器,好在默认是使能的,然后就是gadget层的配置,这块比较绕:
- USB Gadget Support 要编译进内核,不是模块
- UVC Gadget 要勾上,依赖Video4Linux框架
- Frame Buffer相关的v4l2输出设备也得有,不然没图像源
- 别忘了DMA引擎,USB高速传输要是走CPU搬运数据,那帧率直接拉胯
重新编译内核花了我一个半小时,中间还因为工具链版本问题报错了好几次,说实话,嵌入式Linux最烦人的就是这种环境问题,代码本身没毛病,编译链差一个小版本号就给你颜色看,不过当内核打印出“uvc-gadget registered”的时候,那种感觉还挺治愈的。
板子这头怎么把视频喂给USB
内核配好了只算走了一半,UVC Gadget框架搭起来了,但它是空的,没有数据源,你需要把视频数据从采集端“灌”到USB输出端,当时我琢磨了两种路径:
第一种是走v4l2框架内部路由,DM365的视频处理子系统叫VPSS,里面有视频输入前端和输出后端,如果摄像头传感器已经在采集数据了,VPSS可以直接把处理好的YUV或MJPEG流送到v4l2 output设备上,USB gadget驱动从那个设备读数据就行,这套走下来延迟最低,但要求你对DM365的媒体控制器和通路配置比较熟。
第二种是用户空间中转,也就是写个应用程序用v4l2 API把数据读出来再写进去,灵活是灵活,但来回拷贝开销大,1080p的MJPEG流还好,要是YUV裸数据,USB带宽分分钟被撑满,我一开始用了这种偷懒的办法,结果640x480还行,上到720p就各种丢帧。
最后我还是咬牙把VPSS通路配通了,数据在硬件内部走零拷贝路径,大致的数据流是这样的:摄像头传感器 → ISP → IPIPE → 缩放器 → v4l2输出节点 → USB UVC Gadget → 电脑,中间每一步都是在内存buffer之间传递指针,CPU基本不参与搬运,帧率稳定在30fps没问题。
电脑这头的效果,比我想象的好
USB线插上去的那一刻,Windows弹了个“正在设置设备”的提示,几秒钟后设备管理器里多了个“USB Camera”,打开自带的相机应用,画面出来了,虽然延时大概有200毫秒的样子,但颜色和帧率都正常。
Linux电脑上用v4l2-ctl看了一下支持的格式:
- MJPG: 1920x1080, 1280x720, 640x480
- YUYV: 640x480, 320x240
MJPEG在1080p下占的USB带宽大概在40-60Mbps之间波动,离480Mbps的理论上限还远着呢,瓶颈在编码器而不是USB上,不过对于一块十几年前的板子来说,这个表现我已经很满意了,中间遇到过一次USB断开重连的问题,查了半天发现是电源电流不够,板子满载的时候USB PHY掉电,换了个2A的电源适配器就稳了。
折腾这通下来,最大的感受是文档太重要了,DM365的VPSS驱动文档、USB gadget框架的说明,还有Davinci平台的PSP包里的例程,这三样东西来回翻了好多遍,网上现成的教程大多是针对树莓派那种生态完善的板子的,Davinci平台用的人少,很多坑都得自己踩,不过踩完了也就觉得,底层的东西其实都差不多,USB协议栈是标准的,v4l2框架也是标准的,换个平台思路照样能用。
现在这块板子已经连着USB在我桌上稳定跑了两天了,摄像头对着窗外的树,偶尔有鸟飞过就录一段,也不知道它还能稳定多久,先就这么用着吧。




网友评论