CSE 466 Lab 5: Introduction to the iMote2

Introduction

Now that you've worked with a simple 8-bit microcontroller, we'll be exploring more powerful embedded devices. For the rest of the quarter, we'll be using the iMote2, which has a 32-bit, 415 MHz ARMv5 microcontroller (The PXA271), with 32 MB of flash and 32 MB of RAM. This microcontroller was designed for use in cell phones and PDAs. This lab will introduce you to the iMote2 platform, and using Linux as an embedded operating system.
WARNING: NEVER attach or detach the iMote2 from the debug board or the sensor board when power is attached. ALWAYS make sure you've unplugged ALL of the USB cables when connecting or disconnecting the sensor board or debug board.

Objectives

In this lab, you will learn:

Hints

Suggested Reading and Resources

Part 1: Getting acquainted with the platform

In this section, you will become familiar with the new boards in your kit, and learn the basics of connecting to the iMote2 with a computer to install and run programs.

In your kit, you should now have five boards: two iMote2s, two basic sensor boards (BSBs), and one debug board.

iMote 2
The iMote2
Basic Sensor Board
The Basic Sensor Board (BSB)
Debug Board
The Debug Board

The iMote2 is a complete system consisting of a PXA271 Xscale microprocessor, 32 MB of flash program and data storage, 32 MB of RAM, and an 802.15.4 ZigBee wireless radio.  It also has an RGB LED on the board that can be used as a simple output device for debugging.  It has two sets of connectors for expansion: the basic connector set (shown in the photo above) and the advanced connector set.  You will use both expansion connectors by the end of the course.

The Basic Sensor Board (BSB) connects to the iMote2 via the basic connector side.  It provides an accelerometer, light sensor, temperature and humidity sensor, and a general purpose A-D converter.  In this course, we will primarily use the BSB for the accelerometer.

The debug board features the same USB-to-serial interface chip that you used in Lab 4.  You'll generally be using the USB ethernet interface to connect to the iMote2, but the debug board is useful for logging in if you cannot establish a network connection or need to change the network settings.  The debug board also has a JTAG interface which can be used to re-flash an iMote2 if the software or configuration becomes corrupted or damaged.

We've pre-loaded the Linux kernel, root filesystem, and the bootloader (BLOB) onto your iMote2 using the JTAG interface.  You should be able to follow these directions to log into the iMote2:

  1. Connect the iMote2 to the computer with a USB cable, and press the power button.  The LED will turn blue while the iMote2 is starting up, and then green when startup is complete.  Wait for the LED to turn green.
  2. Launch PuTTY, and enter 192.168.99.101 for the IP address.
  3. Once you see the login prompt, log in with username root and password rootme.

You're now logged in to the iMote2.  Take a moment to familiarize yourself with the environment.  It's more or less a standard Linux shell from which you can manage files and execute programs.

Next, you'll compile your first kernel module (driver) and user-level application for the iMote2.  This simple driver will blink the LED on the iMote2, and the user application will allow you to change the rate at which the LED blinks.

  1. Download and unzip the blink application code to your attu account. 
  2. To compile the kernel module, simply run make.  This should produce a file called blink-mod.ko, which is the kernel module.
  3. To compile the user application, run:

    /cse/courses/cse466/iMote2/cross-compiler/arm/3.4.1/bin/arm-linux-gcc -o blink-app blink-app.c


    This should produce a file called blink-app, which is a user-level utility to set the blink rate.
  4. Copy the files over to the iMote2 using WinSCP3.  To do so:
  5. To load your kernel module, run insmod blink-mod.ko on the iMote2 console.  This "inserts" the module into the running kernel.  For more information on insmod, see the manual page.
  6. In Linux, like all other UNIX-like operating systems, devices appear as special files.  Devices can either be character devices, which act like infinite streams of bytes, or block devices, which communicate with fixed-size blocks of data.  Devices are part of the regular file system namespace, usually appearing in the /dev directory.  For each device "file," the filesystem contains an entry mapping that "file" to a device number, split into major and minor parts.  Major numbers correspond to a particular kind of device, or a driver responsible for that device.  Minor numbers correspond to specific instances of those devices, which are managed by a common driver.  You can view these major and minor numbers by running ls -l /dev.

    Since the number of available major device numbers is small, well-behaved drivers request a major number when they are inserted into the kernel.  Now that the kernel module has been laoded, we need to find out which major device number Linux has assigned to our new device.  To do so, run cat /proc/devices.  Under "Character devicces," you should see a line like 254 blink.  In this case, 254 is the major device number.  Since we only have one blink device, we use 0 as the minor number.  To make a filesystem entry for the blink device, run mknod /dev/blink c 254 0.  This creates a character device named /dev/blink that points to device number 254,0.  For more information on mknod, see the manual page.
  7. Make sure that blink-app is executable by running chmod +x blink-app.
  8. Execute ./blink-app 1 to blink the LED at 1 Hz.
  9. To remove the blink module, execute rmmod blink.  For more information on rmmod, see the manual page.

Part 2: Extending the blink module

Now that you've successfully built a kernel module and an application that uses it, let's take a look at how it works. From there, you'll extend the blink module to drive three PWM signals to the tri-color LED (similar to lab 3).

Let's take a look at the blink-mod.c file.

Now, your task is to modify the blink module and application so that you can set the tri-color LED to any color using PWM. Specifically:

  1. Modify the blink kernel module to generate PWM signals to all three LEDs, like you did in lab 3. You should be able independently control each LED’s duty cycle.
  2. Modify blink-app into a user-level application that sets the color output of the tri-color LED. You’ll need to extend the kernel module’s ioctl interface for this.
Question 1: To acknowledge an interrupt, you write a 1 to the corresponding bit in the correct interrupt flag register. This clears the corresponding bit, and bits to which you wrote zeros are left alone. What is the reason behind this seemingly strange convention?

Question 2: In blink_irq_handler, we acknowledge the compare match interrupt for timer 4 with the code OSSR = OIER_E4 where OIER_E4 is defined as (1<<4). What could go wrong if you did OSSR |= OIER_E4 instead? (This was a bug in the skeleten code distributed for previous quarters.)

Part 3: Using the accelerometer

In this part, you'll finish implementing a driver for the accelerometer on the Basic Sensor Board, and write an application that converts accelerometer readings to colors, like in lab 3.

  1. Download the accelerometer skeleton code here. It should contain the following files:
  2. Before getting started, here's some things to note about the skeleton driver:
  3. Implement accel_irq_handler and accel_ioctl in accel.c.
  4. Test your module with the provided accel-dump application.
  5. Create an application that translates the accelerometer readings into color values on the RGB LED. You do not need to do any fancy HSV to RGB mapping -- simply using each axis of the accelerometer to control a single color is sufficient.
Question 3: If the measurements for each of the axes are not read by the time the next measurement is ready, the accelerometer will stall and set flags to indicate that an overrun has occurred. Why might this be desired behavior, rather than simply overwriting the old values?

Question 4: Why is it particularly important to minimize the number of SPI transactions in the interrupt service routine?

Deliverables

  1.  The following files should be turned in:
  2. Submit files to the Catalyst drop box for your section:
  3. Demonstrate your completed Part 3 to a TA during the first half-hour of next week's lab period.