Using USB Flash with LPC1788 under uClinux |
This application note explains how to use a USB Flash device with LPC1788 under uClinux.
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 the mini-B to USB 2.0 A Female cable is plugged into the J25 mini-USB connector on the LPC1788-DEV-KIT board and that a pre-formatted USB Flash disk with an empty FAT32 partition is plugged into the USB 2.0 A Female connector of the above cable.
The procedure described here explains how to install the bootable Linux image (usbflash.uImage) to the target. Here is how you can build and install the bootable Linux image from the project sources (usbflash.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.11.0. If you are using a different release, some porting changes may be needed.
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.11.0 (Jul 08 2013 - 16:17:00) 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) ) #6 Sat Oct 5 11:40:10 +0400 2013 The USB controller is initialized: ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver The USB mass storage device driver is initialized: Initializing USB Mass Storage driver... The USB Flash device is detected and configured: ~ # usb 1-1: new high speed USB device using musb_hdrc and address 2 At this point, the USB Flash is accessible as a disk. The following command is used to examine the disk, which is detected as a 4GBytes disk partitioned to have a single FAT32 partition: ~ # fdisk -l /dev/sda Let's mount the FAT32 file system. As expected, it is empty at this point: ~ # mount /dev/sda1 /mnt ~ # while true; do date >> /mnt/data.log; sleep 1; done Having let the "data harvesting" run for a few seconds, let's interrupt it (by pressing ^-C) and take a look at what data we have collected: ^C Now, let's unmount the USB Flash and unplug the device from the USB connector: ~ # umount /mnt At this point, the USB Flash device can be taken to a PC for further data processing. Just plug in the USB Flash into a USB port on your PC and the PC software will be able to mount the device as a FAT32 file system. Note that the format of Windows and Unix text files differs slightly. In Windows, lines end with both the line feed and carriage return ASCII characters, but Unix uses only a line feed. As a consequence, some Windows applications will not show the line breaks in Unix-format files. Assuming that data is stored in a text file (vs a binary file) and Windows is a data processing host, Linux data harvesting applications should take care of the difference by adding a carriage return character to data logs.
Write throughput to a 4GB Kingston USB Flash is measured to be the following: ~ # dd if=/dev/zero of=/mnt/10m bs=1M count=10 Read throughput using the same USB Flash device is as follows: ~ # dd if=/mnt/10m of=/dev/null bs=1M count=10
It is important to understand that VFAT supports write-back in Linux, which means that file changes do not go to the physical media straight away and instead are cached in memory and go to the Flash at a later time. This helps to reduce amount to I/O to the physical Flash, resulting in a better performance overall. The write-back creates a certain issue for embedded devices however. If the power to the device is shut down unexpectedly, or the USB Flash is unplugged without a proper unmount or sync, some of latest file changes may be lost. As it is typical with Linux, the issue can be handled in many ways. Data synchronization can be ensured on a per-file, per-subtree, per-filesystem or system-wide basis. Synchronization can be transparent for the user or may require issuing an explicit API call or a shell command. The most obvious solution is to mount the file system in synchronous mode (note the -o sync parameter in the call below): ~ # mount -o sync /dev/sda1 /mnt When the file system is mounted for synchronous operation, Linux guarantees that data is written to the physical media before any write() returns to a calling application. The tradeoff is that written data is no longer cached in memory, which reduces the write performance substantially. |