发新帖本帖赏金 5.00元(功能说明)我要提问
12345下一页
返回列表
打印
[STM32F4]

【STM32F469I试用】Linux下USB无线网卡驱动的移植

[复制链接]
17158|88
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 lin704932121 于 2017-1-27 10:24 编辑

       看到名单上有我,心里其实挺激动的,毕竟还是第一次收到板子。板子价格也不菲,拿到板子自己也要写点有用的东西才行。USB-Wireless-LAN-Driver-for-STM32F4xx 是我两年前移植的联发科在Linux下USB无线网卡驱动DPO_RT5572_LinuxSTA_2.6.1.3_20121022,使用uC/OS-III操作系统 和 lwip网络协议栈。当时苦于市面上都是WIFI转串口或者WIFI转SPI之类的模块,很少有能直接驱动802.11物理层芯片的模块,既然找不到项目又需要自己便着手移植联发科的USB无线网卡驱动。移植过程花了近半年,这个过程还是挺辛苦的,自己开始时对USB协议和802.11是一窍不通,联发科的驱动虽然开源但是没有任何文档,对ST参考手册上USB 寄存器更是完全不理解。自己只能不断学习,不断在Linux下调时和阅读源代码,不断看ST的参考手册。就这样,慢慢地把工程搭建了起来。去年我将这个软件开源,下半年又抽时间对它进行了些优化,现在驱动占用约64KB的RAM,在USB FS接口下带宽可达3.3Mbits的上行速率、6Mbits的下行速率。在USB HS接口DMA模式下(嵌入式PHY)可达6Mbits的上行速率、7Mbits的下行速率。它还有以下的特性。
1.支持USB无线网卡热插拔
2.支持WEP、WPAPSK-AES、WPAPSK-TKIP、WPA2PSK-AES、WPA2PSK-TKIP等认证和加密方式
3.支持802.11b/g/n
4.使用iwpriv工具对无线网卡进行配置
5.当前支持的USB无线网卡型号为RT5370和RT3070

这个软件原本是在STM32F4-Discovery板子下运行的,收到板子后,花了几天时间将它移植到了STM32F469I-Discovery。
有关 DPO_RT5572_LinuxSTA_2.6.1.3_20121022驱动是如何移植到STM32F4下,修改了哪些宏和那部分源代码,在附件的一篇文档里有详细的说明,这里介绍在STM32F469I-Discovery板子如何使用USB无线网卡。

一、硬件连接

       用一根OTG线连接板子上USB FS端口,并插入USB无线网卡。

二、配置无线网卡
     
     附件的代码里默认的配置为:
     SSID=mytest
     AuthMode=WPA2PSK
     EncrypType=AES
     WPAPSK=12345678

     如果你的无线路由器不是以上配置,那么要修改EvalBoards\ST\STM32469I-Discovery\uCOS-III\rt2870sta_conf.h  中以上几个值。
     SSID 为你无线路由器的信道名称。
     AuthMode 认证模式可以为"WEPAUTO", "OPEN", "SHARED", "WPAPSK", "WPA2PSK", "WPANONE"
     EncrypType  加密类型可以为  "NONE", "WEP", "TKIP", "AES"
     WPAPSK 为无线路由器密码
     现在大多数的无线路由的 AuthMode为WPA2PSK    EncrypType为AES,因为这种认证和加密类型相比于其它是最安全的。

     运行 EvalBoards\ST\STM32469I-Discovery\uCOS-III\KeilMDK\uCOS-III.uvproj  ,编译并直接烧写程序。工程环境用的是MDK 4.7,虽然没有STM32F469I的型号,但可以用STM32F407代替,只要将RAM,ROM的大小修改成STM32F469I 大小就可以。程序烧写完成后会同时在USART3和LCD上输出信息。USART3 连接到了板子上的STLINK,PC机上直接打开这个虚拟串口就可以使用它了。在USB无线网卡成功连接到AP后,会使用DHCP获取IP地址。串口和LCD输出如下:
    wireless_send_event[35842] (RT2860) BSS(ra0)Scanning
    wireless_send_event[35842] (RT2860) BSS(ra0) scancompleted
    wireless_send_event[35842] (RT2860) BSS(ra0) hadassociated successfully
    wireless_send_event[35842] (RT2860)STA(f4:ee:14:54:4d:2e) connects with our wireless client
    dhcp_start...
    DHCP IP:192.168.1.117
    DHCP GW:192.168.1.1
    DHCP MASK:255.255.255.0

接着在串口终端中输入ping 命令, 串口和LCD会同时回显以下信息:

三、使用iperf进行网络性能测试
        板子上的iperf是移植Linux下的,包含最基本的测试命令。现假设STM32F469I-Discovery的IP地址为192.168.1.117,  PC机的IP地址为192.168.1.178。

       UDP客户端带宽测试
        PC机上输入 iperf -s -u   ,其中-s代表PC机处于服务器模式,-u代表UDP测试。
        STM32F469I-Discovery中输入 iperf -c 192.168.1.178 -u -b 4Mbits    其中-c代表客户端模式后面跟着服务器IP地址,-u代表UDP测试, -b带表测试带宽为4Mbits。
      

        可以看到在4Mbits的带宽测试下,丢包率在7.6%左右。

      UDP服务器带宽测试
        STM32F469I-Discovery中输入 iperf -s -u -i 1  其中-s代表PC机处于服务器模式,-u代表UDP测试, -i 1 代表每秒输出一次报告。
         PC机上输入 iperf -c 192.168.1.117 -u -b 8Mbits
        
       可以看到在8Mbits的带宽测试下,丢包率在20%左右。
四、总结
      
以上都是使用USB FS接口,由于USB FS接口不支持DMA模式,所以软件中USB主机调度控制器的负荷还是比较高的,大概占用CPU 45%的利用率,因为它需要轮询USB设备端点是否有数据要发送使用USB HS接口DMA模式,CPU负荷率会很低,而且USB性能也有很大提高。STM32F469I-Discovery 板子上没有USB HS 的接口,需要自己焊洞洞板。这个后面在具体写一下。

完整的工程附件,分卷压缩,记得全部下载。
USB-Wireless-LAN-Driver-for-STM32F4xx-master.part01.rar (4 MB)
USB-Wireless-LAN-Driver-for-STM32F4xx-master.part02.rar (2.01 MB)

打赏榜单

xingjizhilv 打赏了 1.00 元 2020-05-11
理由:最近再做类似的项目,非常感谢您提供的方案,小小心意不成敬意

ewin66 打赏了 3.00 元 2017-09-12
理由:具有共享精神,对我帮助很大。

dong_abc 打赏了 1.00 元 2016-01-17

评分
参与人数 1威望 +10 收起 理由
colin2135 + 10 很给力!非常棒啊!!!!
来自 2楼
lin704932121|  楼主 | 2016-1-16 19:54 | 只看该作者
STM32F4xx  只有USB HS接口是支持DMA的,USB FS并不支持。使用USB HS接口会提高数据的传输速率,并降低CPU使用率。STM32F469I-Discovery板子使用USB HS 要自己焊洞洞板。



       1 引脚接板子上5V电源
      2 引脚接CN5扩展口D12
      3 引脚接CN5扩展口D11
      4 引脚接板子上的GND

硬件连接好,直接烧写附件中的程序,就可以使用啦。


使用特权

评论回复
来自 3楼
lin704932121|  楼主 | 2017-1-25 15:37 | 只看该作者
本帖最后由 lin704932121 于 2017-1-25 15:43 编辑

这个驱动不仅支持STA模式,还支持Adhoc模式。

1、修改rt2870sta_conf.h文件
     (1) 将NetworkType参数修改为Adhoc
     (2) 将AuthMode参数修改为OPEN
     (3) 将EncrypType参数修改为NONE

2、修改wlan.c文件
      (1) 将lwip的网络接口地址设置为静态ip地址192.168.1.165,在wlan.c文件的最开始添加如下语句禁止DHCP Client:
           #undef LWIP_DHCP
      (2) 在Netif_Config()函数里初始化DHCP Server,添加如下语句:
            dhcpd_init(&ipaddr, &netmask);

以上修改已经打包好成附件,将附件解压到EvalBoards\ST\STM32469I-Discovery目录下,打开工程文件EvalBoards\ST\STM32469I-Discovery\uCOS-III_Adhoc\KeilMDK\uCOS-III.uvproj进行编译即可。在PC中进行搜索,即可搜索到无线网卡生成的Adhoc热点mytest。连接Adhoc后,将会为PC分配一个IP地址。





uCOS-III_Adhoc.rar

196.49 KB

使用特权

评论回复
来自 4楼
lin704932121|  楼主 | 2017-1-26 16:23 | 只看该作者
本帖最后由 lin704932121 于 2017-1-27 10:18 编辑

    智能家居现在还处于发展阶段,由于大部分智能设备不具备人机交互界面,不能输入WIFI的密码。因此,想要让智能设备联网,首先要解决智能设备如何获取WIFI密码的问题。
目前流行的wifi配置模式一般有以下2种:
1:智能硬件处于AP模式,手机用于station模式,手机连接智能插座的AP后组成局域网,手机发送需要连接路由的SSID及密码至智能插座,智能硬件主动去连接指定路由后,完成连接
2:智能连接(smarlink)模式:智能硬件处于监听模式下,监听802.11网络中的所有报文;手机APP将SSID和密码编码到UDP报文中,通过广播包或组播报发送,智能硬件接收到UDP报文后解码,得到正确的SSID和密码,然后主动连接指定SSID的路由,完成连接。

一、WIFI智能连接原理
    这里介绍一下第二种智能连接(smarlink)模式:手机通过发送UDP组播数据包来配置智能设备。如下图所示,802.11帧头部包含有AP的MAC地址(RA域)、源MAC地址(SA/TA域)以及目的MAC地址(DA域)。虽然WIFI数据包是加密的,但是802.11帧头部是没有加密的,这就给了我们通过编码目的MAC地址(DA域)来传输数据的机会。


如何编码目的MAC地址呢?组播的目的MAC地址与目的IP地址有映射关系:将MAC地址的前25位设定为01:00:5e,而MAC地址的后23位对应组播IP地址的位。其中组播地址是保留的D类地址从224.0.0.0-239.255.255.255。如下图所示,假设我们要传输AP_NAME这几个字符给智能设备,将AP_NAME分四次发送。
第一次发送,将UDP组播IP地址设置为234.0.'A'.'P',对应的MAC地址为01:00:5E:00:'A':'P',发送的数据包长度为100。
第二次发送,将UDP组播IP地址设置为234.0.'_'.'N',对应的MAC地址为01:00:5E:00:'_':'N',发送的数据包长度为101。
第三次发送,将UDP组播IP地址设置为234.0.'A'.'M',对应的MAC地址为01:00:5E:00:'A':'M',发送的数据包长度为102。
第四次发送,将UDP组播IP地址设置为234.0.'E'.'\0',对应的MAC地址为01:00:5E:00:'E':'\0',发送的数据包长度为103。


发送的数据包长度每次加一。数据包长度可以用来作为数据索引,从而防止接收到的802.11帧次序不同的情况。

二、智能连接的使用
    这个无线网卡驱动支持监听模式,因此我们可以编写智能连接的程序。
    1、将smartlink.c文件导入MDK工程。
    2、在app.c中AppTaskStart()函数里添加智能连接程序的初始化函数smartlink_init()
    3、在无线网卡的热插拔回调函数ralink_hotplug_call_back()里,添加智能连接的启动和停止函数smartlink_start()、smartlink_stop()。
    4、重新编译工程。
    以上修改已经打包好成附件,将附件uCOS-III_SmartLink.rar解压到EvalBoards\ST\STM32469I-Discovery目录下,打开工程文件EvalBoards\ST\STM32469I-Discovery\uCOS-III_SmartLink\KeilMDK\uCOS-III.uvproj进行编译即可。

    安装手机端Android智能连接应用(见附件),连接指定热点后,打开智能连接应用。如下图所示,SSID里会显示当前连接的WIFI名称,输入密码后点击”开始智能连接“按钮,应用程序将会一直发送包含SSID和密码的UDP组播数据包。

    设备端的程序会不停地切换无线网卡的信道,来监听802.11数据包。在串口里看到以下信息:

wireless_send_event[0x8c02][0x217] (RT2860) BSS(ra0) Scanning
smartlink set STA to monitor mode
smartlink setup packet detected
4 of 77 bytes received
10 of 77 bytes received
12 of 77 bytes received
14 of 77 bytes received
16 of 77 bytes received
              ┋
68 of 77 bytes received
70 of 77 bytes received
72 of 77 bytes received
74 of 77 bytes received
76 of 77 bytes received
All data received
SSID: NetWork_Main
PSK : guodanian
smartlink try to connect NetWork_Main
wireless_send_event[0x8c02][0x217] (RT2860) BSS(ra0) Scanning
wireless_send_event[0x8c02][0x211] (RT2860) BSS(ra0) scan completed
wireless_send_event[0x8c02][0x200] (RT2860) BSS(ra0) had associated successfully
wireless_send_event[0x8c02][0x210] (RT2860) STA(a8:57:4e:83:f9:28) disconnects with our wireless client
wireless_send_event[0x8c02][0x20f] (RT2860) STA(a8:57:4e:83:f9:28) connects with our wireless client
dhcp_start...
DHCP IP:192.168.2.101
DHCP GW:192.168.2.1
DHCP MASK:255.255.255.0

    设备一旦在某个信道监听到了数据,将会保持在该信道,直到获得所有剩余数据。设备获得了AP的SSID和密码后,将会切换到STA模式来连接AP,并通过DHCP来获取IP地址。

uCOS-III_SmartLink.rar

195.68 KB

smartlink_android_source.rar

4.4 MB

使用特权

评论回复
5
msblast| | 2016-1-16 08:52 | 只看该作者
有干货,赞。

使用特权

评论回复
6
duxingkei| | 2016-1-16 10:00 | 只看该作者
很牛啊,以前就想过,tb上便宜的9.9包邮的网卡要是能用到STM32之类的上面该多省成本啊,没想到你做到了!!顶起,膜拜下

使用特权

评论回复
7
笑鸟007| | 2016-1-16 10:25 | 只看该作者
好牛啊!!!赞

使用特权

评论回复
8
le062| | 2016-1-16 11:54 | 只看该作者
这个是真牛X

使用特权

评论回复
9
jinyi7016| | 2016-1-16 14:58 | 只看该作者
你的这个是linux还是uclinux,自己移植的么?

使用特权

评论回复
10
lin704932121|  楼主 | 2016-1-16 17:38 | 只看该作者
jinyi7016 发表于 2016-1-16 14:58
你的这个是linux还是uclinux,自己移植的么?

USB无线网卡驱动原本是在linux下运行的,我将它移植到uC/OS-III下, 中间做了一些Linux内核API到uC/OS-III API的转换以使驱动能运行,并不属于uclinux。

使用特权

评论回复
11
jinyi7016| | 2016-1-16 17:52 | 只看该作者
lin704932121 发表于 2016-1-16 17:38
USB无线网卡驱动原本是在linux下运行的,我将它移植到uC/OS-III下, 中间做了一些Linux内核API到uC/OS-II ...

理解错了啊。

使用特权

评论回复
12
dawei360| | 2016-1-16 18:21 | 只看该作者
源码用网盘打包下载吧

使用特权

评论回复
13
Simon21ic| | 2016-1-16 18:29 | 只看该作者
很厉害,RT5572内置80211层的代码吗?
这个资源占用有些多啊

使用特权

评论回复
14
lin704932121|  楼主 | 2016-1-16 18:53 | 只看该作者
Simon21ic 发表于 2016-1-16 18:29
很厉害,RT5572内置80211层的代码吗?
这个资源占用有些多啊

RT5572 应该是802.11物理层芯片,只负责接收和发送802.11数据包。所有802.11数据包的处理都是由驱动软件完成的。对于联发科的USB无线网卡驱动还没有了解透,驱动应该还有很多可以优化的地方。

使用特权

评论回复
15
yklstudent| | 2016-1-16 19:06 | 只看该作者
楼主是真牛X了

使用特权

评论回复
16
sblpp| | 2016-1-16 20:55 | 只看该作者
牛X!
顶一个先,不过貌似高速USB也没发挥出高速的优势啊!

使用特权

评论回复
17
lin704932121|  楼主 | 2016-1-16 21:12 | 只看该作者
sblpp 发表于 2016-1-16 20:55
牛X!
顶一个先,不过貌似高速USB也没发挥出高速的优势啊!

高速USB不外置PHY的话还是工作在全速15Mbits下,只是DMA和增大的硬件FIFO提高了性能。
外置PHY现在还不可用,暂时没那么多时间去测试了。

使用特权

评论回复
18
maiweiqi| | 2016-1-16 23:31 | 只看该作者
牛X!!!

使用特权

评论回复
19
paderboy| | 2016-1-17 09:42 | 只看该作者
仰望下。。。。。学习了

使用特权

评论回复
20
Simon21ic| | 2016-1-17 14:25 | 只看该作者
lin704932121 发表于 2016-1-16 18:53
RT5572 应该是802.11物理层芯片,只负责接收和发送802.11数据包。所有802.11数据包的处理都是由驱动软件 ...

我们最近也在准备做USB wifi的驱动,如果是直接使用类似linux内核里的80211_hw结构以及相应的代码的话,资源占用确实会比较多,如果还算上RTOS的话,很多芯片都无法实现的。
我们之前做的博通的SDIO wifi的驱动倒是还好,因为博通内置了80211的协议,高层通过ioctrl就可以控制芯片,配合上我们自己实现的系统以及tcpip协议栈,flash占用25-30K,RAM占用3K+skb,不过这个是不用做80211层的。

使用特权

评论回复
21
lin704932121|  楼主 | 2016-1-17 15:45 | 只看该作者
本帖最后由 lin704932121 于 2016-1-17 15:50 编辑
Simon21ic 发表于 2016-1-17 14:25
我们最近也在准备做USB wifi的驱动,如果是直接使用类似linux内核里的80211_hw结构以及相应的代码的话, ...

好像很多厂商都是用博通的芯片来做的。你们移植的是什么驱动呢?

使用特权

评论回复
22
Simon21ic| | 2016-1-17 18:08 | 只看该作者
lin704932121 发表于 2016-1-17 15:45
好像很多厂商都是用博通的芯片来做的。你们移植的是什么驱动呢?

我们参照WICED的代码,全部重写了驱动,也自己做了tcpip协议栈,只是为了优化系统资源的使用

使用特权

评论回复
发新帖 本帖赏金 5.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

82

帖子

18

粉丝