在一些物联网项目中,我没有使用嵌入式Linux中常见的GPIO/SPI/I2C内核编译的方式。而尝试使用USB CDC为基础提供ACM/ECM的编程接口。编程语言方面,也没有选用C/C++/Makefile,而是使用脚本语言如Python/JavaScript/Lua来构建应用层设计。标准接口带来的方便是不言而喻的,USB的ACM类对应串口编程,ECM对应Socket编程,在Linux中非常容易。
但是我发现来源不同的USB Stack在不同的Linux发布版中却不是都能够工作正常。我选择了STM32F103/401作为硬件,而USB Device堆栈选用了
- mbed社区第三方堆栈,是STM32F1 Cube HAL SDK的C++封装;
- Keil 4/5内置的RTX USB堆栈,C库;
- MicroPython的USB CDC堆栈,STM32F4 Cube HAL SDK,C源码;
- STLINK/V2复合设备中的CDC设备,闭源
- mbed CMSIS-DAP的mbed USBSerial 堆栈,开源,Github。
目标操作系统包括:
- Windows XP/7/8/10
- OpenWRT on WRTnode
- Ubuntu 12.04 server/desktop
- Ubuntu 14.04 server
- Ubuntu 15.04 desktop
- Ubuntu 17.04 desktop
发现固件1/2即mbed社区/Keil的USB堆栈在Windows,以及Ubuntu 15.04以上的操作系统可以工作,而OpenWRT和Ubuntu 12.04/14.04均没有任何输出。
在Ubuntu中,我分别测试了stty/cat/echo/gtkterm/minicom,以及Python/Lua,测试证明这些方式表现一致,没有输出的问题至少与编程语言无关。采用了内置的usbmon工具来测试。
- f3e3f9c0 857391360 S Ii:1:004:1 -115:2 16 <
- f3f2e180 857391559 S Co:1:004:0 s 21 22 0003 0000 0000 0
- f3f2e180 857414072 C Co:1:004:0 0 0
- f3e3fa80 857414467 S Bi:1:004:2 -115 128 <
- f3e3fb40 857414547 S Bi:1:004:2 -115 128 <
- f3e3ff00 857414595 S Bi:1:004:2 -115 128 <
- f3e3fe40 857414636 S Bi:1:004:2 -115 128 <
- f3e3f900 857414676 S Bi:1:004:2 -115 128 <
- f3e3f780 857414716 S Bi:1:004:2 -115 128 <
- f3e3f6c0 857417325 S Bi:1:004:2 -115 128 <
- f3e3f600 857417399 S Bi:1:004:2 -115 128 <
- f3e3fc00 857417435 S Bi:1:004:2 -115 128 <
- f3e3fcc0 857417469 S Bi:1:004:2 -115 128 <
- f3e3f540 857417502 S Bi:1:004:2 -115 128 <
- f3e3f480 857417533 S Bi:1:004:2 -115 128 <
- f3e3f3c0 857417565 S Bi:1:004:2 -115 128 <
- f3e3f300 857417594 S Bi:1:004:2 -115 128 <
- f3e3f240 857417622 S Bi:1:004:2 -115 128 <
- f3e3f180 857417650 S Bi:1:004:2 -115 128 <
- ----------------------------------------
- f3e3f9c0 1138689644 S Ii:1:004:1 -115:2 16 <
- f51fd6c0 1138692116 S Co:1:004:0 s 21 22 0003 0000 0000 0
- f51fd6c0 1138703025 C Co:1:004:0 0 0
- f3e3fa80 1138703444 S Bi:1:004:2 -115 128 <
- f3e3fb40 1138703524 S Bi:1:004:2 -115 128 <
- f3e3ff00 1138703570 S Bi:1:004:2 -115 128 <
- f3e3fe40 1138703610 S Bi:1:004:2 -115 128 <
- f3e3f900 1138703652 S Bi:1:004:2 -115 128 <
- f3e3f780 1138703692 S Bi:1:004:2 -115 128 <
- f3e3f6c0 1138703817 S Bi:1:004:2 -115 128 <
- f3e3f600 1138703865 S Bi:1:004:2 -115 128 <
- f3e3fc00 1138703906 S Bi:1:004:2 -115 128 <
- f3e3fcc0 1138703947 S Bi:1:004:2 -115 128 <
- f3e3f540 1138703987 S Bi:1:004:2 -115 128 <
- f3e3f480 1138704026 S Bi:1:004:2 -115 128 <
- f3e3f3c0 1138704066 S Bi:1:004:2 -115 128 <
- f3e3f300 1138704106 S Bi:1:004:2 -115 128 <
- f3e3f240 1138704147 S Bi:1:004:2 -115 128 <
- f3e3f180 1138704188 S Bi:1:004:2 -115 128 <
- f6c65840 1138704450 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
- f6c65cc0 1138704878 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
- f6c65d80 1138704970 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
- f6c65600 1138705045 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
- f6c65240 1138705117 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
- f6c65000 1138705189 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
- f6c659c0 1138705261 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
- f6c65b40 1138705333 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
- f6c656c0 1138705459 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
- f6c65300 1138705515 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
- f6c65f00 1138705559 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
- f6c65900 1138705603 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
- f6c65780 1138705646 S Bo:1:004:2 -115 13 = 48656c6c 6f20776f 726c640d 0a
从上面的日志可以看到,该端口的Bulkin无输出,而Bulkout可以输入数据(Hello world\r\n)。而如果换到Windows下,串行终端中会输出“Hello world message x”。
这个问题有些跨领域,(MCU和Linux),我请教了mbed社区、Stackoverflow和STM32社区。目前
唯二有帮助的是:
1. 这些固件在Ubuntu15.04以上工作正常;
2. 可能和Linux设备文件和USB设备描述符有关。
英文网址: