Difference between revisions of "EBC Exercise 10 Flashing an LED"

From eLinux.org
Jump to: navigation, search
(Adding sysfs details)
m (Added adafruit link)
(96 intermediate revisions by 12 users not shown)
Line 1: Line 1:
 
[[Category:EmbeddedBeagleClass]]
 
[[Category:EmbeddedBeagleClass]]
 
[[Category:ECE497]]
 
[[Category:ECE497]]
 +
{{YoderHead}}
 +
{{EBC3.8}}This page is for the Bone (Black or White) running the 3.8 Kernel. See [[EBC_Exercise_10_Flashing_an_LED_-_xM_WhiteBone]] for the White Bone or xM running 3.2.
  
The [http://en.wikipedia.org/wiki/Hello_world_program "Hello World"] program is the traditional first program for many classes.  Flashing an LED is the embedded equivalent.  Here we will explore a few ways to flash and LED on the Beagle and explore General Purpose I/O (gpio) along the way.
+
The [http://en.wikipedia.org/wiki/Hello_world_program "Hello World"] program is the traditional first program for many classes.  Flashing an LED is the embedded equivalent.  Here we will explore a few ways to flash an LED on the Beagle and explore General Purpose I/O (gpio) along the way.  These calls will be done from the command line of the Beagle, so there is no need for the host computer.
  
 
== gpio via the Shell Command Line and sysfs ==
 
== gpio via the Shell Command Line and sysfs ==
  
The easiest way to do general purpose I/O (gpio) on the Beagle is through a terminal window and a shell prompt. In Linux more everything is treated as a file.  Even things that aren't files. In our class we'll use a virtual file system called ''sysfs''.  sysfs exposes the drivers for the hardware so you get easily use them.
+
('''Note''':  Draw the new diagrams with [http://engineersofthecorn.blogspot.com/2012/06/fritzing-part-for-beaglebone.html this].)
 +
 
 +
The easiest way to do general purpose I/O (gpio) on the Beagle is through a terminal window and a shell prompt. In Linux, almost everything is treated as a file, even things that aren't files. In our class we'll use a virtual file system called '''sysfs'''.  sysfs exposes the drivers for the hardware so you can easily use them.
 +
 
 +
Try this, open a terminal and type:
 +
 
 +
beagle$ '''cd /sys'''
 +
beagle$ '''ls -F'''
 +
block/  bus/  class/  dev/  devices/  firmware/  fs/  kernel/  module/  power/
  
Try this:
 
<pre>
 
$ cd /sys
 
$ ls -F
 
block/  bus/  class/  dev/  devices/  firmware/  fs/  kernel/  module/  power/
 
</pre>
 
 
Here we see several directories that represent hardware we can control. Explore a bit and see what you find.
 
Here we see several directories that represent hardware we can control. Explore a bit and see what you find.
  
 
Now try:
 
Now try:
<pre>
 
$ cd /sys/class
 
$ ls -F
 
bccat/      hwmon/        mtd/            scsi_disk/    usb_device/
 
bdi/        i2c-adapter/  net/            scsi_generic/  usbmon/
 
block/      i2c-dev/      omap-previewer/  scsi_host/    vc/
 
bluetooth/  input/        omap-resizer/    sound/        video4linux/
 
bsg/        leds/        pvr/            spi_master/    vtconsole/
 
display/    mdio_bus/    regulator/      spidev/
 
firmware/  mem/          rfkill/          thermal/
 
gpio/      misc/        rtc/            tty/
 
graphics/  mmc_host/    scsi_device/    ubi/
 
</pre>
 
Explore some.  What do you find?  In '''graphics''' you will see the 3 frame buffers supported by the processor.  In '''sound''' you'll see the [http://www.alsa-project.org/main/index.php/Main_Page alsa] sound devices.
 
  
=== Reading the Keyboard and Mouse ===
+
beagle$ '''cd /sys/class'''
Try this:
+
beagle$ '''ls -F'''
<pre>
+
backlight/  firmware/    lcd/      mtd/          scsi_disk/  ubi/
$ cd /sys/class/input
+
bdi/        gpio/        leds/      net/          scsi_host/  udc/
$ ls -F
+
block/      graphics/    mbox/      power_supply/  sound/      uio/
$ evtest event2
+
bluetooth/  hwmon/        mdio_bus/  regulator/    spi_master/  usbmon/
Hit ctrl-C to stop
+
bsg/        i2c-adapter/  mem/      rfkill/        spidev/      vc/
</pre>
+
dma/        i2c-dev/      misc/      rtc/          thermal/    vtconsole/
Now move your mouse around, or try you keyboardMy mouse is plugged into the bottom left USB port and event2 responds to itWhere do your keyboard and mouse appear?
+
drm/        input/        mmc_host/  scsi_device/  tty/        watchdog/
 +
 
 +
Explore some.  What do you find?  In '''graphics''' you will see the frame buffer supported by the processor.  In '''sound''' you'll see the [http://www.alsa-project.org/main/index.php/Main_Page alsa] sound devices.
 +
 
 +
== Flashing the user LEDs ==
 +
 
 +
The Beagle Black has four user LEDS, '''usr0''' - '''usr3''', that you can control. Try this:
 +
 
 +
beagle$ '''cd /sys/class/leds'''
 +
beagle$ '''ls -1F'''
 +
beaglebone:green:usr0@
 +
beaglebone:green:usr1@
 +
beaglebone:green:usr2@
 +
beaglebone:green:usr3@
 +
 
 +
Here you see the directories for controlling each of the user LEDs. By default, usr0 flashes a heartbeat pattern and usr1 flashes when the micro SD card is accessedLet's control usr0.
 +
 
 +
  beagle$ '''cd beagleboard\:green\:usr0'''
 +
beagle$ '''ls -F'''
 +
brightness  device@  max_brightness  power/  subsystem@  trigger  uevent
  
=== Flashing the LEDs ===
 
The Beagle has a '''user0''' and '''user1''' LED that you can control. Try this:
 
<pre>
 
$ cd /usr/class/leds
 
$ ls -F
 
beagleboard::pmu_stat@  beagleboard::usr0@  beagleboard::usr1@
 
</pre>
 
Here you see the directories for controlling each of the usr LEDs. By default, usr0 flashes a heartbeat patter and usr1 flashes when the micro SD card is accessed.  Let's control usr0.
 
<pre>
 
$ cd beagleboard::usr0
 
$ ls -F
 
brightness  device@  max_brightness  power/  subsystem@  trigger  uevent
 
</pre>
 
 
See what's in '''brightness''', '''max_brightness''' and '''trigger''' by using the <code>cat</code> command.  For example:
 
See what's in '''brightness''', '''max_brightness''' and '''trigger''' by using the <code>cat</code> command.  For example:
<pre>
+
 
$ cat trigger
+
beagle$ '''cat trigger'''
none nand-disk mmc0 [heartbeat]
+
none nand-disk mmc0 mmc1 timer oneshot [heartbeat] backlight gpio cpu0 default-on transient
</pre>
+
 
This shows trigger can have 4 values.  The present value is '''heartbeat'''.  Check the LED, is the beating?  You can stop the heartbeat via:
+
This shows trigger can have many values.  The present value is '''heartbeat'''.  Check the LED, is it beating?  You can stop the heartbeat via:
<pre>
+
 
$ echo none > trigger
+
beagle$ '''echo none > trigger'''
$ cat trigger
+
beagle$ '''cat trigger'''
[none] nand-disk mmc0 heartbeat  
+
[none] nand-disk mmc0 mmc1 timer oneshot heartbeat backlight gpio cpu0 default-on transient
</pre>
+
 
 
Did it stop beating?  You can now turn it on and off with:
 
Did it stop beating?  You can now turn it on and off with:
<pre>
+
 
$ echo 1 > brightness
+
beagle$ '''echo 1 > brightness'''
$ echo 0 > brightness
+
beagle$ '''echo 0 > brightness'''
</pre>
+
 
 
Is it responding correctly?
 
Is it responding correctly?
 +
 +
The Bone has more trigger options.  Try:
 +
 +
beagle$ '''cat trigger'''
 +
[none] nand-disk mmc0 mmc1 timer oneshot heartbeat backlight gpio cpu0 default-on transient
 +
beagle$ '''echo timer > trigger'''
 +
beagle$ '''ls -F'''
 +
brightness  delay_on  max_brightness  subsystem@  uevent
 +
delay_off  device@  power/          trigger
 +
beagle$ '''echo 100 > delay_on'''
 +
beagle$ '''echo 900 > delay_off'''
 +
 +
What does this do?
 +
 +
== Adding your own LED ==
 +
(If you need to brush up on wiring, check out Adafruit's [http://learn.adafruit.com/category/beaglebone BeagleBone] site.)
 +
 +
It's not hard to use the gpio pins to control your own LED. All you need is an LED and a 220&Omega; resistor. Here's a picture of how it's wired. We are just doing the LED at the top of the breadboard for now.
 +
 +
[[File:Bone gpio.JPG|300px]]
 +
[[File:BoneGPIO.png|300px]]
 +
 +
So how do you know where to connect it?  The BeagleBone [https://github.com/CircuitCo/BeagleBone-Black/blob/master/BBB_SRM.pdf?raw=true System Reference Manual] has the details.  Figure 45 on page 74 shows:
 +
 +
[[File:BlackHeaders.jpg]]
 +
 +
There at two expansion headers, P8 and P9.  Look at the bottom of the left header and you'll see it's labeled '''P9'''. Table 11 on page 78 shows the pinout for P9.
 +
 +
[[File:HeaderP9.jpg|800px]]
 +
 +
On the first photo above you can see that pin 1 (Ground) is wired to the '''-''' bus and pin 3 (3.3V) is wired to the '''+''' bus. The 220&Omega; resistor is wired to the '''-''' bus and the other end is attached to the negative lead of the LED.  The positive lead is attached to pin 12 which, as shown in Table 11, is attached to '''gpio1_28'''.  The gpio pins are in banks of 32 each, so to find the gpio number to use on the Beagle, use 1*32+28='''60'''.  Here's how you turn it on
 +
 +
beagle$ '''cd /sys/class/gpio'''
 +
beagle$ '''ls -F'''
 +
export  gpiochip0@  gpiochip32@  gpiochip64@  gpiochip96@  unexport
 +
 +
Presently no gpio pins are visible.  You need to tell it which pin to export
 +
 +
beagle$ '''echo 60 > export'''
 +
beagle$ '''ls -F'''
 +
export  gpio60@  gpiochip0@  gpiochip32@  gpiochip64@  gpiochip96@  unexport
 +
 +
Notice '''gpio60''' has appeared.  All we need to do is tell it which direction and then turn it on.
 +
 +
beagle$ '''cd gpio60'''
 +
beagle$ '''echo out > direction'''
 +
beagle$ '''echo 1 > value'''
 +
 +
Your LED should be on!  When you are done you can unexport the pin and it will disappear.
 +
beagle$ '''cd ..'''
 +
beagle$ '''echo 60 > unexport'''
 +
 +
== Reading a switch ==
 +
 +
Now that you have an LED working, wiring in a switch is easy.  The picture above shows a push button switch wired in at the bottom of the P9 header.  Attach the '''+''' bus to one pole on the switch with a wire.  The other end of the switch is attached to pin 42 which is '''gpio0_7'''.
 +
 +
Based on what you saw above, show how to read the switch.
 +
 +
Once you have the switch and LED working you can use the following scripts to play with them.
 +
 +
beagle$ '''cd ~/exercises/gpio'''
 +
beagle$ '''./togglegpio.sh 60 0.1'''
 +
 +
The LED should be blinking on and off.
 +
 +
beagle$ '''./readgpio.sh 7'''
 +
 +
Push the pushbutton and see what happens.
 +
 +
How can this work without a pulldown resistor? It turns out the Bone has an internal pulldown (and up) resistor that can be software enabled.  We'll discuss how when we cover device trees.
 +
 +
=== Challenge ===
 +
 +
* Can you modify the scripts above to read the switch and turn the LED on and off?
 +
 +
== Assignment: gpio from the shell ==
 +
 +
=== <span style="color:green;">Measuring a gpio pin on an Oscilloscope</span> ===
 +
 +
Get an oscilloscope so you can measure the output of your gpio pins.  Run
 +
beagle$ '''./togglegpio.sh 60 0.1'''
 +
 +
and answer the following questions about gpio measurements.
 +
 +
# What's the min and max voltage? 
 +
# What period is it? 
 +
# How close is it to 100ms? 
 +
# Why do they differ?
 +
# Run '''htop''' and see how much processor you are using.
 +
# Try different values for the sleep time (2nd argument). What's the shortest period you can get? Make a table of the values you try and the corresponding period and processor usage.
 +
# How stable is the period? 
 +
# Try launching something like '''mplayer'''. How stable is the period?
 +
# Try cleaning up togglegpio.sh and removing unneeded lines.  Does it impact the period?
 +
# togglegpio uses bash (first line in file).  Try using sh.  Is the period shorter?
 +
# What's the shortest period you can get?
 +
 +
=== Toggling the LEDs ===
 +
 +
Modify togglegpio.sh (call it toggleLED) to toggle the on-board LEDs.  Can you get the LED to appear to dim by changing the duty cycle of the toggling?
 +
 +
=== Count the User Button Presses ===
 +
 +
Write a shell script that displays a count of the number of times the Button has been pressed.
 +
 +
=== Copy gpio 7 to gpio 60===
 +
 +
Write a shell script that copies the value of gpio pin 7 (your switch) to gpio pin 60 (Your LED).  How much CPU time does it take?  What's the delay from the time the input changes until the output changes?  How constant is the delay?
 +
 +
You may need to get a function generator and set it to a square wave (0 to 3.3V) and attach it to pin 7 and attached an oscilloscope to pin 60.
 +
 
== Resources ==
 
== Resources ==
  
Line 79: Line 185:
 
# [https://groups.google.com/forum/?hl=en#!msg/beagleboard/20rM-r8C2YY/hVZiN2ahI8YJ Here] is a posting in the Beagle Google group about gpio.
 
# [https://groups.google.com/forum/?hl=en#!msg/beagleboard/20rM-r8C2YY/hVZiN2ahI8YJ Here] is a posting in the Beagle Google group about gpio.
 
# [http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/gpio.txt;h=36af58eba136bac198ea3b1f33f34236be9ce5df;hb=HEAD Here] is some information about gpio from the kernel point of view.
 
# [http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/gpio.txt;h=36af58eba136bac198ea3b1f33f34236be9ce5df;hb=HEAD Here] is some information about gpio from the kernel point of view.
 +
# [http://wiki.gumstix.org/index.php?title=GPIO_Event_Driver Here] is some info on a GPIO Event Driver
 +
# [https://www.ridgerun.com/developer/wiki/index.php/How_to_use_GPIO_signals Here] is info on how to set '''edge''' to falling and poll() the pin.
 +
# [http://www.kernel.org/doc/Documentation/gpio.txt Here] is the kernel Documentation on gpio.
 +
 +
{{YoderFoot}}

Revision as of 08:28, 12 September 2013

thumb‎ Embedded Linux Class by Mark A. Yoder


3.8 Kernel

This page is for the Bone (Black or White) running the 3.8 Kernel. See EBC_Exercise_10_Flashing_an_LED_-_xM_WhiteBone for the White Bone or xM running 3.2.

The "Hello World" program is the traditional first program for many classes. Flashing an LED is the embedded equivalent. Here we will explore a few ways to flash an LED on the Beagle and explore General Purpose I/O (gpio) along the way. These calls will be done from the command line of the Beagle, so there is no need for the host computer.

gpio via the Shell Command Line and sysfs

(Note: Draw the new diagrams with this.)

The easiest way to do general purpose I/O (gpio) on the Beagle is through a terminal window and a shell prompt. In Linux, almost everything is treated as a file, even things that aren't files. In our class we'll use a virtual file system called sysfs. sysfs exposes the drivers for the hardware so you can easily use them.

Try this, open a terminal and type:

beagle$ cd /sys
beagle$ ls -F
block/  bus/  class/  dev/  devices/  firmware/  fs/  kernel/  module/  power/

Here we see several directories that represent hardware we can control. Explore a bit and see what you find.

Now try:

beagle$ cd /sys/class
beagle$ ls -F
backlight/  firmware/     lcd/       mtd/           scsi_disk/   ubi/
bdi/        gpio/         leds/      net/           scsi_host/   udc/
block/      graphics/     mbox/      power_supply/  sound/       uio/
bluetooth/  hwmon/        mdio_bus/  regulator/     spi_master/  usbmon/
bsg/        i2c-adapter/  mem/       rfkill/        spidev/      vc/
dma/        i2c-dev/      misc/      rtc/           thermal/     vtconsole/
drm/        input/        mmc_host/  scsi_device/   tty/         watchdog/

Explore some. What do you find? In graphics you will see the frame buffer supported by the processor. In sound you'll see the alsa sound devices.

Flashing the user LEDs

The Beagle Black has four user LEDS, usr0 - usr3, that you can control. Try this:

beagle$ cd /sys/class/leds
beagle$ ls -1F
beaglebone:green:usr0@
beaglebone:green:usr1@
beaglebone:green:usr2@
beaglebone:green:usr3@

Here you see the directories for controlling each of the user LEDs. By default, usr0 flashes a heartbeat pattern and usr1 flashes when the micro SD card is accessed. Let's control usr0.

beagle$ cd beagleboard\:green\:usr0
beagle$ ls -F
brightness  device@  max_brightness  power/  subsystem@  trigger  uevent

See what's in brightness, max_brightness and trigger by using the cat command. For example:

beagle$ cat trigger
none nand-disk mmc0 mmc1 timer oneshot [heartbeat] backlight gpio cpu0 default-on transient

This shows trigger can have many values. The present value is heartbeat. Check the LED, is it beating? You can stop the heartbeat via:

beagle$ echo none > trigger
beagle$ cat trigger
[none] nand-disk mmc0 mmc1 timer oneshot heartbeat backlight gpio cpu0 default-on transient 

Did it stop beating? You can now turn it on and off with:

beagle$ echo 1 > brightness
beagle$ echo 0 > brightness

Is it responding correctly?

The Bone has more trigger options. Try:

beagle$ cat trigger
[none] nand-disk mmc0 mmc1 timer oneshot heartbeat backlight gpio cpu0 default-on transient 
beagle$ echo timer > trigger
beagle$ ls -F
brightness  delay_on  max_brightness  subsystem@  uevent
delay_off   device@   power/          trigger
beagle$ echo 100 > delay_on
beagle$ echo 900 > delay_off

What does this do?

Adding your own LED

(If you need to brush up on wiring, check out Adafruit's BeagleBone site.)

It's not hard to use the gpio pins to control your own LED. All you need is an LED and a 220Ω resistor. Here's a picture of how it's wired. We are just doing the LED at the top of the breadboard for now.

Bone gpio.JPG BoneGPIO.png

So how do you know where to connect it? The BeagleBone System Reference Manual has the details. Figure 45 on page 74 shows:

BlackHeaders.jpg

There at two expansion headers, P8 and P9. Look at the bottom of the left header and you'll see it's labeled P9. Table 11 on page 78 shows the pinout for P9.

HeaderP9.jpg

On the first photo above you can see that pin 1 (Ground) is wired to the - bus and pin 3 (3.3V) is wired to the + bus. The 220Ω resistor is wired to the - bus and the other end is attached to the negative lead of the LED. The positive lead is attached to pin 12 which, as shown in Table 11, is attached to gpio1_28. The gpio pins are in banks of 32 each, so to find the gpio number to use on the Beagle, use 1*32+28=60. Here's how you turn it on

beagle$ cd /sys/class/gpio
beagle$ ls -F
export  gpiochip0@  gpiochip32@  gpiochip64@  gpiochip96@  unexport

Presently no gpio pins are visible. You need to tell it which pin to export

beagle$ echo 60 > export
beagle$ ls -F
export  gpio60@  gpiochip0@  gpiochip32@  gpiochip64@  gpiochip96@  unexport

Notice gpio60 has appeared. All we need to do is tell it which direction and then turn it on.

beagle$ cd gpio60
beagle$ echo out > direction
beagle$ echo 1 > value

Your LED should be on! When you are done you can unexport the pin and it will disappear.

beagle$ cd ..
beagle$ echo 60 > unexport

Reading a switch

Now that you have an LED working, wiring in a switch is easy. The picture above shows a push button switch wired in at the bottom of the P9 header. Attach the + bus to one pole on the switch with a wire. The other end of the switch is attached to pin 42 which is gpio0_7.

Based on what you saw above, show how to read the switch.

Once you have the switch and LED working you can use the following scripts to play with them.

beagle$ cd ~/exercises/gpio
beagle$ ./togglegpio.sh 60 0.1

The LED should be blinking on and off.

beagle$ ./readgpio.sh 7

Push the pushbutton and see what happens.

How can this work without a pulldown resistor? It turns out the Bone has an internal pulldown (and up) resistor that can be software enabled. We'll discuss how when we cover device trees.

Challenge

  • Can you modify the scripts above to read the switch and turn the LED on and off?

Assignment: gpio from the shell

Measuring a gpio pin on an Oscilloscope

Get an oscilloscope so you can measure the output of your gpio pins. Run

beagle$ ./togglegpio.sh 60 0.1

and answer the following questions about gpio measurements.

  1. What's the min and max voltage?
  2. What period is it?
  3. How close is it to 100ms?
  4. Why do they differ?
  5. Run htop and see how much processor you are using.
  6. Try different values for the sleep time (2nd argument). What's the shortest period you can get? Make a table of the values you try and the corresponding period and processor usage.
  7. How stable is the period?
  8. Try launching something like mplayer. How stable is the period?
  9. Try cleaning up togglegpio.sh and removing unneeded lines. Does it impact the period?
  10. togglegpio uses bash (first line in file). Try using sh. Is the period shorter?
  11. What's the shortest period you can get?

Toggling the LEDs

Modify togglegpio.sh (call it toggleLED) to toggle the on-board LEDs. Can you get the LED to appear to dim by changing the duty cycle of the toggling?

Count the User Button Presses

Write a shell script that displays a count of the number of times the Button has been pressed.

Copy gpio 7 to gpio 60

Write a shell script that copies the value of gpio pin 7 (your switch) to gpio pin 60 (Your LED). How much CPU time does it take? What's the delay from the time the input changes until the output changes? How constant is the delay?

You may need to get a function generator and set it to a square wave (0 to 3.3V) and attach it to pin 7 and attached an oscilloscope to pin 60.

Resources

  1. Here is wh1ts article on flashing an LED. It is referenced in the readgpio file that comes on the Beagle.
  2. This Make magazine article has a few more details.
  3. Here in a gpio reference for Linux in general. It includes sample 'C' code for flashing at 1 Hz.
  4. Here is a posting in the Beagle Google group about gpio.
  5. Here is some information about gpio from the kernel point of view.
  6. Here is some info on a GPIO Event Driver
  7. Here is info on how to set edge to falling and poll() the pin.
  8. Here is the kernel Documentation on gpio.




thumb‎ Embedded Linux Class by Mark A. Yoder