Setup Development Tools for Android

Software needed

  • Eclipse IDE for Java Developers (at least Eclipse 4.2  – Juno) – link
  • Android ADT Plugin
  • Android SDK
  • Android NDK

Eclipse and ADT

  1. Decompress Eclipse inside your user folder
  2. Start Eclipse with a default workplace
  3. Click on Help -> Install New Software
  4. Click on Add
  5. Enter ADT Plugin as the Repository Name
  6. In Location enter https://dl-ssl.google.com/android/eclipse/ 
  7. Click Ok
  8. Select Developer Tools and NDK Plugins
  9. Click Next and follow the installation instructions.
Proceed restarting the Eclipse if you are prompt to do so.

Installing ADT

When starting Eclipse again, you will see a dialog with a Welcome message. If you don’t have the latest Android SDK, install it.

Once you have installed and set up the IDE, you are ready to start developing Android apps. It’s recommended to install more SDKs from the Android SDK Manager. For Example, Android 4.1 (the latest version is 4.2) and Android 2.3.

Building Android Jelly Bean (4.1.2) for Beagleboard xM

Jelly Bean on Beagleboard xM

Prerequisites

  • Ubuntu 12.04 LTS – AMD64
    • A 64-bit OS is needed in order to build Android 4.x from source code
  • Dual- or Quad-core  (recommended) CPU
  • At least 4GB of RAM
  • 45GB of free disk space
  • Internet connection

Installing utils and libs

From a Terminal console execute
sudo aptitude install ia32-libs
sudo apt-get install git-core gnupg flex bison gperf build-essential
zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev
libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386
libgl1-mesa-dev g++-multilib mingw32 openjdk-6-jdk tofrodos
python-markdown libxml2-utils xsltproc zlib1g-dev:i386

and then
sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so

Installing Oracle Java JDK

  1. Download Oracle Java6 JDK from here (file: jdk-6u34-linux-x86.bin) to ~/Downloads
  2. In a Terminal cnosole execute
    1. cd ~/Downloads
    2. cp jdk-6u43-linux-x64.bin ~/
    3. cd ~/
    4. chmod +x  jdk-6u43-linux-x64.bin
    5. ./jdk-6u43-linux-x64.bin
    6. sudo mv jdk1.6.0_43/ /usr/lib/jvm/
  3. Add Oracle Java6 JDK to Ubuntu JVM list
    1. sudo update-alternatives –install /usr/bin/javac javac /usr/lib/jvm/jdk1.6.0_43/bin/javac 1
    2. sudo update-alternatives –install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_43/bin/java 1
    3. sudo update-alternatives –install /usr/bin/javaws javaws /usr/lib/jvm/jdk1.6.0_43/bin/javaws 1
  4. Select Oracle Java6 JDK as default JVM
    1. sudo update-alternatives –config javac
    2. sudo update-alternatives –config java
    3. sudo update-alternatives –config javaws

In this three last commands, select Oracle Java6 JDK as default, like in the example below

kimi@X-Server:~$ sudo update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).

Selection Path Priority Status
————————————————————
0 /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java 1061 auto mode
1 /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java 1061 manual mode
* 2 /usr/lib/jvm/jdk1.6.0_34/bin/java 1 manual mode
Press enter to keep the current choice[*], or type selection number: 2

Installing REPO

Repo is a tool created by Google in order to admin git repositories easyly.
In a Terminal console execute

  1. mkdir ~/bin
  2. export PATH=~/bin:$PATH
  3. curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
  4. chmod a+x ~/bin/repo

Initialize the repository

  1. mkdir ~/rowboat-android
  2. cd ~/rowboat-android
  3. repo init -u git://gitorious.org/rowboat/manifest.git -m rowboat-jb-am37x.xml                         (JB for Beagleboard)
  4. repo sync

If a warning telling you that there is a new REPO version appears. Stop the sync process and update

  1.  cp ~/rowboat-android/.repo/repo/repo  ~/bin/repo
  2. chmod a+x ~/bin/repo
  3. repo sync

Once the repo is successfully synced, you will see a message like this:

* [new branch]      rowboat-froyo -> rowboat/rowboat-froyo
* [new branch]      rowboat-gingerbread -> rowboat/rowboat-gingerbread
* [new branch]      rowboat-ics -> rowboat/rowboat-ics
* [new branch]      rowboat-jb -> rowboat/rowboat-jb
* [new branch]      ti-dsp     -> rowboat/ti-dsp
Fetching projects: 100% (261/261), done.
Checking out files: 100% (8843/8843), done.out files:  10% (949/8843)
Checking out files: 100% (24601/24601), done.ut files:  50% (12308/24601)
Checking out files: 100% (18021/18021), done.ut files:   3% (616/18021)
Checking out files: 100% (35638/35638), done.ut files:   1% (663/35638)
Checking out files: 100% (2088/2088), done. out files:   6% (134/2088)
Checking out files: 100% (974/974), done.ng out files:  34% (336/974)
Checking out files: 100% (667/667), done.ng out files:  18% (123/667)
Checking out files: 100% (2412/2412), done. out files:   4% (106/2412)
Checking out files: 100% (26958/26958), done.ut files:  24% (6516/26958)
Checking out files: 100% (81/81), done.
Checking out files: 100% (441/441), done.ng out files:  43% (194/441)
Checking out files: 100% (6505/6505), done. out files:   1% (108/6505)
Syncing work tree: 100% (261/261), done.

kimi@X-Server:~/rowboat-android$

Cross compiling Jelly Bean for Beagleboard

Now we are going to modify the PATH variable in order to include the binary directory of the GCC compiler. The following command should be executed every time you open a new Terminal console and want to compile the code. Unless, you include the new PATH into your ‘.bashrc’ or ‘.bash_profile’ file.
export PATH=~/rowboat-android/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin:$PATH

X-loader

X-loader is a small first stage boot loader derived from the u-boot base code to be loaded into the internal static ram by the OMAP ROM code. Because the internal static ram is very small (64k-32k), x-loader is stripped down to the essentials and is used to initialize memory and enough of the peripheral devices to access and load the second stage loader (U-boot) into main memory.
In order to build X-loader we will follow these steps
cd ~/rowboat-android/x-loader/
make CROSS_COMPILE=arm-eabi- distclean
make CROSS_COMPILE=arm-eabi- omap3beagle_config
make CROSS_COMPILE=arm-eabi- -j4

the parameter ‘-j4’ will tell the make to use up to 4 threads to build the code. If you have a dual-core/two-threads CPU, use ‘-j2’. Omitting this parameter will also compile the code, but using just a single thread (which for x-loader or u-boot is not a big problem, but the Android source code can take many hours).
The result of this process is a file named ‘x-load.bin’ on the current directory. This file should be signed with a tool called ‘signGP’ before x-loader gets into the MMC card.

Downloading Rowboat-tools for Jelly Bean

cd ~
curl http://rowboat.googlecode.com/files/RowboatTools.tar.gz > RowboatTools.tar.gz
tar -zxvf RowboatTools.tar.gz

Signing x-load.bin

cp ~/RowboatTools/signGP/signGP ~/rowboat-android/x-loader/signGP
cd ~/rowboat-android/x-loader
./signGP x-load.bin
cp x-load.bin.ift MLO

Now we have a ‘MLO’ file which is a signed version of the binary x-loader, and this file can be used in the board.

Uboot

Uboot is a universal bootloader program that developed for the loading and starting of embedded Linux systems. Uboot essentially can load a (linux) kernel from one of several locations, and start it with corresponding arguments.

cd ~/rowboat-android/u-boot/
make CROSS_COMPILE=arm-eabi- distclean
make CROSS_COMPILE=arm-eabi- omap3_beagle_config
make CROSS_COMPILE=arm-eabi- -j4

The result of this process is ‘u-boot.bin’ file. And a successful build generates an output like this:

api/libapi.a post/libpost.a board/ti/beagle/libbeagle.a --end-group /home/kimi/rowboat-android/u-boot/arch/arm/lib/eabi_compat.o -L /home/kimi/rowboat-android/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/../lib/gcc/arm-eabi/4.6.x-google -lgcc -Map u-boot.map -o u-boot
arm-eabi-objcopy -O srec u-boot u-boot.srec
arm-eabi-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
kimi@X-Server:~/rowboat-android/u-boot$

Building Android, Kernel and SGX

In order to build Android, its kernel and SGX (which provides the Hardware Acceleration needed by Android 3.x+)

cd ~/rowboat-android
make TARGET_PRODUCT=beagleboard OMAPES=5.x -j4

(This step takes aprox. 1 hour)
If this commad successed you will see something like this on the console

Installation complete!

cat install.sh >install
chmod a+x install
make[1]: Leaving directory `/home/kimi/rowboat-android/hardware/ti/sgx’
If you don’t see an output like this, try running the command without “-j4”.
If everything is Ok, then it’s time to create the root filesystem and compress it into a tar.gz file. (20 minutes. aprox)
cd ~/rowboat-android
make TARGET_PRODUCT=beagleboard fs_tarball -j4

Building Kernel and Android separately

It is possible to build the kernel and Android separately, and this is recommended once you have done a full build and you have modified only a small part of the code.

Builing the Kernel

cd ~/rowboat-android/kernel
make ARCH=arm CROSS_COMPILE=arm-eabi- distclean
make ARCH=arm CROSS_COMPILE=arm-eabi- omap3_beagle_android_defconfig
make ARCH=arm CROSS_COMPILE=arm-eabi- uImage -j4

This will generate ‘uImage’ (kernel image) in “~/rowboat-android/kernel/arch/arm/boot”

Builing Android

cd ~/rowboat-android
make TARGET_PRODUCT=beagleboard droid -j4

Again, in order to create the root filesystem, run

cd ~/rowboat-android
make TARGET_PRODUCT=beagleboard fs_tarball

Creating a bootable SD-Card

Once x-load, Uboot, kernel and Android are built, it’s time to create a bootable SD-Card with all this files.

Boot arguments

Edit boot arguments for am37x.
cd ~/RowboatTools/am37x/mk-bootscr
gedit boot.scr

Change mem=256M with mem=448M. This will increase the amount of RAM available in Android for applications.
Generate boot script
./mkbootscr

Putting all together

Format the SD Card into a single FAT32 partition. A +4GB SD Card is recommended, while the minimum amount of memory is 2GB.

mkdir ~/rowboat-image
cp ~/rowboat-android/kernel/arch/arm/boot/uImage ~/rowboat-image
cp ~/rowboat-android/u-boot/u-boot.bin ~/rowboat-image
cp ~/rowboat-android/x-loader/MLO ~/rowboat-image
cp ~/RowboatTools/am37x/mk-bootscr/boot.scr ~/rowboat-image
cp ~/rowboat-android/out/target/product/beagleboard/rootfs.tar.bz2 ~/rowboat-image
cp ~/RowboatTools/am37x/mk-mmc/mkmmc-android.sh ~/rowboat-image

Execute the script

cd ~/rowboat-image
sudo ./mkmmc-android.sh /dev/sdb  MLO u-boot.bin uImage boot.scr rootfs.tar.bz2

Change /dev/sdb with the path for your SD Card
If you don’t see anything executed on the console, may be mkmmc-android.sh has a hidden char that generates problem. Try opening the file with gEdit and copying the content to another file, for example mkmmc.sh. Then make that file executable and try again.

Ready!

Now you are ready to extract the SD Card, insert it into the Beagleboard and run Android. Be patience, the first start up can take several minutes. The second time you start up Android it takes minutes more or less.

Performance

Some SD Cards show a very poor performance. Most Kingston micro SDHC cards have this performance issue. San Disk micro SDHC or Sony micro SDHC are recommended.

Known issues

  • mmc0: error -110 whilst initializing SD card
Your are using a SDHC Card affected by preemption model in Kernel 2.6. Look to this post about loading “rootfs” from USB . This avoids the bug, and gives more performance & storage space.

Android USB Host + USB VCP Driver [Part 3]

The Abstraction Layer

Once the prototype works and could establish a great communication between the Xoom and the FT232 IC, I decided to separate the project in order to let anyone creates a VCP Driver adding just a few methods.
The Abstraction Layer is present in the USB VCP Library for Android. It consists of 5 classes as you can see in the following picture:

VCPDriver

It is the main class. It represents the driver which lets the user connect and disconnect from the device. It also handles the low level connection and disconnection from the USB Device, and provides 5 abstract methods.

The user should call “connect” with a valid RS232 Configuration and a (may be null) object that implements the Async. Receveiver Interface. The “disconnect” method should be used in order to de-initialize variables but must call VCPDriver.closeDevice() in order to release all the USB stack.

 
“transfer” is a generic method that lets the user do synchronised transactions. The user can call this method in order to send and/or receive a package from the device.
“initialize” should be called from “connect” and will perform several controlTransfer commands in order to setup the device (including the RS232 configuration).

Finally, the AsyncReceiver is an interface with a very simple method. If your class implements this interface, you will receive async information from the driver.
As the VCPDriver has some abstract methods, all the class is abstract. So for every IC manufacturer, you should create a specialised Driver class, as I have created the FT232Driver class.
 
 

Android USB Host + USB VCP Driver [Part 2]

(Un)fortunately I have just signed a NDA (Non-Disclosure Agreement) with FTDI Chip in order to develop the Android version of their FT(2)232 chip.

This agreement was approved by FTDI so I cannot publish either the documentation I have just received, or the source code I develop based on that documentation.
I will go on writing about my experience developing the USB VCP driver for Android entirely on Java, and  may be as a result of the project an obfuscate binary will be published in order to communicate with the FT(2)232 family.
One more thing to mention: FTDI writes very clear and nice documentation.

Android USB Host + USB VCP Driver [Part 1]

I have connected a USB device that creates a USB VCP profile to my Motorola Xoom in order to enable my Xoom apps to interface with RS232 devices.
My small test program shows the following details for the USB device:

Model: /dev/bus/usb/002/002
Id: 2002
Class: 0
SubClass: 0
Protocol: 0
VendorId: 1659
ProductId: 8963
Number of Interfaces: 1
>> Interface 0 -> 3 Endpoints

With all the information we can tell the device to open a custom application when the USB device is attached. To do so, the following information should be added to the ‘activity’ tag in the Manifest.

<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/usb_device_filter" />

The XML file is a resource file that contains information about the USB Device, that should be placed in /res/xml

<resources>
<usb-device vendor-id="1659" product-id="8963" class="0" subclass="0"
 protocol="0"/>
</resources>

When the activity starts, it can retrieve the USB Device information by calling:

device = (UsbDevice)getIntent().getParcelableExtra(UsbManager.EXTRA_DEVICE);

If the device is not null, then you can open an UsbInterface and get the UsbEndpoint in order to read and write information.

How Android sees an attached USB Device

In the long way that my project must walk, I decided to start testing some small things in order to understand how the Android USB Host API and Open Accessory API (two different things) work.
Basically the USB Host API lets your Android device acts as a computer. With this API you can connect from a Bluetooth USB adapter to any standard USB device that you can find in a store. The Open Accessory API works the other way, your Android acts as a device, so you have to connect a USB Host controller in the other side. I don’t find this second approach very useful. First because not all the microcontrollers in the world support USB Host (Remember, your Android is a Device for the Open Accessory API) Second because it does not allow seemless development of a product using a computer and a natural port to Android using the USB Host API. I still cannot find three nice examples of when I will prefer to use my Tablet as a USB Device, but I can find millions of application for my Tablet (and Phone) to be a USB Host.
So in this short post, I will show you how it a USB Device attached to a  Honeycomb-enabled device looks like. Take special attention to the fact that even though Android 2.x has an option USB toolkit, and the classes have the same name, they belong to a different package (so the imports are not the same).
The Motorola Xoom with Android 3.2 is USB Host capable, and even thought I connected a USB keyboard and it didn’t work in the OS, the following short example demonstrates that the Motorola Xoom detects a USB Bluetooth adapter.

When attaching the USB Bluetooth adapter the following message can be seen using “logcat” (connected via TCP as the USB port is busy with the adapter)



 

Debugging Android wirelessly

Recently I flashed my Motorola Xoom with Android 3.2 in order to start playing with USB Host API and Open Accessory API, but both functionalities are implemented on the unique USB port that the Xoom has. This is not a problem when you own a Dock, or you own a Acer A500 which has one USB host and one USB device. Debugging an Android application using abd can be done wirelessly over WiFi using the followings instructions.

When debugging applications that use USB accessory or host features, you most likely will have USB hardware connected to your Android-powered device. This will prevent you from having an adb connection to the Android-powered device via USB. You can still access adb over a network connection. To enable adb over a network connection:

  1. Connect the Android-powered device via USB to your computer.
  2. From your SDK platform-tools/ directory, enter adb tcpip 5555 at the command prompt.
  3. Enter adb connect <device-ip-address>:5555 You should now be connected to the Android-powered device and can issue the usual adb commands like adb logcat.
  4. To set your device to listen on USB, enter adb usb.