This application note explains how to use a USB WiFi module with the STM32F4 with the USB High Speed (HS) interface under uClinux. The demo described in this note configures the STM32F4 as a WiFi access point (AP), allowing other wireless devices, such as a notebook or smartphone, to connect to the STM32F4 using WiFi without any additional equipment. This capability makes it very easy to access a standalone STM32F4-based device over TCP/IP, for instance, for checking the device status or offloading collected data for further processing.
Hardware Platform
The hardware platform is the Emcraft Systems STM32F4 SOM Starter Kit, which is comprised of the STM32F4 System-On-Module (SOM) plugged into the SOM-BSB-EXT development baseboard.
The demo documented in this application note assumes that the Mini-B to USB 2.0 A Female cable is plugged into the USB OTG interface connector on the SOM-BSB-EXT baseboard and that the USB Wireless adapter (Comfast WU815N) is plugged into the USB 2.0 A Female connector of the above cable.
Note also that to power the STM32F4 Starter Kit for this demo, you have to plug a mini-USB Y-cable into the P1 mini-USB connector on the SOM-BSB-EXT board and then connect both links of the Y-cable into free USB ports on your PC. This is needed since this demo requires more than 500 mA for reliable operation.
Installing the Demo
The procedure described here explains how to install the bootable Linux image (usbwifi.uImage) to the target.
Here is how you can build and install the bootable Linux image from the project sources (usbwifi.tgz), having installed them on top of the Emcraft Systems STM32F4 uClinux distribution.
Note: The Linux image and the sample project have been built and validated in context of the Emcraft Systems Release 1.12.4. If you are using a different release, some porting changes may be needed.
Starting the WiFi Access Point
On power-up reset, U-Boot loads the Linux image from the NOR Flash to the SDRAM and passes control to the kernel entry point:
U-Boot 2010.03-linux-cortexm-1.12.4 (Sep 18 2014 - 13:58:38)
CPU : STM32F4 (Cortex-M4)
Freqs: SYSCLK=168MHz,HCLK=168MHz,PCLK1=42MHz,PCLK2=84MHz
Board: STM-SOM Rev Rev 2.A, www.emcraft.com
DRAM: 32 MB
Flash: 16 MB
In: serial
Out: serial
Err: serial
Net: STM32_MAC
Hit any key to stop autoboot: 0
## Booting kernel from Legacy Image at c0007fc0 ...
Image Name: Linux-2.6.33-arm1
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3727008 Bytes = 3.6 MB
Load Address: c0008000
Entry Point: c0008001
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK
Starting kernel ...
The kernel proceeds to boot-up, initializing the configured I/O interfaces and sub-systems:
Linux version 2.6.33-arm1 (vlad@ ocean.emcraft.com) (gcc version 4.4.1 (Sourcery G++ Lite 2010q1-189) ) #23 Fri Sep 19 13:12:07 +0400 2014
CPU: ARMv7-M Processor [410fc241] revision 1 (ARMv7M)
CPU: NO data cache, NO instruction cache
Machine: STMicro STM32
Built 1 zonelists in Zone order, mobility grouping off. Total pages: 8128
Kernel command line: stm32_platform=stm32f4x9-som console=ttyS0,115200 panic=10 ip=172.17.4.211:172.17.0.1:::stm32f4x9-som:eth0:off ip=172.17.4.211:172.17.0 ethaddr=C0:B1:3C:88:88:89
PID hash table entries: 128 (order: -3, 512 bytes)
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 32MB = 32MB total
Memory: 28776k/28776k available, 3992k reserved, 0K highmem
Virtual kernel memory layout:
vector : 0x00000000 - 0x00001000 ( 4 kB)
fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
vmalloc : 0x00000000 - 0xffffffff (4095 MB)
lowmem : 0xc0000000 - 0xc2000000 ( 32 MB)
modules : 0xc0000000 - 0xc2000000 ( 32 MB)
.init : 0xc0008000 - 0xc0242000 (2280 kB)
.text : 0xc0242000 - 0xc037e000 (1264 kB)
.data : 0xc037e000 - 0xc0395ea0 ( 96 kB)
Hierarchical RCU implementation.
NR_IRQS:90
Calibrating delay loop... 34.61 BogoMIPS (lpj=173056)
Mount-cache hash table entries: 512
NET: Registered protocol family 16
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Switching to clocksource cm3-systick
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 1, 8192 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
TCP reno registered
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
JFFS2 version 2.2. (NAND) б╘ 2001-2006 Red Hat, Inc.
alg: No test for stdrng (krng)
Serial: STM32 USART driver
stm32serial.0: ttyS0 at MMIO 0x40011000 (irq = 37) is a STM32 USART Port
console [ttyS0] enabled
blackfin-eth: found MAC at 0x40028000, irq 61
blackfin_mii_bus: probed
found PHY id 0x221556 addr 0
eth0: using MII interface
eth0: attached PHY driver [Generic PHY] (mii_bus:phy_addr=00:00, irq=-1)
The USB controller is initialized:
USB: DWC2 USB driver
dwc2 dwc2.0: DWC OTG Controller
dwc2 dwc2.0: new USB bus registered, assigned bus number 1
dwc2 dwc2.0: irq 77, io mem 0x00000000
usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb1: Product: DWC OTG Controller
usb usb1: Manufacturer: Linux 2.6.33-arm1 dwc2_hsotg
usb usb1: SerialNumber: dwc2.0
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
TCP cubic registered
NET: Registered protocol family 17
ARMv7-M VFP Extension supported
IP-Config: Guessing netmask 255.255.0.0
IP-Config: Complete:
device=eth0, addr=172.17.4.211, mask=255.255.0.0, gw=255.255.255.255,
host=stm32f4x9-som, domain=, nis-domain=(none),
bootserver=172.17.0.0, rootserver=172.17.0.0, rootpath=
Freeing init memory: 2280K
init started: BusyBox v1.17.0 (2014-09-18 18:13:55 +0400)
The USB WiFi module is initialized by the USB device driver:
usb 1-1: new high speed USB device using dwc2 and address 2
The startup script /etc/rc loads the required kernel modules for the WiFi support:
loading modules...
compat
usb 1-1: New USB device found, idVendor=148f, idProduct=5370
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Product: 802.11 n WLAN
usb 1-1: Manufacturer: Ralink
usb 1-1: SerialNumber: 1.0
Compat-wireless backport release: compat-wireless-v3.4-rc3-1
Backport based on linux-stable.git v3.4-rc3
cfg80211
PHY: 00:00 - Link is Up - 100/Full
cfg80211: Calling CRDA to update world regulatory domain
mac80211
rt2x00lib
rt2x00usb
rt2800lib
rt2800usb
usb 1-1: reset high speed USB device using dwc2 and address 2
usbcore: registered new interface driver rt2800usb
~ #
The script below implements the needed actions to start the WiFi access point:
~ # cat /start_ap
#!/bin/sh
echo "Starting AP"
ifconfig wlan0 192.168.1.1 up
ifconfig wlan0
hostapd /etc/hostapd-minimal.conf &
echo "Starting DHCP server"
udhcpd -f /etc/udhcpd.conf &
~ #
The script enables the wlan0 WiFi interface, then starts the user-space daemon implementing access point functionality. The daemon configuration file, /etc/hostapd-minimal.conf, has a minimal configuration to implement a no-encryption access point named mytest:
~ # cat /etc/hostapd-minimal.conf
#change wlan0 to your wireless device
interface=wlan0
driver=nl80211
ssid=mytest
hw_mode=g
max_num_sta=255
channel=2
~ #
The last line in the above script starts the DHCP daemon, providing network auto-configuration for connected clients. The DHCP daemon is configured to assign an address from the 192.168.1.2 - 192.168.1.255 range to the WiFi client.
Let's start the access point by running the script:
~ # ./start_ap
Starting AP
rt2800usb 1-1:1.0: firmware: using built-in firmware rt2870.bin
wlan0 Link encap:Ethernet HWaddr 00:0F:13:33:0A:E6
inet addr:192.168.1.1 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Starting DHCP server
~ #
Configuration file: /etc/hostapd-minimal.conf
Using interface wlan0 with hwaddr 00:0f:13:33:0a:e6 and ssid 'mytest'
udhcpd (v1.17.0) started
At this point, the access point is ready to accept requests for connection. Using a WiFi-connected notebook or smartphone, scan for available wireless networks and connect to the mytest network:
While connecting, you should see the progress on the STM32F4 console:
~ # wlan0: STA f0:6b:ca:d2:22:b3 IEEE 802.11: authenticated
wlan0: STA f0:6b:ca:d2:22:b3 IEEE 802.11: associated (aid 1)
wlan0: AP-STA-CONNECTED f0:6b:ca:d2:22:b3
Sending OFFER of 192.168.1.2
Sending ACK to 192.168.1.2
~ #
At this point, the STM32F4 is connected to the notebook (or smartphone) over TCP/IP. Let's start the HTTP daemon with a demo webpage on the STM32F4:
~ # httpd -h /httpd/html
~ #
On the notebook, open http://192.168.1.1 in the browser and observe the page generated by the STM32F4: