It is long overdue to talk about porting specific projects to Android. It is astonishingly easy to do so with the Android platform.
Since we are using USB for our project we found it convenient to work with libusb 1.0. Using the Beagleboard we are able to make use of the USB 2.0 high speed functionality of libusb.
Libusb itself consists of a shared library and two sample applications. One of those applications is the lsusb command which lists connected USB devices in the console.
These five Steps is all it takes to port the existing libusb open source project to the Android platform.
1. Get the libusb-1.0 sources [link] and create an empty “libusb-1.0.3″ folder in the external directory of your Android sources. Unpack the libusb folder into the new directory.
2. Create Android.mk files in each of the libusb directories. In the top folder your Android.mk just calls your mk files in the libusb subfolders :
LOCAL_PATH := $(call my-dir)
ubdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \ libusb \
))
include $(subdirs)
in the libusb folder add the following Android.mk
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ core.c \ descriptor.c \ io.c \ sync.c \ os/linux_usbfs.c LOCAL_C_INCLUDES += \ external/libusb-1.0.3/ \ external/libusb-1.0.3/libusb/ \ external/libusb-1.0.3/libusb/os LOCAL_MODULE:= libusb include $(BUILD_SHARED_LIBRARY)
You see the syntax of these Android.mk files is very simple. You just tell the compiler what modules you want to include and where your header files are.
3. Soon we are ready to compile the library; if we do so now, we will notice that the macro TIMESPEC_TO_TIMEVAL is not defined by the sources inside Android. To overcome this problem we just need to define the macro in the lubusb/io.c file.
#define TIMESPEC_TO_TIMEVAL(tv, ts) \ do { \ (tv)->tv_sec = (ts)->tv_sec; \ (tv)->tv_usec = (ts)->tv_nsec / 1000; \ } while (0)
If you compile your libusb now, there is going to be the following error: build/tools/apriori/prelinkmap.c(137): library ‘libusb.so’ not in prelink map. This is because Android keeps track of all the shared libraries of the root file system (RFS). Therefore we need to add the library to the prelinked map found in ./build/core/prelink-linux-arm.map. We did so and just added libusb.so below libqcamera.so.
libqcamera.so 0xA9400000 libusb.so 0xA8000000
You are now all set to compile libusb. Execute the following commands in your Android root directory:
$ . build/envsetup.sh $ choosecombo
Choose your build variant. Afterwards you can compile the whole RFS with make or just that one project:
mmm -j4 /external/libusb
4. Your library is ready… but your usb-file system is almost certainly not mounted yet. In your init.rc of the RFS add the following command to mount your USBFS.
mount usbfs none /proc/bus/usb -o devmode=0666
Add the line somewhere below the “on boot” event.
5. Now we need to compile lsusb. The sources are located in the examples folder of libusb. Create a folder lsusb in the ./external directory of the Android sources. Copy the lsusb.c module into it and create a Android.mk file:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= lsusb.c LOCAL_MODULE := lsusb LOCAL_C_INCLUDES += external/libusb-1.0.3/ LOCAL_SHARED_LIBRARIES := libc libusb include $(BUILD_EXECUTABLE)
Execute the build command:
mmm -j4 /external/lsusb
and we are done! Congratulations! You just ported an entirely non-Android specific project to your Android platform!
Simply execute lsusb in your Android shell to verify if everything worked properly.
Update 15.07.2011
Thank you for all your comments. With the new Android versions there are a few things that changed for the tutorial.