Difference between revisions of "GPIOlib"

From ArmadeusWiki
Jump to: navigation, search
(Get APFxxDev i.MX switch status)
(Datasheet GPIO number correspondance)
 
(29 intermediate revisions by 5 users not shown)
Line 1: Line 1:
  
 +
 +
==Introduction==
 
With recent Linux kernel (> 2.6.3x), there is an abstraction layer meant to ease GPIO usage: ''gpiolib''. We will explain here how to use it.
 
With recent Linux kernel (> 2.6.3x), there is an abstraction layer meant to ease GPIO usage: ''gpiolib''. We will explain here how to use it.
 +
 +
For this purpose we will use the user LED and button of the button to let you operate the GPIO feature without any hardware modification.
 +
 +
Linux provides specific drivers for [[GPIO_LEDS|LEDs]] and [[GPIO_keys|switches]] - as explained in the [http://www.kernel.org/doc/Documentation/gpio.txt Linux documentation of the  GPIO] - "that should be used instead of talking directly to the GPIOs; they integrate with kernel frameworks better than your userspace code could."
 +
 +
== Datasheet GPIO number correspondance ==
 +
 +
Linux manages GPIO with a simple number, but under datasheet GPIO are referenced with port number (or letter) and pin number. To convert in single integer, use following formula :
 +
 +
* [[APF9328]]: TODO.
 +
* [[APF27]]: (port letter (A=0, B=1, ...) x 32 ) + pin number.
 +
** Example : '''PF14''' = (5x32) + 14 = '''174'''
 +
* [[APF28]]: (Bank number x 32) + pin number
 +
** Example : '''GPIO_0_21''' = (0x32) + 21 = '''21'''
 +
* [[APF51]], [[APF6]], [[OPOS6UL]] and [[OPOS6UL_SP]]: ((Bank number - 1) x 32) + pin number
 +
** Example : '''GPIO1_2''' = (0 x 32) + 2 = '''2'''
  
 
==Installation==
 
==Installation==
* If not already done:
+
* Configure Linux kernel:
 
<pre class="host">
 
<pre class="host">
$ make linux26-menuconfig
+
$ make linux-menuconfig
 
</pre>
 
</pre>
 +
* If not already done, enable the sysfs interface of the GPIOlib:
 
<pre class="config">
 
<pre class="config">
 
Device Drivers  --->
 
Device Drivers  --->
Line 12: Line 31:
 
         [*]  /sys/class/gpio/... (sysfs interface)
 
         [*]  /sys/class/gpio/... (sysfs interface)
 
</pre>
 
</pre>
 +
* In order to test the GPIOlib with the user LED and SWITCH of the board you will have to disable the [[GPIO_keys]] and [[GPIO_LEDS]] drivers that are the regular driver for such device.
 +
<pre class="config">
 +
Device Drivers  --->
 +
    Input device support  --->
 +
        [*]  Keyboards  --->
 +
            < >  GPIO Buttons (be sure GPIO Buttons is unchecked)
 +
</pre>
 +
<pre class="config">
 +
Device Drivers  --->
 +
    [ ] LED Support  --->  (be sure "LED Support" or "GPIO connected LEDs" (hereafter) is unchecked)
 +
        < >  LED Support for GPIO connected LEDs
 +
</pre>
 +
* On Linux version supporting device tree (ex [[OPOS6UL]]), this configuration has to be done in your devt board ''.dts'' description file and not by selecting drivers (ex ''bsp/buildroot/output/build/linux-4.8.10/arch/arm/boot/dts/imx6ul-opos6uldev.dts'').
 +
* Save your new configuration and rebuild your kernel (if needed):
 
<pre class="host">
 
<pre class="host">
 
$ make
 
$ make
 
</pre>
 
</pre>
* reflash your kernel (if needed)
+
* and reflash your kernel image (if needed) or your .dtb
  
 
==Usage==
 
==Usage==
Line 21: Line 54:
 
* Find the GPIO number connected to the LED, eg:
 
* Find the GPIO number connected to the LED, eg:
 
** for APF27Dev: '''PF14 ->''' PortF (n°6) pin 14 -> (6-1)*32 + 14 -> GPIO n°'''174'''
 
** for APF27Dev: '''PF14 ->''' PortF (n°6) pin 14 -> (6-1)*32 + 14 -> GPIO n°'''174'''
** for APF51Dev: GPIO1_2 -> Port 1 pin 2 -> GPIO n° 2
+
** for APF51Dev/APF6Dev: GPIO1_2 -> Port 1 pin 2 -> GPIO n° 2
 +
** for APF28Dev: Bank 0, pin 21 -> GPIO n° 21 (0*32 + 21)
 +
** for [[OPOS6ULDev]]: Bank 3, pin 4 -> GPIO n° 68
 
* Define envt variable (for portability):
 
* Define envt variable (for portability):
 
<pre class="apf">
 
<pre class="apf">
 
# export LED=174    (APF27Dev)
 
# export LED=174    (APF27Dev)
 
or
 
or
# export LED=2   (APF51Dev)
+
# export LED=2     (APF51Dev/APF6Dev)
 +
or
 +
# export LED=21    (APF28Dev)
 +
or
 +
# export LED=68    (OPOS6ULDev)
 
</pre>
 
</pre>
 
* Ask kernel to export the GPIO:
 
* Ask kernel to export the GPIO:
Line 54: Line 93:
 
===Get APFxxDev i.MX switch status===
 
===Get APFxxDev i.MX switch status===
 
* Find the GPIO number connected to the switch, eg:
 
* Find the GPIO number connected to the switch, eg:
** for APF27Dev: '''PF15 ->''' PortF (n°6) pin 15 -> (6-1)*32 + 15 -> '''GPIO n°175'''
+
** for APF27Dev: '''PF13 ->''' PortF (n°6) pin 13 -> (6-1)*32 + 13 -> '''GPIO n°173'''
** for APF51Dev: '''GPIO1_3''' -> Port 1 pin 3 -> '''GPIO n°3''' ((1-1)*32 + 3)
+
** for APF51Dev/APF6Dev: '''GPIO1_3''' -> Port 1 pin 3 -> '''GPIO n°3''' ((1-1)*32 + 3)
 +
** for APF6Dev: '''GPIO1_9''' -> '''GPIO n°9'''
 +
** for APF28Dev: Bank 0, pin 17 -> GPIO n° 17 (0*32 + 17)
 +
** for OPOS6ULDev: GPIO2_11 -> GPIO n° 43
 
* Define envt variable (for portability):
 
* Define envt variable (for portability):
 
<pre class="apf">
 
<pre class="apf">
# export SWITCH=175   (APF27Dev)
+
# export SWITCH=173   (APF27Dev)
 
or
 
or
# export SWITCH=3   (APF51Dev)
+
# export SWITCH=3     (APF51Dev)
 +
or
 +
# export SWITCH=9      (APF6Dev)
 +
or
 +
# export SWITCH=17    (APF28Dev)
 +
or
 +
# export SWITCH=33    (OPOS6ULDev)
 
</pre>
 
</pre>
 
* Ask kernel to export the GPIO:
 
* Ask kernel to export the GPIO:
Line 90: Line 138:
 
none
 
none
 
# echo both > /sys/class/gpio/gpio$SWITCH/edge
 
# echo both > /sys/class/gpio/gpio$SWITCH/edge
 +
</pre>
 +
 +
== AsGpio ==
 +
 +
An example of AsDevices usage for GPIO in C can be found in armadeus BSP. To compile it:
 +
 +
<pre class="host">
 +
$ cd target/demos/toggle_gpio
 +
$ make
 +
</pre>
 +
 +
==Tips==
 +
* [[Linux_Debug#Using_DebugFS|Show already allocated GPIOS]]
 +
* ''/usr/bin/gpio_helpers.sh'' script contains 2 functions that can help usage of output GPIOs: gpio_direction_output() and gpio_set_value(). For example to set GPIO N°12 as output and set it to 0:
 +
<pre class="apf">
 +
# source /usr/bin/gpio_helpers.sh
 +
# gpio_direction_output 12 0
 
</pre>
 
</pre>
  
 
==Links==
 
==Links==
 
* http://www.kernel.org/doc/Documentation/gpio.txt
 
* http://www.kernel.org/doc/Documentation/gpio.txt
 +
* [http://bec-systems.com/site/281/how-to-implement-an-interrupt-driven-gpio-input-in-linux how to implement an interrupt driven gpio input in linux]

Latest revision as of 09:46, 29 April 2019


Introduction

With recent Linux kernel (> 2.6.3x), there is an abstraction layer meant to ease GPIO usage: gpiolib. We will explain here how to use it.

For this purpose we will use the user LED and button of the button to let you operate the GPIO feature without any hardware modification.

Linux provides specific drivers for LEDs and switches - as explained in the Linux documentation of the GPIO - "that should be used instead of talking directly to the GPIOs; they integrate with kernel frameworks better than your userspace code could."

Datasheet GPIO number correspondance

Linux manages GPIO with a simple number, but under datasheet GPIO are referenced with port number (or letter) and pin number. To convert in single integer, use following formula :

  • APF9328: TODO.
  • APF27: (port letter (A=0, B=1, ...) x 32 ) + pin number.
    • Example : PF14 = (5x32) + 14 = 174
  • APF28: (Bank number x 32) + pin number
    • Example : GPIO_0_21 = (0x32) + 21 = 21
  • APF51, APF6, OPOS6UL and OPOS6UL_SP: ((Bank number - 1) x 32) + pin number
    • Example : GPIO1_2 = (0 x 32) + 2 = 2

Installation

  • Configure Linux kernel:
$ make linux-menuconfig
  • If not already done, enable the sysfs interface of the GPIOlib:
Device Drivers  --->
    -*- GPIO Support  --->
        [*]   /sys/class/gpio/... (sysfs interface)
  • In order to test the GPIOlib with the user LED and SWITCH of the board you will have to disable the GPIO_keys and GPIO_LEDS drivers that are the regular driver for such device.
Device Drivers  --->
    Input device support  --->
        [*]   Keyboards  --->
            < >   GPIO Buttons (be sure GPIO Buttons is unchecked)
 
Device Drivers  --->
    [ ] LED Support  --->  (be sure "LED Support" or "GPIO connected LEDs" (hereafter) is unchecked)
         < >   LED Support for GPIO connected LEDs
 
  • On Linux version supporting device tree (ex OPOS6UL), this configuration has to be done in your devt board .dts description file and not by selecting drivers (ex bsp/buildroot/output/build/linux-4.8.10/arch/arm/boot/dts/imx6ul-opos6uldev.dts).
  • Save your new configuration and rebuild your kernel (if needed):
$ make
  • and reflash your kernel image (if needed) or your .dtb

Usage

Blink APFxxDev i.MX LED

  • Find the GPIO number connected to the LED, eg:
    • for APF27Dev: PF14 -> PortF (n°6) pin 14 -> (6-1)*32 + 14 -> GPIO n°174
    • for APF51Dev/APF6Dev: GPIO1_2 -> Port 1 pin 2 -> GPIO n° 2
    • for APF28Dev: Bank 0, pin 21 -> GPIO n° 21 (0*32 + 21)
    • for OPOS6ULDev: Bank 3, pin 4 -> GPIO n° 68
  • Define envt variable (for portability):
# export LED=174    (APF27Dev)
or
# export LED=2      (APF51Dev/APF6Dev)
or
# export LED=21     (APF28Dev)
or
# export LED=68     (OPOS6ULDev)
  • Ask kernel to export the GPIO:
# echo $LED > /sys/class/gpio/export
  • Access functions are created:
# ls /sys/class/gpio/gpio$LED/
active_low  edge        subsystem   value
direction   power       uevent
  • Check GPIO direction and put in output:
# cat /sys/class/gpio/gpio$LED/direction
in
# echo out > /sys/class/gpio/gpio$LED/direction
# cat /sys/class/gpio/gpio$LED/direction
out
  • Play with GPIO value to blink LED:
# echo 1 > /sys/class/gpio/gpio$LED/value
# echo 0 > /sys/class/gpio/gpio$LED/value

Get APFxxDev i.MX switch status

  • Find the GPIO number connected to the switch, eg:
    • for APF27Dev: PF13 -> PortF (n°6) pin 13 -> (6-1)*32 + 13 -> GPIO n°173
    • for APF51Dev/APF6Dev: GPIO1_3 -> Port 1 pin 3 -> GPIO n°3 ((1-1)*32 + 3)
    • for APF6Dev: GPIO1_9 -> GPIO n°9
    • for APF28Dev: Bank 0, pin 17 -> GPIO n° 17 (0*32 + 17)
    • for OPOS6ULDev: GPIO2_11 -> GPIO n° 43
  • Define envt variable (for portability):
# export SWITCH=173    (APF27Dev)
or
# export SWITCH=3      (APF51Dev)
or
# export SWITCH=9      (APF6Dev)
or
# export SWITCH=17     (APF28Dev)
or
# export SWITCH=33     (OPOS6ULDev)
  • Ask kernel to export the GPIO:
# echo $SWITCH > /sys/class/gpio/export
  • Access functions are created:
# ls /sys/class/gpio/gpio$SWITCH/
active_low  edge        subsystem   value
direction   power       uevent
  • Check GPIO direction and put in output:
# cat /sys/class/gpio/gpio$SWITCH/direction
in
  • Get switch status:
# cat /sys/class/gpio/gpio$SWITCH/value
1    (released)
...
# cat /sys/class/gpio/gpio$SWITCH/value
0    (pressed)
  • Block until an event occur:
# cat /sys/class/gpio/gpio$SWITCH/edge
none
# echo both > /sys/class/gpio/gpio$SWITCH/edge

AsGpio

An example of AsDevices usage for GPIO in C can be found in armadeus BSP. To compile it:

$ cd target/demos/toggle_gpio
$ make

Tips

  • Show already allocated GPIOS
  • /usr/bin/gpio_helpers.sh script contains 2 functions that can help usage of output GPIOs: gpio_direction_output() and gpio_set_value(). For example to set GPIO N°12 as output and set it to 0:
# source /usr/bin/gpio_helpers.sh
# gpio_direction_output 12 0

Links