This application note explains how to use a USB WiFi module with SmartFusion2 under uClinux. The demo described in this note configures the SmartFusion2 as a WiFi access point (AP), allowing other wireless devices, such as a notebook or smartphone, to connect to the SmartFusion2 using WiFi without any additional equipment. This capability makes it very easy to access a standalone SmartFusion2-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 Microsemi's SF2-DEV-KIT board. The Cortex-M3 core is configured to run at 166 MHz. The on-chip cache is enabled by software for DDR3.
The demo documented in this application note assumes that the Micro-B to USB 2.0 A Female cable is plugged into the USB Micro AB interface connector on the SF2-DEV-KIT board and that a USB Wireless adapter is plugged into the USB 2.0 A Female connector of the above cable. Supported USB Wireless adapters are based on the Ralink RT5370 chipset (for example, D-Link DWA-140 (H/W rev B3) or Comfast WU815N).
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 SmartFusion2 uClinux distribution.
Note: The Linux image and the sample project have been built and validated in context of the Emcraft Systems Release 1.10.1. 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 SPI Flash to the DDR3 and passes control to the kernel entry point:
U-Boot 2010.03-linux-cortexm-1.10.0 (May 17 2013 - 16:09:15)
CPU : SmartFusion2 SoC (Cortex-M3 Hard IP)
Freqs: CORTEX-M3=166MHz,PCLK0=83MHz,PCLK1=83MHz
Board: SF2-DEV-KIT Rev 1.0, Microsemi
DRAM: 256 MB
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
8192 KiB AT25DF641 at 0:0 is now current device
## Booting kernel from Legacy Image at a0007fc0 ...
Image Name: Linux-2.6.33-arm1
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3600640 Bytes = 3.4 MB
Load Address: a0008000
Entry Point: a0008001
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 (psl @ocean.emcraft.com) (gcc version 4.4.1 (Sourcery G++ Lite 2010q1-189) ) #8 Fri May 17 18:58:33 +0400 2013
CPU: ARMv7-M Processor [412fc231] revision 1 (ARMv7M)
CPU: NO data cache, 8K instruction cache
Machine: Actel M2S
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 65024
Kernel command line: m2s_platform=sf2-dev-kit console=ttyS1,115200 panic=10
ip=172.17.4.163:172.17.0.1:::sf2-dev-kit:eth0:off ethaddr=C0:B1:3C:83:84:84
PID hash table entries: 1024 (order: 0, 4096 bytes)
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
Memory: 256MB = 256MB total
Memory: 256324k/256324k available, 5820k reserved, 0K highmem
Virtual kernel memory layout:
vector : 0x00000000 - 0x00001000 ( 4 kB)
fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
vmalloc : 0x00000000 - 0xffffffff (4095 MB)
lowmem : 0xa0000000 - 0xb0000000 ( 256 MB)
modules : 0xa0000000 - 0x01000000 (1552 MB)
.init : 0xa0008000 - 0xa0237000 (2236 kB)
.text : 0xa0318d80 - 0xa0360000 ( 285 kB)
.data : 0xa0360000 - 0xa0377100 ( 93 kB)
Hierarchical RCU implementation.
NR_IRQS:83
Calibrating delay loop... 155.23 BogoMIPS (lpj=776192)
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 mss_timer2
The USB controller is initialized:
musb_hdrc: version 6.0, musb-dma, host, debug=0
musb_hdrc: USB Host mode controller at 40043000 using DMA, IRQ 20
musb_hdrc musb_hdrc: MUSB HDRC host driver
musb_hdrc musb_hdrc: new USB bus registered, assigned bus number 1
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: MUSB HDRC host driver
usb usb1: Manufacturer: Linux 2.6.33-arm1 musb-hcd
usb usb1: SerialNumber: musb_hdrc
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
NET: Registered protocol family 2
IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
TCP established hash table entries: 8192 (order: 4, 65536 bytes)
TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
TCP: Hash tables configured (established 8192 bind 8192)
TCP reno registered
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
alg: No test for stdrng (krng)
Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0x40000000 (irq = 10) is a 16550A
serial8250.1: ttyS1 at MMIO 0x40010000 (irq = 11) is a 16550A
console [ttyS1] enabled
TCP cubic registered
NET: Registered protocol family 17
The USB WiFi module is initialized by the USB controller:
usb 1-1: new high speed USB device using musb_hdrc and address 2
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
...
Freeing init memory: 2236K
init started: BusyBox v1.17.0 (2013-05-17 18:42:56 +0400)
The startup script /etc/rc loads the required kernel modules for the WiFi support:
loading modules...
compat
Compat-wireless backport release: compat-wireless-v3.4-rc3-1
Backport based on linux-stable.git v3.4-rc3
cfg80211
cfg80211: Calling CRDA to update world regulatory domain
mac80211
rt2x00lib
rt2x00usb
rt2800lib
rt2800usb
usb 1-1: reset high speed USB device using musb_hdrc 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 smartFusion2:
~ # cat /etc/hostapd-minimal.conf
#change wlan0 to your wireless device
interface=wlan0
driver=nl80211
ssid=smartFusion2
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:12:44:0C:5D
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
udhcpd (v1.17.0) started
Configuration file: /etc/hostapd-minimal.conf
Using interface wlan0 with hwaddr 00:0f:12:44:0c:5d and ssid 'smartFusion2'
~ #
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 smartFusion2 network:
While connecting, you should see the progress on the SmartFusion2 console:
wlan0: STA e4:ce:8f:3f:bd:b4 IEEE 802.11: authenticated
wlan0: STA e4:ce:8f:3f:bd:b4 IEEE 802.11: associated (aid 1)
wlan0: AP-STA-CONNECTED e4:ce:8f:3f:bd:b4
Sending OFFER of 192.168.1.2
Sending OFFER of 192.168.1.2
Sending ACK to 192.168.1.2
At this point, the SmartFusion2 is connected to the notebook (or smartphone) over TCP/IP. Let's start the HTTP daemon with a demo webpage on the SmartFusion2:
~ # httpd -h /httpd/html
~ #
On the notebook, open http://192.168.1.1 in the browser and observe the page generated by SmartFusion2:
How Fast is TCP/IP on SmartFusion2 using USB WiFi?
As a very rough estimate for the TCP performance of SmartFusion2 using USB WiFi here is the output of an FTP get command transferring a file from a host in a local network to SmartFusion2:
~ # time wget ftp://192.168.1.3/pub/test.dat
Connecting to 192.168.1.3 (192.168.1.3:21)
test.dat 100% |*******************************| 9380k --:--:-- ETA
real 0m 8.05s
user 0m 0.83s
sys 0m 3.57s
~ #
Processing the above results, we get the following TCP performance figure: 9380KB/8.05s = 1165.22 KB/s.
As an estimate of the UDP performance, here is the output of a copy command transferring the same file from an NFS-host to the SmartFusion2:
~ # mount -o nolock 192.168.1.3:/home/psl /mnt
~ # time cp /mnt/test.dat /
real 0m 6.31s
user 0m 0.00s
sys 0m 0.81s
~ #
The UDP performance is 9380KB/6.31s=1486.53KB/s.
The WiFi connection rate (as reported in the connection status) was 54 Mb/sec in the above test.