Tinkering with USB devices

Whenever you connect a USB slave device to your Nexus 7, you also loose one thing: ADB over USB. In order to still be able to tinker with your tablet, or just to view logs in realtime, you need 'Boot with ADB over network'.



This feature will make the use of Android Debug Bridge as simple, as if your USB port was not really occupied. Once activated, you will be able to reboot your device any number of times and it will always come up with ADB over network activated. Connect to your WiFi-AP and get your local IP-address from Settings / Developer options / ADB-over-Network. Then use the local IP-address to access your tablet from your PC:

adb connect x.x.x.x
adb -s x.x.x.x:5555 shell ...

or:

adb connect x.x.x.x
adb -s x.x.x.x:5555 shell
...
...

Adding drivers for new USB devices

In order to activate a new USB slave device on the Nexus 7, you will likely go through the following four stages:


  1. Find out if and how your device has been integrated on another Linux platform. What are the device driver names? What is the minimum kernel version requirement?
  2. Get hold of the necessary device driver(s), compiled for your target platform (CPU + kernel version).
  3. Create simple shell scripts for loading and unloading of the required device drivers.

Step 1 is an investigational process. A person responsible for a Linux distribution (in this case, that would be me), may be able to help you with steps 2 and 4. Step number 3 is where access to the physical device is needed the most. This is, where you can help. This is also, where the Boot with ADB over network feature can be used with great benefit.

Sample DVB-T scripts

The outcome of step 3 could look like the following two scripts, made for loading and unloading of all device drivers needed, to run a AF9015 DVB-T stick. Script 1: load all required device drivers:

echo "starting DVB support"
insmod dvb-core.ko
insmod dvb-pll.ko
insmod rc-core.ko
insmod dvb-usb.ko
insmod mt2060.ko
insmod qt1010.ko
insmod af9013.ko
insmod mxl5007t.ko
insmod tda18218.ko
insmod mxl5005s.ko
insmod dvb-usb-af9005-remote.ko
insmod dvb-usb-af9005.ko
insmod dvb-usb-af9015.ko
echo "Waiting for device"
sleep 5
cd /
mkdir /dev/dvb
chmod 777 /dev/dvb
mkdir /dev/dvb/adapter0
chmod 777 /dev/adapter0
cd /dev/dvb/adapter0
ln -s /dev/dvb0.frontend0 frontend0
ln -s /dev/dvb0.demux0 demux0
ln -s /dev/dvb0.dvr0 dvr0
ln -s /dev/dvb0.dvr0 dvr0.ts
chmod 777 /dev/dvb*
echo "DONE!"

Script 2: unload all device drivers in reverse order:

echo "removing DVB support"
rmmod dvb-usb-af9015
rmmod dvb_usb_af9005
rmmod dvb_usb_af9005_remote
rmmod af9013
rmmod mxl5005s
rmmod tda18218
rmmod mxl5007t
rmmod qt1010.ko
rmmod mt2060.ko
rmmod dvb_usb
rmmod rc_core
rmmod dvb_pll
rmmod dvb_core
echo "DONE!"

A DVB-T device with a remote control unit is a complex piece of hardware. The device you have in mind may be easier to get up and running.


Getting the device to work

You will need to open multiple terminal windows for different tasks:


  1. to run a remote shell on your Android device (as shown above)
  2. to run a local shell, to copy files from your PC to your Android device
  3. to have live access to the Linux kernel log
  4. to have live access to the Android system log



Start displaying the Linux kernel log in a dedicated window (3)

adb -s x.x.x.x:5555 shell
cat /proc/kmsg |grep -vE "cpu|CPU|bq27541|temp=|tegra-i2c"

Start displaying the Android system log in a dedicated window (4)

adb -s x.x.x.x:5555 logcat|grep -vE "/dalvik"

Use your remote shell (1) to create a new folder "test" under /data on your Android device

su
mkdir /data/test

Use your local shell (2) to copy the required device driver to the new folder on your Android device

adb -s x.x.x.x:5555 push test.ko /data/test/

Use your remote shell (1) to load the device driver

cd /data/test
insmod test.ko

Now watch your kernel log (3) and see what messages are being generated as a reponse to the device driver being loaded.


This, basically, is the framework. If multiple device drivers are needed, the load order will likely play an important role. If you skip one driver, the next one may tell you that something missing. In this case, you will have to unload the last driver (using 'rmmod drivename') and change the order. "lsmod" can be used to show the currently loaded kernel modules.


When the last driver is loaded and there are no error messages being shown, you can start the specific Android application, making use of the new device drivers. You need to watch both kernel and system logs carefully for suspicious messages.


Once you can use your device, you need to create a script file on your PC, containing all the steps you executed manually. You also need to create an unload script, doing all steps in reverse order and using rmmod instead of insmod. Transfer both scripts to your Android device.

adb -s x.x.x.x:5555 push test.sh /data/test/
adb -s x.x.x.x:5555 push untest.sh /data/test/

You need to make your scripts executable. In your remote shell run

chmod 777 *.sh

Now play with the two scripts. It should be possible to execute them in alternating order, without new error messages showing up. The two scripts should work also after you rebooted your Android device.

./untest.sh
./test.sh
(test the app)
./untest.sh
./test.sh
(test the app)

In a final step, you can add the start script to /data/local/userinit.sh in order to have it run automatically on every system boot.

echo "/data/test/test.sh" >> /data/local/userinit.sh