How to get started with Embedded Android on the Wandboard: Building and Deploying the Bootloader, Kernel and Android Root File System

wandboard

The community based Wandboard project (http://www.wandboard.org) is a very interesting open Freescale iMx6 hardware platform. The most recent release of the Android 4.2.2 Source Code for the board makes it an ideal candidate to prototype an Embedded Android System.

For this Blog Post we are using:
Android 4.2.2 wandboard repo sources
IMX Kernel 3.0.35+ (supplied by the Android sources)
U-Boot IMX Fork (supplied by the Android sources)
Host: Ubuntu 12.10 64 Bit (username: user)

Understanding how Android Boots

In this blog post we are looking a bit closer in how to get started with booting the platform using the patched Linux Kernel and u-boot. Both come with the Android Source code which is available for downloading with Android’s repo tool.

Continue reading “How to get started with Embedded Android on the Wandboard: Building and Deploying the Bootloader, Kernel and Android Root File System”

Embedded Android Tutorial: Part II, Setting up the Arduino to measure light intensity and reconfigure the Pandaboard’s kernel for communication

In this post we are going to set up the Arduino Uno to measure light intensity. Furthermore, we configure and recompile the Pandaboard’s kernel to communicate with the Arduino Uno through USB-serial.

For measuring light, we will require some kind of photoresistor. If you do not have any spare ones around, you can easily get them on ebay. A photoresistor is a resistor that changes its resistance depending on the current light intensity. In the end, we will simply measure an analogue voltage that changes depending on the attached photoresistor.

For this tutorial you will need:

  • Pandaboard with Linaro’s Android build from Part I
  • Arduino Uno
  • 1 Photoresistor
  • 1 Resistor with a value around 3 kilo-ohm (we are using 3.9kOhm)
  • Breadboard
  • 3 jumper wire cables (male-male)

Continue reading “Embedded Android Tutorial: Part II, Setting up the Arduino to measure light intensity and reconfigure the Pandaboard’s kernel for communication”

Embedded Android Tutorial: Part I, Setting up the Pandaboard with the Linaro Android Build

Recently we have been setting up the Pandaboard with Android to get started with Embedded System Development.

In this first post we would like to share of what steps were necessary to set up the build environment, Android source from Linaro and toolchain to get started on an Ubuntu 12.04 64 Bit machine.

Android Build and Version: Linaro Android Build, 4.1.1 Jellybean
Host Machine: Lenovo T420, Ubuntu 12.04 64 Bit
Hardware Target: Pandaboard
Deployment Target: SD-Card

Please note that since the Android ICS release, the Android Source can (sadly) only be built on a 64 bit OS, without the need to do workarounds.

Important Links for further reading:

Linaro Android Project
Build Environment Initializing
Current Linaro Build version information

Setting up the build environment

Before you can get started to build the Android Source code and Kernel, you need to set up the build environment properly. Part of this is installing packages from the Ubuntu repositories (for instance build tools like make and host side gcc etc.) and also the java version (from sun/oracle) which cannot be found in the current Ubuntu repositories.

Continue reading “Embedded Android Tutorial: Part I, Setting up the Pandaboard with the Linaro Android Build”

Arduino USB transfers

In this post we will show you how to communicate between the Arduino Uno and your computer using plain USB bulk and control transfers, not relying on a serial communication interface. Our development computer runs Ubuntu 11.10 (Oneiric Ocelot).

This is a follow up to Programming the Arduino Uno with Eclipse on Linux. The next post in this series is Android USB Host + Arduino: How to communicate without rooting your Android Tablet or Phone.

The Arduino Uno has an on-board USB-to-serial converter (ATMega8u2 or ATMega16u2 since rev. 3). The preloaded firmware on this converter presents itself as an USB Communication Device Class (CDC). Usually, no further software driver is needed on the host computer. You can simply plug in the Arduino Uno to your computer, and you will be able to communicate with the Arduino’s main microcontroller, the ATMega328, over an emulated serial communication interface.

For many applications, a serial communication interface is just fine. You can use minicom, gtkterm or a similar terminal application to send and receive data from your microcontroller. Or even use a python serial library and start off from there. In some circumstances however, you might not have the possibility to open a serial communication. Android for instance does not have a native serial communication interface, instead it features an USB host API. In this case, you must rely solely on USB control and bulk transfers.

When you connect an Arduino Uno to your linux computer with an USB cable, you will notice that a new device node /dev/ttyACM0 or similar is created. For this purpose, check out the last few lines from dmesg right after connecting the Arduino Uno.
$ dmesg | tail
...
[] usb 1-5.2: new full speed USB device number 43 using ehci_hcd
[] cdc_acm 1-5.2:1.0: ttyACM0: USB ACM device

In the above example, the Arduino Uno is assigned to USB device number 43, and a new device node /dev/ttyACM0 is created. This device node is automatically created by the module cdc_acm and represents a serial communication interface which you can use with minicom, gtkterm, etc. However, we are not going to do that. We want to find out how to talk to this device using USB transfers, right? 😉

Further investigations with the vendor (0x2341) and product (0x0001) id …
lsusb -v -d 2341:0001
… yield more interesting information about this device. For instance, bNumInterfaces = 2 shows that there are two available interfaces. This stems from the mentioned pre-loaded Arduino firmware. There you will see two projects:

  • arduino-usbdfu is the Arduino USB DFU bootloader firmware, which is used for flashing the ATmega8u2 or ATmega16u2 respectively.
  • arduino-usbserial is the real firmware of the USB-to-serial converter. This is where the magic happens 🙂

Again, looking at the output of …
lsusb -v -d 2341:0001
… you will see two interface descriptors. The first one with bInterfaceNumber=0 is the DFU bootloader, and the second one with bInterfaceNumber=1 is our usb-serial firmware interface descriptor. You can double-check that in arduino-usbdfu/Descriptors.c and arduino-usbserial/Descriptors.c respectively.

The starting point of the usb-serial project is in firmwares/arduino-usbserial/Arduino-usbserial.c. At the top, a variable VirtualSerial_CDC_Interface is initialized, and it is then passed in the main’s for-loop:
...
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
USB_USBTask();

The function CDC_Device_USBTask() is part of the LUFA-lib (Lighweight USB Framework Library), and is defined in CDCClassDevice.c. Likewise, this source file can be considered as the heart-piece of the usb-serial firmware. There we find all important functions such as CDC_Device_SendByte and CDC_Device_ReceiveByte. You will notice that almost every function returns immediately if no LineEncoding/Baudrate has been set. Luckily, the function CDC_Device_ProcessControlRequest (also in CDCClassDevice.c) unravels the mysteries of setting the LineEncoding, Baudrate, LineState, etc. Here is a shortened excerpt:

void CDC_Device_ProcessControlRequest() {
 switch (USB_ControlRequest.bRequest){
  case CDC_REQ_SetLineEncoding:
  if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)){
   CDCInterfaceInfo->State.LineEncoding.BaudRateBPS = Endpoint_Read_32_LE();
   CDCInterfaceInfo->State.LineEncoding.CharFormat  = Endpoint_Read_8();
   CDCInterfaceInfo->State.LineEncoding.ParityType  = Endpoint_Read_8();
   CDCInterfaceInfo->State.LineEncoding.DataBits    = Endpoint_Read_8();
  }
...

Now we’re cooking :-). To set the LineEncoding we therefore need to send an USB control request with bRequest = CDC_REQ_SetLineEncoding = 0x20 (as defined in CDCClassCommon.h) and with bmRequestType = 0x21. Also, the data must hold 7 bytes with corresponding values.

Once you know which requests to look for, it is pretty straightforward. Use an USB sniffer like wireshark and observe what happens when you plug in your Arduino board. With wireshark, you can also search for a specific bmRequestType by applying a filter like:
usb.bmRequestType == 0x21

As it turns out, there are two important control transfers when connecting the Arduino board to the computer. The first one has bRequest = CDC_REQ_SetControlLineState = 0x22 = 34 and the second one bRequest = CDC_REQ_SetLineEncoding = 0x20 = 32.

If you want to try it for yourself, download and run this python script (with sudo). This script will initialize the usb-serial-converter with USB control transfers and then send single bytes from your computer to the Arduino Uno using bulk transfers. Just make sure to remove the cdc_acm module beforehand by issuing:
$ sudo rmmod cdc_acm
As this module will otherwise lock access to the USB device. Also, you will need appropriate software running on your Arduino board. You may download this source code and flash it onto the device. This will set the duty cycle of a PWM signal on PIN3 according to the byte received from the computer. Also it will light up the on-board LED if the received byte is an odd value and shut it off when an even value is received.

Programming the Arduino with Eclipse on Linux

This is the first of a series of three posts. The ultimate goal is to setup a communication interface between an Arduino Uno/Mega board and an Android tablet over USB. Everything will be as user-friendly as possible, i.e. no root will be required on your Android tablet. The following posts Arduino USB transfers and Android USB Host + Arduino: How to communicate without rooting your Android Tablet or Phone conclude the series.

The Arduino Uno is a popular and affordable hardware platform which comes with its own IDE and core libraries for programming. If you like the Arduino IDE you may skip this post, however, if you feel more comfortable developing in Eclipse this might help you out.
We are using Ubuntu 11.10 (oneiric ocelot) and Eclipse 3.6.1 (helios), although this should not play an important role (as it turns out, Eclipse Indigo might need a few tweaks, check the end of this post). Also, setting up Eclipse for programming the Arduino Uno Atmega328P is pretty straightforward. Nevertheless, here is a quick how-to for the Arduino Uno (Arduino Mega 2560 below):

  1. Install avrdude and AVR libraries:
    sudo apt-get install gcc-avr avr-libc avrdude
  2. Start Eclipse and install CDT Plugin (C/C++ Development Tools):
    • Help -> Install New Software…
    • Work with: (your current Eclipse version)
      i.e. “Helios – http://download.eclipse.org/releases/helios”
    • Download the “pending” software package (don’t worry, download starts automatically 😉 )
    • Choose “Programming Languages” and select “C/C++ Development Tools”
    • Accept and continue by restarting Eclipse
  3. Install AVR Eclipse Plugin:
    • Help -> Install New Software…
    • Add new repository: http://avr-eclipse.sourceforge.net/updatesite/
    • Re-download the “pending” software package, download will be faster since it is probably cached 😀
    • Download AVR Eclipse Plugin and restart Eclipse
  4. Create new C project named “BlinkBlink”:
    • Project Type AVR Cross Target Application (Empty Project, AVR-GCC Toolchain)
    • Click next…
    • Untick “Debug” (in Debug mode, no hex-files are generated and avrdude can’t flash the device)
    • Click Advanced settings…
    • AVR -> AVRDude -> Programmer configuration…
    • Create a new programmer and name it “Arduino Uno”. Make sure this newly created programmer configuration is selected for the current project.
      • Programmer Hardware: Arduino
      • Override default port: /dev/ttyACM0 or similar
      • Override default baudrate: 115200
    • AVR -> Target Hardware:
      • MCU Type: ATmega328P (or load from MCU)
      • MCU Clock Frequency: 16000000 (default external clock source of Arduino Uno)
  5. Click Apply and OK to leave the properties window and click Finish to create the new project in the workspace.
  6. Create a new source file main.c and copy the contents from this link. Make sure to save main.c before proceeding (File -> Save).
  7. Project -> Build Project
  8. Click on the AVR Button within Eclipse to upload the generated hex file from BlinkBlink/Release/BlinkBlink.hex.
    Your Arduino Uno’s LED should be blinking on and off repeatedly. If somehow it doesn’t work, right-click your Project and select Properties. Make sure all AVR and Programmer settings are active as mentioned above.

For the Arduino Mega 2560 you should choose Atmel STK500 Version 2.x firmware as Programmer Hardware, and ATMega2560 as target hardware, the rest is the same as with the Arduino Uno. Also, if you are using the above source file for testing, you should change the definition of LED from PB5 to PB7, since the LED on the Arduino Mega is on Pin7 of Port B.

Update: if you are using Eclipse Indigo, some specific AVR symbols such as DDRB (data direction register of port b) may not be recognized.
To solve this problem go to preferences…

  • C/C++
  • Language Mappings
  • Add the following mappings:
    • Content Type: C Header File / Language: GNU C
    • Content Type: C Source File / Language: GNU C
  • Make sure to click on Apply afterwards… also you may need to restart eclipse after adding the mappings

Your Language Mapping preference window should look like the following screenshot:

If it still does not work, also try adding this line at the beginning of your main.c source file:
#include <avr/iom128.h>