水水水木木木 发表于 2024-4-17 15:55:04

分享基于安富莱ThreadX全家桶2.0版本实现的USBX CDC ACM+PPP连接服务器

1.本人菜鸟一直在索取,从未回报大家,这次花了2个多星期的时间,学习了USBX和NetX,整理出来了此模板分享给大家:
采用安富莱ThreadX全家桶2.0版本为模板,H7开发板,使用USBX的CDC_ACM驱动,实现虚拟串口,枚举出EC20和EC800N的Modem接口,然后使用NetX Duo的PPP协议拨号上网,使用TCP协议连接服务器。
(一定要用新版驱动包!也建议大家在开发其他项目时候尽量选择比较新的驱动版本,老的版本bug非常多。尤其是ST的USB协议栈,1.9和1.9.1完全是天地之差,这是我花了一个星期时间得出来血的教训。建议大家开发USB协议栈直接用ST-H7的1.11.2版本的BSP驱动包。ThreadX全家桶用6.3版本就够了。其实ThreadX全家桶也有bug,或者说是不完善的地方,就比如说PPP协议,在2022年驱动EC600N的时候就会有问题,2022年底修复了这个问题。如果你在2022年用PPP拨号的话,就需要花很大精力找问题,修改代码。上面说这么多,就是告诉大家从零调试一定要选择最新的驱动包,否则十分有可能调不出结果)


目前模板不完善的地方:

1.1 4G模块是复合设备,所以会枚举出几个串口,如何选择其中的一个串口作为通信对象,还没研究。当前解决方案是在枚举的时候固定了某个串口。
1.2 异常处理机制不完善。USB报错、PPP报错、TCP报错都需要汇总处理,重启4G模块、重启网络服务,重启USB服务等方式。

2.移植过程


2.1.CDC ACM驱动移植:和CDC ECM驱动移植不一样,ECM不需要改动任何源码,可以直接枚举出ECM设备。ACM需要修改源码。像移远的EC20和EC800N模块,AT接口的类型代码bInterfaceClass是0xFF,默认的ACM接口数据类型是0x0A。所以要修改成0xFF。宏定义UX_HOST_CLASS_CDC_DATA_CLASS修改成0xFF即可。其他地方不需要改动。如果默认的12个USB通道不够用,可以修改成16个,H7支持16个,F4只有8个,修改UX_HCD_STM32_MAX_NB_CHANNELS为16即可。
最后就是在枚举回调函数里面,选择某一个串口为通信接口(未实现,有哪位前辈可以指导下怎么获取几个串口的句柄)。目前我是在_ux_host_class_cdc_acm_entry函数里面,根据4G模块的Modem接口编号,指定枚举该接口。
2.2.PPP协议移植:PPP协议官方也有流程指导。唯一没有的就是ISR中断部分的代码参考。我也是卡在这上面了几天时间。PPP数据接收直接在USB ACM函数里面做就可以了。
主要是数据发送,PPP数据发送是每次1个字节,我原本是每来1个字节就调用ACM接口写,这样做的效率非常低,导致网速测试的时候,数据量大就容易掉线,原因是USB接口处理不过来这么频繁的数据。
后面改用缓存,一直接收PPP发来的数据,直到PPP不发数据了,我将所有的数据一次性写到ACM接口。这种方式就非常稳定。如果大家有其他好的方式也可以分享一下。

3.简单说下CDC-ECM驱动移植:用2.0版本的ThreadX家桶,按照USBX文档里面的流程就可以实现ECM驱动EC20。获取LINK状态成功之后,就是DHCP获取IP,然后就可以联网了。我用了一个多星期的时间搞出来,一直卡在通讯不稳定,原因是ST的1.9版本的USB协议栈问题很大,USB通讯不稳定。我换成1.11.0版本联网就很稳定了。实际移植ECM比ACM还简单。

4.网速测试:
H7开发板 + USB CDC ECM + EC20:
10K需要400ms。
100K需要1000ms。
500K需要2000ms,
1M需要3000ms。
平均来看,网速在200K-300K左右。如果传输大于1M字节的数据,速率应该还能提升。由于USB全速设备12Mbps,因此最大上限在1M字节/s。一般不会超过500K/s。

H7开发板 + USB CDC ACM + PPP + EC20:

1K:1ms
10K:最小150ms,最大633ms。15-66K/s
100K:最小1394ms,最大1743。57-71K/s
500K:最小7783ms,最大10081ms。50-64K/s
1M:最小16959ms,最大21090ms。47-59K/s


H7开发板 + USB CDC ACM + PPP + EC800N:

1K:最小1ms,最大2ms。这个可以认为是误差。
10K:最小119ms,最大244ms。41-84K/s
100K:最小998ms,最大2226。45-100K/s
500K:最小7065ms,最大9773ms。50-70K/s
1M:最小18315ms,最大24373ms。40-50K/s



F407 + RTX5全家桶 + 硬件串口 + 921600bps + PPP拨号 + EC800M:
1K:10ms
10K:280ms。36K/s
100K:3250ms。31K/s
500K:16600ms。30K/s
1M:33000ms。30K/s



总结:
1.虚拟串口的平均速率在50K左右,最高能到100K。我测试硬件串口的速率稍低,但是硬汉老师说硬件串口也可以做到50K/秒,大家根据自己的项目可以实测下。
2.数据量越大,平均速率和最高速率就越低。
3.PPP拨号效率较低,在USB全速12Mb/s的情况下,CAT1和CAT4的速率近似。
4.CDC-ECM驱动EC20,传输1M只需要3秒,且数据量越大,平均速率就越高。基本上可以做到300K-500K/s。
ACM+PPP是50K/s,ECM直驱是300K+/s,差距很大了。由于搞不定ECM驱动EC800N,所以没办法比较CAT1的ECM直驱和ACM+PPP差距究竟有多大。

如果有前辈可以指导下,感激不尽。毕竟4G-CAT1更配MCU,CAT4贵,而且MCU不需要这么高的网速。

上传的模板适配的是H7开发板+EC800N模块。
x度网盘链接:

链接:https://pan.baidu.com/s/1JhYPh4p5qg5EMzPomQrfdA
提取码:1234


https://www.armbbs.cn/static/image/filetype/zip.gifThreadX-CDC-ACM.zip (67.37MB)

eric2013 发表于 2024-4-17 16:09:29

谢谢分享{:8:}

水水水木木木 发表于 2024-4-18 09:39:23

USB虚拟串口PPP网速测试补充个合宙的Air780E模块:
合宙Air780E测试:
1K:1ms
10K:最小162ms,最大320ms。31-61K/s。
100K:最小1538ms,最大3818ms。26-65K/s。
500K:最小12228ms,最大13542ms。37-41K/s。
1M:未通过测试,一直重启

水水水木木木 发表于 2024-4-18 09:41:03

合宙模块在100K以上就容易重启。测试了十几次,没有1次可以跑到1M的,500K测试成功了2次。100K也就成功了几次。1K和10K每次都可以成功。数据量大容易导致PPP接口出现非法字符,导致USB设备被移除。

yuanzhongda 发表于 2024-4-18 10:40:26

请教下,ppp是通过acm发出去的吗,对ppp不太了解

yuanzhongda 发表于 2024-4-18 11:13:06

你好,cdc ecm的程序可以分享下吗

yuanzhongda 发表于 2024-4-18 11:13:27

你好 cdc ecm的程序可以分享下吗

水水水木木木 发表于 2024-4-18 14:45:21

yuanzhongda 发表于 2024-4-18 10:40
请教下,ppp是通过acm发出去的吗,对ppp不太了解

是的,ACM虚拟串口

水水水木木木 发表于 2024-4-18 17:29:52

优化了程序,重新测试了网速:
合宙Air780E网速测试:
1K: 2 ms。
10K: 192 ms。52K/s。
100K: 1538 ms。65K/s。
500K: 4947 ms。101K/s。
1M: 11433 ms。87K/s。
移远EC800N网速测试:
1K: 2 ms。
10K: 187 ms。53K/s。
100K: 1213 ms。82k/s。
500K: 6450 ms。77K/s。
1M: 9922 ms。101K/s。
两个模块的网速相近,互有胜负。按照现在100K/秒来算,比硬件串口最高50K/秒确实要高不少。也符合了USB FS全速12Mbit/秒的速率。毕竟硬件串口才921600bps。之前测试的USB虚拟串口的网速低了不少。

cryfcr 发表于 2024-4-19 08:51:03

{:32:}{:32:}{:32:}{:32:}

hanlin 发表于 2024-4-19 09:13:40

阔以哦,找到好东西了,之前用过esp32 + esp_modem 来使用物理串口实现cmux + ppp

Aesthetics 发表于 2024-4-19 10:29:00

谢谢分享{:8:}

水水水木木木 发表于 2024-4-22 18:01:04

关于ECM驱动合宙Air780E和移远EC800N模块联网不成功的问题,我已经提交bug给官方了。
我买了USB 1.1集线器,将模块插到集线器上,集线器再插到电脑上,这样就强制把模块的USB接口速率从HS高速降低成为FS全速。
linux下经过测试两个模块都不能联网,但是EC20可以联网。linux系统下测试结果和RTOS下的结果一样,因此可以判断是模块FS接口的ECM驱动有问题。
接下来就等官方修复问题。如果修复了,我再和大家汇报。

ruboss 发表于 2024-4-22 23:55:16

我最近也在调4G模块,F427 + RTX5全家桶 + 硬件串口 + 115200bps + PPP拨号 + EC800G。比较有概率出现工作十几分钟之后TCP超时,数据量也不大(NTRIP获取1Hz的RTCM,大概也就1kB/s)。
最开始是4G模块的天线不匹配信号比较差,后面换天线了好了不少,但还是有概率超时

eric2013 发表于 2024-4-23 07:55:11

ruboss 发表于 2024-4-22 23:55
我最近也在调4G模块,F427 + RTX5全家桶 + 硬件串口 + 115200bps + PPP拨号 + EC800G。比较有概率出现工作 ...

不使用全家桶,仅使用AT的TCP透传,稳定性怎么样。

水水水木木木 发表于 2024-4-23 08:48:29

ruboss 发表于 2024-4-22 23:55
我最近也在调4G模块,F427 + RTX5全家桶 + 硬件串口 + 115200bps + PPP拨号 + EC800G。比较有概率出现工作 ...

没遇到过此类问题。没使用过NTRIP和RTCM。我正常使用没出现过TCP超时问题

ruboss 发表于 7 天前

eric2013 发表于 2024-4-23 07:55
不使用全家桶,仅使用AT的TCP透传,稳定性怎么样。

开始的工程是直接用cubeMX创建的,比较简陋,后面因为需求变为多个TCP连接,就没有测试多久,直接换RTX全家桶了,所以还不清楚仅使用AT的TCP透传稳定性怎么样,在简短的半个小时测试里没出现问题。

现在这个问题咨询过厂家,常见建议使用RNDIS。

我个人有几个问题点的猜想:
1.波特率115200可能不够,网络不稳定时PPP服务器那测可能有数据冲击,导致大量数据拥塞在4G模块内出现异常。这个我现在改为921600了,在找机会测试
2.所在环境信号不稳定,天线等硬件存在问题。这个已经换天线了,信号有改善,断联的现象暂时还没复现,只是数据交付不及时的问题还在(正常稳定1Hz,异常时可能十多秒都没数据)
3.模块的DTR引脚可能出现异常跳变,导致模块退出PPP连接(模块默认D2,DTR低电平变高电平断开连接并切换为命令模式)。目前将该引脚下拉了,后续测试对比;这个也还有一个办法可以验证,就是在断联的时候发送“AT”查询模块是否是命令模式

eric2013 发表于 6 天前

ruboss 发表于 2024-4-24 18:10
开始的工程是直接用cubeMX创建的,比较简陋,后面因为需求变为多个TCP连接,就没有测试多久,直接换RTX全 ...

非常感谢分享。

hpdell 发表于 6 天前

不错,貌似研究的很透彻哟,

hpdell 发表于 6 天前

貌似我对 cat1, cat4 , catxx 等总是记不住,很容易就忘记了,惭愧惭愧呀 :lol

morning_enr6U 发表于 6 天前

{:34:}{:34:}{:34:}{:34:}{:34:}

水水水木木木 发表于 5 天前

ruboss 发表于 2024-4-24 18:10
开始的工程是直接用cubeMX创建的,比较简陋,后面因为需求变为多个TCP连接,就没有测试多久,直接换RTX全 ...

移远的模块我使用过2G的,当时用的就是AT透传。没出现过你说的问题。可能是数据量不是很大吧。唯一出问题的就是AT指令、透传经常报错,报错误码,我程序设计的错误码不全,导致经常掉线。比如说AT+CCID这个指令,或者在透传模式下,2G模块突然返回个错误码,我没有处理流程,所以导致容易掉线,后来改用PPP方式,有问题就重启模块,终于做的很稳定了。

水水水木木木 发表于 5 天前

hpdell 发表于 2024-4-25 09:53
貌似我对 cat1, cat4 , catxx 等总是记不住,很容易就忘记了,惭愧惭愧呀

速率不同而已。单片机用CAT1就行。MPU才需要CAT4的高速。
页: [1]
查看完整版本: 分享基于安富莱ThreadX全家桶2.0版本实现的USBX CDC ACM+PPP连接服务器