Please note that User Registration has been temporarily disabled due to a recent increase in automated registrations. If anyone needs an account, please request one here: RequestAccount. Thanks for your patience!--Wmat (talk)
Please email User:Wmat if you experience any issues with the Request Account form.

Difference between revisions of "EBC Exercise 11 gpio Polling and Interrupts"

From eLinux.org
Jump to: navigation, search
m
(8 intermediate revisions by one other user not shown)
Line 1: Line 1:
 
[[Category:EmbeddedBeagleClass]]
 
[[Category:EmbeddedBeagleClass]]
 
[[Category:ECE497]]
 
[[Category:ECE497]]
 +
{{YoderHead}}
  
In the previous exercise ([[EBC Exercise 02 Flashing an LED]]) we saw how to interact with the general purpose I/O pins via the command shell and the sysfs files.  These are rather easy ways to work with gpio; however they tend to be slow and require a lot of the CPU.  In this exercise we explore using sysfs via C.  We also see how using interrupts can greatly reduce the CPU usage and increase our max output speed.
+
In the previous exercise ([[EBC Exercise 10 Flashing an LED]]) we saw how to interact with the general purpose I/O pins via the command shell and the sysfs files.  These are rather easy ways to work with gpio; however they tend to be slow and require a lot of the CPU.  In this exercise we explore using sysfs via C.  We also see how using interrupts can greatly reduce the CPU usage and increase our max output speed.
  
== gpio via C and sysfs ==
+
== <span style="color:green">gpio via C and sysfs </span>==
  
Since <code>/sys/class/gpio/gpio130/value</code> is just a file, we can read and write it from a C program just as easily as from the shell.  [http://www.avrfreaks.net/wiki/index.php/Documentation:Linux/GPIO#Example_of_GPIO_access_from_within_a_C_program Here] is a nice example of how it's done. I've cleaned it up a bit and put a copy called '''togglegpio.c''' [http://www.rose-hulman.edu/~yoder/Beagle/exercises/ here]. Get a copy and look it over.  It' presently hardwired to use gpio130.  Later you will get to make it work with any port.
+
Since <code>/sys/class/gpio/gpio130/value</code> is just a file, we can read and write it from a C program just as easily as from the shell.  [http://www.avrfreaks.net/wiki/index.php/Documentation:Linux/GPIO#Example_of_GPIO_access_from_within_a_C_program Here] is a nice example of how it's done. I've cleaned it up a bit and put a copy called '''togglegpio.c''' in '''exercises/gpio'''. If your git repository is set up just:
 +
beagle$ '''cd exercises'''
 +
beagle$ '''git pull'''
 +
beagle$ '''cd gpio'''
 +
beagle$ '''gedit togglegpio.c &'''
 +
(Follow the instructions [[EBC_Exercise_01a_Getting_Exercise_Support_Materials | here]] if you aren't set up for git.)
 +
 
 +
It's presently hardwired to use gpio130.  Later you will get to make it work with any port.
  
 
# Compile and run it.  Does the correct waveform appear on the oscilloscope?   
 
# Compile and run it.  Does the correct waveform appear on the oscilloscope?   
 
# Use '''htop''' to measure the CPU usage.
 
# Use '''htop''' to measure the CPU usage.
 
# Try different periods.  Make a chart of the input period vs. the measured period vs. CPU usage.
 
# Try different periods.  Make a chart of the input period vs. the measured period vs. CPU usage.
 +
# How stable is the waveform?  Look at several cycles.  Are they always the same length.  Explain.
  
 
This program is really interrupt based.  When the '''usleep''' command is run, the process suspends until the correct time has elapsed.  Other processes are allowed to run.  When the time is up the CPU is interrupted and our process is allowed to continue.
 
This program is really interrupt based.  When the '''usleep''' command is run, the process suspends until the correct time has elapsed.  Other processes are allowed to run.  When the time is up the CPU is interrupted and our process is allowed to continue.
Line 24: Line 33:
 
Look over the example.  The first part should be familiar.  The new stuff starts [https://www.ridgerun.com/developer/wiki/index.php/How_to_use_GPIO_signals#GPIO_interrupts_from_user_space here]. It describes how to use the '''poll()''' command to wait until the gpio pin has changed. Your process will block (i.e. let other processes run) while poll() waits for an interupt to occur.  
 
Look over the example.  The first part should be familiar.  The new stuff starts [https://www.ridgerun.com/developer/wiki/index.php/How_to_use_GPIO_signals#GPIO_interrupts_from_user_space here]. It describes how to use the '''poll()''' command to wait until the gpio pin has changed. Your process will block (i.e. let other processes run) while poll() waits for an interupt to occur.  
  
I've put a modified copy of '''gpio-int-test.c''' [http://www.rose-hulman.edu/~yoder/Beagle/exercises/ here]. Get it.  Study it. Compile and run it.  You'll need to setup an input signal.  gpio4 is the User button.  Try it.  Does the program respond correctly?
+
I've put a modified copy of '''gpio-int-test.c''' in '''gpio'''. Get it.  Study it. Compile and run it.  You'll need to setup an input signal.  gpio4 is the User button.  Try it.  Does the program respond correctly?
  
 
== Assignments ==
 
== Assignments ==
  
=== Modify togglegpio.c ===
+
=== <span style="color:green">Modify togglegpio.c </span>===
  
 
# Modify togglegpio.c to take the gpio number.  
 
# Modify togglegpio.c to take the gpio number.  
Line 36: Line 45:
 
# What's the highest frequency you can see on the 'scope?
 
# What's the highest frequency you can see on the 'scope?
  
=== Modify gpio-int-test.c ===
+
===<span style="color:green"> Modify gpio-int-test.c </span>===
  
 
# Modify gpio-init-test.c to count the number of times the User button has been pressed.  Set '''edge''' to only count releases.
 
# Modify gpio-init-test.c to count the number of times the User button has been pressed.  Set '''edge''' to only count releases.
Line 43: Line 52:
 
# What's the highest frequency the output will track the input?  What's the CPU usage?
 
# What's the highest frequency the output will track the input?  What's the CPU usage?
 
# What's the delay from when the input changes to when the output changes?
 
# What's the delay from when the input changes to when the output changes?
 +
 +
{{YoderFoot}}

Revision as of 04:28, 18 September 2012

thumb‎ Embedded Linux Class by Mark A. Yoder


In the previous exercise (EBC Exercise 10 Flashing an LED) we saw how to interact with the general purpose I/O pins via the command shell and the sysfs files. These are rather easy ways to work with gpio; however they tend to be slow and require a lot of the CPU. In this exercise we explore using sysfs via C. We also see how using interrupts can greatly reduce the CPU usage and increase our max output speed.

gpio via C and sysfs

Since /sys/class/gpio/gpio130/value is just a file, we can read and write it from a C program just as easily as from the shell. Here is a nice example of how it's done. I've cleaned it up a bit and put a copy called togglegpio.c in exercises/gpio. If your git repository is set up just:

beagle$ cd exercises
beagle$ git pull
beagle$ cd gpio
beagle$ gedit togglegpio.c &

(Follow the instructions here if you aren't set up for git.)

It's presently hardwired to use gpio130. Later you will get to make it work with any port.

  1. Compile and run it. Does the correct waveform appear on the oscilloscope?
  2. Use htop to measure the CPU usage.
  3. Try different periods. Make a chart of the input period vs. the measured period vs. CPU usage.
  4. How stable is the waveform? Look at several cycles. Are they always the same length. Explain.

This program is really interrupt based. When the usleep command is run, the process suspends until the correct time has elapsed. Other processes are allowed to run. When the time is up the CPU is interrupted and our process is allowed to continue.

gpio via Interrupts

Next we want to write some code that will read one gpio pin and copy its value to another. We could modify togglegpio.c to continually read one pin and write it to another, but that would wither be slow at responding to changes (a usleep is used between reads), or it would take all the CPU time (always reading in case a change was made).

A better approach is to let the OS tell you when the input has changed. In a traditional microprocessor one would set up the input pin to interrupt the processor when its input value has changed. We'll do something similar here.

The folks at RidgeRun have a nice example of how this is done.

Look over the example. The first part should be familiar. The new stuff starts here. It describes how to use the poll() command to wait until the gpio pin has changed. Your process will block (i.e. let other processes run) while poll() waits for an interupt to occur.

I've put a modified copy of gpio-int-test.c in gpio. Get it. Study it. Compile and run it. You'll need to setup an input signal. gpio4 is the User button. Try it. Does the program respond correctly?

Assignments

Modify togglegpio.c

  1. Modify togglegpio.c to take the gpio number.
  2. Clean things up a bit and use the structure of gpio-int-test.c.
  3. Presently one parameter specifies both the on and off time. Modify the code so the on and off times are controlled separately.
  4. Add in interrupt handler (see gpio-int-test.c) to trap ctrl-C and close things properly.
  5. What's the highest frequency you can see on the 'scope?

Modify gpio-int-test.c

  1. Modify gpio-init-test.c to count the number of times the User button has been pressed. Set edge to only count releases.
  2. Copy gpio-init-test.c to gpioThru.c and modify it to copy the value of one port to another. You'll have to add code to open a second gpio port for writing (check gpio_set_dir).
  3. gpio 131 is attached to pin 19 of the Main Extension Header on the Beagle. Attach a function generator to this pin. Be sure to set the HiLevel to 1.8V and the LoLevel to 0. Does the output track the input?
  4. What's the highest frequency the output will track the input? What's the CPU usage?
  5. What's the delay from when the input changes to when the output changes?




thumb‎ Embedded Linux Class by Mark A. Yoder