Using USB WiFi with LPC1788 under uClinux Print


This application note explains how to use a USB WiFi module with LPC1788 under uClinux. The demo described in this note configures the LPC1788 as a WiFi access point (AP), allowing other wireless devices, such as a notebook or smartphone, to connect to the LPC1788 using WiFi without any additional equipment. This capability makes it very easy to access a standalone LPC1788-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 Embedded Artists' LPC1788-DEV-KIT board. The Cortex-M3 core is configured to run at 108 MHz.

The demo documented in this application note assumes that a USB Wireless adapter is plugged into the USB interface connector on the EA-LPC1788 board. Supported USB Wireless adapters are based on the Ralink RT5370 chipset (for example, D-Link DWA-140 (H/W rev B3) or Comfast WU815N).

Note also that to power the LPC1788-DEV-KIT for this demo, you should plug the mini-USB Y-cable into the J25 mini-USB connector on the EA-LPC1788 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 LPC1788 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 NOR Flash to the LPDDR and passes control to the kernel entry point:

U-Boot 2010.03-linux-cortexm-1.10.1 (Jun 13 2013 - 16:19:44)

CPU : LPC178x/7x series (Cortex-M3)
Board: EA-LPC1788 rev 1
Flash: 4 MB
In: serial
Out: serial
Err: serial
Net: LPC178X_MAC
Hit any key to stop autoboot: 0
## Booting kernel from Legacy Image at 80020000 ...
Image Name: Linux-2.6.33-arm1
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3691136 Bytes = 3.5 MB
Load Address: a0008000
Entry Point: a0008001
Verifying Checksum ... OK
Loading Kernel Image ... 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 (gcc version 4.4.1 (Sourcery G++ Lite 2010q1-189) ) #607 Thu Jun 13 15:59:48 +0400 2013
CPU: ARMv7-M Processor [412fc230] revision 0 (ARMv7M)
CPU: NO data cache, NO instruction cache
Machine: NXP LPC178x/7x
Built 1 zonelists in Zone order, mobility grouping off. Total pages: 8128
Kernel command line: lpc178x_platform=ea-lpc1788 console=ttyS0,115200 panic=10
ip= ip= ethaddr=C0:B1:3C:81:76:81
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: 28820k/28820k available, 3948k reserved, 0K highmem
Virtual kernel memory layout:
vector : 0x00000000 - 0x00001000 ( 4 kB)
fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
vmalloc : 0x00000000 - 0xffffffff (4095 MB)
lowmem : 0xa0000000 - 0xa2000000 ( 32 MB)
modules : 0xa0000000 - 0x01000000 (1552 MB)
.init : 0xa0008000 - 0xa022c000 (2192 kB)
.text : 0xa022c000 - 0xa0375000 (1316 kB)
.data : 0xa0376000 - 0xa038d280 ( 93 kB)
Hierarchical RCU implementation.
Calibrating delay loop... 30.92 BogoMIPS (lpj=154624)
Mount-cache hash table entries: 512
NET: Registered protocol family 16
bio: create slab <bio-0> at 0
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)
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
Serial: 8250/16550 driver, 5 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0x4000c000 (irq = 5) is a 16550A
console [ttyS0] enabled
serial8250.2: ttyS1 at MMIO 0x40098000 (irq = 7) is a 16550A
physmap platform flash device: 00400000 at 80000000
physmap-flash: Found 1 x16 devices at 0x0 in 16-bit bank
Support for command set 0701 not present
gen_probe: No supported Vendor Command Set found
Found: SST 39VF3201
physmap-flash: Found 1 x16 devices at 0x0 in 16-bit bank
number of JEDEC chips: 1
RedBoot partition parsing not available
Using physmap partition information
Creating 3 MTD partitions on "physmap-flash":
0x000000000000-0x000000020000 : "flash_uboot_env"
0x000000020000-0x000000300000 : "flash_linux_image"
0x000000300000-0x000000400000 : "flash_jffs2"
lpc_mii_bus: probed

eth0: using RMII interface
eth0: LPC mac at 0x20084000 irq 28
eth0: attached PHY driver [Generic PHY] (mii_bus:phy_addr=0:01, irq=-1)

The USB controller is initialized:

ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
lpc178x-ohci lpc178x-ohci: LPC178x OHCI
lpc178x-ohci lpc178x-ohci: new USB bus registered, assigned bus number 1
lpc178x-ohci lpc178x-ohci: irq 24, io mem 0x2008c000
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
TCP cubic registered
NET: Registered protocol family 17
lib80211: common routines for IEEE802.11 drivers

The USB WiFi module is initialized by the USB controller:

usb 1-2: new full speed USB device using lpc178x-ohci and address 2
IP-Config: Guessing netmask
IP-Config: Complete:
device=eth0, addr=, mask=, gw=,
host=ea-lpc1788, domain=, nis-domain=(none),
bootserver=, rootserver=, rootpath=
Freeing init memory: 2192K
init started: BusyBox v1.17.0 (2013-05-30 14:37:36 +0400)

The startup script /etc/rc loads the required kernel modules for the WiFi support:

loading modules...
Compat-wireless backport release: compat-wireless-v3.4-rc3-1
Backport based on linux-stable.git v3.4-rc3
cfg80211: Calling CRDA to update world regulatory domain
usb 1-2: reset full speed USB device using lpc178x-ohci 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

echo "Starting AP"
ifconfig wlan0 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 lpc1788:

~ # cat /etc/hostapd-minimal.conf
#change wlan0 to your wireless device
~ #

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 - 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: Bcast: Mask:
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 'lpc1788'
~ #

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 lpc1788 network:

While connecting, you should see the progress on the LPC1788 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
Sending OFFER of
Sending ACK to

At this point, the LPC1788 is connected to the notebook (or smartphone) over TCP/IP. Let's start the HTTP daemon with a demo webpage on the LPC1788:

~ # httpd -h /httpd/html
~ #

On the notebook, open in the browser and observe the page generated by LPC1788:

How Fast is TCP/IP on LPC1788 using USB WiFi?

As a very rough estimate for the TCP performance of LPC1788 using USB WiFi here is the output of an FTP get command transferring a file from a host in a local network to LPC1788:

~ # time wget
Connecting to (
test.dat 100% |*******************************| 9380k --:--:-- ETA
real 0m 26.08s
user 0m 1.33s
sys  0m 12.84s
~ #

Processing the above results, we get the following TCP performance figure: 9380KB/26.08 = 359.66 KB/sec

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 LPC1788:

~ # mount -o nolock /mnt
~ # time cp /mnt/test.dat /
real 0m 11.03s
user 0m 0.01s
sys  0m 2.59s
~ #

The UDP performance is 9380KB/11.03=850.41 KB/sec.

The WiFi connection rate (as reported in the connection status) was 54 Mb/sec in the above test.