In this activity we will use the ADB command line and shell running on the development system, to directly manipulate the Dragonboard 410c GPIO pins. A version of "Blinky" will be implemented that periodically flashes a LED of the target. A second version will turn the LED on/off under control of a press button. The "app" will run as batch file of ADB commands on the dev machine remotely controlling Dragonboard. A Linux shell script running on the target will also be used that encapsulates the batched ADB commands..
Previous blogs in this series have covered the Dragonboard features, setting up the Android development system and developing an Android UI app to access hardware (the sensors class). In the later activity, ADB was (under the hood) used to deploy the app from the dev machine to the target. You can also run an ADB command line to directly use ADB commands and even run a shell in which you can make Linux command line calls on the target.
Target System: Dragonboard 410c in factory state (runs Android).Development System: Windows 10 desktop Version 1511Development Environment: Android Studio
For this activity you need ADB to be in the command prompt path, which was covered in the a previous blog.
Android Architecture: More detail here
Android is a mobile operating system championed by Google. Its source code is released by Google under Open Source licensing although commercially shipped Android devices (eg Phones) tend to have proprietary software components. It is essentially a graphical user interface operating system, with a toiuch focus. Apps are written using the Android SDK and are generally written in Java. For development purposes, emulators are available.The OS for an Android system is essentially in two parts. One is the Android UI, the other is the Linux Kernel. The kernel implements to low level aspects of the OS including hardware interfacing. The Android Debug Bridge (ADB) enables us to drill into the hardware from a remote terminal.
The Android Debug Bridge (ADB) provides connectivity to the target Android device. Connectivity normally is via USB but can be over a local (eg WiFi) network. Android Studio uses ADB to deploy, run and debug apps. You can also use it via a command line as a remote terminal into the target from your development system. You can copy files to and from the target, access its its file system, manually deploy apps, run a Linux shell remotely and directly manipulate hardware such as GPIO.
To access ADB, connect up your target device to the development system using a USB cable (USB-OTG (micro USB) on target to USB Host on dev system).Run a command prompt (admin might be useful) Alternatively you can use the Android Monitor Window in Android Studio.Enter (In what follows > is the prompt so don't enter that as well)
>adb version >adb devices ... you should see your device listed
Comment: You can have more than one device connected to your dev machine; in which case you need to specify which target you want to apply a command on. For simplicity, it is assumed that you are only using one device. See the Android Debug Bridge document on how to specify a target.Note: To enable ADB debugging on a device, it must be enabled. See the second previous blog.
PS: adb –d <command> will direct attention to the one and only USB device (assumes only one).
>adb shell
adb <adb command>
>adb shell ls
ADB commands can be run individually using >ad shell <command> which then returns to the PCs command prompt. If though a series of commands are required, you would enter the shell as follows:
>adb devices >adb root >adb remount >adb shell
Unless otherwise stated, in what follows, it is assumed you are in a shell as above when ADB commands are used.
The 40 pin Low Speed connector provides a physical interface to the target system's GPI pins. There are potentially 12 such pins available on pins 23 to 34. They are called
Potentially" because they may be configured for other use. For example, GPIO_F is not available for GPIO unles the kernel is reconfigured. Our focus here on the pins that can be set or cleared as output or can be read as input (hi or lo).The connector also provides connectivity to
Android runs as user interface on top of a Linux kernel. Services, such as Sensors can sit on between Android and the kernel and are loaded under Linux. With ADB we are communicating with the kernel via a service (ADB), no Android UI interactions. The various hardware devices are configured and interacted with via Linux drivers that are loaded when the system starts. The Android UI then interacts with the drivers through a Hardware Abstraction Layer (HAL). For example , the Sensors class used in the previous blog has a HAL manifestation.
Within the adb kernel command shell, hardware is interacted with as part of the file system. You navigate down to a hardware's folder where elements in that folder are properties that hardware that can be set by echoing to them or cat-ed to read from them. Try:
>ls /sys/class/gpio
>root@msm8916_64:/ # ls /sys/class/gpio export gpiochip576 gpiochip608 .... .... gpiochip900 gpiochip902 unexport
We have to activate them using .. before they show. We can send ports’ APQ number to export (activated/enabled) or to unexport (deactivated/disabled)
The GPIO ports have to be “activated” before you can use them. For each GPIO port A to L in the schematic above, note its APQ_GPIO number. For example, GPIO_A is APQ_GPIO_36. The “magic number you need for this port then is 938, which is determined by adding 902 the the APQ number. The GPIO_A is then enabled by the following command:
>echo 938 > /sys/class/gpio/export
>ls /adb/class/gpio will now list gpio36 which is GPIO_A.
>root@msm8916_64:/ # ls /sys/class/gpio export gpio938 gpiochip576 gpiochip608 .... .... gpiochip900 gpiochip902 unexport
To disable that port:
>echo 938 > /sys/class/gpio/unexport
If we now issue the command:
>ls /sys/class/gpio/gpio938
we get a list of things we can do with GPIO_A (gpio38)…
126|root@msm8916_64:/data # cd /sys/class/gpio/gpio938 root@msm8916_64:/sys/class/gpio/gpio938 # ls active_low device direction edge power subsystem uevent value root@msm8916_64:/sys/class/gpio/gpio938 # cd $home
Note the highlighted attributes direction and value for the GPIO port. Examine the following:
root@msm8916_64:/data # echo "out" > /sys/class/gpio/gpio938/direction root@msm8916_64:/data # cat /sys/class/gpio/gpio938/direction out root@msm8916_64:/data # echo "1" > /sys/class/gpio/gpio938/value root@msm8916_64:/data # cat /sys/class/gpio/gpio938/value 1 root@msm8916_64:/data # echo "0" > /sys/class/gpio/gpio938/value root@msm8916_64:/data # cat /sys/class/gpio/gpio938/value 0 root@msm8916_64:/data # echo "in" > /sys/class/gpio/gpio938/direction root@msm8916_64:/data # cat /sys/class/gpio/gpio938/direction in root@msm8916_64:/data # cat /sys/class/gpio/gpio938/value 0
If pin #23 was then connected to ground or Vcc we would examine its input state using the last command.Ps (a big) Nb: The pin voltages are 1.8v on the Dragonboard. Do not exceed that
In the ADB GPIO commands, refer to a GPIO port via its gpio column value
You can connect a LED directly across pins 1 and 23.
You can then toggle the LED with the following commands:
>echo "out" > /sys/class/gpio/gpio938/direction >echo "1" > /sys/class/gpio/gpio938/value >echo "0" > /sys/class/gpio/gpio938/valueetc.
Now wouldn’t it be nice if we could run this as an app with a period between blinks. Lets do it as a batch file:
One way I have found works is to script adb shell commands into a text file, type the file using the DOS type command and pipe the output into adb shell. eg:
>type commands.txt | adb shell
commands.txt needs two lines after the commands:
adb-command1 adb-command2 exit <- Blank line here
The blank line makes sure that when the adb commands are run in the shell, the process exits adb shell back to the Windows command prompt..
The following script, setup.txt, would setup GPIO_A:
echo 938 > /sys/class/gpio/export echo "out" > /sys/class/gpio/gpio938/direction exit |
The following script on.txt would set GPIO_A:
echo "1" > /sys/class/gpio/gpio938/value exit |
The following script off.txt would clear GPIO_A:
echo 938 > /sys/class/gpio/unexport exit |
In these scripts, the | in the last line is only meant to indicate a blank line, not a literal |.
A set of the scripts can be encapsulated by being called in sequence from a batch file. The following is Blinky as a batch file:
@echo off adb devices adb root rem adb remount type setup.txt | adb shell @echo . @echo Ready to blink on and off for 20 seconds pause for /l %%i in (1,1,10) do call :blink %%i goto end :blink @echo . @echo %1 ON type on.txt | adb shell timeout 1 > nul @echo %1 OFF type off.txt | adb shell timeout 1 > nul exit /b :end @echo . type setdown.txt | adb shell @echo Done pause
We should though be able to script all of the above as a Linux shell script. The version of Linux running on the Dragon board uses sh as its shell. So we would script Blinky as blinky.sh:
#!/system/bin/sh #Setup.txt echo 938 > /sys/class/gpio/export echo "out" > /sys/class/gpio/gpio938/direction a=0 while [ $a -lt 4 ] do #Loop counter a=$(( a+1)) echo $a ON #on.txt echo "1" > /sys/class/gpio/gpio938/value sleep 1 echo $a OFF #off.txt echo "0" > /sys/class/gpio/gpio938/value sleep 1 done #Setdown.txt echo 938 > /sys/class/gpio/unexport exit
It can be run by piping it to adb shell as previous:
>type blinky.sh | adb shell
Part 2 : Running it as a complete shell script.
This is a first draft so I have a few typos to fix tonight. Plz leave a comment.