[STM32F4] STM32F4使用USB接口3G网卡

[复制链接]
16683|23
 楼主| lin704932121 发表于 2017-1-24 16:44 | 显示全部楼层 |阅读模式
本帖最后由 lin704932121 于 2018-5-4 23:34 编辑

    大概去年这时候,21ic发了一波STM32F469I-Discovery板子。我很高兴能拿到这拿到这块板子,并写了两篇试用帖子【STM32F469I试用】Linux下USB无线网卡驱动的移植【STM32F469I试用】USB摄像头的采集与显示。最近,有坛友问我是否有相应的3G网卡驱动,我趁这个假期把之前移植好的代码整理了一下,分享给大家。这个3G网卡驱动大概消耗十几KB的内存。
一、USB 3G网卡拨号流程
    USB 3G网卡和PC一般是通过modem(也可以说是虚拟串口)来进行通信的。3G网卡插入后,首先要用AT指令拨打指定运营商号码,再通过PPP认证协议获取到自身的IP地址。然而现在厂商为了方便用户安装驱动程序,
3G网卡一上电是一个存储类,用户通过它可以安装.exe文件的驱动程序。驱动程序安装完成后,3G网卡再次上电,驱动程序会向3G网卡发送一串特定指令。3G 网卡收到特定指令后,会使USB的D+和D-引脚浮空,造成USB断开。接着PC会再一次枚举3G网卡,此时3G网卡就会成为modem(虚拟串口)类。由于每个厂商甚至每种型号的3G网卡的特定指令都不一样,因此如果厂商没有提供Linux下的驱动话,在Linux下进行拨号上网就便的很困难。还好,有人抓取了windows下的驱动程序和3G网卡之间的USB通信协议包,获取到了这些特定指令,详情可见usb_modeswitch这个开源项目。
    下图是将
usb_modeswitch移植到STM32F4后的拨号流程图,3G网卡插入后,首先判断modem驱动是否支持该型号网卡,如果支持就直接使用AT指令进行拨号,然后再进行ppp认证。如果不支持再判断usb_modeswitch是否可以转换网卡的模式
3G网卡拨号流程图.PNG

二、联通USB 3G网卡的使用
   
我手上有个联通华为E261型号的3G网卡,就用它来做测试吧。

    1.运行 EvalBoards\ST\STM32469I-Discovery\uCOS-III\KeilMDK\uCOS-III.uvproj  ,编译并直接烧写程序。工程环境用的是MDK 4.7。
    2.程序烧写完成后会同时在USART3和LCD上输出信息。USART3 连接到了板子上的STLINK,PC机上直接打开这个虚拟串口就可以使用它了。
    2.用一根OTG线连接板子上USB FS端口,并插入3G网卡。   
    3.如下图串口终端中输入ping命令测试网络连通性

测试实物i图

测试实物i图

     
    UDP上行带宽测试

   
工程里包含有iperf带宽测试程序。如下图,在
串口终端中输入:
     iperf -c 120.25.217.198 -u -b 4Mbits -t 18 -i 1
    其中,
120.25.217.198是我的一个云服务器ip地址,-u代表udp测试,-b 4Mbits代表测试带宽4Mbits/s,-t 18代表测试时间18秒,-i 1代表每秒钟报告一次测试结果。
   

E261 UDP带宽测试

E261 UDP带宽测试

    可以看到,服务器报告的测试带宽为1.58Mbits,丢包率0.044%。

    TCP上行测试
    如下图,在串口终端中输入:
     iperf -c 120.25.217.198 -t 18 -i 1

E261 TCP测试1

E261 TCP测试1

      可以看到,TCP测试带宽仅为250Kbits/s,远远不如UDP测试的速率。这其中一方面是因为3g网卡和服务器的传输延迟大,另一方面是lwip配置的发送缓冲区不够大。将lwipopts.h中TCP_SND_BUF修改为(8*TCP_MSS),重新编译。
  1. /* TCP sender buffer space (bytes). */
  2. #define TCP_SND_BUF             (4*TCP_MSS)
-->
  1. /* TCP sender buffer space (bytes). */
  2. #define TCP_SND_BUF             (8*TCP_MSS)
   如下图,重新进行TCP上行测试,可以看到TCP测试带宽提高到了550Kbits/s。然而提高发送缓冲区也意味着消耗更多内存,终端中输入stats命令,可以看到内存堆的最高消耗由15KB提高到了21KB。
MEM HEAP
        avail: 24576
        used: 1532
        max: 15920
        err: 0
-->
MEM HEAP
        avail: 24576
        used: 1532
        max: 21836
        err: 0

E261 TCP测试2

E261 TCP测试2


三、其它运营商3G网卡使用
    usb_modeswitch只是转换3G网卡模式,并不识别3g网卡的运营商。代码中默认是中国联通的拨号脚本,如果想使用中国移动或中国电信3g上网卡,需要在modem.c文件modem_probe()函数中,取消注释相应运营商的拨号函数。
  1.     for(i=0;i<4;i++)
  2.     {
  3.         msleep(3000+2000*i);
  4.         if((ret = modem_dial_china_unicom(modem)) == 0) break;           //中国联通拨号脚本函数
  5. //        if((ret = modem_dial_china_telecom(modem)) == 0) break;        //中国电信拨号脚本函数
  6. //        if((ret = modem_dial_china_mobile(modem)) == 0) break;         //中国移动拨号脚本函数
  7.     }
当然,也可以尝试使用AT+COPS?指令来识别出3g网卡当前所使用的运营商,再使用不同的拨号脚本。

手里还有另一块华为MU509联通制式模块,顺便也附上它的UDP带宽测试结果图吧。测试结果的带宽并不高,只有380Kbits/s左右。
MU509 UDP测试.jpg

USB-3G-Modem-for-STM32F4xx.rar (4.08 MB, 下载次数: 347)

2017/2/19追记:
我重新运行了板子上的代码。插上华为E261型号3G网卡后,AT指令拨号总是失败。然而我假期在家里测试是可以的,来到北京就不行了?
我试着在PC上使用USBPcap抓取3G网卡通讯协议包,发现PC对3G网卡发送有一条特殊AT指令AT&FE0V1X1&D2&C1S0=0。将该指令添加到拨号脚本的函数里,3G网卡可以正常拨号。暂时还不明白这条指令是什么意思。
在modem.c文件modem_dial_china_unicom()函数里,添加AT&FE0V1X1&D2&C1S0=0指令。
  1.      struct modem_chat chat[] =
  2.      {
  3.         {"AT\r","OK"},
  4.         {"AT+CGDCONT=1,"IP","3gnet",,0,0\r","OK"},
  5.         {"AT+CFUN=1\r","OK"},            
  6.         {"ATDT*99#\r", "CONNECT"},
  7.         { } /* Terminating entry */
  8.      };
  修改为:
  1.     struct modem_chat chat[] =
  2.     {
  3.         {"AT\r","OK"},
  4.         {"AT+CGDCONT=1,"IP","3gnet",,0,0\r","OK"},
  5.         {"AT+CFUN=1\r","OK"},           
  6.         {"AT&FE0V1X1&D2&C1S0=0\r","OK"},
  7.         {"ATDT*99#\r", "CONNECT"},
  8.         { } /* Terminating entry */
  9.     };

评论

强  发表于 2018-4-25 06:59
 楼主| lin704932121 发表于 2017-2-19 23:52 | 显示全部楼层
本帖最后由 lin704932121 于 2017-2-26 17:34 编辑

STM32469I-Discovery板子是去年ST新出的,价格还是比较高。这里使用更普遍、更便宜的板子STM32F4-Discovery来演示这个demo。

1、如下图,用USB-TTL转串口连接STM32F4-Discovery 板子上的USART2(PA2和PA3引脚)。
2、将附件STM32F4-Discovery.rar解压到目录EvalBoards\ST下面。
3、打开工程文件EvalBoards\ST\STM32F4-Discovery\uCOS-III\KeilMDK\uCOS-III.uvproj,编译并下载程序。
4、将PC上的串口调试工具设置成115200波特率,即可看到3G网卡的枚举和拨号过程。

IMG_20170219_232726.jpg

STM32F4-Discovery.rar

685.15 KB, 下载次数: 230

yiyigirl2014 发表于 2017-1-25 10:00 | 显示全部楼层
我有一个这,不知道咋回事,电脑都驱动不起来,,,电信的
hanzixi_angel 发表于 2017-2-1 17:55 | 显示全部楼层
楼主威武  终于发布了  非常非常感谢
sanxingnote7 发表于 2017-2-1 22:59 | 显示全部楼层
这个3G的USB驱动怎么写的?
chenci2013 发表于 2017-2-1 23:02 | 显示全部楼层
这个是自己写的操作系统吗?
 楼主| lin704932121 发表于 2017-2-2 12:00 | 显示全部楼层
本帖最后由 lin704932121 于 2017-2-2 12:05 编辑
chenci2013 发表于 2017-2-1 23:02
这个是自己写的操作系统吗?

不是,用的是uCOS-III嵌入式操作系统。
 楼主| lin704932121 发表于 2017-2-2 12:25 | 显示全部楼层
本帖最后由 lin704932121 于 2017-2-2 12:38 编辑
sanxingnote7 发表于 2017-2-1 22:59
这个3G的USB驱动怎么写的?

modem驱动是自己写的,usb_modeswitch驱动是移植的,而USB协议栈接口是移植linux内核的。驱动和3G网卡通信一般使用USB协议里的批量传输来进行通信。
wangdezhi 发表于 2017-2-2 23:17 | 显示全部楼层
lin704932121 发表于 2017-2-2 12:00
不是,用的是uCOS-III嵌入式操作系统。

uCOS-III的驱动代码是开源的吗?
wangdezhi 发表于 2017-2-2 23:18 | 显示全部楼层
lin704932121 发表于 2017-2-2 12:25
modem驱动是自己写的,usb_modeswitch驱动是移植的,而USB协议栈接口是移植linux内核的。驱动和3G网卡通信 ...

,厉害,这个没有嵌入式的功底,还真是不一定会弄。
 楼主| lin704932121 发表于 2017-2-3 11:20 | 显示全部楼层
wangdezhi 发表于 2017-2-2 23:18
,厉害,这个没有嵌入式的功底,还真是不一定会弄。

谢谢,uCOS-III只是个内核,还没有驱动部分的代码。
jsbrains 发表于 2017-2-11 23:57 | 显示全部楼层
谢谢楼主无私奉献,受教了。
我们之前用stm32简单用uart连接过华为4G模块,通过AT命令利用模块自身实现的网络协议栈测试了TCP和UDP通信。
请教楼主,如果使用407的USB与华为模块连接,是否也有办法像linux下一样虚拟出一个高速的com进行通讯么?这样的话,大部分的应用都可以不用LwIP而直接利用模块上的协议栈,不知道速度上会不会有很大突破。
 楼主| lin704932121 发表于 2017-2-12 13:23 来自手机 | 显示全部楼层
jsbrains 发表于 2017-2-11 23:57
谢谢楼主无私奉献,受教了。
我们之前用stm32简单用uart连接过华为4G模块,通过AT命令利用模块自身实现的网 ...

我没有使用过模块内部的TCP/UDP协议栈,也没有比较过模块USB接口和UART接口速率的区别。但我测试的华为MU509模块USB接口的速率并不高,只有380Kbits/s左右,UART接口可能也会达到这个速率吧。
sblpp 发表于 2017-11-29 23:58 | 显示全部楼层
顶楼主,太强了!
beyond696 发表于 2018-4-18 11:16 | 显示全部楼层
这个不错,有时间了也玩玩
wandersky 发表于 2018-6-12 14:40 | 显示全部楼层
你好,我看你的驱动了,3G模块在上位机上模拟了3个USB接口,你只用了第一个,另外2个接口不需要使用吗?
 楼主| lin704932121 发表于 2018-6-15 13:01 | 显示全部楼层
wandersky 发表于 2018-6-12 14:40
你好,我看你的驱动了,3G模块在上位机上模拟了3个USB接口,你只用了第一个,另外2个接口不需要使用吗? ...

3个接口在PC机上看到的就是3个COM口,拨号和数据连接只用到其中一个接口就行了。具体是哪个接口不同的3G模块可能不一样,驱动里默认使用第一个接口。
menglogic 发表于 2019-12-12 11:05 | 显示全部楼层
楼主好厉害!万分感谢楼主分享!
 楼主| lin704932121 发表于 2019-12-17 18:10 | 显示全部楼层
menglogic 发表于 2019-12-12 11:05
楼主好厉害!万分感谢楼主分享!

不客气
hanhuliang 发表于 2019-12-31 15:58 | 显示全部楼层
最近会用到
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

82

帖子

18

粉丝
快速回复 在线客服 返回列表 返回顶部